如何使用LLVMBuildStore API

时间:2018-11-21 02:44:56

标签: c api llvm

long i=3;
long *j;
j=&i;

我想使用LLVM C API将上面的代码(特别是最后一行)转换为llvm代码。现在我在LLVM C API中搜索正确的函数,我认为应该使用“ LLVMBuildStore”,但是有“&”运算符,如何我翻译吗? LLVMBuildStore的第二个参数是LLVMValueRef类型值,在这种情况下,该值引用“ i”,如何从该值获取地址?

2 个答案:

答案 0 :(得分:1)

鉴于您已经为j提供了地址分配表达式,我想这些变量不是全局变量,而是在函数内部分配的。

因此,要将这个C代码片段转换为LLVM IR,您首先需要在堆栈中为变量i和指针j分配空间,然后将常数3存储到i的地址,并将i地址存储到指针的地址。

在LLVM IR中:

%i = alloca i64, align 8  ;allocation for i. %i is a pointer i64* to variable i
%j = alloca i64*, align 8  ;respectively, the type of %j is i64** (pointer to i64*)
store i64 3, i64* %i, align 8  ; i=3
store i64* %i, i64** %j, align 8  ; store %i (the address of var i) to the address of pointer j

我不知道如何使用LLVM C API生成这些指令,因为我从未使用过它。但是,希望C和C ++ API之间可能存在相关性,也许提供我将使用C ++ API编写的代码可能会帮助您了解需要使用的参数类型。希望对您有所帮助。

AllocaInst *alloc_i = new AllocaInst(Type::getInt64Ty(M.getContext()), //Type i64
                                          0,        //AddressSpace
                                          nullptr,  //Arraysize
                                          8,        //Alignment
                                          "i",      //name of result in IR. Leave "" for default
                                          I);       //Add alloca instruction before Instruction I

AllocaInst *alloc_j = new AllocaInst(Type::getInt64PtrTy(M.getContext()), //Type i64*
                                          0,        //AddressSpace
                                          nullptr,  //Arraysize
                                          8,        //Alignment
                                          "i",      //name of result in IR. Leave "" for default
                                          I);       //Add alloca instruction before Instruction I

StoreInst *store_i = new StoreInst(ConstantInt::get(Type::getInt64Ty(M.getContext()), 3), //get constant 3 of type i64
                                          alloc_i,   //store to the result Value* of alloc_i
                                          false, 
                                          8,         //Alignment
                                          I);        //Insert before instr I

StoreInst *store_j = new StoreInst(alloc_i,   //i64* pointer to i
                                          alloc_j,   //store to the address of pointer j
                                          false, 
                                          8,         //Alignment
                                          I);        //Insert before instr I

最后,考虑使用C ++ API。

答案 1 :(得分:0)

考虑以下C函数

int main() {
      long i=3;
      long *j;
      j=&i;
      return 0;
}

Clang 3.8将生成:

define i32 @main() {
  %1 = alloca i32, align 4
  %2 = alloca i64, align 8
  %3 = alloca i64*, align 8
  store i32 0, i32* %1, align 4
  store i64 3, i64* %2, align 8
  store i64* %2, i64** %3, align 8
  ret i32 0
}

从生成的代码中我们可以看到,clang生成了一个基本块。 在此基本块中,我们生成了三个alloca指令,三个存储指令和一个ret指令,这些指令终止了该基本块。

有关商店的说明,可以使用LLVMBuildStore()。 LLVMBuildStore接受三个参数,第一个是您的构建器。第二个参数是您要存储的参数,第三个是存储它的位置。 对于前两个存储指令,您可以仅使用代表整数的LLVM值。

对于第三个参数,直接使用LLVMBuildStore指令,而无需加载变量。第二个参数是您在创建时从先前的LLVMBuildAlloca()中收到的LLVMValueRef:

%2 = alloca i64*, align 8