यह शायद कुछ बुनियादी क्योंकि मैं सिर्फ LLVM जानने के लिए शुरू कर रहा हूँ ..एलएलवीएम जेआईटी segfaults। मैं क्या गलत कर रहा हूं?
निम्नलिखित एक भाज्य समारोह बनाता है और Git और यह अमल (मुझे पता है क्योंकि मैं और स्थिर संकलन करने में सक्षम था उत्पन्न समारोह सही है की कोशिश करता है इसे निष्पादित करो)। लेकिन मैं विभाजन समारोह के निष्पादन पर गलती मिल (EE- में> runFunction (TheF, args))
#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;
}
संपादित करें: JIT सक्षम करने के लिए (नीचे स्वीकार किए जाते हैं जवाब देखें) सही तरीका:
1.#include "llvm/ExecutionEngine/Jit.h"`
2.InitializeNativeTarget();
धन्यवाद। बहुत उपयोगी जानकारी। क्या इसका मतलब यह है कि जेआईटी का उपयोग करने के लिए और इंटरपरेटर नहीं, मुझे llvm/ExecutionEngine/Interpreter.h के निष्पादन एंजिन/JIT.h INSTEAD शामिल करना चाहिए? – GabiMe
हां, यदि आप जेआईटी चाहते हैं, तो JIT.h शामिल करें और ExecutionEngine बनाने से पहले InitializeNativeTarget() को कॉल करना सुनिश्चित करें। आप यह सुनिश्चित करने के लिए कि आप एक जेआईटी प्राप्त कर रहे हैं, सुनिश्चित करने के लिए .create() को कॉल करने से पहले EngineBuilder.setEngineKind (EngineKind :: JIT) को भी कॉल करना चाहेंगे। –
मेरी इच्छा है कि मैं इसे और अधिक वोट दे सकता हूं। मैंने इस मुद्दे को शिकार करने में लगभग एक घंटा बिताया। मुझे लगता है कि मुझे थोड़ा बेहतर आरटीएफएम सीखना होगा। :) एक बार फिर धन्यवाद! – HVS