Navneet Potti via llvm-dev
2015-Nov-13 03:06 UTC
[llvm-dev] Using Global Variables in MCJIT
Hi folks, I’m trying to JIT compile some functions in an existing C/C++ program at runtime, but I’m running into some trouble with global variable initialization. Specifically, the approach I’ve taken is to use Clang to precompile the program into IR bitcode modules in addition to the executable. At runtime, the program loads the modules, transforms them (program specialization), compiles and executes them. As it turns out, I have some global variables that get initialized and modified during execution of the “host” program. Currently, these globals are also getting initialized in the JIT compiled code, whereas I’d like them to be mapped to the host global variables instead. Can someone help me with this? A small repro is excerpted below. Full source code is in the attached zip file. The file somefunc.cpp gets precompiled during build, and is loaded in the main() function in testCompile.cpp. The global variable xyz is initialized to point to 25 in somefunc.cpp, but I’d like it to point to 10 as in main() instead. In other words, the assertion in main() should succeed. I tried a few different ways to solve this problem. The ChangeGlobal() function attempts (unsuccessfully) to achieve this updateGlobalMapping(). The second, more hacky approach uses a new global variable initialized appropriately. I can get this latter approach to work for some types of globals, but is there a more elegant approach than this? Cheers, Navneet Potti ————— somefunc.h ———————— extern int *xyz; —————— somefunc.cpp —————— int abc = 25; int *xyz = &abc; int somefunc() { return *xyz; } —————— testCompile.cpp —————— class JitCompiler { public: JitCompiler(const std::string module_file); void LoadModule(const std::string& file); template <typename FnType> FnType CompileFunc(FnType fn, const std::string& fn_name); void ChangeGlobal(); private: std::unique_ptr<LLVMContext> context_; Module *module_; std::unique_ptr<ExecutionEngine> engine_; }; void JitCompiler::ChangeGlobal() { // ----------------- #1: UpdateGlobalMapping ----------------- //auto g = engine_->FindGlobalVariableNamed("xyz"); //engine_->updateGlobalMapping(g, &xyz); //assert(engine_->getGlobalValueAddress("xyz") == (uint64_t) &xyz); // ----------------- #2: Replace with new global ———————— // ------- Ugly hack that works for globals of type T** ---------- auto g = engine_->FindGlobalVariableNamed("xyz"); Constant *addr_i = ConstantInt::get(*context_, APInt(64, (uint64_t) xyz)); auto addr = ConstantExpr::getIntToPtr( addr_i, g->getType()->getPointerElementType()); GlobalVariable *n = new GlobalVariable( *module_, g->getType()->getPointerElementType(), g->isConstant(), g->getLinkage(), addr, g->getName() + "_new"); g->replaceAllUsesWith(n); n->takeName(g); g->eraseFromParent(); } int main() { xyz = new int (10); JitCompiler jit("somefunc.bc"); jit.ChangeGlobal(); auto fn = jit.CompileFunc(&somefunc, "somefunc"); assert(somefunc() == fn()); } -------------- next part -------------- A non-text attachment was scrubbed... Name: repro.zip Type: application/zip Size: 2446 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151112/c8b8d4f4/attachment.zip> -------------- next part --------------
Hi Naveet, Sorry about the delayed reply. Your repro case is currently passing for me on MacOSX - are you still seeing this issue? Cheers, Lang. On Thu, Nov 12, 2015 at 7:06 PM, Navneet Potti via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi folks, > I’m trying to JIT compile some functions in an existing C/C++ program at > runtime, but I’m running into some trouble with global variable > initialization. Specifically, the approach I’ve taken is to use Clang to > precompile the program into IR bitcode modules in addition to the > executable. At runtime, the program loads the modules, transforms them > (program specialization), compiles and executes them. As it turns out, I > have some global variables that get initialized and modified during > execution of the “host” program. Currently, these globals are also getting > initialized in the JIT compiled code, whereas I’d like them to be mapped to > the host global variables instead. Can someone help me with this? > > A small repro is excerpted below. Full source code is in the attached zip > file. The file somefunc.cpp gets precompiled during build, and is loaded in > the main() function in testCompile.cpp. The global variable xyz is > initialized to point to 25 in somefunc.cpp, but I’d like it to point to 10 > as in main() instead. In other words, the assertion in main() should > succeed. > > I tried a few different ways to solve this problem. The ChangeGlobal() > function attempts (unsuccessfully) to achieve this updateGlobalMapping(). > The second, more hacky approach uses a new global variable initialized > appropriately. I can get this latter approach to work for some types of > globals, but is there a more elegant approach than this? > > Cheers, > Navneet Potti > > > > > ————— somefunc.h ———————— > extern int *xyz; > > —————— somefunc.cpp —————— > int abc = 25; > int *xyz = &abc; > > int somefunc() { > return *xyz; > } > > —————— testCompile.cpp —————— > class JitCompiler { > public: > JitCompiler(const std::string module_file); > void LoadModule(const std::string& file); > template <typename FnType> > FnType CompileFunc(FnType fn, const std::string& fn_name); > void ChangeGlobal(); > > private: > std::unique_ptr<LLVMContext> context_; > Module *module_; > std::unique_ptr<ExecutionEngine> engine_; > }; > > void JitCompiler::ChangeGlobal() { > // ----------------- #1: UpdateGlobalMapping ----------------- > //auto g = engine_->FindGlobalVariableNamed("xyz"); > //engine_->updateGlobalMapping(g, &xyz); > //assert(engine_->getGlobalValueAddress("xyz") == (uint64_t) &xyz); > > // ----------------- #2: Replace with new global ———————— > // ------- Ugly hack that works for globals of type T** ---------- > auto g = engine_->FindGlobalVariableNamed("xyz"); > Constant *addr_i = ConstantInt::get(*context_, APInt(64, > (uint64_t) xyz)); > auto addr = ConstantExpr::getIntToPtr( > addr_i, > g->getType()->getPointerElementType()); > > GlobalVariable *n = new GlobalVariable( > *module_, > g->getType()->getPointerElementType(), > g->isConstant(), > g->getLinkage(), > addr, > g->getName() + "_new"); > g->replaceAllUsesWith(n); > n->takeName(g); > g->eraseFromParent(); > } > > int main() { > xyz = new int (10); > JitCompiler jit("somefunc.bc"); > > jit.ChangeGlobal(); > auto fn = jit.CompileFunc(&somefunc, "somefunc"); > assert(somefunc() == fn()); > } > > > > > > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151215/5a669e66/attachment.html>