X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FExecutionEngine%2FExecutionEngine.h;h=199cf8deb8bbcaff47a8ed6740b122721d0a30e5;hb=42fdb1f00ffc5d0a0326f11cadaeec1c26691688;hp=ef5e9ec644f15a5ff8b4305705c95173d5fd2970;hpb=714b34fc24d5df02aff01bd64eb80e5945d663ac;p=oota-llvm.git diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index ef5e9ec644f..199cf8deb8b 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -12,24 +12,28 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTION_ENGINE_H -#define LLVM_EXECUTION_ENGINE_H +#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H +#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H -#include -#include -#include +#include "llvm-c/ExecutionEngine.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/MC/MCCodeGenInfo.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include namespace llvm { struct GenericValue; class Constant; +class DataLayout; class ExecutionEngine; class Function; class GlobalVariable; @@ -39,9 +43,16 @@ class JITMemoryManager; class MachineCodeInfo; class Module; class MutexGuard; -class TargetData; +class ObjectCache; +class RTDyldMemoryManager; +class Triple; class Type; +namespace object { + class Archive; + class ObjectFile; +} + /// \brief Helper class for helping synchronize access to the global address map /// table. class ExecutionEngineState { @@ -84,7 +95,7 @@ public: /// \brief Erase an entry from the mapping table. /// - /// \returns The address that \arg ToUnmap was happed to. + /// \returns The address that \p ToUnmap was happed to. void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap); }; @@ -100,7 +111,7 @@ class ExecutionEngine { ExecutionEngineState EEState; /// The target data for the platform for which execution is being performed. - const TargetData *TD; + const DataLayout *TD; /// Whether lazy JIT compilation is enabled. bool CompilingLazily; @@ -119,9 +130,7 @@ protected: /// optimize for the case where there is only one module. SmallVector Modules; - void setTargetData(const TargetData *td) { - TD = td; - } + void setDataLayout(const DataLayout *td) { TD = td; } /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -133,41 +142,23 @@ protected: Module *M, std::string *ErrorStr, JITMemoryManager *JMM, - CodeGenOpt::Level OptLevel, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl& MAttrs); + TargetMachine *TM); static ExecutionEngine *(*MCJITCtor)( Module *M, std::string *ErrorStr, - JITMemoryManager *JMM, - CodeGenOpt::Level OptLevel, + RTDyldMemoryManager *MCJMM, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl& MAttrs); - static ExecutionEngine *(*InterpCtor)(Module *M, - std::string *ErrorStr); + 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 AllExceptionTables; - - public: - /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and + /// lock - This lock protects the ExecutionEngine, MCJIT, JIT, JITResolver and /// JITEmitter classes. It must be held while changing the internal state of /// any of those classes. sys::Mutex lock; @@ -185,14 +176,14 @@ public: /// \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 compatability, + /// 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, + CodeGenOpt::Default, bool GVsWithCode = true); /// createJIT - This is the factory method for creating a JIT for the current @@ -205,10 +196,11 @@ public: std::string *ErrorStr = 0, JITMemoryManager *JMM = 0, CodeGenOpt::Level OptLevel = - CodeGenOpt::Default, + CodeGenOpt::Default, bool GVsWithCode = true, + Reloc::Model RM = Reloc::Default, CodeModel::Model CMM = - CodeModel::Default); + 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 @@ -217,9 +209,36 @@ public: Modules.push_back(M); } + /// addObjectFile - Add an ObjectFile to the execution engine. + /// + /// This method is only supported by MCJIT. MCJIT will immediately load the + /// object into memory and adds its symbols to the list used to resolve + /// external symbols while preparing other objects for execution. + /// + /// Objects added using this function will not be made executable until + /// needed by another object. + /// + /// MCJIT will take ownership of the ObjectFile. + virtual void addObjectFile(object::ObjectFile *O) { + llvm_unreachable( + "ExecutionEngine subclass doesn't implement addObjectFile."); + } + + /// addArchive - Add an Archive to the execution engine. + /// + /// This method is only supported by MCJIT. MCJIT will use the archive to + /// resolve external symbols in objects it is loading. If a symbol is found + /// in the Archive the contained object file will be extracted (in memory) + /// and loaded for possible execution. + /// + /// MCJIT will take ownership of the Archive. + virtual void addArchive(object::Archive *A) { + llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive."); + } + //===--------------------------------------------------------------------===// - const TargetData *getTargetData() const { return TD; } + const DataLayout *getDataLayout() const { return TD; } /// removeModule - Remove a Module from the list of modules. Returns true if /// M is found. @@ -228,18 +247,70 @@ public: /// 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); + virtual 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 &ArgValues) = 0; + /// 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. + /// + /// This function is deprecated for the MCJIT execution engine. + /// + /// FIXME: the JIT and MCJIT interfaces should be disentangled or united + /// again, if possible. + /// + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) = 0; + + /// mapSectionAddress - map a section to its target address space value. + /// Map the address of a JIT section as returned from the memory manager + /// to the address in the target process as the running code will see it. + /// This is the address which will be used for relocation resolution. + virtual void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) { + llvm_unreachable("Re-mapping of section addresses not supported with this " + "EE!"); + } + + /// generateCodeForModule - Run code generationen for the specified module and + /// load it into memory. + /// + /// When this function has completed, all code and data for the specified + /// module, and any module on which this module depends, will be generated + /// and loaded into memory, but relocations will not yet have been applied + /// and all memory will be readable and writable but not executable. + /// + /// This function is primarily useful when generating code for an external + /// target, allowing the client an opportunity to remap section addresses + /// before relocations are applied. Clients that intend to execute code + /// locally can use the getFunctionAddress call, which will generate code + /// and apply final preparations all in one step. + /// + /// This method has no effect for the legacy JIT engine or the interpeter. + virtual void generateCodeForModule(Module *M) {} + + /// finalizeObject - ensure the module is fully processed and is usable. + /// + /// It is the user-level function for completing the process of making the + /// object usable for execution. It should be called after sections within an + /// object have been relocated using mapSectionAddress. When this method is + /// called the MCJIT execution engine will reapply relocations for a loaded + /// object. This method has no effect for the legacy JIT engine or the + /// interpeter. + virtual void finalizeObject() {} + /// 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); + virtual void runStaticConstructorsDestructors(bool isDtors); /// runStaticConstructorsDestructors - This method is used to execute all of /// the static constructors or destructors for a particular module. @@ -280,10 +351,16 @@ public: /// getPointerToGlobalIfAvailable - This returns the address of the specified /// global value if it is has already been codegen'd, otherwise it returns /// null. + /// + /// This function is deprecated for the MCJIT execution engine. It doesn't + /// seem to be needed in that case, but an equivalent can be added if it is. 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. + /// + /// This function is deprecated for the MCJIT execution engine. Use + /// getGlobalValueAddress instead. void *getPointerToGlobal(const GlobalValue *GV); /// getPointerToFunction - The different EE's represent function bodies in @@ -291,22 +368,48 @@ public: /// 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. + /// + /// This function is deprecated for the MCJIT execution engine. Use + /// getFunctionAddress instead. 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. + /// + /// This function will not be implemented for the MCJIT execution engine. 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. + /// + /// This function is deprecated for the MCJIT execution engine. Use + /// getFunctionAddress instead. virtual void *getPointerToFunctionOrStub(Function *F) { // Default implementation, just codegen the function. return getPointerToFunction(F); } + /// getGlobalValueAddress - Return the address of the specified global + /// value. This may involve code generation. + /// + /// This function should not be called with the JIT or interpreter engines. + virtual uint64_t getGlobalValueAddress(const std::string &Name) { + // Default implementation for JIT and interpreter. MCJIT will override this. + // JIT and interpreter clients should use getPointerToGlobal instead. + return 0; + } + + /// getFunctionAddress - Return the address of the specified function. + /// This may involve code generation. + virtual uint64_t getFunctionAddress(const std::string &Name) { + // Default implementation for JIT and interpreter. MCJIT will override this. + // JIT and interpreter clients should use getPointerToFunction instead. + return 0; + } + // The JIT overrides a version that actually does this. virtual void runJITOnFunction(Function *, MachineCodeInfo * = 0) { } @@ -320,7 +423,7 @@ public: /// GenericValue *. It is not a pointer to a GenericValue containing the /// address at which to store Val. void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, - const Type *Ty); + Type *Ty); void InitializeMemory(const Constant *Init, void *Addr); @@ -339,8 +442,11 @@ public: /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the /// Emitter. + /// + /// This function is deprecated for the MCJIT execution engine. Use + /// getGlobalValueAddress instead. virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) { - return getPointerToGlobal((GlobalValue*)GV); + return getPointerToGlobal((const GlobalValue *)GV); } /// Registers a listener to be called back on various events within @@ -350,6 +456,12 @@ public: virtual void RegisterJITEventListener(JITEventListener *) {} virtual void UnregisterJITEventListener(JITEventListener *) {} + /// Sets the pre-compiled object cache. The ownership of the ObjectCache is + /// not changed. Supported by MCJIT but not JIT. + virtual void setObjectCache(ObjectCache *) { + llvm_unreachable("No support for an object cache"); + } + /// 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 @@ -402,41 +514,6 @@ public: 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::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); @@ -446,7 +523,7 @@ protected: GenericValue getConstantValue(const Constant *C); void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, - const Type *Ty); + Type *Ty); }; namespace EngineKind { @@ -467,8 +544,11 @@ private: EngineKind::Kind WhichEngine; std::string *ErrorStr; CodeGenOpt::Level OptLevel; + RTDyldMemoryManager *MCJMM; JITMemoryManager *JMM; bool AllocateGVsWithCode; + TargetOptions Options; + Reloc::Model RelocModel; CodeModel::Model CMModel; std::string MArch; std::string MCPU; @@ -480,9 +560,12 @@ private: WhichEngine = EngineKind::Either; ErrorStr = NULL; OptLevel = CodeGenOpt::Default; + MCJMM = NULL; JMM = NULL; + Options = TargetOptions(); AllocateGVsWithCode = false; - CMModel = CodeModel::Default; + RelocModel = Reloc::Default; + CMModel = CodeModel::JITDefault; UseMCJIT = false; } @@ -500,11 +583,28 @@ public: 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. + /// setMCJITMemoryManager - Sets the MCJIT memory manager to use. This allows + /// clients to customize their memory allocation policies for the MCJIT. This + /// is only appropriate for the MCJIT; setting this and configuring the builder + /// to create anything other than MCJIT will cause a runtime error. If create() + /// is called and is successful, the created engine takes ownership of the + /// memory manager. This option defaults to NULL. Using this option nullifies + /// the setJITMemoryManager() option. + EngineBuilder &setMCJITMemoryManager(RTDyldMemoryManager *mcjmm) { + MCJMM = mcjmm; + JMM = NULL; + return *this; + } + + /// setJITMemoryManager - Sets the JIT memory manager to use. This allows + /// clients to customize their memory allocation policies. This is only + /// appropriate for either JIT or MCJIT; setting this and configuring the + /// builder to create an interpreter will cause a runtime error. If create() + /// is called and is successful, the created engine takes ownership of the + /// memory manager. This option defaults to NULL. This option overrides + /// setMCJITMemoryManager() as well. EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) { + MCJMM = NULL; JMM = jmm; return *this; } @@ -523,8 +623,23 @@ public: return *this; } + /// setTargetOptions - Set the target options that the ExecutionEngine + /// target is using. Defaults to TargetOptions(). + EngineBuilder &setTargetOptions(const TargetOptions &Opts) { + Options = Opts; + 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::Default". + /// data is using. Defaults to target specific default + /// "CodeModel::JITDefault". EngineBuilder &setCodeModel(CodeModel::Model M) { CMModel = M; return *this; @@ -569,9 +684,25 @@ public: return *this; } - ExecutionEngine *create(); + TargetMachine *selectTarget(); + + /// selectTarget - Pick a target either via -march or by guessing the native + /// arch. Add any CPU features specified via -mcpu or -mattr. + TargetMachine *selectTarget(const Triple &TargetTriple, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl& MAttrs); + + ExecutionEngine *create() { + return create(selectTarget()); + } + + ExecutionEngine *create(TargetMachine *TM); }; +// Create wrappers for C Binding types (see CBindingWrapping.h). +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef) + } // End llvm namespace #endif