question about ExectuionEngine::Create

I found the following problem when I try to debug “target does not support mc emission” in linux (the same code executes OK in windows):

Below is a snippet extracted from this method,

if (UseMCJIT && ExecutionEngine::MCJITCtor) {
ExecutionEngine *EE =
ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, OptLevel,
AllocateGVsWithCode, TM);
if (EE) return EE;
} else if (ExecutionEngine::JITCtor) {
ExecutionEngine *EE =
ExecutionEngine::JITCtor(M, ErrorStr, JMM, OptLevel,
AllocateGVsWithCode, TM);
if (EE) return EE;
}

Both ExecutionEngine::MCJITCtor and ExecutionEngine::JITCtor are function pointers (static members in class ExecutionEngine) and are initialized at the very beginning of ExecutionEngine.cpp to be 0 (NULL):

ExecutionEngine *(*ExecutionEngine::JITCtor)(
Module *M,
std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
bool GVsWithCode,
TargetMachine *TM) = 0;
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
Module *M,
std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
bool GVsWithCode,
TargetMachine *TM) = 0;

When I create the engine, I set UseMCJIT to “true” using
engineBuilder.setUseMCJIT(true);

Then I call
engineBuilder.crate()
to create the Execution engine.

In windows and Linux (Ubuntu), I got a different execution path when it reaches the if/else structure mentioned in the very beginning of this email:
Windows: it goes into the “else if” branch, which means that ExecutionEngine::MCJITCtor is evaluated as 0/NULL. It then uses ExecutionEngine::JITCtor to create the engine and successful. However, this is not what I meant to do.
Linux: it goes into the “if” branch, which means ExecutionEngine::MCJITCtor is not 0/NULL, and it must have been assigned a value somewhere. Then it uses ExecutionEngine::MCJITCtor (which is what I meant to do) but fails, giving me an error “target does not support mc emission”

In Windows, I am linking all the libraries (.lib) statically; In Linux, I am dynamic linking libLLVM3.0.so

Question:

  1. Where and when do ExecutionEngine::MCJITCtor and ExecutionEngine::JITCtor get assigned a different value other than 0/NULL?
  2. Why the value of ExecutionEngine::MCJITCtor are different in Windows and Linux?

Thanks.

The MCJITCtor and JITCtor are initialized from static constructors defined in MCJIT.cpp and JIT.cpp respectively.

The problem you are seeing is probably caused by the linker optimizing out these static constructors on Windows. In order to force these constructors to be linked in, you need to include “llvm/ExecutionEngine/MCJIT.h” from some module that you know contains non-static code.

-Andy