[LLVMdev] X86 JIT

Eric Rannaud eric.rannaud at gmail.com
Tue Jun 23 02:31:36 PDT 2009


On Mon, Jun 22, 2009 at 4:43 PM, Chris Lattner <clattner at apple.com>
wrote:
>
> On Jun 22, 2009, at 2:19 PM, Kasra wrote:
>
> Hi,
>
> for some reason I could not get the machine code generator for x86
> working. The interpreter is the only thing that works, is there
> anything that I am missing here?
>
> This recently changed.  In your main program, please #include
> "llvm/Target/TargetSelect.h" and call InitializeNativeTarget(); before
> setting up the execution engine,


Actually, you also need to include:

#include <llvm/ExecutionEngine/JIT.h>
or
#include <llvm/ExecutionEngine/Interpreter.h>

If not, you can get a segfault.


To reproduce, apply:

Index: tools/lli/lli.cpp
===================================================================
--- tools/lli/lli.cpp   (revision 73952)
+++ tools/lli/lli.cpp   (working copy)
@@ -18,8 +18,9 @@
 #include "llvm/Type.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
-#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
+//#include "llvm/ExecutionEngine/JIT.h"
+//#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/ExecutionEngine/GenericValue.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ManagedStatic.h"


Note that lli compiles OK with the patch. However:


[tmp]$ lli test6.bc
0   lli             0x0000000000d91488
1   lli             0x0000000000d91969
2   libpthread.so.0 0x00000034cb20ed30
3   lli             0x0000000000af7c02
llvm::SmallVectorImpl<llvm::ModuleProvider*>::size() const + 12
4   lli             0x0000000000af5bfc
llvm::ExecutionEngine::runStaticConstructorsDestructors(bool) + 40
5   lli             0x0000000000772b33 main + 1366
6   libc.so.6       0x00000034ca61e32a __libc_start_main + 250
7   lli             0x0000000000772009
Stack dump:
0.      Program arguments: lli test6.bc
Segmentation fault


I do not quite understand why, but it appears that the constructor of
the static variable

static struct RegisterJIT {
  RegisterJIT() { JIT::Register(); }
} JITRegistrator;

in lib/ExecutionEngine/JIT/JIT.cpp is only called if either JIT.h or
Interpreter.h is included. When they are not included, JIT::Register()
is not called, and ExecutionEngine::JITCtor and
ExecutionEngine::InterpCtor are both NULL, and ExecutionEngine::create()
returns NULL.

This is not caught by (in lli.cpp):

  if (!EE && !ErrorMsg.empty()) {
    std::cerr << argv[0] << ":error creating EE: " << ErrorMsg << "\n";
    exit(1);
  }

as ErrorMsg is empty. Then it segfaults line 190.

This is quite nasty behavior. I don't know what the proper fix is, but
relying on static constructors seems misplaced. And certainly, a missing
header should not result in a runtime fault.

Thanks,
Eric.




More information about the llvm-dev mailing list