This question is about an error thrown by KaleidoscopeJIT.h. I am currently following the LLVM tutorial here but adding some more classes and objects to the design. Since I am using an older version of LLVM, I am borrowing some of the code from the older version (v10.0.0) of the llvm-project repo.
Where the issue is
I am currently am on Chapter 4 and I am trying to get the JIT compilation to work for top-level expressions (specifically simple arithmetic like 4+5 => "Evaluated to 9.0"). I am using a LLVMIRGen class with a method generateIR(/*AST root*/)
. This is then evaluated as follows :
int LLVMIRGenerator::generateIR(const std::unique_ptr<NodeAST> &root) {
if (FunctionAST *functionAST = dynamic_cast<FunctionAST *>(root.get())) {
/** stuff for functions and top-level expressions */
} else if (PrototypeAST *prototypeAST = dynamic_cast<PrototypeAST *>(root.get())) {
/* stuff for prototypes */
} else {
/* error msg etc. */
}
return 0;
}
The error stems from the following piece of my code:
if (functionAST->getPrototype()->getName().find("__anon_expr") != std::string::npos) {
std::unique_ptr<Module> copied = CloneModule(*TheModule.get());
auto H = myJIT->addModule(std::move(copied)); // THIS IS WHERE THE ERROR OCCURS.
// Search the JIT for the __anon_expr symbol.
auto ExprSymbol = myJIT->findSymbol("__anon_expr" + std::to_string(anon_counter++));
assert(ExprSymbol && "Function not found");
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
// Delete the anonymous expression module from the JIT.
myJIT->removeModule(H);
}
The above piece of code checks if the function is an "anonymous function" (i.e a top level expression) and if it is then it executes the expression. This piece of code is taken from the HandleTopLevelExpression()
function in the linked llvm-project repository above.
However, when I type in 4+5
in the prompt the exact error is :
ready>4+5
LLVM ERROR: Cannot select: 0x70f290: f64 = add 0x70f5d0, 0x70f568
0x70f5d0: f64,ch = load<(load 8 from constant-pool)> 0x6937a8, 0x70f638, undef:i64
0x70f638: i64 = X86ISD::Wrapper TargetConstantPool:i64<double 4.000000e+00> 0
0x70f1c0: i64 = TargetConstantPool<double 4.000000e+00> 0
0x70f500: i64 = undef
0x70f568: f64,ch = load<(load 8 from constant-pool)> 0x6937a8, 0x70f6a0, undef:i64
0x70f6a0: i64 = X86ISD::Wrapper TargetConstantPool:i64<double 5.000000e+00> 0
0x70f228: i64 = TargetConstantPool<double 5.000000e+00> 0
0x70f500: i64 = undef
In function: __anon_expr0
I think I have correctly initialized the Kaleidoscope JIT in the constructor as :
LLVMIRGenerator() {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
// Open a new context and module.
myJIT = std::make_unique<orc::KaleidoscopeJIT>();
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("KEANE'S JIT.C", *TheContext);
TheModule->setDataLayout(myJIT->getTargetMachine().createDataLayout());
....
}
Why exactly am I getting this error ?
What have I done so far ?
I am following the code from the Kaleidoscope project closely.One thing I have changed however is that the module I have is for the entire AST and not just for a single expression like they have done in the code. Hence I do not have the InitializeModuleAndPassManager()
line in my code.
I am not sure why I am getting this issue. So far I have tried moving the initialization of the JIT around to different places but to no avail.
My code is currently in the linked Github repo : verCE