Failed to create Execution Engine

Hi,

I’m a green hand at LLVM. Lately I run into an issue about creating a ExecutionEngine object. I downloaded the latest source codes of LLVM 13.0.0, called the command cmake -S llvm -B build -G ‘Visual Studio 16 2019’ to generate a VS solution, then build all projects by VS. After that, I wrote a demo as below:
int main()

{
LLVMContext myContext;
Module *module = new Module(“my module”, myContext);
LLVMInitializeAllTargets();
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargetMCs();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();

std::string err;
EngineBuilder EB(std::move(std::unique_ptr(module)));
EB.setEngineKind(EngineKind::JIT).setErrorStr(&err);
ExecutionEngine* EE = EB.create() // EE is null here

}

Debugged and found that TargetRegistry::lookupTarget() returned null. I’m not sure why. Hope some one can give me a suggestion. Many thanks.

Lin

This is really just a guess, but maybe you need to set the target for the module?

have you checked out the error message (i.e. the err string)?

Also only speculating…

  1. You can try to set the target triple explicitly at at module
  2. Comparing with ExceptionDemo.cpp. line 1912 ff., you do not set a memory manager.

I stumbled across bullet 1 when playing around with OrcJIT. In most cases the host target triple is used if it is not set on the module, but with the OrcJIT I had to set it explicitly in some cases.

@redstar @mshockwave @pogo59
I find out the root cause. After removing the dependency llvm-c.lib from my solution, then it works. Thanks to all of you for your kindly help.

And I have another question, can we call c++ method in LLVM IR? For example, there is a c++ method defined outside main function, how can we call it via LLVM IR?

int foo(int a, int b)
{
return a + b;
}
int main()
{

std::string err;
EngineBuilder EB(std::move(std::unique_ptr(module)));
EB.setEngineKind(EngineKind::JIT).setErrorStr(&err);
ExecutionEngine* EE = EB.create()
// How can we call foo function via LLVM IR?

}

And, if that foo function is defined in a dll, how to do it? I’d appreciate it if any example is provided.

Best Regards,
Lin

That’s possible, but I am not sure about the MCJT API.
With OrcJIT, you can call DynamicLibrarySearchGenerator to add the symbols defined in dll’s into the search path. In this way, you can call printf from the jitted module.

I have not tried it, but I think as long as it’s in the same process, you can call ExecutorAddr::fromPtr(&foo) to get the address of the foo function, and turn it into an address callable from the JIT.
Again, that’s for OrcJIT. For MCJIT, there might be a different API.

Here is an example with OrcJIT, being able to call printf from the jitted module: JIT example.

@redstar ,

Really appreciate your patiently reply. I reviewed JIT example, but I still don’t know how to achieve that. Do you mind to show me a simpler example when you have time?

(BTW, I tried to compile JIT example, but it’s not succeed. Seemly llvm version is not matched. Mine is 13.0.0)

Best Regards,
Lin