自上次进度报告以来取得了不少进展!自上次进度报告以来,已有476 次提交。
你可以在https://github.com/rust-lang/rustc_codegen_cranelift/releases/tag/dev找到 cg_clif 的预编译版本,或者如果你想尝试,也可以在 rustc-codegen-cranelift-preview rustup 组件中找到。
过去 7 个月的成就
unwind
Cranelift 终于在 Linux 上实现了栈展开期间的清理支持。
一段历史:大约一年前,作为我的学士论文的一部分,我在 Cranelift 中实现了 unwind 支持。这大部分是可行的,然而,当我在完成论文写作后重新审视代码以将其上游化时,我发现有些情况下,寄存器分配器会在可以 unwind 的调用指令后插入移动操作,然后期望这些移动操作在跳转到调用指令的任何后继者之前执行。然而,在 unwind 时这是不可能的,因为 unwind 会直接从 unwind 调用跳转到异常处理程序块。我尝试了一些修复,但在 Cranelift 的寄存器分配器的限制下遇到了困难。此外,我忙于日常工作。快进到大约两个月前,Chris Fallin(Cranelift 主要部分的主要作者)开始在 Cranelift 中实现异常处理支持,在此过程中修复了我遇到的寄存器分配器的限制。总体设计与我的提议相似,尽管 Cranelift IR 扩展的细节比我之前提出的更优雅。在 Cranelift 方面进行了一些小的修复后,我能够将我论文中的 cg_clif 更改基于新引入的 Cranelift 更改进行 rebasing,这需要很少的努力。非常感谢 Chris 为 Cranelift 的 unwind 支持所做的工作!
在 cg_clif 中 unwind 的实际实现的概述可以在https://tweedegolf.nl/en/blog/157/exception-handling-in-rustc-codegen-cranelift找到。
cg_clif 中的 unwind 支持目前将默认保持禁用状态,等待对一些构建性能问题的调查。此外,它目前在 Windows 和 macOS 上不起作用。在 macOS 上,围绕 unwind 表的确切编码存在一些小的差异尚未实现。在 Windows 上添加支持将更加复杂。Windows 使用基于 funclets 的 SEH 而不是基于 landingpads 的 itanium unwind(.eh_frame
)进行 unwind。Cranelift 仅支持 landingpads。
- issue wasmtime#1677:在 unwind 期间支持清理
- bytecodealliance/rfcs#36:在 Wasmtime 中实现异常处理提议
- issue #1567:在 panic 时支持 unwind
- wasmtime#10485:Cranelift:在关键边缘块上删除块参数。(感谢 @cfallin!)
- wasmtime#10502:Cranelift:在调用站点的调用后删除返回值指令。(感谢 @cfallin!)
- wasmtime#10510:Cranelift:初始 try_call / try_call_indirect(异常)支持。(感谢 @cfallin!)
- wasmtime#10593:try_call 的一些修复
- wasmtime#10609:Cranelift:将异常处理程序元数据移动到调用站点。(我和 @cfallin )
- wasmtime#10702:在 arm64 存在 try_call 的情况下避免破坏所有浮点寄存器
- wasmtime#10709:Cranelift:在 try-call 带有空处理程序列表时修复无效的 regalloc 约束。(感谢 @cfallin!)
- ab514c9:将 UnwindAction 传递给几个函数
- 9495eb5:将 Module 传递给 UnwindContext
- #1575:异常处理支持的准备工作
- #1584:Linux 上的实验性异常处理支持
ARM
CI 现在在原生 arm64 Linux 系统上构建和测试,而不是在 QEMU 中测试一部分测试。arm64 上的内联汇编现在可以使用向量寄存器。并且 half 和 bytecount 包现在在 arm64 上已修复。
f16/f128 支持
@beetrees 贡献了对不稳定的 f16 和 f128 类型的支持。
- wasmtime#8860:初始 f16 和 f128 支持(感谢 @beetrees!)
- wasmtime#9045:向 x64 后端添加初始 f16 和 f128 支持(感谢 @beetrees!)
- wasmtime#9076:向 aarch64 后端添加初始 f16 和 f128 支持(感谢 @beetrees!)
- wasmtime#10652:向 riscv64 后端添加初始不使用 Zfh 的 f16 和 f128 支持(感谢 @beetrees!)
- wasmtime#10691:向 s390x 后端添加初始 f16 和 f128 支持(感谢 @beetrees!)
- #1574:添加 f16/f128 支持(感谢 @beetrees!)
在代码生成后端之间共享代码
我向 rustc 提交了两个 PR,以在代码生成后端之间共享更多代码。这减轻了 cg_clif 和 rustc 的维护负担。未来,我希望将 cg_clif 的整个内联汇编处理迁移到 cg_ssa,以用作不原生支持内联汇编的代码生成后端的回退。
- rust#132820:为 CodegenBackend::link 添加默认实现
- rust#134232:在 cg_ssa 和 cg_clif 之间共享裸汇编实现
- rust#141769:将 dylibs 的元数据对象生成移动到链接器代码
SIMD
实现了一些新的供应商内在函数。
- b004312:实现 arm64 vaddlvq_u8 和 vld1q_u8_x4 供应商内在函数
- 1afce7c:实现 simd_insert_dyn 和 simd_extract_dyn 内在函数
- 49bfa1a:使用非指针大小的索引修复 simd_insert_dyn 和 simd_extract_dyn 内在函数
ABI
128 位整数库调用的 ABI 处理已得到改进。此外,我们测试的 abi-cafe 版本已更新到 1.0。由于它具有许多新功能,我们不再需要修补其源代码,这使得未来的更新更容易。
挑战
SIMD
虽然core::simd
通过使用标量操作的仿真完全支持,但core::arch
中的许多平台特定供应商内在函数不受支持。不过,随着最重要的 x86_64 和 arm64 供应商内在函数的实现,这种情况正在改善。
如果你的程序使用任何不受支持的供应商内在函数,你将收到一个编译时警告,如果它实际被到达,程序将以错误消息中止,指示哪个内在函数未实现。如果发生这种情况,请打开一个问题。
- issue #171:std::arch SIMD 内在函数
ABI
与 LLVM 仍有几个剩余的 ABI 兼容性问题。在 arm64 Linux 上,与 C ABI 有一个小的不兼容性,但 Rust ABI 工作正常。在 arm64 macOS 上,有几个影响 Rust ABI 的 ABI 不兼容性,因此不建议在那里混合使用 cg_clif 和 cg_llvm。在 x86_64 Windows 上,在涉及 i128 的返回值方面也存在不兼容性。我正在慢慢努力解决这些问题。
- issue #1525:abi-cafe 失败的跟踪问题
贡献
始终欢迎贡献。随意查看good first issues,如果遇到困难,可以在相关的 github 问题上 ping 我(@bjorn3),或者最好在rust lang zulip 上。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。