| //===- ExecutionEngine.h - Abstract Execution Engine Interface --*- 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 abstract interface that implements execution support | |
| // for LLVM. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_EXECUTION_ENGINE_H | |
| #define LLVM_EXECUTION_ENGINE_H | |
| #include <vector> | |
| #include <map> | |
| #include <string> | |
| #include "llvm/MC/MCCodeGenInfo.h" | |
| #include "llvm/ADT/SmallVector.h" | |
| #include "llvm/ADT/StringRef.h" | |
| #include "llvm/ADT/ValueMap.h" | |
| #include "llvm/ADT/DenseMap.h" | |
| #include "llvm/Support/ValueHandle.h" | |
| #include "llvm/Support/Mutex.h" | |
| #include "llvm/Target/TargetMachine.h" | |
| namespace llvm { | |
| struct GenericValue; | |
| class Constant; | |
| class ExecutionEngine; | |
| class Function; | |
| class GlobalVariable; | |
| class GlobalValue; | |
| class JITEventListener; | |
| class JITMemoryManager; | |
| class MachineCodeInfo; | |
| class Module; | |
| class MutexGuard; | |
| class TargetData; | |
| class Type; | |
| /// \brief Helper class for helping synchronize access to the global address map | |
| /// table. | |
| class ExecutionEngineState { | |
| public: | |
| struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> { | |
| typedef ExecutionEngineState *ExtraData; | |
| static sys::Mutex *getMutex(ExecutionEngineState *EES); | |
| static void onDelete(ExecutionEngineState *EES, const GlobalValue *Old); | |
| static void onRAUW(ExecutionEngineState *, const GlobalValue *, | |
| const GlobalValue *); | |
| }; | |
| typedef ValueMap<const GlobalValue *, void *, AddressMapConfig> | |
| GlobalAddressMapTy; | |
| private: | |
| ExecutionEngine &EE; | |
| /// GlobalAddressMap - A mapping between LLVM global values and their | |
| /// actualized version... | |
| GlobalAddressMapTy GlobalAddressMap; | |
| /// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap, | |
| /// used to convert raw addresses into the LLVM global value that is emitted | |
| /// at the address. This map is not computed unless getGlobalValueAtAddress | |
| /// is called at some point. | |
| std::map<void *, AssertingVH<const GlobalValue> > GlobalAddressReverseMap; | |
| public: | |
| ExecutionEngineState(ExecutionEngine &EE); | |
| GlobalAddressMapTy &getGlobalAddressMap(const MutexGuard &) { | |
| return GlobalAddressMap; | |
| } | |
| std::map<void*, AssertingVH<const GlobalValue> > & | |
| getGlobalAddressReverseMap(const MutexGuard &) { | |
| return GlobalAddressReverseMap; | |
| } | |
| /// \brief Erase an entry from the mapping table. | |
| /// | |
| /// \returns The address that \arg ToUnmap was happed to. | |
| void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap); | |
| }; | |
| /// \brief Abstract interface for implementation execution of LLVM modules, | |
| /// designed to support both interpreter and just-in-time (JIT) compiler | |
| /// implementations. | |
| class ExecutionEngine { | |
| /// The state object holding the global address mapping, which must be | |
| /// accessed synchronously. | |
| // | |
| // FIXME: There is no particular need the entire map needs to be | |
| // synchronized. Wouldn't a reader-writer design be better here? | |
| ExecutionEngineState EEState; | |
| /// The target data for the platform for which execution is being performed. | |
| const TargetData *TD; | |
| /// Whether lazy JIT compilation is enabled. | |
| bool CompilingLazily; | |
| /// Whether JIT compilation of external global variables is allowed. | |
| bool GVCompilationDisabled; | |
| /// Whether the JIT should perform lookups of external symbols (e.g., | |
| /// using dlsym). | |
| bool SymbolSearchingDisabled; | |
| friend class EngineBuilder; // To allow access to JITCtor and InterpCtor. | |
| protected: | |
| /// The list of Modules that we are JIT'ing from. We use a SmallVector to | |
| /// optimize for the case where there is only one module. | |
| SmallVector<Module*, 1> Modules; | |
| void setTargetData(const TargetData *td) { TD = td; } | |
| /// getMemoryforGV - Allocate memory for a global variable. | |
| virtual char *getMemoryForGV(const GlobalVariable *GV); | |
| // To avoid having libexecutionengine depend on the JIT and interpreter | |
| // libraries, the execution engine implementations set these functions to ctor | |
| // pointers at startup time if they are linked in. | |
| static ExecutionEngine *(*JITCtor)( | |
| Module *M, | |
| std::string *ErrorStr, | |
| JITMemoryManager *JMM, | |
| CodeGenOpt::Level OptLevel, | |
| bool GVsWithCode, | |
| TargetMachine *TM); | |
| static ExecutionEngine *(*MCJITCtor)( | |
| Module *M, | |
| std::string *ErrorStr, | |
| JITMemoryManager *JMM, | |
| CodeGenOpt::Level OptLevel, | |
| bool GVsWithCode, | |
| TargetMachine *TM); | |
| static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); | |
| /// LazyFunctionCreator - If an unknown function is needed, this function | |
| /// pointer is invoked to create it. If this returns null, the JIT will | |
| /// abort. | |
| void *(*LazyFunctionCreator)(const std::string &); | |
| /// ExceptionTableRegister - If Exception Handling is set, the JIT will | |
| /// register dwarf tables with this function. | |
| typedef void (*EERegisterFn)(void*); | |
| EERegisterFn ExceptionTableRegister; | |
| EERegisterFn ExceptionTableDeregister; | |
| /// This maps functions to their exception tables frames. | |
| DenseMap<const Function*, void*> AllExceptionTables; | |
| public: | |
| /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and | |
| /// JITEmitter classes. It must be held while changing the internal state of | |
| /// any of those classes. | |
| sys::Mutex lock; | |
| //===--------------------------------------------------------------------===// | |
| // ExecutionEngine Startup | |
| //===--------------------------------------------------------------------===// | |
| virtual ~ExecutionEngine(); | |
| /// create - This is the factory method for creating an execution engine which | |
| /// is appropriate for the current machine. This takes ownership of the | |
| /// module. | |
| /// | |
| /// \param GVsWithCode - Allocating globals with code breaks | |
| /// freeMachineCodeForFunction and is probably unsafe and bad for performance. | |
| /// However, we have clients who depend on this behavior, so we must support | |
| /// it. Eventually, when we're willing to break some backwards compatibility, | |
| /// this flag should be flipped to false, so that by default | |
| /// freeMachineCodeForFunction works. | |
| static ExecutionEngine *create(Module *M, | |
| bool ForceInterpreter = false, | |
| std::string *ErrorStr = 0, | |
| CodeGenOpt::Level OptLevel = | |
| CodeGenOpt::Default, | |
| bool GVsWithCode = true); | |
| /// createJIT - This is the factory method for creating a JIT for the current | |
| /// machine, it does not fall back to the interpreter. This takes ownership | |
| /// of the Module and JITMemoryManager if successful. | |
| /// | |
| /// Clients should make sure to initialize targets prior to calling this | |
| /// function. | |
| static ExecutionEngine *createJIT(Module *M, | |
| std::string *ErrorStr = 0, | |
| JITMemoryManager *JMM = 0, | |
| CodeGenOpt::Level OptLevel = | |
| CodeGenOpt::Default, | |
| bool GVsWithCode = true, | |
| Reloc::Model RM = Reloc::Default, | |
| CodeModel::Model CMM = | |
| CodeModel::JITDefault); | |
| /// addModule - Add a Module to the list of modules that we can JIT from. | |
| /// Note that this takes ownership of the Module: when the ExecutionEngine is | |
| /// destroyed, it destroys the Module as well. | |
| virtual void addModule(Module *M) { | |
| Modules.push_back(M); | |
| } | |
| //===--------------------------------------------------------------------===// | |
| const TargetData *getTargetData() const { return TD; } | |
| /// removeModule - Remove a Module from the list of modules. Returns true if | |
| /// M is found. | |
| virtual bool removeModule(Module *M); | |
| /// FindFunctionNamed - Search all of the active modules to find the one that | |
| /// defines FnName. This is very slow operation and shouldn't be used for | |
| /// general code. | |
| Function *FindFunctionNamed(const char *FnName); | |
| /// runFunction - Execute the specified function with the specified arguments, | |
| /// and return the result. | |
| virtual GenericValue runFunction(Function *F, | |
| const std::vector<GenericValue> &ArgValues) = 0; | |
| /// runStaticConstructorsDestructors - This method is used to execute all of | |
| /// the static constructors or destructors for a program. | |
| /// | |
| /// \param isDtors - Run the destructors instead of constructors. | |
| void runStaticConstructorsDestructors(bool isDtors); | |
| /// runStaticConstructorsDestructors - This method is used to execute all of | |
| /// the static constructors or destructors for a particular module. | |
| /// | |
| /// \param isDtors - Run the destructors instead of constructors. | |
| void runStaticConstructorsDestructors(Module *module, bool isDtors); | |
| /// runFunctionAsMain - This is a helper function which wraps runFunction to | |
| /// handle the common task of starting up main with the specified argc, argv, | |
| /// and envp parameters. | |
| int runFunctionAsMain(Function *Fn, const std::vector<std::string> &argv, | |
| const char * const * envp); | |
| /// addGlobalMapping - Tell the execution engine that the specified global is | |
| /// at the specified location. This is used internally as functions are JIT'd | |
| /// and as global variables are laid out in memory. It can and should also be | |
| /// used by clients of the EE that want to have an LLVM global overlay | |
| /// existing data in memory. Mappings are automatically removed when their | |
| /// GlobalValue is destroyed. | |
| void addGlobalMapping(const GlobalValue *GV, void *Addr); | |
| /// clearAllGlobalMappings - Clear all global mappings and start over again, | |
| /// for use in dynamic compilation scenarios to move globals. | |
| void clearAllGlobalMappings(); | |
| /// clearGlobalMappingsFromModule - Clear all global mappings that came from a | |
| /// particular module, because it has been removed from the JIT. | |
| void clearGlobalMappingsFromModule(Module *M); | |
| /// updateGlobalMapping - Replace an existing mapping for GV with a new | |
| /// address. This updates both maps as required. If "Addr" is null, the | |
| /// entry for the global is removed from the mappings. This returns the old | |
| /// value of the pointer, or null if it was not in the map. | |
| void *updateGlobalMapping(const GlobalValue *GV, void *Addr); | |
| /// getPointerToGlobalIfAvailable - This returns the address of the specified | |
| /// global value if it is has already been codegen'd, otherwise it returns | |
| /// null. | |
| void *getPointerToGlobalIfAvailable(const GlobalValue *GV); | |
| /// getPointerToGlobal - This returns the address of the specified global | |
| /// value. This may involve code generation if it's a function. | |
| void *getPointerToGlobal(const GlobalValue *GV); | |
| /// getPointerToFunction - The different EE's represent function bodies in | |
| /// different ways. They should each implement this to say what a function | |
| /// pointer should look like. When F is destroyed, the ExecutionEngine will | |
| /// remove its global mapping and free any machine code. Be sure no threads | |
| /// are running inside F when that happens. | |
| virtual void *getPointerToFunction(Function *F) = 0; | |
| /// getPointerToBasicBlock - The different EE's represent basic blocks in | |
| /// different ways. Return the representation for a blockaddress of the | |
| /// specified block. | |
| virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; | |
| /// 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. See | |
| /// getPointerToFunction for the requirements on destroying F. | |
| virtual void *getPointerToFunctionOrStub(Function *F) { | |
| // Default implementation, just codegen the function. | |
| return getPointerToFunction(F); | |
| } | |
| // The JIT overrides a version that actually does this. | |
| virtual void runJITOnFunction(Function *, MachineCodeInfo * = 0) { } | |
| /// getGlobalValueAtAddress - Return the LLVM global value object that starts | |
| /// at the specified address. | |
| /// | |
| const GlobalValue *getGlobalValueAtAddress(void *Addr); | |
| /// StoreValueToMemory - Stores the data in Val of type Ty at address Ptr. | |
| /// Ptr is the address of the memory at which to store Val, cast to | |
| /// GenericValue *. It is not a pointer to a GenericValue containing the | |
| /// address at which to store Val. | |
| void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, | |
| Type *Ty); | |
| void InitializeMemory(const Constant *Init, void *Addr); | |
| /// 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 | |
| /// VM::getPointerToFunction(). | |
| virtual void *recompileAndRelinkFunction(Function *F) = 0; | |
| /// freeMachineCodeForFunction - Release memory in the ExecutionEngine | |
| /// corresponding to the machine code emitted to execute this function, useful | |
| /// for garbage-collecting generated code. | |
| virtual void freeMachineCodeForFunction(Function *F) = 0; | |
| /// getOrEmitGlobalVariable - Return the address of the specified global | |
| /// variable, possibly emitting it to memory if needed. This is used by the | |
| /// Emitter. | |
| virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) { | |
| return getPointerToGlobal((GlobalValue*)GV); | |
| } | |
| /// Registers a listener to be called back on various events within | |
| /// the JIT. See JITEventListener.h for more details. Does not | |
| /// take ownership of the argument. The argument may be NULL, in | |
| /// which case these functions do nothing. | |
| virtual void RegisterJITEventListener(JITEventListener *) {} | |
| virtual void UnregisterJITEventListener(JITEventListener *) {} | |
| /// DisableLazyCompilation - When lazy compilation is off (the default), the | |
| /// JIT will eagerly compile every function reachable from the argument to | |
| /// getPointerToFunction. If lazy compilation is turned on, the JIT will only | |
| /// compile the one function and emit stubs to compile the rest when they're | |
| /// first called. If lazy compilation is turned off again while some lazy | |
| /// stubs are still around, and one of those stubs is called, the program will | |
| /// abort. | |
| /// | |
| /// In order to safely compile lazily in a threaded program, the user must | |
| /// ensure that 1) only one thread at a time can call any particular lazy | |
| /// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock | |
| /// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a | |
| /// lazy stub. See http://llvm.org/PR5184 for details. | |
| void DisableLazyCompilation(bool Disabled = true) { | |
| CompilingLazily = !Disabled; | |
| } | |
| bool isCompilingLazily() const { | |
| return CompilingLazily; | |
| } | |
| // Deprecated in favor of isCompilingLazily (to reduce double-negatives). | |
| // Remove this in LLVM 2.8. | |
| bool isLazyCompilationDisabled() const { | |
| return !CompilingLazily; | |
| } | |
| /// DisableGVCompilation - If called, the JIT will abort if it's asked to | |
| /// allocate space and populate a GlobalVariable that is not internal to | |
| /// the module. | |
| void DisableGVCompilation(bool Disabled = true) { | |
| GVCompilationDisabled = Disabled; | |
| } | |
| bool isGVCompilationDisabled() const { | |
| return GVCompilationDisabled; | |
| } | |
| /// DisableSymbolSearching - If called, the JIT will not try to lookup unknown | |
| /// symbols with dlsym. A client can still use InstallLazyFunctionCreator to | |
| /// resolve symbols in a custom way. | |
| void DisableSymbolSearching(bool Disabled = true) { | |
| SymbolSearchingDisabled = Disabled; | |
| } | |
| bool isSymbolSearchingDisabled() const { | |
| return SymbolSearchingDisabled; | |
| } | |
| /// InstallLazyFunctionCreator - If an unknown function is needed, the | |
| /// specified function pointer is invoked to create it. If it returns null, | |
| /// the JIT will abort. | |
| void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { | |
| LazyFunctionCreator = P; | |
| } | |
| /// InstallExceptionTableRegister - The JIT will use the given function | |
| /// to register the exception tables it generates. | |
| void InstallExceptionTableRegister(EERegisterFn F) { | |
| ExceptionTableRegister = F; | |
| } | |
| void InstallExceptionTableDeregister(EERegisterFn F) { | |
| ExceptionTableDeregister = F; | |
| } | |
| /// RegisterTable - Registers the given pointer as an exception table. It | |
| /// uses the ExceptionTableRegister function. | |
| void RegisterTable(const Function *fn, void* res) { | |
| if (ExceptionTableRegister) { | |
| ExceptionTableRegister(res); | |
| AllExceptionTables[fn] = res; | |
| } | |
| } | |
| /// DeregisterTable - Deregisters the exception frame previously registered | |
| /// for the given function. | |
| void DeregisterTable(const Function *Fn) { | |
| if (ExceptionTableDeregister) { | |
| DenseMap<const Function*, void*>::iterator frame = | |
| AllExceptionTables.find(Fn); | |
| if(frame != AllExceptionTables.end()) { | |
| ExceptionTableDeregister(frame->second); | |
| AllExceptionTables.erase(frame); | |
| } | |
| } | |
| } | |
| /// DeregisterAllTables - Deregisters all previously registered pointers to an | |
| /// exception tables. It uses the ExceptionTableoDeregister function. | |
| void DeregisterAllTables(); | |
| protected: | |
| explicit ExecutionEngine(Module *M); | |
| void emitGlobals(); | |
| void EmitGlobalVariable(const GlobalVariable *GV); | |
| GenericValue getConstantValue(const Constant *C); | |
| void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, | |
| Type *Ty); | |
| }; | |
| namespace EngineKind { | |
| // These are actually bitmasks that get or-ed together. | |
| enum Kind { | |
| JIT = 0x1, | |
| Interpreter = 0x2 | |
| }; | |
| const static Kind Either = (Kind)(JIT | Interpreter); | |
| } | |
| /// EngineBuilder - Builder class for ExecutionEngines. Use this by | |
| /// stack-allocating a builder, chaining the various set* methods, and | |
| /// terminating it with a .create() call. | |
| class EngineBuilder { | |
| private: | |
| Module *M; | |
| EngineKind::Kind WhichEngine; | |
| std::string *ErrorStr; | |
| CodeGenOpt::Level OptLevel; | |
| JITMemoryManager *JMM; | |
| bool AllocateGVsWithCode; | |
| Reloc::Model RelocModel; | |
| CodeModel::Model CMModel; | |
| std::string MArch; | |
| std::string MCPU; | |
| SmallVector<std::string, 4> MAttrs; | |
| bool UseMCJIT; | |
| /// InitEngine - Does the common initialization of default options. | |
| void InitEngine() { | |
| WhichEngine = EngineKind::Either; | |
| ErrorStr = NULL; | |
| OptLevel = CodeGenOpt::Default; | |
| JMM = NULL; | |
| AllocateGVsWithCode = false; | |
| RelocModel = Reloc::Default; | |
| CMModel = CodeModel::JITDefault; | |
| UseMCJIT = false; | |
| } | |
| public: | |
| /// EngineBuilder - Constructor for EngineBuilder. If create() is called and | |
| /// is successful, the created engine takes ownership of the module. | |
| EngineBuilder(Module *m) : M(m) { | |
| InitEngine(); | |
| } | |
| /// setEngineKind - Controls whether the user wants the interpreter, the JIT, | |
| /// or whichever engine works. This option defaults to EngineKind::Either. | |
| EngineBuilder &setEngineKind(EngineKind::Kind w) { | |
| WhichEngine = w; | |
| return *this; | |
| } | |
| /// setJITMemoryManager - Sets the memory manager to use. This allows | |
| /// clients to customize their memory allocation policies. If create() is | |
| /// called and is successful, the created engine takes ownership of the | |
| /// memory manager. This option defaults to NULL. | |
| EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) { | |
| JMM = jmm; | |
| return *this; | |
| } | |
| /// setErrorStr - Set the error string to write to on error. This option | |
| /// defaults to NULL. | |
| EngineBuilder &setErrorStr(std::string *e) { | |
| ErrorStr = e; | |
| return *this; | |
| } | |
| /// setOptLevel - Set the optimization level for the JIT. This option | |
| /// defaults to CodeGenOpt::Default. | |
| EngineBuilder &setOptLevel(CodeGenOpt::Level l) { | |
| OptLevel = l; | |
| return *this; | |
| } | |
| /// setRelocationModel - Set the relocation model that the ExecutionEngine | |
| /// target is using. Defaults to target specific default "Reloc::Default". | |
| EngineBuilder &setRelocationModel(Reloc::Model RM) { | |
| RelocModel = RM; | |
| return *this; | |
| } | |
| /// setCodeModel - Set the CodeModel that the ExecutionEngine target | |
| /// data is using. Defaults to target specific default | |
| /// "CodeModel::JITDefault". | |
| EngineBuilder &setCodeModel(CodeModel::Model M) { | |
| CMModel = M; | |
| return *this; | |
| } | |
| /// setAllocateGVsWithCode - Sets whether global values should be allocated | |
| /// into the same buffer as code. For most applications this should be set | |
| /// to false. Allocating globals with code breaks freeMachineCodeForFunction | |
| /// and is probably unsafe and bad for performance. However, we have clients | |
| /// who depend on this behavior, so we must support it. This option defaults | |
| /// to false so that users of the new API can safely use the new memory | |
| /// manager and free machine code. | |
| EngineBuilder &setAllocateGVsWithCode(bool a) { | |
| AllocateGVsWithCode = a; | |
| return *this; | |
| } | |
| /// setMArch - Override the architecture set by the Module's triple. | |
| EngineBuilder &setMArch(StringRef march) { | |
| MArch.assign(march.begin(), march.end()); | |
| return *this; | |
| } | |
| /// setMCPU - Target a specific cpu type. | |
| EngineBuilder &setMCPU(StringRef mcpu) { | |
| MCPU.assign(mcpu.begin(), mcpu.end()); | |
| return *this; | |
| } | |
| /// setUseMCJIT - Set whether the MC-JIT implementation should be used | |
| /// (experimental). | |
| EngineBuilder &setUseMCJIT(bool Value) { | |
| UseMCJIT = Value; | |
| return *this; | |
| } | |
| /// setMAttrs - Set cpu-specific attributes. | |
| template<typename StringSequence> | |
| EngineBuilder &setMAttrs(const StringSequence &mattrs) { | |
| MAttrs.clear(); | |
| MAttrs.append(mattrs.begin(), mattrs.end()); | |
| return *this; | |
| } | |
| /// selectTarget - Pick a target either via -march or by guessing the native | |
| /// arch. Add any CPU features specified via -mcpu or -mattr. | |
| static TargetMachine *selectTarget(Module *M, | |
| StringRef MArch, | |
| StringRef MCPU, | |
| const SmallVectorImpl<std::string>& MAttrs, | |
| Reloc::Model RM, | |
| CodeModel::Model CM, | |
| std::string *Err); | |
| ExecutionEngine *create(); | |
| }; | |
| } // End llvm namespace | |
| #endif |