JIT.cpp revision e2947531280503a4e73e8d94a6161f68bea857a7
1//===-- JIT.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 "JIT.h"
16#include "llvm/DerivedTypes.h"
17#include "llvm/Function.h"
18#include "llvm/GlobalVariable.h"
19#include "llvm/ModuleProvider.h"
20#include "llvm/CodeGen/MachineCodeEmitter.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/ExecutionEngine/GenericValue.h"
23#include "llvm/Target/TargetMachine.h"
24#include "llvm/Target/TargetJITInfo.h"
25#include "Support/DynamicLinker.h"
26#include <iostream>
27
28using namespace llvm;
29
30JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji)
31  : ExecutionEngine(MP), TM(tm), TJI(tji), PM(MP) {
32  setTargetData(TM.getTargetData());
33
34  // Initialize MCE
35  MCE = createEmitter(*this);
36
37  // Add target data
38  PM.add (new TargetData (TM.getTargetData ()));
39
40  // Compile LLVM Code down to machine code in the intermediate representation
41  TJI.addPassesToJITCompile(PM);
42
43  // Turn the machine code intermediate representation into bytes in memory that
44  // may be executed.
45  if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
46    std::cerr << "lli: target '" << TM.getName()
47              << "' doesn't support machine code emission!\n";
48    abort();
49  }
50}
51
52JIT::~JIT() {
53  delete MCE;
54  delete &TM;
55}
56
57/// run - Start execution with the specified function and arguments.
58///
59GenericValue JIT::runFunction(Function *F,
60                              const std::vector<GenericValue> &ArgValues) {
61  assert (F && "Function *F was null at entry to run()");
62    GenericValue rv;
63
64  if (ArgValues.size() == 3) {
65    int (*PF)(int, char **, const char **) =
66      (int(*)(int, char **, const char **))getPointerToFunction(F);
67    assert(PF && "Pointer to fn's code was null after getPointerToFunction");
68
69    // Call the function.
70    int ExitCode = PF(ArgValues[0].IntVal, (char **) GVTOP (ArgValues[1]),
71                      (const char **) GVTOP (ArgValues[2]));
72
73    rv.IntVal = ExitCode;
74  } else {
75    // FIXME: This code should handle a couple of common cases efficiently, but
76    // it should also implement the general case by code-gening a new anonymous
77    // nullary function to call.
78    assert(ArgValues.size() == 1);
79    void (*PF)(int) = (void(*)(int))getPointerToFunction(F);
80    assert(PF && "Pointer to fn's code was null after getPointerToFunction");
81    PF(ArgValues[0].IntVal);
82  }
83
84  return rv;
85}
86
87/// runJITOnFunction - Run the FunctionPassManager full of
88/// just-in-time compilation passes on F, hopefully filling in
89/// GlobalAddress[F] with the address of F's machine code.
90///
91void JIT::runJITOnFunction(Function *F) {
92  static bool isAlreadyCodeGenerating = false;
93  assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!");
94
95  // JIT the function
96  isAlreadyCodeGenerating = true;
97  PM.run(*F);
98  isAlreadyCodeGenerating = false;
99
100  // If the function referred to a global variable that had not yet been
101  // emitted, it allocates memory for the global, but doesn't emit it yet.  Emit
102  // all of these globals now.
103  while (!PendingGlobals.empty()) {
104    const GlobalVariable *GV = PendingGlobals.back();
105    PendingGlobals.pop_back();
106    EmitGlobalVariable(GV);
107  }
108}
109
110/// getPointerToFunction - This method is used to get the address of the
111/// specified function, compiling it if neccesary.
112///
113void *JIT::getPointerToFunction(Function *F) {
114  if (void *Addr = getPointerToGlobalIfAvailable(F))
115    return Addr;   // Check if function already code gen'd
116
117  // Make sure we read in the function if it exists in this Module
118  try {
119    MP->materializeFunction(F);
120  } catch ( std::string& errmsg ) {
121    std::cerr << "Error parsing bytecode file: " << errmsg << "\n";
122    abort();
123  } catch (...) {
124    std::cerr << "Error parsing bytecode file!\n";
125    abort();
126  }
127
128  if (F->isExternal()) {
129    void *Addr = getPointerToNamedFunction(F->getName());
130    addGlobalMapping(F, Addr);
131    return Addr;
132  }
133
134  runJITOnFunction(F);
135
136  void *Addr = getPointerToGlobalIfAvailable(F);
137  assert(Addr && "Code generation didn't add function to GlobalAddress table!");
138  return Addr;
139}
140
141// getPointerToFunctionOrStub - If the specified function has been
142// code-gen'd, return a pointer to the function.  If not, compile it, or use
143// a stub to implement lazy compilation if available.
144//
145void *JIT::getPointerToFunctionOrStub(Function *F) {
146  // If we have already code generated the function, just return the address.
147  if (void *Addr = getPointerToGlobalIfAvailable(F))
148    return Addr;
149
150  // If the target supports "stubs" for functions, get a stub now.
151  if (void *Ptr = TJI.getJITStubForFunction(F, *MCE))
152    return Ptr;
153
154  // Otherwise, if the target doesn't support it, just codegen the function.
155  return getPointerToFunction(F);
156}
157
158/// getOrEmitGlobalVariable - Return the address of the specified global
159/// variable, possibly emitting it to memory if needed.  This is used by the
160/// Emitter.
161void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) {
162  void *Ptr = getPointerToGlobalIfAvailable(GV);
163  if (Ptr) return Ptr;
164
165  // If the global is external, just remember the address.
166  if (GV->isExternal()) {
167    Ptr = GetAddressOfSymbol(GV->getName().c_str());
168    if (Ptr == 0) {
169      std::cerr << "Could not resolve external global address: "
170                << GV->getName() << "\n";
171      abort();
172    }
173  } else {
174    // If the global hasn't been emitted to memory yet, allocate space.  We will
175    // actually initialize the global after current function has finished
176    // compilation.
177    Ptr =new char[getTargetData().getTypeSize(GV->getType()->getElementType())];
178    PendingGlobals.push_back(GV);
179  }
180  addGlobalMapping(GV, Ptr);
181  return Ptr;
182}
183
184
185/// recompileAndRelinkFunction - This method is used to force a function
186/// which has already been compiled, to be compiled again, possibly
187/// after it has been modified. Then the entry to the old copy is overwritten
188/// with a branch to the new copy. If there was no old copy, this acts
189/// just like JIT::getPointerToFunction().
190///
191void *JIT::recompileAndRelinkFunction(Function *F) {
192  void *OldAddr = getPointerToGlobalIfAvailable(F);
193
194  // If it's not already compiled there is no reason to patch it up.
195  if (OldAddr == 0) { return getPointerToFunction(F); }
196
197  // Delete the old function mapping.
198  addGlobalMapping(F, 0);
199
200  // Recodegen the function
201  runJITOnFunction(F);
202
203  // Update state, forward the old function to the new function.
204  void *Addr = getPointerToGlobalIfAvailable(F);
205  assert(Addr && "Code generation didn't add function to GlobalAddress table!");
206  TJI.replaceMachineCodeForFunction(OldAddr, Addr);
207  return Addr;
208}
209