Access Elements in LLVM Arrays

I'm trying to get started with LLVM to add a just-in-time compilation for my code, but it’s very difficult to find links to how to do what I want in LLVM, even though I checked in the Kaleidoscope manual, the reference guide for language, programmer's manual and doxygen documentation. Are there more links to the LLVM C ++ API than these?

Now for a specific question. I selected an array object with two elements (which, I believe, corresponds to double[2] in C ++):

 const llvm::Type* double_t = llvm::Type::getDoubleTy(llvm::getGlobalContext()); const llvm::Type* array_t = llvm::ArrayType::get(double_t,2) 

Later in the code, I create a function where this array is one of the arguments. Then in my function, I retrieve the first element in the array and return it to the user:

 llvm::Function::arg_iterator AI = jit_function_->arg_begin(); llvm::Value *x = AI; llvm::Value *x0 = Builder.CreateExtractValue(x,0); Builder.CreateRet(x0); 

The jits code is fine, but when I try to run it, it does not work. For example:

 typedef double (*GenType)(double[2]); GenType FP = GenType(intptr_t(TheExecutionEngine->getPointerToFunction(jit_function_))); double y[2] = {10,20}; double r = FP(y); printf("r = %g\n", r); 

The return value is just nonsense, and I don’t see what I am doing wrong. If I pass the values ​​in the array (10 and 20) as scalar arguments to the function, it works fine.

+7
source share
2 answers

I think I can answer my own question. For the first part of the question, a good reference to LLVM (besides the ones mentioned above) is to write what you want in simple C, and compile it with Clang and look at the LLVM output: clang -S -emit-llvm test.c -o - .

In a specific question, my problem was that I assumed that I was passing an array of two two-local numbers to a jitted function, while in reality I was passing a pointer to an array with two values. Therefore, the decision should change:

 const llvm::Type* array_t = llvm::ArrayType::get(double_t,2); 

to

 const llvm::Type* array_t = llvm::PointerType::getUnqual(llvm::ArrayType::get(double_t,2)); 

And to add extra dereference by changing

 llvm::Value *x0 = Builder.CreateExtractValue(x,0); 

to

 llvm::Value *x0 = Builder.CreateExtractValue(Builder.CreateLoad(x),0); 
+8
source

If you are using LLVM 3.0 or 3.1, CreateExtractValue takes an ArrayRef with indexes.

0
source

All Articles