via llvm-dev
2016-Sep-19 12:34 UTC
[llvm-dev] llvm interpreter does not find function defined by addGlobalMapping
Hi, I want to use a function defined in c(++)-code from code generated by llvm. For this I use ExecutionEngine.addGlobalMapping(). I started with the JIT execution engine and everything worked, then I switched to the interpreter engine and it stopped working, but only if compiled on a Linux system. More precisely it works if I use llvm 3.8.1 + gcc (Linux) + JIT llvm 3.8.0 + mingw-gcc (Windows) + JIT llvm 3.8.0 + mingw-gcc (Windows) + Interpreter But it does not work for llvm 3.8.1 + gcc (Linux) + Interpreter. In that case I get the error message "LLVM ERROR: Tried to execute an unknown external function: testFunction." Am I using ExecutionEngine.addGlobalMapping() in the wrong way, even it works in three out of four scenarios? #include <llvm/Support/TargetSelect.h> #include <llvm/Analysis/Passes.h> #include <llvm/Transforms/Scalar.h> #include <llvm/Transforms/IPO/PassManagerBuilder.h> #include <llvm/Transforms/IPO.h> #include <llvm/IR/Verifier.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ExecutionEngine/Interpreter.h> #include <llvm/ExecutionEngine/MCJIT.h> #include <llvm/ExecutionEngine/GenericValue.h> #include <llvm/IR/LegacyPassManager.h> #include <llvm/IR/IRBuilder.h> extern "C" double testFunction(){ return 42.0; } int main() { // initialization needed for JIT llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetAsmParser(); llvm::LLVMContext &context(llvm::getGlobalContext()); llvm::Module *pModule = new llvm::Module("a module", context); // Here the EngineKind-flag decides if JIT or interpreter is used. auto pExecutionEngine = llvm::EngineBuilder(std::unique_ptr<llvm::Module>(pModule) ).setEngineKind(llvm::EngineKind::Interpreter).create(); pModule->setDataLayout(pExecutionEngine->getDataLayout()); // declaration of the c function. std::vector<llvm::Type *> noArgTypes; llvm::FunctionType* ft = llvm::FunctionType::get(llvm::Type::getDoubleTy(context),noArgTypes, false); auto pFunction = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, "testFunction",pModule); pExecutionEngine->addGlobalMapping(pFunction,reinterpret_cast<void*>(&testFunction)); // generation of llvm code auto pBlock = llvm::BasicBlock::Create(context, "evaluation"); llvm::IRBuilder<> builder(context); builder.SetInsertPoint(pBlock); // code for call of the c function. auto pFunction2 = pModule->getFunction("testFunction"); auto temp = builder.CreateCall(pFunction2, std::vector<llvm::Value*>(), "calltmp"); builder.CreateRet(temp); // generation of the llvm function calling the c function llvm::FunctionType* ftWrapper = llvm::FunctionType::get(llvm::Type::getDoubleTy(context),noArgTypes, false); auto pWrapperFunction = llvm::Function::Create(ftWrapper, llvm::Function::ExternalLinkage, "AFunction",pModule); pWrapperFunction->getBasicBlockList().push_back(pBlock); // calling the generated llvm function pExecutionEngine->finalizeObject(); pExecutionEngine->runFunction(pWrapperFunction,std::vector<llvm::GenericValue>()); } Thanks for any help, Markus
Lang Hames via llvm-dev
2016-Oct-20 20:33 UTC
[llvm-dev] llvm interpreter does not find function defined by addGlobalMapping
Hi Markus, What happens if you set the data layout on pModule before creating the engine? - Lang. On Mon, Sep 19, 2016 at 5:34 AM, via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Hi, > > I want to use a function defined in c(++)-code from code generated by > llvm. For this I use ExecutionEngine.addGlobalMapping(). I started with > the JIT execution engine and everything worked, then I switched to the > interpreter engine and it stopped working, but only if compiled on a Linux > system. More precisely it works if I use > > llvm 3.8.1 + gcc (Linux) + JIT > llvm 3.8.0 + mingw-gcc (Windows) + JIT > llvm 3.8.0 + mingw-gcc (Windows) + Interpreter > > But it does not work for llvm 3.8.1 + gcc (Linux) + Interpreter. In that > case I get the error message "LLVM ERROR: Tried to execute an unknown > external function: testFunction." Am I using ExecutionEngine.addGlobalMapping() > in the wrong way, even it works in three out of four scenarios? > > #include <llvm/Support/TargetSelect.h> > #include <llvm/Analysis/Passes.h> > #include <llvm/Transforms/Scalar.h> > #include <llvm/Transforms/IPO/PassManagerBuilder.h> > #include <llvm/Transforms/IPO.h> > #include <llvm/IR/Verifier.h> > #include <llvm/ExecutionEngine/ExecutionEngine.h> > #include <llvm/ExecutionEngine/Interpreter.h> > #include <llvm/ExecutionEngine/MCJIT.h> > #include <llvm/ExecutionEngine/GenericValue.h> > #include <llvm/IR/LegacyPassManager.h> > #include <llvm/IR/IRBuilder.h> > > extern "C" double testFunction(){ > return 42.0; > } > > int main() { > // initialization needed for JIT > llvm::InitializeNativeTarget(); > llvm::InitializeNativeTargetAsmPrinter(); > llvm::InitializeNativeTargetAsmParser(); > > llvm::LLVMContext &context(llvm::getGlobalContext()); > llvm::Module *pModule = new llvm::Module("a module", context); > > // Here the EngineKind-flag decides if JIT or interpreter is used. > auto pExecutionEngine = llvm::EngineBuilder(std:: > unique_ptr<llvm::Module>(pModule) > ).setEngineKind(llvm::EngineKind::Interpreter).create(); > pModule->setDataLayout(pExecutionEngine->getDataLayout()); > > // declaration of the c function. > std::vector<llvm::Type *> noArgTypes; > llvm::FunctionType* ft = llvm::FunctionType::get(llvm:: > Type::getDoubleTy(context),noArgTypes, false); > auto pFunction = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, > "testFunction",pModule); > pExecutionEngine->addGlobalMapping(pFunction,reinterpret_cast<void*>(& > testFunction)); > > // generation of llvm code > auto pBlock = llvm::BasicBlock::Create(context, "evaluation"); > llvm::IRBuilder<> builder(context); > builder.SetInsertPoint(pBlock); > > // code for call of the c function. > auto pFunction2 = pModule->getFunction("testFunction"); > auto temp = builder.CreateCall(pFunction2, std::vector<llvm::Value*>(), > "calltmp"); > builder.CreateRet(temp); > > // generation of the llvm function calling the c function > llvm::FunctionType* ftWrapper = llvm::FunctionType::get(llvm:: > Type::getDoubleTy(context),noArgTypes, false); > auto pWrapperFunction = llvm::Function::Create(ftWrapper, > llvm::Function::ExternalLinkage, "AFunction",pModule); > pWrapperFunction->getBasicBlockList().push_back(pBlock); > > // calling the generated llvm function > pExecutionEngine->finalizeObject(); > pExecutionEngine->runFunction(pWrapperFunction,std::vector< > llvm::GenericValue>()); > } > > Thanks for any help, > Markus > _______________________________________________ > 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/20161020/49a901ae/attachment.html>
via llvm-dev
2016-Oct-24 07:09 UTC
[llvm-dev] llvm interpreter does not find function defined by addGlobalMapping
Hi Lang,> What happens if you set the data layout on pModule before creating the > engine?The output of pExecutionEngine->getDataLayout().getStringRepresentation() is an empty string if I do not set the layout on pModule before creating the interpreter engine. If I set the layout before, the output is the specified layout. But unfortunately, the error is still there. Markus> > - Lang. > > On Mon, Sep 19, 2016 at 5:34 AM, via llvm-dev <llvm-dev at lists.llvm.org> > wrote: > > > Hi, > > > > I want to use a function defined in c(++)-code from code generated by > > llvm. For this I use ExecutionEngine.addGlobalMapping(). I started with > > the JIT execution engine and everything worked, then I switched to the > > interpreter engine and it stopped working, but only if compiled on a > Linux > > system. More precisely it works if I use > > > > llvm 3.8.1 + gcc (Linux) + JIT > > llvm 3.8.0 + mingw-gcc (Windows) + JIT > > llvm 3.8.0 + mingw-gcc (Windows) + Interpreter > > > > But it does not work for llvm 3.8.1 + gcc (Linux) + Interpreter. In that > > case I get the error message "LLVM ERROR: Tried to execute an unknown > > external function: testFunction." Am I using > ExecutionEngine.addGlobalMapping() > > in the wrong way, even it works in three out of four scenarios? > > > > #include <llvm/Support/TargetSelect.h> > > #include <llvm/Analysis/Passes.h> > > #include <llvm/Transforms/Scalar.h> > > #include <llvm/Transforms/IPO/PassManagerBuilder.h> > > #include <llvm/Transforms/IPO.h> > > #include <llvm/IR/Verifier.h> > > #include <llvm/ExecutionEngine/ExecutionEngine.h> > > #include <llvm/ExecutionEngine/Interpreter.h> > > #include <llvm/ExecutionEngine/MCJIT.h> > > #include <llvm/ExecutionEngine/GenericValue.h> > > #include <llvm/IR/LegacyPassManager.h> > > #include <llvm/IR/IRBuilder.h> > > > > extern "C" double testFunction(){ > > return 42.0; > > } > > > > int main() { > > // initialization needed for JIT > > llvm::InitializeNativeTarget(); > > llvm::InitializeNativeTargetAsmPrinter(); > > llvm::InitializeNativeTargetAsmParser(); > > > > llvm::LLVMContext &context(llvm::getGlobalContext()); > > llvm::Module *pModule = new llvm::Module("a module", context); > > > > // Here the EngineKind-flag decides if JIT or interpreter is used. > > auto pExecutionEngine = llvm::EngineBuilder(std:: > > unique_ptr<llvm::Module>(pModule) > > ).setEngineKind(llvm::EngineKind::Interpreter).create(); > > pModule->setDataLayout(pExecutionEngine->getDataLayout()); > > > > // declaration of the c function. > > std::vector<llvm::Type *> noArgTypes; > > llvm::FunctionType* ft = llvm::FunctionType::get(llvm:: > > Type::getDoubleTy(context),noArgTypes, false); > > auto pFunction = llvm::Function::Create(ft, > llvm::Function::ExternalLinkage, > > "testFunction",pModule); > > pExecutionEngine->addGlobalMapping(pFunction,reinterpret_cast<void*>(& > > testFunction)); > > > > // generation of llvm code > > auto pBlock = llvm::BasicBlock::Create(context, "evaluation"); > > llvm::IRBuilder<> builder(context); > > builder.SetInsertPoint(pBlock); > > > > // code for call of the c function. > > auto pFunction2 = pModule->getFunction("testFunction"); > > auto temp = builder.CreateCall(pFunction2, std::vector<llvm::Value*>(), > > "calltmp"); > > builder.CreateRet(temp); > > > > // generation of the llvm function calling the c function > > llvm::FunctionType* ftWrapper = llvm::FunctionType::get(llvm:: > > Type::getDoubleTy(context),noArgTypes, false); > > auto pWrapperFunction = llvm::Function::Create(ftWrapper, > > llvm::Function::ExternalLinkage, "AFunction",pModule); > > pWrapperFunction->getBasicBlockList().push_back(pBlock); > > > > // calling the generated llvm function > > pExecutionEngine->finalizeObject(); > > pExecutionEngine->runFunction(pWrapperFunction,std::vector< > > llvm::GenericValue>()); > > } > > > > Thanks for any help, > > Markus > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > >
Lang Hames via llvm-dev
2016-Oct-25 03:27 UTC
[llvm-dev] llvm interpreter does not find function defined by addGlobalMapping
Hi Markus, I don't know the Interpreter code well (and it's very poorly maintained) but from a quick inspection it doesn't seem to be inspecting the global mapping during external function resolution at all. The reason the code works on windows anyway is that (I would guess) it's an exported symbol in your program, and the Interpreter *does* look for those. On Linux, where symbols are not exported from the main binary by default, this fails. So: global mappings do not work in the interpreter at the moment. Is there any particular reason for you to use the interpreter? Given that it is poorly maintained, I would encourage you to use MCJIT instead (or, even better, ORC: http://llvm.org/docs/tutorial/BuildingAJIT1.html). Cheers, Lang. On Mon, Oct 24, 2016 at 12:09 AM, <markus.parker at arcor.de> wrote:> Hi Lang, > > > What happens if you set the data layout on pModule before creating the > > engine? > > The output of pExecutionEngine->getDataLayout().getStringRepresentation() > is an empty string if I do not set the layout on pModule before creating > the interpreter engine. If I set the layout before, the output is the > specified layout. But unfortunately, the error is still there. > > Markus > > > > > - Lang. > > > > On Mon, Sep 19, 2016 at 5:34 AM, via llvm-dev <llvm-dev at lists.llvm.org> > > wrote: > > > > > Hi, > > > > > > I want to use a function defined in c(++)-code from code generated by > > > llvm. For this I use ExecutionEngine.addGlobalMapping(). I started > with > > > the JIT execution engine and everything worked, then I switched to the > > > interpreter engine and it stopped working, but only if compiled on a > > Linux > > > system. More precisely it works if I use > > > > > > llvm 3.8.1 + gcc (Linux) + JIT > > > llvm 3.8.0 + mingw-gcc (Windows) + JIT > > > llvm 3.8.0 + mingw-gcc (Windows) + Interpreter > > > > > > But it does not work for llvm 3.8.1 + gcc (Linux) + Interpreter. In > that > > > case I get the error message "LLVM ERROR: Tried to execute an unknown > > > external function: testFunction." Am I using > > ExecutionEngine.addGlobalMapping() > > > in the wrong way, even it works in three out of four scenarios? > > > > > > #include <llvm/Support/TargetSelect.h> > > > #include <llvm/Analysis/Passes.h> > > > #include <llvm/Transforms/Scalar.h> > > > #include <llvm/Transforms/IPO/PassManagerBuilder.h> > > > #include <llvm/Transforms/IPO.h> > > > #include <llvm/IR/Verifier.h> > > > #include <llvm/ExecutionEngine/ExecutionEngine.h> > > > #include <llvm/ExecutionEngine/Interpreter.h> > > > #include <llvm/ExecutionEngine/MCJIT.h> > > > #include <llvm/ExecutionEngine/GenericValue.h> > > > #include <llvm/IR/LegacyPassManager.h> > > > #include <llvm/IR/IRBuilder.h> > > > > > > extern "C" double testFunction(){ > > > return 42.0; > > > } > > > > > > int main() { > > > // initialization needed for JIT > > > llvm::InitializeNativeTarget(); > > > llvm::InitializeNativeTargetAsmPrinter(); > > > llvm::InitializeNativeTargetAsmParser(); > > > > > > llvm::LLVMContext &context(llvm::getGlobalContext()); > > > llvm::Module *pModule = new llvm::Module("a module", context); > > > > > > // Here the EngineKind-flag decides if JIT or interpreter is used. > > > auto pExecutionEngine = llvm::EngineBuilder(std:: > > > unique_ptr<llvm::Module>(pModule) > > > ).setEngineKind(llvm::EngineKind::Interpreter).create(); > > > pModule->setDataLayout(pExecutionEngine->getDataLayout()); > > > > > > // declaration of the c function. > > > std::vector<llvm::Type *> noArgTypes; > > > llvm::FunctionType* ft = llvm::FunctionType::get(llvm:: > > > Type::getDoubleTy(context),noArgTypes, false); > > > auto pFunction = llvm::Function::Create(ft, > > llvm::Function::ExternalLinkage, > > > "testFunction",pModule); > > > pExecutionEngine->addGlobalMapping(pFunction, > reinterpret_cast<void*>(& > > > testFunction)); > > > > > > // generation of llvm code > > > auto pBlock = llvm::BasicBlock::Create(context, "evaluation"); > > > llvm::IRBuilder<> builder(context); > > > builder.SetInsertPoint(pBlock); > > > > > > // code for call of the c function. > > > auto pFunction2 = pModule->getFunction("testFunction"); > > > auto temp = builder.CreateCall(pFunction2, > std::vector<llvm::Value*>(), > > > "calltmp"); > > > builder.CreateRet(temp); > > > > > > // generation of the llvm function calling the c function > > > llvm::FunctionType* ftWrapper = llvm::FunctionType::get(llvm:: > > > Type::getDoubleTy(context),noArgTypes, false); > > > auto pWrapperFunction = llvm::Function::Create(ftWrapper, > > > llvm::Function::ExternalLinkage, "AFunction",pModule); > > > pWrapperFunction->getBasicBlockList().push_back(pBlock); > > > > > > // calling the generated llvm function > > > pExecutionEngine->finalizeObject(); > > > pExecutionEngine->runFunction(pWrapperFunction,std::vector< > > > llvm::GenericValue>()); > > > } > > > > > > Thanks for any help, > > > Markus > > > _______________________________________________ > > > 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/20161024/9573d4ab/attachment.html>