-O2优化printf("%s \n",str)为puts(str)

Lod*_*ner 5 c optimization assembly clang

随身携带clang,我编译了一个包含这一行的C程序:

printf("%s\n", argv[0]);
Run Code Online (Sandbox Code Playgroud)

在没有优化的情况下进行编译时,printf在设置寄存器后调用汇编输出:

movq    (%rcx), %rsi
movq    %rax, %rdi
movb    $0, %al
callq   _printf
Run Code Online (Sandbox Code Playgroud)

我试过编译clang -O2.该printf调用替换为一个puts呼叫:

movq    (%rsi), %rdi
callq   _puts
Run Code Online (Sandbox Code Playgroud)

虽然这在这种情况下非常有意义,但它提出了两个问题:

  1. 在优化编译中,函数调用替换的频率是多少?这是常见的还是stdio是个例外?
  2. 我可以为自己的库编写编译器优化吗?我该怎么办?

Gab*_*ern 3

  1. 优化编译中函数调用替换发生的频率是多少?这是经常出现的情况还是 stdio 是一个例外?

printfLLVM 中替换的优化puts是在类中LibCallSimplifier您可以在llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h中看到头文件,在llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp中看到实现。查看这些文件将给出一些已完成的其他库调用替换优化的示例(头文件可能更容易开始)。当然,LLVM 还进行了许多其他优化,您可以通过查看LLVM 通道列表来了解其中一些优化。

  1. 我可以为自己的库编写编译器优化吗?我该怎么做呢?

是的,你可以。LLVM 非常模块化,并通过一系列通道对 IR 执行转换。因此,如果您想为自己的库添加自定义通道,您可以这样做(尽管了解 LLVM 编译器流程的工作原理仍然需要大量工作)。文档是一个很好的起点:Writing an LLVM Pass