[llvm-dev] llvm interpreter does not find function defined by addGlobalMapping

Lang Hames via llvm-dev llvm-dev at lists.llvm.org
Mon Oct 24 20:27:21 PDT 2016


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>


More information about the llvm-dev mailing list