C++ LLVM JIT错误。我做错了什么?
这可能是一些基本的东西,因为我刚刚开始学习LLVM 下面创建一个阶乘函数并尝试git和执行它(我知道生成的func是正确的,因为我能够静态编译和执行它)。 但在执行函数时(在EE->runFunction(off,Args)中)会出现分段错误C++ LLVM JIT错误。我做错了什么?,c++,llvm,C++,Llvm,这可能是一些基本的东西,因为我刚刚开始学习LLVM 下面创建一个阶乘函数并尝试git和执行它(我知道生成的func是正确的,因为我能够静态编译和执行它)。 但在执行函数时(在EE->runFunction(off,Args)中)会出现分段错误 包含该头文件(llvm/ExecutionEngine/explorer.h)将强制对JIT进行静态初始化。这不是最好的设计决策,但至少它是有效的。我敢打赌ExecutionEngine指针是空的。。。。您缺少对InitializeNativeTarget
包含该头文件(
llvm/ExecutionEngine/explorer.h
)将强制对JIT进行静态初始化。这不是最好的设计决策,但至少它是有效的。我敢打赌ExecutionEngine指针是空的。。。。您缺少对InitializeNativeTarget
的调用,文档中说:
InitializeNativeTarget—主程序应调用此函数初始化与主机对应的本机目标。这对于JIT应用程序非常有用,可以确保正确链接目标
因为如果不调用InitializeNativeTarget,就没有JIT编译器可用,ModuleBuilder会选择解释器(如果可用)。可能不是你想要的。您可能需要。谢谢。非常有用的信息。这是否意味着要使用JIT而不是interperter,我应该包含ExecutionEngine/JIT.h而不是llvm/ExecutionEngine/解释器.h?是的,如果需要JIT,请包含JIT.h,并确保在创建ExecutionEngine之前调用InitializeNativeTarget()。在调用.create()之前,您可能还需要调用EngineBuilder.setEngineKind(EngineKind::JIT),以确保您获得了JIT。我希望我能对此进行更多的投票。我花了大约一个小时研究这个问题。我想我需要更好地学习RTFM。:)再次感谢!看起来从LLVM 6.0.0开始,您需要包含此文件:
#包含“LLVM/ExecutionEngine/MCJIT.h”
这使HowToUseJIT示例停止在使用Visual Studio 2017的Windows 10上崩溃。x64调试生成。万花筒-Ch4仍在崩溃。我认为该示例只搜索外部函数声明,但仍然试图找到根本原因。@Damian幸运吗?
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
#include "llvm/CallingConv.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/GenericValue.h"
using namespace llvm;
Module* makeLLVMModule() {
// Module Construction
LLVMContext& ctx = getGlobalContext();
Module* mod = new Module("test", ctx);
Constant* c = mod->getOrInsertFunction("fact64",
/*ret type*/ IntegerType::get(ctx,64),
IntegerType::get(ctx,64),
/*varargs terminated with null*/ NULL);
Function* fact64 = cast<Function>(c);
fact64->setCallingConv(CallingConv::C);
/* Arg names */
Function::arg_iterator args = fact64->arg_begin();
Value* x = args++;
x->setName("x");
/* Body */
BasicBlock* block = BasicBlock::Create(ctx, "entry", fact64);
BasicBlock* xLessThan2Block= BasicBlock::Create(ctx, "xlst2_block", fact64);
BasicBlock* elseBlock = BasicBlock::Create(ctx, "else_block", fact64);
IRBuilder<> builder(block);
Value *One = ConstantInt::get(Type::getInt64Ty(ctx), 1);
Value *Two = ConstantInt::get(Type::getInt64Ty(ctx), 2);
Value* xLessThan2 = builder.CreateICmpULT(x, Two, "tmp");
//builder.CreateCondBr(xLessThan2, xLessThan2Block, cond_false_2);
builder.CreateCondBr(xLessThan2, xLessThan2Block, elseBlock);
/* Recursion */
builder.SetInsertPoint(elseBlock);
Value* xMinus1 = builder.CreateSub(x, One, "tmp");
std::vector<Value*> args1;
args1.push_back(xMinus1);
Value* recur_1 = builder.CreateCall(fact64, args1.begin(), args1.end(), "tmp");
Value* retVal = builder.CreateBinOp(Instruction::Mul, x, recur_1, "tmp");
builder.CreateRet(retVal);
/* x<2 */
builder.SetInsertPoint(xLessThan2Block);
builder.CreateRet(One);
return mod;
}
int main(int argc, char**argv) {
long long x;
if(argc > 1)
x = atol(argv[1]);
else
x = 4;
Module* Mod = makeLLVMModule();
verifyModule(*Mod, PrintMessageAction);
PassManager PM;
PM.add(createPrintModulePass(&outs()));
PM.run(*Mod);
// Now we going to create JIT
ExecutionEngine *EE = EngineBuilder(Mod).create();
// Call the function with argument x:
std::vector<GenericValue> Args(1);
Args[0].IntVal = APInt(64, x);
Function* TheF = cast<Function>(Mod->getFunction("fact64")) ;
/* The following CRASHES.. */
GenericValue GV = EE->runFunction(TheF, Args);
outs() << "Result: " << GV.IntVal << "\n";
delete Mod;
return 0;
}
1.#include "llvm/ExecutionEngine/Jit.h"`
2.InitializeNativeTarget();
#include "llvm/ExecutionEngine/Interpreter.h"