summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/ExecutionEngine/MCJIT
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
committerdim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
commit2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch)
tree4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/ExecutionEngine/MCJIT
parent678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff)
parente27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff)
downloadFreeBSD-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.cpp125
-rw-r--r--contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h96
-rw-r--r--contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp27
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() {
OpenPOWER on IntegriCloud