10

我最近一直在看一些由 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 插入的,用于以后的代码生成/分析目的,表明代码的有趣部分。

4

2 回答 2

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
于 2009-10-26T00:55:26.630 回答
-1

在互联网上找到这个:可以在编译时确定大小的 Allocas 将在计算堆栈帧大小时在堆栈上分配空间。对于可变大小的分配器,目标特定的代码必须调整堆栈大小,根据需要调整帧指针和堆栈指针,并将传出参数的位置调整到堆栈顶部。

听起来它在那里可以使一些堆栈空间正常工作。

于 2009-08-22T15:57:25.117 回答