我正在尝试使用LLVM来为我的代码添加即时编译,但是发现很难找到关于如何在LLVM中执行我想要的事情的参考,尽管已经检查了Kaleidoscope教程,语言参考手册,程序员手册和doxygen文档。是否有更多对LLVM的C ++ API的引用?
现在提出具体问题。我已经分配了一个带有两个元素的数组对象(我假设它对应于C ++中的double[2]
):
const llvm::Type* double_t = llvm::Type::getDoubleTy(llvm::getGlobalContext());
const llvm::Type* array_t = llvm::ArrayType::get(double_t,2)
稍后在代码中,我创建了一个函数,其中此数组是参数之一。然后,在我的函数中,我提取数组中的第一个元素并将其返回给用户:
llvm::Function::arg_iterator AI = jit_function_->arg_begin();
llvm::Value *x = AI;
llvm::Value *x0 = Builder.CreateExtractValue(x,0);
Builder.CreateRet(x0);
代码很好,但是当我尝试运行它时,它不起作用。例如:
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);
返回值只是胡说八道,我看不出我做错了什么。如果我将数组(10和20)中的值作为函数的标量参数传递,它可以正常工作。
答案 0 :(得分:11)
我想我能够回答我自己的问题。对于问题的第一部分,对LLVM的一个很好的引用(除了上面提到的那些)是在纯C中编写你想要的东西并用Clang编译它并查看LLVM输出:clang -S -emit-llvm test.c -o -
。< / p>
对于具体问题,我的问题是我假设我将两个双精度数组传递给jitted函数,而实际上我将指针传递给具有两个值的数组。因此解决方案是改变:
const llvm::Type* array_t = llvm::ArrayType::get(double_t,2);
到
const llvm::Type* array_t = llvm::PointerType::getUnqual(llvm::ArrayType::get(double_t,2));
并通过更改
添加其他解除引用llvm::Value *x0 = Builder.CreateExtractValue(x,0);
到
llvm::Value *x0 = Builder.CreateExtractValue(Builder.CreateLoad(x),0);
答案 1 :(得分:0)
如果您使用的是LLVM 3.0或3.1,CreateExtractValue
将使用索引获取ArrayRef。