diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
commit | 2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch) | |
tree | 4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/ExecutionEngine/MCJIT | |
parent | 678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff) | |
parent | e27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff) | |
download | FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.zip FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.tar.gz |
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine/MCJIT')
-rw-r--r-- | contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp | 125 | ||||
-rw-r--r-- | contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h | 96 | ||||
-rw-r--r-- | contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp | 27 |
3 files changed, 160 insertions, 88 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 195c458..e9ba96a 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -14,17 +14,20 @@ #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/ExecutionEngine/ObjectImage.h" -#include "llvm/PassManager.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/Object/Archive.h" +#include "llvm/PassManager.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MutexGuard.h" +#include "llvm/Target/TargetLowering.h" using namespace llvm; @@ -47,7 +50,7 @@ ExecutionEngine *MCJIT::createJIT(Module *M, // Try to register the program as a source of symbols to resolve against. // // FIXME: Don't do this here. - sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); + sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr); return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(), GVsWithCode); @@ -55,8 +58,8 @@ ExecutionEngine *MCJIT::createJIT(Module *M, MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM, bool AllocateGVsWithCode) - : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(this, MM), Dyld(&MemMgr), - ObjCache(0) { + : ExecutionEngine(m), TM(tm), Ctx(nullptr), MemMgr(this, MM), Dyld(&MemMgr), + ObjCache(nullptr) { OwnedModules.addModule(m); setDataLayout(TM->getDataLayout()); @@ -77,15 +80,24 @@ MCJIT::~MCJIT() { Modules.clear(); Dyld.deregisterEHFrames(); - LoadedObjectMap::iterator it, end = LoadedObjects.end(); - for (it = LoadedObjects.begin(); it != end; ++it) { - ObjectImage *Obj = it->second; + LoadedObjectList::iterator it, end; + for (it = LoadedObjects.begin(), end = LoadedObjects.end(); it != end; ++it) { + ObjectImage *Obj = *it; if (Obj) { NotifyFreeingObject(*Obj); delete Obj; } } LoadedObjects.clear(); + + + SmallVector<object::Archive *, 2>::iterator ArIt, ArEnd; + for (ArIt = Archives.begin(), ArEnd = Archives.end(); ArIt != ArEnd; ++ArIt) { + object::Archive *A = *ArIt; + delete A; + } + Archives.clear(); + delete TM; } @@ -101,6 +113,21 @@ bool MCJIT::removeModule(Module *M) { +void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) { + ObjectImage *LoadedObject = Dyld.loadObject(std::move(Obj)); + if (!LoadedObject || Dyld.hasError()) + report_fatal_error(Dyld.getErrorString()); + + LoadedObjects.push_back(LoadedObject); + + NotifyObjectEmitted(*LoadedObject); +} + +void MCJIT::addArchive(object::Archive *A) { + Archives.push_back(A); +} + + void MCJIT::setObjectCache(ObjectCache* NewCache) { MutexGuard locked(lock); ObjCache = NewCache; @@ -115,14 +142,16 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) { PassManager PM; - PM.add(new DataLayout(*TM->getDataLayout())); + M->setDataLayout(TM->getDataLayout()); + PM.add(new DataLayoutPass(M)); // The RuntimeDyld will take ownership of this shortly - OwningPtr<ObjectBufferStream> CompiledObject(new ObjectBufferStream()); + std::unique_ptr<ObjectBufferStream> CompiledObject(new ObjectBufferStream()); // Turn the machine code intermediate representation into bytes in memory // that may be executed. - if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), false)) { + if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), + !getVerifyModules())) { report_fatal_error("Target does not support MC emission!"); } @@ -136,11 +165,11 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) { if (ObjCache) { // MemoryBuffer is a thin wrapper around the actual memory, so it's OK // to create a temporary object here and delete it after the call. - OwningPtr<MemoryBuffer> MB(CompiledObject->getMemBuffer()); + std::unique_ptr<MemoryBuffer> MB(CompiledObject->getMemBuffer()); ObjCache->notifyObjectCompiled(M, MB.get()); } - return CompiledObject.take(); + return CompiledObject.release(); } void MCJIT::generateCodeForModule(Module *M) { @@ -155,12 +184,12 @@ void MCJIT::generateCodeForModule(Module *M) { if (OwnedModules.hasModuleBeenLoaded(M)) return; - OwningPtr<ObjectBuffer> ObjectToLoad; + std::unique_ptr<ObjectBuffer> ObjectToLoad; // Try to load the pre-compiled object from cache if possible - if (0 != ObjCache) { - OwningPtr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M)); - if (0 != PreCompiledObject.get()) - ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.take())); + if (ObjCache) { + std::unique_ptr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M)); + if (PreCompiledObject.get()) + ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.release())); } // If the cache did not contain a suitable object, compile the object @@ -170,9 +199,9 @@ void MCJIT::generateCodeForModule(Module *M) { } // Load the object into the dynamic linker. - // MCJIT now owns the ObjectImage pointer (via its LoadedObjects map). - ObjectImage *LoadedObject = Dyld.loadObject(ObjectToLoad.take()); - LoadedObjects[M] = LoadedObject; + // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list). + ObjectImage *LoadedObject = Dyld.loadObject(ObjectToLoad.release()); + LoadedObjects.push_back(LoadedObject); if (!LoadedObject) report_fatal_error(Dyld.getErrorString()); @@ -231,11 +260,10 @@ void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { } uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) { - // Check with the RuntimeDyld to see if we already have this symbol. - if (Name[0] == '\1') - return Dyld.getSymbolLoadAddress(Name.substr(1)); - return Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() - + Name)); + Mangler Mang(TM->getDataLayout()); + SmallString<128> FullName; + Mang.getNameWithPrefix(FullName, Name); + return Dyld.getSymbolLoadAddress(FullName); } Module *MCJIT::findModuleForSymbol(const std::string &Name, @@ -258,7 +286,7 @@ Module *MCJIT::findModuleForSymbol(const std::string &Name, } } // We didn't find the symbol in any of our modules. - return NULL; + return nullptr; } uint64_t MCJIT::getSymbolAddress(const std::string &Name, @@ -271,6 +299,31 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name, if (Addr) return Addr; + SmallVector<object::Archive*, 2>::iterator I, E; + for (I = Archives.begin(), E = Archives.end(); I != E; ++I) { + object::Archive *A = *I; + // Look for our symbols in each Archive + object::Archive::child_iterator ChildIt = A->findSym(Name); + if (ChildIt != A->child_end()) { + // FIXME: Support nested archives? + ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr = + ChildIt->getAsBinary(); + if (ChildBinOrErr.getError()) + continue; + std::unique_ptr<object::Binary> ChildBin = std::move(ChildBinOrErr.get()); + if (ChildBin->isObject()) { + std::unique_ptr<object::ObjectFile> OF( + static_cast<object::ObjectFile *>(ChildBin.release())); + // This causes the object file to be loaded. + addObjectFile(std::move(OF)); + // The address should be here now. + Addr = getExistingSymbolAddress(Name); + if (Addr) + return Addr; + } + } + } + // If it hasn't already been generated, see if it's in one of our modules. Module *M = findModuleForSymbol(Name, CheckFunctionsOnly); if (!M) @@ -317,18 +370,16 @@ void *MCJIT::getPointerToFunction(Function *F) { generateCodeForModule(M); else if (!OwnedModules.hasModuleBeenLoaded(M)) // If this function doesn't belong to one of our modules, we're done. - return NULL; + return nullptr; // FIXME: Should the Dyld be retaining module information? Probably not. - // FIXME: Should we be using the mangler for this? Probably. // // This is the accessor for the target address, so make sure to check the // load address of the symbol, not the local address. - StringRef BaseName = F->getName(); - if (BaseName[0] == '\1') - return (void*)Dyld.getSymbolLoadAddress(BaseName.substr(1)); - return (void*)Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() - + BaseName).str()); + Mangler Mang(TM->getDataLayout()); + SmallString<128> Name; + TM->getNameWithPrefix(Name, F, Mang); + return (void*)Dyld.getSymbolLoadAddress(Name); } void *MCJIT::recompileAndRelinkFunction(Function *F) { @@ -363,7 +414,7 @@ Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName, if (Function *F = (*I)->getFunction(FnName)) return F; } - return 0; + return nullptr; } Function *MCJIT::FindFunctionNamed(const char *FnName) { @@ -495,17 +546,17 @@ void *MCJIT::getPointerToNamedFunction(const std::string &Name, report_fatal_error("Program used external function '"+Name+ "' which could not be resolved!"); } - return 0; + return nullptr; } void MCJIT::RegisterJITEventListener(JITEventListener *L) { - if (L == NULL) + if (!L) return; MutexGuard locked(lock); EventListeners.push_back(L); } void MCJIT::UnregisterJITEventListener(JITEventListener *L) { - if (L == NULL) + if (!L) return; MutexGuard locked(lock); SmallVector<JITEventListener*, 2>::reverse_iterator I= diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h index 86b478b..100e9a2 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -31,43 +31,53 @@ public: LinkingMemoryManager(MCJIT *Parent, RTDyldMemoryManager *MM) : ParentEngine(Parent), ClientMM(MM) {} - virtual uint64_t getSymbolAddress(const std::string &Name); + uint64_t getSymbolAddress(const std::string &Name) override; // Functions deferred to client memory manager - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName) { + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, + StringRef SectionName) override { return ClientMM->allocateCodeSection(Size, Alignment, SectionID, SectionName); } - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName, - bool IsReadOnly) { + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool IsReadOnly) override { return ClientMM->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly); } - virtual void notifyObjectLoaded(ExecutionEngine *EE, - const ObjectImage *Obj) { + void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO, + uintptr_t DataSizeRW) override { + return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW); + } + + bool needsToReserveAllocationSpace() override { + return ClientMM->needsToReserveAllocationSpace(); + } + + void notifyObjectLoaded(ExecutionEngine *EE, + const ObjectImage *Obj) override { ClientMM->notifyObjectLoaded(EE, Obj); } - virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { + void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, + size_t Size) override { ClientMM->registerEHFrames(Addr, LoadAddr, Size); } - virtual void deregisterEHFrames(uint8_t *Addr, - uint64_t LoadAddr, - size_t Size) { + void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, + size_t Size) override { ClientMM->deregisterEHFrames(Addr, LoadAddr, Size); } - virtual bool finalizeMemory(std::string *ErrMsg = 0) { + bool finalizeMemory(std::string *ErrMsg = nullptr) override { return ClientMM->finalizeMemory(ErrMsg); } private: MCJIT *ParentEngine; - OwningPtr<RTDyldMemoryManager> ClientMM; + std::unique_ptr<RTDyldMemoryManager> ClientMM; }; // About Module states: added->loaded->finalized. @@ -206,8 +216,10 @@ class MCJIT : public ExecutionEngine { OwningModuleContainer OwnedModules; - typedef DenseMap<Module *, ObjectImage *> LoadedObjectMap; - LoadedObjectMap LoadedObjects; + SmallVector<object::Archive*, 2> Archives; + + typedef SmallVector<ObjectImage *, 2> LoadedObjectList; + LoadedObjectList LoadedObjects; // An optional ObjectCache to be notified of compiled objects and used to // perform lookup of pre-compiled code to avoid re-compilation. @@ -226,18 +238,24 @@ public: /// @name ExecutionEngine interface implementation /// @{ - virtual void addModule(Module *M); - virtual bool removeModule(Module *M); + void addModule(Module *M) override; + void addObjectFile(std::unique_ptr<object::ObjectFile> O) override; + void addArchive(object::Archive *O) override; + bool removeModule(Module *M) override; /// 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. - virtual Function *FindFunctionNamed(const char *FnName); + Function *FindFunctionNamed(const char *FnName) override; /// Sets the object manager that MCJIT should use to avoid compilation. - virtual void setObjectCache(ObjectCache *manager); + void setObjectCache(ObjectCache *manager) override; + + void setProcessAllSections(bool ProcessAllSections) override { + Dyld.setProcessAllSections(ProcessAllSections); + } - virtual void generateCodeForModule(Module *M); + void generateCodeForModule(Module *M) override; /// finalizeObject - ensure the module is fully processed and is usable. /// @@ -248,7 +266,7 @@ public: /// object. /// Is it OK to finalize a set of modules, add modules and finalize again. // FIXME: Do we really need both of these? - virtual void finalizeObject(); + void finalizeObject() override; virtual void finalizeModule(Module *); void finalizeLoadedModules(); @@ -256,18 +274,18 @@ public: /// the static constructors or destructors for a program. /// /// \param isDtors - Run the destructors instead of constructors. - void runStaticConstructorsDestructors(bool isDtors); + void runStaticConstructorsDestructors(bool isDtors) override; - virtual void *getPointerToBasicBlock(BasicBlock *BB); + void *getPointerToBasicBlock(BasicBlock *BB) override; - virtual void *getPointerToFunction(Function *F); + void *getPointerToFunction(Function *F) override; - virtual void *recompileAndRelinkFunction(Function *F); + void *recompileAndRelinkFunction(Function *F) override; - virtual void freeMachineCodeForFunction(Function *F); + void freeMachineCodeForFunction(Function *F) override; - virtual GenericValue runFunction(Function *F, - const std::vector<GenericValue> &ArgValues); + GenericValue runFunction(Function *F, + const std::vector<GenericValue> &ArgValues) override; /// getPointerToNamedFunction - This method returns the address of the /// specified function by using the dlsym function call. As such it is only @@ -277,25 +295,27 @@ public: /// found, this function silently returns a null pointer. Otherwise, /// it prints a message to stderr and aborts. /// - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); + void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) override; /// 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) { + void mapSectionAddress(const void *LocalAddress, + uint64_t TargetAddress) override { Dyld.mapSectionAddress(LocalAddress, TargetAddress); } - virtual void RegisterJITEventListener(JITEventListener *L); - virtual void UnregisterJITEventListener(JITEventListener *L); + void RegisterJITEventListener(JITEventListener *L) override; + void UnregisterJITEventListener(JITEventListener *L) override; // If successful, these function will implicitly finalize all loaded objects. // To get a function address within MCJIT without causing a finalize, use // getSymbolAddress. - virtual uint64_t getGlobalValueAddress(const std::string &Name); - virtual uint64_t getFunctionAddress(const std::string &Name); + uint64_t getGlobalValueAddress(const std::string &Name) override; + uint64_t getFunctionAddress(const std::string &Name) override; + + TargetMachine *getTargetMachine() override { return TM; } /// @} /// @name (Private) Registration Interfaces @@ -322,7 +342,7 @@ protected: /// emitObject -- Generate a JITed object in memory from the specified module /// Currently, MCJIT only supports a single module and the module passed to /// this function call is expected to be the contained module. The module - /// is passed as a parameter here to prepare for multiple module support in + /// is passed as a parameter here to prepare for multiple module support in /// the future. ObjectBufferStream* emitObject(Module *M); diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp index cf90e77..5986084 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp @@ -71,15 +71,15 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, // // FIXME: Initialize the Near member for each memory group to avoid // interleaving. - error_code ec; + std::error_code ec; sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(RequiredSize, &MemGroup.Near, sys::Memory::MF_READ | sys::Memory::MF_WRITE, ec); if (ec) { - // FIXME: Add error propogation to the interface. - return NULL; + // FIXME: Add error propagation to the interface. + return nullptr; } // Save this address as the basis for our next request @@ -105,7 +105,7 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) { // FIXME: Should in-progress permissions be reverted if an error occurs? - error_code ec; + std::error_code ec; // Don't allow free memory blocks to be used after setting protection flags. CodeMem.FreeMem.clear(); @@ -143,19 +143,20 @@ bool SectionMemoryManager::finalizeMemory(std::string *ErrMsg) return false; } -error_code SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, - unsigned Permissions) { +std::error_code +SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions) { for (int i = 0, e = MemGroup.AllocatedMem.size(); i != e; ++i) { - error_code ec; - ec = sys::Memory::protectMappedMemory(MemGroup.AllocatedMem[i], - Permissions); - if (ec) { - return ec; - } + std::error_code ec; + ec = + sys::Memory::protectMappedMemory(MemGroup.AllocatedMem[i], Permissions); + if (ec) { + return ec; + } } - return error_code::success(); + return std::error_code(); } void SectionMemoryManager::invalidateInstructionCache() { |