Accessing elements in LLVM arrays

被刻印的时光 ゝ 提交于 2019-12-21 09:00:12

问题


I am trying to get started with LLVM in order to add just-in-time compilation for my code, but finding it very difficult find references on how to do the things I want in LLVM, despite having checked through the Kaleidoscope tutorial, the language reference manual, the programmer's manual and the doxygen documentation. Are there more references to LLVM's C++ API than these?

Now for the concrete question. I have allocated an array object with two elements (which I assume 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 extract 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 code jits fine, but when I try to run it, it doesn't 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 can't see what I'm doing wrong. If I pass the values in the array (10 and 20) as scalar arguments to the function, it works fine.


回答1:


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

For the concrete question, my problem was that I assumed that I was passing an array of two doubles to the jitted function, while in fact I was passing a pointer to an array with two values. So the solution is to 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 an additional dereferencing by changing

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

to

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



回答2:


If you're using LLVM 3.0 or 3.1, CreateExtractValue takes an ArrayRef with the indices.



来源:https://stackoverflow.com/questions/9637803/accessing-elements-in-llvm-arrays

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!