Clang 的 -O0 输出:分支位移和大小增加

主要观点:

  • Clang 19 将在 -O0 时移除 -mrelax-all 默认设置,显著减小 x86 的文本段大小。
  • 存在“跨度依赖指令”,汇编器需选择最佳指令大小,常见汇编器倾向“从小开始增长”的方法。
  • 在 -O0 且使用集成汇编器时,clangDriver 会向 LLVM MC 库传递 -mrelax-all 标志,可能导致某些指令以长形式编码。
  • -mrelax-all 对文本段大小影响显著,尤其在有很多分支指令时,在某些架构上增加较大,但如今编译时间收益可忽略。
  • 已提议移除 -O0 时的 -mrelax-all 默认设置,相关补丁已在 LLVM 19.1 中包含,且 Clang 已改变以尊重该设置。
  • 研究表明 -mrelax-all 在编译时间上的差异主要源于生成的汇编片段数量减少及固定点迭代算法的不同。
  • 人们通常不太在意 -O0 的代码大小,因为 -O0 常与 -g 一起使用,且并非所有项目都能成功在 -O0 下构建。
  • PNaCl 的软件故障隔离机制与 -mrelax-all 相关,启用后可能减少数据片段总数。

关键信息:

  • 汇编器中指令编码形式及选择最佳大小的挑战。
  • -mrelax-all 在不同架构下对文本段大小和编译时间的影响。
  • 相关补丁及改变已在 LLVM 和 Clang 中实施。

重要细节:

  • Thomas G. Szymanski 提出“跨度依赖指令”术语。
  • GNU Assembler 和 LLVM 中与 -mrelax-all 相关的代码部分及函数。
  • 不同优化级别下汇编的差异及示例。
  • PNaCl 中 .bundle_align_mode-mrelax-all 的关系。
阅读 76
0 条评论