mac*_*inn 9 c llvm llvm-codegen
这是一个带有枚举定义和main函数的简单 C 文件:
enum days {MON, TUE, WED, THU};
int main() {
enum days d;
d = WED;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它转换为以下 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
}
Run Code Online (Sandbox Code Playgroud)
%2显然是d变量,它被分配了 2。%1直接返回零对应什么?
寄存器%1是由 clang 生成的,用于处理函数中的多个返回语句。想象一下您正在编写一个函数来计算整数的阶乘。而不是这个
int factorial(int n){
int result;
if(n < 2)
result = 1;
else{
result = n * factorial(n-1);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
你可能会这样做
int factorial(int n){
if(n < 2)
return 1;
return n * factorial(n-1);
}
Run Code Online (Sandbox Code Playgroud)
为什么?因为 Clang 会插入result为您保存返回值的变量。耶。这就是该变量的原因%1。查看 IR 中的代码稍作修改的版本。
修改后的代码,
enum days {MON, TUE, WED, THU};
int main() {
enum days d;
d = WED;
if(d) return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
红外,
define dso_local i32 @main() #0 !dbg !15 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 2, i32* %2, align 4, !dbg !22
%3 = load i32, i32* %2, align 4, !dbg !23
%4 = icmp ne i32 %3, 0, !dbg !23
br i1 %4, label %5, label %6, !dbg !25
5: ; preds = %0
store i32 1, i32* %1, align 4, !dbg !26
br label %7, !dbg !26
6: ; preds = %0
store i32 0, i32* %1, align 4, !dbg !27
br label %7, !dbg !27
7: ; preds = %6, %5
%8 = load i32, i32* %1, align 4, !dbg !28
ret i32 %8, !dbg !28
}
Run Code Online (Sandbox Code Playgroud)
现在你知道%1它本身很有用了吧?大多数具有单个 return 语句的函数都会通过 LLVM 的一次传递删除该变量。