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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
//===-- 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);
/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
/// Relases the Module from the ModuleProvider, materializing it in the
/// process, and returns the materialized Module.
virtual Module *removeModuleProvider(ModuleProvider *MP,
std::string *ErrInfo = 0);
/// deleteModuleProvider - Remove a ModuleProvider from the list of modules,
/// and deletes the ModuleProvider and owned Module. Avoids materializing
/// the underlying module.
virtual void deleteModuleProvider(ModuleProvider *P,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.
///
/// If AbortOnFailure is false and no function with the given name is
/// found, this function silently returns a null pointer. Otherwise,
/// it prints a message to stderr and aborts.
///
void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
// 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);
protected:
/// getMemoryforGV - Allocate memory for a global variable.
virtual char* getMemoryForGV(const GlobalVariable* GV);
};
} // End llvm namespace
#endif
|