summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/JIT/JIT.h
blob: 41fa9bd0028fe5aa490bc4a3b5b67406181e0d07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//===-- JIT.h - Class definition for the JIT --------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the top-level JIT data structure.
//
//===----------------------------------------------------------------------===//

#ifndef JIT_H
#define JIT_H

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/PassManager.h"

namespace llvm {

class Function;
class GlobalValue;
class Constant;
class TargetMachine;
class TargetJITInfo;
class MachineCodeEmitter;

class JITState {
private:
  FunctionPassManager PM;  // Passes to compile a function

  /// PendingGlobals - Global variables which have had memory allocated for them
  /// while a function was code generated, but which have not been initialized
  /// yet.
  std::vector<const GlobalVariable*> PendingGlobals;

public:
  explicit JITState(ModuleProvider *MP) : PM(MP) {}

  FunctionPassManager &getPM(const MutexGuard &L) {
    return PM;
  }

  std::vector<const GlobalVariable*> &getPendingGlobals(const MutexGuard &L) {
    return PendingGlobals;
  }
};


class JIT : public ExecutionEngine {
  TargetMachine &TM;       // The current target we are compiling to
  TargetJITInfo &TJI;      // The JITInfo for the target we are compiling to
  MachineCodeEmitter *MCE; // MCE object

  JITState *jitstate;

  JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji, 
      JITMemoryManager *JMM, bool Fast);
public:
  ~JIT();

  static void Register() {
    JITCtor = create;
  }
  
  /// getJITInfo - Return the target JIT information structure.
  ///
  TargetJITInfo &getJITInfo() const { return TJI; }

  /// create - Create an return a new JIT compiler if there is one available
  /// for the current target.  Otherwise, return null.
  ///
  static ExecutionEngine *create(ModuleProvider *MP, std::string *Err,
                                 bool Fast = false) {
    return createJIT(MP, Err, 0, Fast);
  }

  virtual void addModuleProvider(ModuleProvider *MP);
  virtual Module *removeModuleProvider(ModuleProvider *MP,
                                       std::string *ErrInfo = 0);

  /// runFunction - Start execution with the specified function and arguments.
  ///
  virtual GenericValue runFunction(Function *F,
                                   const std::vector<GenericValue> &ArgValues);

  /// getPointerToNamedFunction - This method returns the address of the
  /// specified function by using the dlsym function call.  As such it is only
  /// useful for resolving library symbols, not code generated symbols.
  ///
  void *getPointerToNamedFunction(const std::string &Name);

  // CompilationCallback - Invoked the first time that a call site is found,
  // which causes lazy compilation of the target function.
  //
  static void CompilationCallback();

  /// getPointerToFunction - This returns the address of the specified function,
  /// compiling it if necessary.
  ///
  void *getPointerToFunction(Function *F);

  /// getOrEmitGlobalVariable - Return the address of the specified global
  /// variable, possibly emitting it to memory if needed.  This is used by the
  /// Emitter.
  void *getOrEmitGlobalVariable(const GlobalVariable *GV);

  /// getPointerToFunctionOrStub - If the specified function has been
  /// code-gen'd, return a pointer to the function.  If not, compile it, or use
  /// a stub to implement lazy compilation if available.
  ///
  void *getPointerToFunctionOrStub(Function *F);

  /// recompileAndRelinkFunction - This method is used to force a function
  /// which has already been compiled, to be compiled again, possibly
  /// after it has been modified. Then the entry to the old copy is overwritten
  /// with a branch to the new copy. If there was no old copy, this acts
  /// just like JIT::getPointerToFunction().
  ///
  void *recompileAndRelinkFunction(Function *F);

  /// freeMachineCodeForFunction - deallocate memory used to code-generate this
  /// Function.
  ///
  void freeMachineCodeForFunction(Function *F);

  /// getCodeEmitter - Return the code emitter this JIT is emitting into.
  MachineCodeEmitter *getCodeEmitter() const { return MCE; }
  
  static ExecutionEngine *createJIT(ModuleProvider *MP, std::string *Err,
                                    JITMemoryManager *JMM, bool Fast);
  
private:
  static MachineCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM);
  void runJITOnFunction (Function *F);
};

} // End llvm namespace

#endif