主要观点:Rust 的所谓“C ABI”不佳,在有效传递复杂类型方面缺乏想象力。介绍了通过-Zcallconv
来改变extern "Rust"
的调用约定,可将其设置为legacy
或fast
,fast
调用约定可更好地利用寄存器传递参数等。还详细说明了如何通过一系列步骤让 LLVM 按照期望传递参数,以及在 Rust 中处理结构体、联合等类型的方式,包括根据有效大小分配寄存器、处理枚举等。同时提到 Rust 可利用优化依赖的 ABI 进行更极端的优化,如丢弃未使用参数等,且介绍了一些相关的注意事项和可能的改进方向。
关键信息:
- Rust 现用 LLVM 的内置 C 调用约定,生成的代码在简单函数时不佳。
extern "Rust"
可通过-Zcallconv
设置调用约定,fast
调用约定可更好利用寄存器。- 确定目标平台可通过寄存器传递的最大数值等步骤来让 LLVM 按期望传递参数。
- Rust 中处理结构体、联合等类型时要根据有效大小分配寄存器等。
- Rust 可利用优化依赖的 ABI 进行更优的优化,如丢弃未使用参数等。
重要细节:
- 在 x86 上,
-Zcallconv=fast
函数签名通常为特定格式,通过poison
语义可避免额外工作。 - Rust 中返回值按有效大小处理,大于输出寄存器空间的转为 by-ref 返回。
- 处理枚举时用适当的判别式-联合对替换,处理联合时根据情况选择传递方式。
- 对于复杂的 Rust 函数,如
do_thing
,展示了处理前后的 LLVM IR 及代码变化。 - 优化依赖的 ABI 可根据函数体情况优化参数传递等,如
HashMap::get()
可避免不必要的内存流量。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。