下面是一个简单的C文件,其中包含一个枚举定义和一个main
函数:
enum days {MON, TUE, WED, THU};
int main() {
enum days d;
d = WED;
return 0;
}
字符串
它转换为以下LLVM IR:
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 2, i32* %2, align 4
ret i32 0
}
型%2
显然是d
变量,它得到2赋值给它。如果直接返回0,%1
对应什么?
3条答案
按热度按时间nwo49xxi1#
%1
寄存器由clang生成,用于处理函数中的多个返回语句。字符串
你可能会这么做
型
为什么?为什么?因为Clang会插入
result
变量来保存返回值。耶。这就是%1
变量的原因。查看IR以获得稍微修改过的代码版本。修改代码,
型
IR,
型
现在你看到
%1
使自己变得有用了吧?大多数带有单个return语句的函数都会通过LLVM的一次传递剥离这个变量。xcitsw882#
为什么这很重要-实际的问题是什么?
我认为你正在寻找的更深层次的答案可能是:LLVM的架构基于相当简单的前端和许多通道。前端必须生成正确的代码,但它不一定是好的代码。它们可以做最简单的事情。
在这种情况下,Clang生成了几条指令,这些指令最终没有被用于任何事情。这通常不是问题,因为LLVM的某些部分会删除多余的指令。Clang相信这会发生。Clang不需要避免发出死代码;它的实现可能会专注于正确性,简单性,可测试性等。
wdebmtf23#
因为Clang已经完成了语法分析,但LLVM甚至还没有开始优化。
Clang前端生成的是IR(Intermediate Representation)而不是机器码。这些变量是SSA(Single Static Representation);它们还没有绑定到寄存器,实际上在优化之后,它们永远不会绑定到寄存器,因为它们是冗余的。
这段代码是源代码的字面表示。它是clang交给LLVM进行优化的代码。基本上,LLVM从那里开始并从那里优化。实际上,对于版本10和x86_64,llc -O2 最终将生成:
字符串