llvm 代码中出现的 %"alloca point" 行的目的是啥?

Posted

技术标签:

【中文标题】llvm 代码中出现的 %"alloca point" 行的目的是啥?【英文标题】:What is the purpose of the %"alloca point" line which occurs in llvm code?llvm 代码中出现的 %"alloca point" 行的目的是什么? 【发布时间】:2010-11-21 13:15:36 【问题描述】:

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

【问题讨论】:

这行我也很好奇;我今晚刚刚在查看一些代码生成的东西时遇到了它。它似乎是 alloca 边界,但我不知道为什么。 【参考方案1】:

来自 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

【讨论】:

是的,这是正确的。还在 LLVM 邮件列表上问了这个问题并得到了类似的回复,确切地说:“它作为插入临时对象的位置的占位符存在:alloca 在比特广播之前开始,实际代码生成在它之后开始。这只是前面的方便-end; instcombine 会消除它,基本上其他一切都会忽略它。”【参考方案2】:

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

听起来是为了让一些堆栈空间正常工作。

【讨论】:

问题不在于 alloca 本身。 OP 正在询问名为“alloca point”的指令,这似乎是一个无操作。

以上是关于llvm 代码中出现的 %"alloca point" 行的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 CMake 脚本找到“alloca”但仍然失败?

LLVM 5.1“不推荐使用的 isa”的编译器错误

Xcode 5“缺少编译器规范 LLVM 4.2”错误

clang 将元数据设置为 allocainst

关于alloca的使用和滥用

如何用llvm-obfuscator混淆代码