【问题标题】:Does LLVM/clang have flags to control code padding?LLVM/clang 是否有标志来控制代码填充?
【发布时间】:2015-02-27 01:07:39
【问题描述】:

我正在使用 LLVM 框架 (v3.3)、clang 前端、X86 目标。 我注意到我总是会在这里和那里得到一点 NOP,这是为了很好地衡量,显然是为了将部分代码与 16B 对齐(至少是循环,也许还有其他块)。

例如 - 这里的 0x401495 处的 nopw:

  401489:       48 89 44 24 10          mov    %rax,0x10(%rsp)
  40148e:       b9 e8 03 00 00          mov    $0x3e8,%ecx
  401493:       eb 0f                   jmp    4014a4 <main+0x34>
  401495:       66 66 2e 0f 1f 84 00    data32 nopw %cs:0x0(%rax,%rax,1)
  40149c:       00 00 00 00
  4014a0:       48 8b 40 08             mov    0x8(%rax),%rax
  4014a4:       ff c9                   dec    %ecx
  4014a6:       75 f8                   jne    4014a0 <main+0x30>
  4014a8:       8b 30                   mov    (%rax),%esi

我想这有助于分支预测器或 I-cache 更好地执行,但我现在不需要这种优化,我需要保持代码的这一部分简单和美观。

有没有办法通过编译器标志禁用此代码填充?类似于 gcc 的 -fno-align-loops (或类似的对齐标志)

我搜索了manual 并浏览了 LLVM 代码以查找与填充、对齐、nops 等相关的任何内容。没有任何相关信息弹出。 我看到的唯一替代方法是使用 -Os 进行编译(它确实删除了这个填充),但这会过于激进地改变其余代码 - 我不想优化空间,而是为了可读性。

【问题讨论】:

  • 我发现nop 指令是反汇编输出中分支目标的有用标记,因为循环通常只有局部标签,无法在编译/反汇编中幸存(与函数入口点不同)。

标签: x86 clang llvm


【解决方案1】:

没有答案的老问题,所以只是一些与 LLVM NOP-padding 相关的指针:

  • LLVM's RFC 提到了与您的示例类似的内容:循环内的 NOP 插入以通过将“如果它们都指向同一个目标,则将 2 个分支从同一个 16B 块中移出”来提高性能。已经实现here

  • 对于 x86 中实际的 NOP 指令生成,您可以在 X86AsmBackend::writeNopData 中找到它。此代码自创建以来已多次修改;在某些时候他们是alternate NOP instructions

希望对你有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多