我最近一直在研究由llvm-gcc生成的一些LLVM程序集,我注意到一个反复出现的声明,我不确定它的用途。
例如,以下C程序:
int main(void)
{
void (*f)(void) = (0x21332);
f();
}
使用“llvm-gcc -emit-llvm -S”编译时会生成以下代码(删除不相关的部分):
define i32 @main() nounwind {
entry:
%retval = alloca i32 ; <i32*> [#uses=1]
%f = alloca void ()* ; <void ()**> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store void ()* inttoptr (i64 135986 to void ()*), void ()** %f, align 4
%0 = load void ()** %f, align 4 ; <void ()*> [#uses=1]
call void %0() nounwind
br label %return
我对这条线的目的很感兴趣:
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
似乎没有做任何事情,因为它所分配的变量从未再次使用过,而bitcast本身也毫无意义。我能想到的是,它实际上是作为一个nop插入的,用于以后的代码生成/分析目的,表明代码中有趣的部分。
答案 0 :(得分:8)
从llvm-gcc源代码:gcc/llvm-convert.cpp,它只是用作辅助值*,它将被死指令消除传递删除。
// Create a dummy instruction in the entry block as a marker to insert new // alloc instructions before. It doesn't matter what this instruction is, // it is dead. This allows us to insert allocas in order without having to // scan for an insertion point. Use BitCast for int -> int
答案 1 :(得分:-1)
在互联网上找到这个: 当计算堆栈帧大小时,可以在编译时确定其大小的Allocas将在堆栈上分配空间。对于可变大小的allocas,目标特定代码必须调整堆栈大小,根据需要调整帧指针和堆栈指针,并将传出参数的位置调整到堆栈顶部。
听起来像是在那里使一些堆栈空间正常工作。