JIT.cpp:
[oota-llvm.git] / lib / ExecutionEngine / JIT / VM.cpp
1 //===-- VM.cpp - LLVM Just in Time Compiler -------------------------------===//
2 //
3 // This tool implements a just-in-time compiler for LLVM, allowing direct
4 // execution of LLVM bytecode in an efficient manner.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "VM.h"
9 #include "llvm/Function.h"
10 #include "llvm/ModuleProvider.h"
11 #include "llvm/CodeGen/MachineCodeEmitter.h"
12 #include "llvm/Target/TargetMachine.h"
13
14 VM::~VM() {
15   delete MCE;
16   delete &TM;
17 }
18
19 /// setupPassManager - Initialize the VM PassManager object with all of the
20 /// passes needed for the target to generate code.
21 ///
22 void VM::setupPassManager() {
23   // Compile LLVM Code down to machine code in the intermediate representation
24   if (TM.addPassesToJITCompile(PM)) {
25     std::cerr << "lli: target '" << TM.getName()
26               << "' doesn't support JIT compilation!\n";
27     abort();
28   }
29
30   // Turn the machine code intermediate representation into bytes in memory that
31   // may be executed.
32   //
33   if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
34     std::cerr << "lli: target '" << TM.getName()
35               << "' doesn't support machine code emission!\n";
36     abort();
37   }
38 }
39
40 /// getPointerToFunction - This method is used to get the address of the
41 /// specified function, compiling it if neccesary.
42 ///
43 void *VM::getPointerToFunction(Function *F) {
44   void *&Addr = GlobalAddress[F];   // Function already code gen'd
45   if (Addr) return Addr;
46
47   // Make sure we read in the function if it exists in this Module
48   MP->materializeFunction(F);
49
50   if (F->isExternal())
51     return Addr = getPointerToNamedFunction(F->getName());
52
53   static bool isAlreadyCodeGenerating = false;
54   assert(!isAlreadyCodeGenerating && "ERROR: RECURSIVE COMPILATION DETECTED!");
55
56   // JIT the function
57   isAlreadyCodeGenerating = true;
58   PM.run(*F);
59   isAlreadyCodeGenerating = false;
60
61   assert(Addr && "Code generation didn't add function to GlobalAddress table!");
62   return Addr;
63 }