X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FExecutionEngine%2FExecutionEngine.h;h=22ce4491b7e42131c4b82daa008293cee4cd8ebc;hb=875710a2fd6b3c4f814961582594bd5c1cdb493a;hp=78198a9951c650ba0a99d34bb803938cd87acf6b;hpb=d40e103ea5bca8a223fc8261b3322b9454e9af12;p=oota-llvm.git diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 78198a9951c..22ce4491b7e 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -12,26 +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/MC/MCCodeGenInfo.h" +#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/IR/ValueHandle.h" +#include "llvm/IR/ValueMap.h" +#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mutex.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; @@ -41,11 +43,18 @@ 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. +/// table. Access to this class should be serialized under a mutex. class ExecutionEngineState { public: struct AddressMapConfig : public ValueMapConfig { @@ -75,19 +84,19 @@ private: public: ExecutionEngineState(ExecutionEngine &EE); - GlobalAddressMapTy &getGlobalAddressMap(const MutexGuard &) { + GlobalAddressMapTy &getGlobalAddressMap() { return GlobalAddressMap; } std::map > & - getGlobalAddressReverseMap(const MutexGuard &) { + getGlobalAddressReverseMap() { 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); + /// \returns The address that \p ToUnmap was happed to. + void *RemoveMapping(const GlobalValue *ToUnmap); }; /// \brief Abstract interface for implementation execution of LLVM modules, @@ -102,7 +111,7 @@ class ExecutionEngine { ExecutionEngineState EEState; /// The target data for the platform for which execution is being performed. - const TargetData *TD; + const DataLayout *DL; /// Whether lazy JIT compilation is enabled. bool CompilingLazily; @@ -114,6 +123,9 @@ class ExecutionEngine { /// using dlsym). bool SymbolSearchingDisabled; + /// Whether the JIT should verify IR modules during compilation. + bool VerifyModules; + friend class EngineBuilder; // To allow access to JITCtor and InterpCtor. protected: @@ -121,7 +133,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 *Val) { DL = Val; } /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -129,19 +141,10 @@ protected: // 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, + RTDyldMemoryManager *MCJMM, TargetMachine *TM); static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); @@ -150,17 +153,8 @@ protected: /// 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; @@ -171,39 +165,6 @@ public: 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. @@ -211,9 +172,29 @@ 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(std::unique_ptr O); + + /// 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. + virtual void addArchive(std::unique_ptr A); + //===--------------------------------------------------------------------===// - const TargetData *getTargetData() const { return TD; } + const DataLayout *getDataLayout() const { return DL; } /// removeModule - Remove a Module from the list of modules. Returns true if /// M is found. @@ -222,18 +203,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. @@ -274,10 +307,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 @@ -285,24 +324,43 @@ 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. - 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) { } + virtual void runJITOnFunction(Function *, MachineCodeInfo * = nullptr) { } /// getGlobalValueAtAddress - Return the LLVM global value object that starts /// at the specified address. @@ -318,23 +376,14 @@ public: 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. + /// + /// 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 @@ -344,6 +393,30 @@ 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"); + } + + /// setProcessAllSections (MCJIT Only): By default, only sections that are + /// "required for execution" are passed to the RTDyldMemoryManager, and other + /// sections are discarded. Passing 'true' to this method will cause + /// RuntimeDyld to pass all sections to its RTDyldMemoryManager regardless + /// of whether they are "required to execute" in the usual sense. + /// + /// Rationale: Some MCJIT clients want to be able to inspect metadata + /// sections (e.g. Dwarf, Stack-maps) to enable functionality or analyze + /// performance. Passing these sections to the memory manager allows the + /// client to make policy about the relevant sections, rather than having + /// MCJIT do it. + virtual void setProcessAllSections(bool ProcessAllSections) { + llvm_unreachable("No support for ProcessAllSections option"); + } + + /// Return the target machine (if available). + virtual TargetMachine *getTargetMachine() { return nullptr; } + /// 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 @@ -389,6 +462,17 @@ public: return SymbolSearchingDisabled; } + /// Enable/Disable IR module verification. + /// + /// Note: Module verification is enabled by default in Debug builds, and + /// disabled by default in Release. Use this method to override the default. + void setVerifyModules(bool Verify) { + VerifyModules = Verify; + } + bool getVerifyModules() const { + return VerifyModules; + } + /// InstallLazyFunctionCreator - If an unknown function is needed, the /// specified function pointer is invoked to create it. If it returns null, /// the JIT will abort. @@ -396,41 +480,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); @@ -461,28 +510,18 @@ 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; SmallVector MAttrs; - bool UseMCJIT; + bool VerifyModules; /// InitEngine - Does the common initialization of default options. - void InitEngine() { - WhichEngine = EngineKind::Either; - ErrorStr = NULL; - OptLevel = CodeGenOpt::Default; - JMM = NULL; - Options = TargetOptions(); - AllocateGVsWithCode = false; - RelocModel = Reloc::Default; - CMModel = CodeModel::JITDefault; - UseMCJIT = false; - } + void InitEngine(); public: /// EngineBuilder - Constructor for EngineBuilder. If create() is called and @@ -498,11 +537,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 = nullptr; + 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 = nullptr; JMM = jmm; return *this; } @@ -543,18 +599,6 @@ public: 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()); @@ -567,10 +611,10 @@ public: return *this; } - /// setUseMCJIT - Set whether the MC-JIT implementation should be used - /// (experimental). - EngineBuilder &setUseMCJIT(bool Value) { - UseMCJIT = Value; + /// setVerifyModules - Set whether the JIT implementation should verify + /// IR modules during compilation. + EngineBuilder &setVerifyModules(bool Verify) { + VerifyModules = Verify; return *this; } @@ -582,21 +626,25 @@ public: return *this; } + TargetMachine *selectTarget(); + /// 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& MAttrs, - const TargetOptions &Options, - Reloc::Model RM, - CodeModel::Model CM, - CodeGenOpt::Level OL, - std::string *Err); - - ExecutionEngine *create(); + 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