d7e76859788912dcbfbc845956543b5b74c8bd37
[oota-llvm.git] / lib / ExecutionEngine / JIT / VM.cpp
1 //===-- VM.cpp - LLVM Just in Time Compiler -------------------------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This tool implements a just-in-time compiler for LLVM, allowing direct
11 // execution of LLVM bytecode in an efficient manner.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "VM.h"
16 #include "llvm/Function.h"
17 #include "llvm/ModuleProvider.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineCodeEmitter.h"
20 #include "llvm/Target/TargetMachine.h"
21
22 namespace llvm {
23
24 VM::~VM() {
25   delete MCE;
26   delete &TM;
27 }
28
29 /// setupPassManager - Initialize the VM PassManager object with all of the
30 /// passes needed for the target to generate code.
31 ///
32 void VM::setupPassManager() {
33   // Compile LLVM Code down to machine code in the intermediate representation
34   if (TM.addPassesToJITCompile(PM)) {
35     std::cerr << "lli: target '" << TM.getName()
36               << "' doesn't support JIT compilation!\n";
37     abort();
38   }
39
40   // Turn the machine code intermediate representation into bytes in memory that
41   // may be executed.
42   //
43   if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
44     std::cerr << "lli: target '" << TM.getName()
45               << "' doesn't support machine code emission!\n";
46     abort();
47   }
48 }
49
50 /// runJITOnFunction - Run the FunctionPassManager full of
51 /// just-in-time compilation passes on F, hopefully filling in
52 /// GlobalAddress[F] with the address of F's machine code.
53 ///
54 void VM::runJITOnFunction (Function *F) {
55   static bool isAlreadyCodeGenerating = false;
56   assert(!isAlreadyCodeGenerating && "ERROR: RECURSIVE COMPILATION DETECTED!");
57
58   // JIT the function
59   isAlreadyCodeGenerating = true;
60   PM.run(*F);
61   isAlreadyCodeGenerating = false;
62 }
63
64 /// getPointerToFunction - This method is used to get the address of the
65 /// specified function, compiling it if neccesary.
66 ///
67 void *VM::getPointerToFunction(Function *F) {
68   void *&Addr = GlobalAddress[F];   // Check if function already code gen'd
69   if (Addr) return Addr;
70
71   // Make sure we read in the function if it exists in this Module
72   MP->materializeFunction(F);
73
74   if (F->isExternal())
75     return Addr = getPointerToNamedFunction(F->getName());
76
77   runJITOnFunction (F);
78   assert(Addr && "Code generation didn't add function to GlobalAddress table!");
79   return Addr;
80 }
81
82 /// recompileAndRelinkFunction - This method is used to force a function
83 /// which has already been compiled, to be compiled again, possibly
84 /// after it has been modified. Then the entry to the old copy is overwritten
85 /// with a branch to the new copy. If there was no old copy, this acts
86 /// just like VM::getPointerToFunction().
87 ///
88 void *VM::recompileAndRelinkFunction(Function *F) {
89   void *&Addr = GlobalAddress[F];   // Check if function already code gen'd
90
91   // If it's not already compiled (this is kind of weird) there is no
92   // reason to patch it up.
93   if (!Addr) { return getPointerToFunction (F); }
94
95   void *OldAddr = Addr;
96   Addr = 0;
97   MachineFunction::destruct (F);
98   runJITOnFunction (F);
99   assert(Addr && "Code generation didn't add function to GlobalAddress table!");
100   TM.replaceMachineCodeForFunction (OldAddr, Addr);
101   return Addr;
102 }
103
104 } // End llvm namespace