LLVM IR中的位转换理解

5
我正在试图理解从C++程序生成的LLVM IR。
int add(int *x);
int func()
{
        int T;
        T=25;
        return add(&T);    
}

生成的 IR(中间代码)如下:
define i32 @_Z4funcv() local_unnamed_addr #0 {
entry:
  %T = alloca i32, align 4
  %0 = bitcast i32* %T to i8*
  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #3
  store i32 25, i32* %T, align 4, !tbaa !2
  %call = call i32 @_Z3addPi(i32* nonnull %T)
  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #3
  ret i32 %call
}

我不理解这行代码的意思 %0 = bitcast i32* %T to i8*。将%Ti32转换为i8有什么作用呢?


4
这是因为指针的值(即内存地址)被传递给了@llvm.lifetime.start内置函数,表示在该函数中直到这一点(即下一个store之前)该指针已经无效。你可以查看文档和LLVM源代码以获取示例用法。 - compor
2个回答

4
假设您已经了解内在函数及其用途作为MemoryDependenceAnalysis的内存使用标记。
选择指针(变量地址)作为i8是为了使其更通用,作为字节寻址的内存区域,并将第一个参数作为malloc中使用的字节数。
因此,要生成内在调用,我们需要一个内存字节地址和sizeof(T)的字节数。这就是为什么我们需要将i32*转换为i8*。
顺便说一下,在您的示例中使用的生命周期内在函数的签名为
请参阅Lang ref以获取更多信息。

1
请注意,LLVM最近进行了更改,通过使用通用指针类型来消除其类型系统中的此需求。 - Chandler Carruth

1

LLVM 是一种类型化和单态化的编程语言。因此,在使用值之前,您需要将其转换为正确的类型。正如其他答案所解释的那样,LLVM 内置函数操作的是 i8* 类型,这在某种程度上相当于 C 语言中的 void*。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接