Reputation: 3379
I am trying to get a llvm::Module with a global variable to compile with the KaleidoscopeJIT Compiler, however, I get an error in the symbol lookup from the JIT compiler. (KaleidoscopeJIT.h source code from https://github.com/llvm-mirror/llvm/blob/master/examples/Kaleidoscope/include/KaleidoscopeJIT.h )
Upon inspection of the Symbol Table in the LegacyRTDyldObjectLinkingLayerBase, I indeed see that the global variable has not been added to Symbol table. Is this because the global variable is uninitialized? If so how should I specify an initializer for a struct using the llvm C++ api?
I have an IR code generated that looks like this
ModuleID = 'my jit module'
source_filename = "my jit module"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
%g = type { double, double }
@r = external global %g
define double @b() {
entry_b:
%p = alloca %g, align 8
%0 = getelementptr %g, %g* %p, i32 0, i32 1
store double 1.170000e+02, double* %0, align 8
%1 = load %g, %g* %p, align 8
store %g %1, %g* @r, align 8
%2 = load double, double* %0, align 8
ret double %2
}
However, when the JIT compiler tries to compile the function "b", I get an error saying
Failure value returned from cantFail wrapped call
Symbols not found: [ _r ]
The error occurs when trying to compile the IR code line
store %g %1, %g* @r, align 8
as the JIT is not able to find the symbol corresponding to the global variable "r" in the symbol table of the JIT.
Upvotes: 1
Views: 772
Reputation: 3379
The problem seems to be that uninitialized global variables are somehow optimized out and not added to the symbol table.
A quick work around to ensure that the variable gets added to the symbol table is to initialize it with an "Undefined value".
The following code allows to do such an initialization with the c++ api
// code defining the struct type
std::vector<llvm::Type *> Members(2, llvm::Type::getDoubleTy(TheContext));
llvm::StructType *TypeG = llvm::StructType::create(TheContext,Members,"g",false);
// defining the global variable
TheModule->getOrInsertGlobal("r",TypeG);
llvm::GlobalVariable *gVar = TheModule->getNamedGlobal("r");
// initialize the variable with an undef value to ensure it is added to the symbol table
gVar->setInitializer(llvm::UndefValue::get(TypeG));
This solves the problem.
Upvotes: 1