X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FExecutionEngine%2FExecutionEngine.h;h=327e9c6aa9290403ec6ff32b4b26b5bb0aa43ef9;hb=77f86ad08775e0ed2a704ef09ffff3dbd6e04583;hp=051d83962898e9db30cff02bb626706ce5e7fb00;hpb=726c1ef2bdd72975f41e3188371bb7d6f40401be;p=oota-llvm.git diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 051d8396289..327e9c6aa92 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -12,18 +12,19 @@ // //===----------------------------------------------------------------------===// -#ifndef EXECUTION_ENGINE_H -#define EXECUTION_ENGINE_H +#ifndef LLVM_EXECUTION_ENGINE_H +#define LLVM_EXECUTION_ENGINE_H #include #include #include #include -#include "llvm/Support/MutexGuard.h" +#include "llvm/System/Mutex.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { -union GenericValue; +struct GenericValue; class Constant; class Function; class GlobalVariable; @@ -32,6 +33,8 @@ class Module; class ModuleProvider; class TargetData; class Type; +class MutexGuard; +class JITMemoryManager; class ExecutionEngineState { private: @@ -47,54 +50,109 @@ private: public: std::map & - getGlobalAddressMap(const MutexGuard &locked) { + getGlobalAddressMap(const MutexGuard &) { return GlobalAddressMap; } std::map & - getGlobalAddressReverseMap(const MutexGuard& locked) { + getGlobalAddressReverseMap(const MutexGuard &) { return GlobalAddressReverseMap; } }; class ExecutionEngine { - Module &CurMod; const TargetData *TD; - ExecutionEngineState state; + bool LazyCompilationDisabled; + bool GVCompilationDisabled; + bool SymbolSearchingDisabled; protected: - ModuleProvider *MP; - - void setTargetData(const TargetData &td) { - TD = &td; + /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We + /// use a smallvector to optimize for the case where there is only one module. + SmallVector 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 JIT and Interpreter set these functions to ctor pointers // at startup time if they are linked in. - typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*); + typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*, std::string*, + bool Fast); static EECtorFn JITCtor, InterpCtor; - + + /// 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*); + static EERegisterFn ExceptionTableRegister; + public: /// lock - This lock is 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; // Used to make this class and subclasses thread-safe - ExecutionEngine(ModuleProvider *P); - ExecutionEngine(Module *M); - virtual ~ExecutionEngine(); + //===--------------------------------------------------------------------===// + // ExecutionEngine Startup + //===--------------------------------------------------------------------===// - Module &getModule() const { return CurMod; } - const TargetData &getTargetData() const { return *TD; } + virtual ~ExecutionEngine(); /// create - This is the factory method for creating an execution engine which - /// is appropriate for the current machine. + /// is appropriate for the current machine. This takes ownership of the + /// module provider. static ExecutionEngine *create(ModuleProvider *MP, - bool ForceInterpreter = false); + bool ForceInterpreter = false, + std::string *ErrorStr = 0, + bool Fast = false); + + /// create - This is the factory method for creating an execution engine which + /// is appropriate for the current machine. This takes ownership of the + /// module. + static ExecutionEngine *create(Module *M); + + /// 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 ModuleProvider and JITMemoryManager if successful. + static ExecutionEngine *createJIT(ModuleProvider *MP, + std::string *ErrorStr = 0, + JITMemoryManager *JMM = 0, + bool Fast = false); + + + + /// addModuleProvider - Add a ModuleProvider to the list of modules that we + /// can JIT from. Note that this takes ownership of the ModuleProvider: when + /// the ExecutionEngine is destroyed, it destroys the MP as well. + virtual void addModuleProvider(ModuleProvider *P) { + Modules.push_back(P); + } + + //===----------------------------------------------------------------------===// + + const TargetData *getTargetData() const { return TD; } + + /// removeModuleProvider - Remove a ModuleProvider from the list of modules. + /// Release module from ModuleProvider. + virtual Module* removeModuleProvider(ModuleProvider *P, + std::string *ErrInfo = 0); + + /// 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. /// @@ -102,9 +160,13 @@ public: const std::vector &ArgValues) = 0; /// runStaticConstructorsDestructors - This method is used to execute all of - /// the static constructors or destructors for a module, depending on the + /// the static constructors or destructors for a program, depending on the /// value of isDtors. void runStaticConstructorsDestructors(bool isDtors); + /// runStaticConstructorsDestructors - This method is used to execute all of + /// the static constructors or destructors for a module, depending on the + /// value of isDtors. + void runStaticConstructorsDestructors(Module *module, bool isDtors); /// runFunctionAsMain - This is a helper function which wraps runFunction to @@ -114,58 +176,32 @@ public: const char * const * envp); - void addGlobalMapping(const GlobalValue *GV, void *Addr) { - MutexGuard locked(lock); - - void *&CurVal = state.getGlobalAddressMap(locked)[GV]; - assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); - CurVal = Addr; - - // If we are using the reverse mapping, add it too - if (!state.getGlobalAddressReverseMap(locked).empty()) { - const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; - assert((V == 0 || GV == 0) && "GlobalMapping already established!"); - V = GV; - } - } - + /// 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. + void addGlobalMapping(const GlobalValue *GV, void *Addr); + /// clearAllGlobalMappings - Clear all global mappings and start over again /// use in dynamic compilation scenarios when you want to move globals - void clearAllGlobalMappings() { - MutexGuard locked(lock); - - state.getGlobalAddressMap(locked).clear(); - state.getGlobalAddressReverseMap(locked).clear(); - } - + 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. - void updateGlobalMapping(const GlobalValue *GV, void *Addr) { - MutexGuard locked(lock); - - void *&CurVal = state.getGlobalAddressMap(locked)[GV]; - if (CurVal && !state.getGlobalAddressReverseMap(locked).empty()) - state.getGlobalAddressReverseMap(locked).erase(CurVal); - CurVal = Addr; - - // If we are using the reverse mapping, add it too - if (!state.getGlobalAddressReverseMap(locked).empty()) { - const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; - assert((V == 0 || GV == 0) && "GlobalMapping already established!"); - V = GV; - } - } - + /// 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 available, otherwise it returns null. + /// global value if it is has already been codegen'd, otherwise it returns + /// null. /// - void *getPointerToGlobalIfAvailable(const GlobalValue *GV) { - MutexGuard locked(lock); - - std::map::iterator I = - state.getGlobalAddressMap(locked).find(GV); - return I != state.getGlobalAddressMap(locked).end() ? I->second : 0; - } + 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. @@ -193,7 +229,8 @@ public: const GlobalValue *getGlobalValueAtAddress(void *Addr); - void StoreValueToMemory(GenericValue Val, GenericValue *Ptr, const Type *Ty); + void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, + const Type *Ty); void InitializeMemory(const Constant *Init, void *Addr); /// recompileAndRelinkFunction - This method is used to force a function @@ -216,8 +253,60 @@ public: virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) { return getPointerToGlobal((GlobalValue*)GV); } + + /// DisableLazyCompilation - If called, the JIT will abort if lazy compilation + /// is ever attempted. + void DisableLazyCompilation(bool Disabled = true) { + LazyCompilationDisabled = Disabled; + } + bool isLazyCompilationDisabled() const { + return LazyCompilationDisabled; + } + + /// 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. + static void InstallExceptionTableRegister(void (*F)(void*)) { + ExceptionTableRegister = F; + } + + /// RegisterTable - Registers the given pointer as an exception table. It uses + /// the ExceptionTableRegister function. + static void RegisterTable(void* res) { + if (ExceptionTableRegister) + ExceptionTableRegister(res); + } protected: + explicit ExecutionEngine(ModuleProvider *P); + void emitGlobals(); // EmitGlobalVariable - This method emits the specified global variable to the @@ -226,7 +315,8 @@ protected: void EmitGlobalVariable(const GlobalVariable *GV); GenericValue getConstantValue(const Constant *C); - GenericValue LoadValueFromMemory(GenericValue *Ptr, const Type *Ty); + void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, + const Type *Ty); }; } // End llvm namespace