为什么 LLVM 不优化掉对下一个函数的尾部调用的不必要的 jmp?

问题描述 投票:0回答:1

以下 LLVM IR:

define tailcc i64 @f() {
  %1 = musttail call tailcc i64 @g(i64 10)
  ret i64 %1
}

define tailcc i64 @g(i64 %0) align 1 optsize noinline {
  ret i64 %0
}

生成此 X86 目标代码 (

clang-18 -O3 test.ll -o test.o && objdump -d test.o
):

0000000000000000 <f>:
   0:   bf 0a 00 00 00          mov    $0xa,%edi
   5:   e9 00 00 00 00          jmp    a <g>

000000000000000a <g>:
   a:   48 89 f8                mov    %rdi,%rax
   d:   c2 08 00                ret    $0x8

为什么从

jmp
f
g
没有优化掉?不需要,因为
g
紧邻
f
下面。

llvm tail-call
1个回答
0
投票

LLVM一般使用pass进行优化,pass共有三种,对函数进行操作的pass是其中一种。

LLVM 试图使编写和组合通道变得容易。事实上,编写一个 pass 来执行您所建议的操作非常容易,但这样做也会做其他事情:对所有后续的 pass 添加新的要求。

比如有了这样一个新的pass,其他pass就不能再分析

call
invoke
指令来找出调用了哪些函数,因为这个新pass增加了一种新的函数调用方式,即落空。

这种效应值得让世界变得复杂吗?我不得不说不,LLVM 的简单界面是一项很有价值的功能,比省略一条汇编指令更有价值。

© www.soinside.com 2019 - 2024. All rights reserved.