summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/ExecutionEngine/Orc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine/Orc')
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp25
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp97
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp43
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h282
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h44
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp275
6 files changed, 619 insertions, 147 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index b439810..34564e4 100644
--- a/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -19,6 +19,9 @@
namespace llvm {
namespace orc {
+void JITCompileCallbackManager::anchor() {}
+void IndirectStubsManager::anchor() {}
+
Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr) {
Constant *AddrIntVal =
ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr);
@@ -37,7 +40,7 @@ GlobalVariable* createImplPointer(PointerType &PT, Module &M,
return IP;
}
-void makeStub(Function &F, GlobalVariable &ImplPointer) {
+void makeStub(Function &F, Value &ImplPointer) {
assert(F.isDeclaration() && "Can't turn a definition into a stub.");
assert(F.getParent() && "Function isn't in a module.");
Module &M = *F.getParent();
@@ -61,9 +64,7 @@ class GlobalRenamer {
public:
static bool needsRenaming(const Value &New) {
- if (!New.hasName() || New.getName().startswith("\01L"))
- return true;
- return false;
+ return !New.hasName() || New.getName().startswith("\01L");
}
const std::string& getRename(const Value &Orig) {
@@ -106,6 +107,9 @@ void makeAllSymbolsExternallyAccessible(Module &M) {
for (auto &GV : M.globals())
raiseVisibilityOnValue(GV, Renamer);
+
+ for (auto &A : M.aliases())
+ raiseVisibilityOnValue(A, Renamer);
}
Function* cloneFunctionDecl(Module &Dst, const Function &F,
@@ -121,7 +125,7 @@ Function* cloneFunctionDecl(Module &Dst, const Function &F,
auto NewArgI = NewF->arg_begin();
for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
++ArgI, ++NewArgI)
- (*VMap)[ArgI] = NewArgI;
+ (*VMap)[&*ArgI] = &*NewArgI;
}
return NewF;
@@ -177,5 +181,16 @@ void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
nullptr, Materializer));
}
+GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
+ ValueToValueMapTy &VMap) {
+ assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
+ auto *NewA = GlobalAlias::create(OrigA.getValueType(),
+ OrigA.getType()->getPointerAddressSpace(),
+ OrigA.getLinkage(), OrigA.getName(), &Dst);
+ NewA->copyAttributesFrom(&OrigA);
+ VMap[&OrigA] = NewA;
+ return NewA;
+}
+
} // End namespace orc.
} // End namespace llvm.
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp
new file mode 100644
index 0000000..d2379cd
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp
@@ -0,0 +1,97 @@
+//===----------- OrcCBindings.cpp - C bindings for the Orc APIs -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcCBindingsStack.h"
+#include "llvm-c/OrcBindings.h"
+
+using namespace llvm;
+
+LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
+ TargetMachine *TM2(unwrap(TM));
+
+ Triple T(TM2->getTargetTriple());
+
+ auto CompileCallbackMgr = OrcCBindingsStack::createCompileCallbackMgr(T);
+ auto IndirectStubsMgrBuilder =
+ OrcCBindingsStack::createIndirectStubsMgrBuilder(T);
+
+ OrcCBindingsStack *JITStack =
+ new OrcCBindingsStack(*TM2, std::move(CompileCallbackMgr),
+ IndirectStubsMgrBuilder);
+
+ return wrap(JITStack);
+}
+
+void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,
+ const char *SymbolName) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ std::string Mangled = J.mangle(SymbolName);
+ *MangledName = new char[Mangled.size() + 1];
+ strcpy(*MangledName, Mangled.c_str());
+}
+
+void LLVMOrcDisposeMangledSymbol(char *MangledName) {
+ delete[] MangledName;
+}
+
+LLVMOrcTargetAddress
+LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
+ LLVMOrcLazyCompileCallbackFn Callback,
+ void *CallbackCtx) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ return J.createLazyCompileCallback(Callback, CallbackCtx);
+}
+
+void LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
+ const char *StubName,
+ LLVMOrcTargetAddress InitAddr) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ J.createIndirectStub(StubName, InitAddr);
+}
+
+void LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
+ const char *StubName,
+ LLVMOrcTargetAddress NewAddr) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ J.setIndirectStubPointer(StubName, NewAddr);
+}
+
+LLVMOrcModuleHandle
+LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
+ LLVMOrcSymbolResolverFn SymbolResolver,
+ void *SymbolResolverCtx) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ Module *M(unwrap(Mod));
+ return J.addIRModuleEager(M, SymbolResolver, SymbolResolverCtx);
+}
+
+LLVMOrcModuleHandle
+LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
+ LLVMOrcSymbolResolverFn SymbolResolver,
+ void *SymbolResolverCtx) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ Module *M(unwrap(Mod));
+ return J.addIRModuleLazy(M, SymbolResolver, SymbolResolverCtx);
+}
+
+void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ J.removeModule(H);
+}
+
+LLVMOrcTargetAddress LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
+ const char *SymbolName) {
+ OrcCBindingsStack &J = *unwrap(JITStack);
+ auto Sym = J.findSymbol(SymbolName, true);
+ return Sym.getAddress();
+}
+
+void LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) {
+ delete unwrap(JITStack);
+}
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
new file mode 100644
index 0000000..e519c7f
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
@@ -0,0 +1,43 @@
+//===-------- OrcCBindingsStack.cpp - Orc JIT stack for C bindings --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcCBindingsStack.h"
+
+#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include <cstdio>
+#include <system_error>
+
+using namespace llvm;
+
+std::unique_ptr<OrcCBindingsStack::CompileCallbackMgr>
+OrcCBindingsStack::createCompileCallbackMgr(Triple T) {
+ switch (T.getArch()) {
+ default: return nullptr;
+
+ case Triple::x86_64: {
+ typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64> CCMgrT;
+ return llvm::make_unique<CCMgrT>(0);
+ }
+ }
+}
+
+OrcCBindingsStack::IndirectStubsManagerBuilder
+OrcCBindingsStack::createIndirectStubsMgrBuilder(Triple T) {
+ switch (T.getArch()) {
+ default: return nullptr;
+
+ case Triple::x86_64:
+ return [](){
+ return llvm::make_unique<
+ orc::LocalIndirectStubsManager<orc::OrcX86_64>>();
+ };
+ }
+}
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
new file mode 100644
index 0000000..2e17624
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
@@ -0,0 +1,282 @@
+//===--- OrcCBindingsStack.h - Orc JIT stack for C bindings ---*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
+#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm-c/OrcBindings.h"
+
+namespace llvm {
+
+class OrcCBindingsStack;
+
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
+
+class OrcCBindingsStack {
+public:
+
+ typedef orc::JITCompileCallbackManager CompileCallbackMgr;
+ typedef orc::ObjectLinkingLayer<> ObjLayerT;
+ typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
+ typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT;
+
+ typedef std::function<std::unique_ptr<CompileCallbackMgr>()>
+ CallbackManagerBuilder;
+
+ typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
+
+private:
+
+ class GenericHandle {
+ public:
+ virtual ~GenericHandle() {}
+ virtual orc::JITSymbol findSymbolIn(const std::string &Name,
+ bool ExportedSymbolsOnly) = 0;
+ virtual void removeModule() = 0;
+ };
+
+ template <typename LayerT>
+ class GenericHandleImpl : public GenericHandle {
+ public:
+ GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
+ : Layer(Layer), Handle(std::move(Handle)) {}
+
+ orc::JITSymbol findSymbolIn(const std::string &Name,
+ bool ExportedSymbolsOnly) override {
+ return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
+ }
+
+ void removeModule() override {
+ return Layer.removeModuleSet(Handle);
+ }
+
+ private:
+ LayerT &Layer;
+ typename LayerT::ModuleSetHandleT Handle;
+ };
+
+ template <typename LayerT>
+ std::unique_ptr<GenericHandleImpl<LayerT>>
+ createGenericHandle(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) {
+ return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
+ std::move(Handle));
+ }
+
+public:
+
+ // We need a 'ModuleSetHandleT' to conform to the layer concept.
+ typedef unsigned ModuleSetHandleT;
+
+ typedef unsigned ModuleHandleT;
+
+ static std::unique_ptr<CompileCallbackMgr> createCompileCallbackMgr(Triple T);
+ static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T);
+
+ OrcCBindingsStack(TargetMachine &TM,
+ std::unique_ptr<CompileCallbackMgr> CCMgr,
+ IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
+ : DL(TM.createDataLayout()), CCMgr(std::move(CCMgr)),
+ ObjectLayer(),
+ CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
+ CODLayer(CompileLayer,
+ [](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
+ *this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
+ IndirectStubsMgr(IndirectStubsMgrBuilder()),
+ CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
+
+ ~OrcCBindingsStack() {
+ // Run any destructors registered with __cxa_atexit.
+ CXXRuntimeOverrides.runDestructors();
+ // Run any IR destructors.
+ for (auto &DtorRunner : IRStaticDestructorRunners)
+ DtorRunner.runViaLayer(*this);
+ }
+
+ std::string mangle(StringRef Name) {
+ std::string MangledName;
+ {
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ }
+ return MangledName;
+ }
+
+ template <typename PtrTy>
+ static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
+ return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
+ }
+
+ orc::TargetAddress
+ createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
+ void *CallbackCtx) {
+ auto CCInfo = CCMgr->getCompileCallback();
+ CCInfo.setCompileAction(
+ [=]() -> orc::TargetAddress {
+ return Callback(wrap(this), CallbackCtx);
+ });
+ return CCInfo.getAddress();
+ }
+
+ void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) {
+ IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported);
+ }
+
+ void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) {
+ IndirectStubsMgr->updatePointer(Name, Addr);
+ }
+
+ std::shared_ptr<RuntimeDyld::SymbolResolver>
+ createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
+ void *ExternalResolverCtx) {
+ auto Resolver = orc::createLambdaResolver(
+ [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
+ // Search order:
+ // 1. JIT'd symbols.
+ // 2. Runtime overrides.
+ // 3. External resolver (if present).
+
+ if (auto Sym = CODLayer.findSymbol(Name, true))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(),
+ Sym.getFlags());
+ if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
+ return Sym;
+
+ if (ExternalResolver)
+ return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(),
+ ExternalResolverCtx),
+ llvm::JITSymbolFlags::Exported);
+
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ return RuntimeDyld::SymbolInfo(nullptr);
+ }
+ );
+
+ return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
+ }
+
+ template <typename LayerT>
+ ModuleHandleT addIRModule(LayerT &Layer,
+ Module *M,
+ std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
+ LLVMOrcSymbolResolverFn ExternalResolver,
+ void *ExternalResolverCtx) {
+
+ // Attach a data-layout if one isn't already present.
+ if (M->getDataLayout().isDefault())
+ M->setDataLayout(DL);
+
+ // Record the static constructors and destructors. We have to do this before
+ // we hand over ownership of the module to the JIT.
+ std::vector<std::string> CtorNames, DtorNames;
+ for (auto Ctor : orc::getConstructors(*M))
+ CtorNames.push_back(mangle(Ctor.Func->getName()));
+ for (auto Dtor : orc::getDestructors(*M))
+ DtorNames.push_back(mangle(Dtor.Func->getName()));
+
+ // Create the resolver.
+ auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
+
+ // Add the module to the JIT.
+ std::vector<Module*> S;
+ S.push_back(std::move(M));
+
+ auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
+ std::move(Resolver));
+ ModuleHandleT H = createHandle(Layer, LH);
+
+ // Run the static constructors, and save the static destructor runner for
+ // execution when the JIT is torn down.
+ orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
+ CtorRunner.runViaLayer(*this);
+
+ IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
+
+ return H;
+ }
+
+ ModuleHandleT addIRModuleEager(Module* M,
+ LLVMOrcSymbolResolverFn ExternalResolver,
+ void *ExternalResolverCtx) {
+ return addIRModule(CompileLayer, std::move(M),
+ llvm::make_unique<SectionMemoryManager>(),
+ std::move(ExternalResolver), ExternalResolverCtx);
+ }
+
+ ModuleHandleT addIRModuleLazy(Module* M,
+ LLVMOrcSymbolResolverFn ExternalResolver,
+ void *ExternalResolverCtx) {
+ return addIRModule(CODLayer, std::move(M), nullptr,
+ std::move(ExternalResolver), ExternalResolverCtx);
+ }
+
+ void removeModule(ModuleHandleT H) {
+ GenericHandles[H]->removeModule();
+ GenericHandles[H] = nullptr;
+ FreeHandleIndexes.push_back(H);
+ }
+
+ orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
+ return Sym;
+ return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
+ }
+
+ orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
+ }
+
+private:
+
+ template <typename LayerT>
+ unsigned createHandle(LayerT &Layer,
+ typename LayerT::ModuleSetHandleT Handle) {
+ unsigned NewHandle;
+ if (!FreeHandleIndexes.empty()) {
+ NewHandle = FreeHandleIndexes.back();
+ FreeHandleIndexes.pop_back();
+ GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
+ return NewHandle;
+ } else {
+ NewHandle = GenericHandles.size();
+ GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
+ }
+ return NewHandle;
+ }
+
+ DataLayout DL;
+ SectionMemoryManager CCMgrMemMgr;
+
+ std::unique_ptr<CompileCallbackMgr> CCMgr;
+ ObjLayerT ObjectLayer;
+ CompileLayerT CompileLayer;
+ CODLayerT CODLayer;
+
+ std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
+
+ std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
+ std::vector<unsigned> FreeHandleIndexes;
+
+ orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
+ std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
index 7dc5164..38a27cf 100644
--- a/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
@@ -137,25 +137,26 @@ public:
}
OrcMCJITReplacement(
- std::shared_ptr<MCJITMemoryManager> MemMgr,
- std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
- std::unique_ptr<TargetMachine> TM)
- : TM(std::move(TM)), MemMgr(*this, std::move(MemMgr)),
- Resolver(*this), ClientResolver(std::move(ClientResolver)),
- NotifyObjectLoaded(*this), NotifyFinalized(*this),
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
+ std::unique_ptr<TargetMachine> TM)
+ : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
+ MemMgr(*this, std::move(MemMgr)), Resolver(*this),
+ ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
+ NotifyFinalized(*this),
ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
- LazyEmitLayer(CompileLayer) {
- setDataLayout(this->TM->getDataLayout());
- }
+ LazyEmitLayer(CompileLayer) {}
void addModule(std::unique_ptr<Module> M) override {
// If this module doesn't have a DataLayout attached then attach the
// default.
- if (M->getDataLayout().isDefault())
- M->setDataLayout(*getDataLayout());
-
+ if (M->getDataLayout().isDefault()) {
+ M->setDataLayout(getDataLayout());
+ } else {
+ assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
+ }
Modules.push_back(std::move(M));
std::vector<Module *> Ms;
Ms.push_back(&*Modules.back());
@@ -174,12 +175,7 @@ public:
std::tie(Obj, Buf) = O.takeBinary();
std::vector<std::unique_ptr<object::ObjectFile>> Objs;
Objs.push_back(std::move(Obj));
- auto H =
- ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
-
- std::vector<std::unique_ptr<MemoryBuffer>> Bufs;
- Bufs.push_back(std::move(Buf));
- ObjectLayer.takeOwnershipOfBuffers(H, std::move(Bufs));
+ ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
}
void addArchive(object::OwningBinary<object::Archive> A) override {
@@ -234,6 +230,10 @@ public:
CompileLayer.setObjectCache(NewCache);
}
+ void setProcessAllSections(bool ProcessAllSections) override {
+ ObjectLayer.setProcessAllSections(ProcessAllSections);
+ }
+
private:
RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {
@@ -252,10 +252,12 @@ private:
object::Archive *A = OB.getBinary();
// Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name);
+ if (std::error_code EC = ChildIt->getError())
+ report_fatal_error(EC.message());
if (ChildIt != A->child_end()) {
// FIXME: Support nested archives?
ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
- ChildIt->getAsBinary();
+ (*ChildIt)->getAsBinary();
if (ChildBinOrErr.getError())
continue;
std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
@@ -289,7 +291,7 @@ private:
"Incorrect number of Infos for Objects.");
for (unsigned I = 0; I < Objects.size(); ++I)
M.MemMgr.notifyObjectLoaded(&M, *Objects[I]);
- };
+ }
private:
OrcMCJITReplacement &M;
@@ -310,7 +312,7 @@ private:
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
- Mang.getNameWithPrefix(MangledNameStream, Name, *TM->getDataLayout());
+ Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
}
return MangledName;
}
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
index 258868a..b931f10 100644
--- a/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
@@ -1,137 +1,170 @@
+//===------- OrcTargetSupport.cpp - Target support utilities for Orc ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
+#include "llvm/Support/Process.h"
#include <array>
-using namespace llvm::orc;
+namespace llvm {
+namespace orc {
-namespace {
+void OrcX86_64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
+ void *CallbackMgr) {
+
+ const uint8_t ResolverCode[] = {
+ // resolver_entry:
+ 0x55, // 0x00: pushq %rbp
+ 0x48, 0x89, 0xe5, // 0x01: movq %rsp, %rbp
+ 0x50, // 0x04: pushq %rax
+ 0x53, // 0x05: pushq %rbx
+ 0x51, // 0x06: pushq %rcx
+ 0x52, // 0x07: pushq %rdx
+ 0x56, // 0x08: pushq %rsi
+ 0x57, // 0x09: pushq %rdi
+ 0x41, 0x50, // 0x0a: pushq %r8
+ 0x41, 0x51, // 0x0c: pushq %r9
+ 0x41, 0x52, // 0x0e: pushq %r10
+ 0x41, 0x53, // 0x10: pushq %r11
+ 0x41, 0x54, // 0x12: pushq %r12
+ 0x41, 0x55, // 0x14: pushq %r13
+ 0x41, 0x56, // 0x16: pushq %r14
+ 0x41, 0x57, // 0x18: pushq %r15
+ 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00, // 0x1a: subq 20, %rsp
+ 0x48, 0x0f, 0xae, 0x04, 0x24, // 0x21: fxsave64 (%rsp)
+ 0x48, 0x8d, 0x3d, 0x43, 0x00, 0x00, 0x00, // 0x26: leaq 67(%rip), %rdi
+ 0x48, 0x8b, 0x3f, // 0x2d: movq (%rdi), %rdi
+ 0x48, 0x8b, 0x75, 0x08, // 0x30: movq 8(%rbp), %rsi
+ 0x48, 0x83, 0xee, 0x06, // 0x34: subq $6, %rsi
+ 0x48, 0xb8, // 0x38: movabsq $0, %rax
+
+ // 0x3a: JIT re-entry fn addr:
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0xff, 0xd0, // 0x42: callq *%rax
+ 0x48, 0x89, 0x45, 0x08, // 0x44: movq %rax, 8(%rbp)
+ 0x48, 0x0f, 0xae, 0x0c, 0x24, // 0x48: fxrstor64 (%rsp)
+ 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00, // 0x4d: addq 20, %rsp
+ 0x41, 0x5f, // 0x54: popq %r15
+ 0x41, 0x5e, // 0x56: popq %r14
+ 0x41, 0x5d, // 0x58: popq %r13
+ 0x41, 0x5c, // 0x5a: popq %r12
+ 0x41, 0x5b, // 0x5c: popq %r11
+ 0x41, 0x5a, // 0x5e: popq %r10
+ 0x41, 0x59, // 0x60: popq %r9
+ 0x41, 0x58, // 0x62: popq %r8
+ 0x5f, // 0x64: popq %rdi
+ 0x5e, // 0x65: popq %rsi
+ 0x5a, // 0x66: popq %rdx
+ 0x59, // 0x67: popq %rcx
+ 0x5b, // 0x68: popq %rbx
+ 0x58, // 0x69: popq %rax
+ 0x5d, // 0x6a: popq %rbp
+ 0xc3, // 0x6b: retq
+ 0x00, 0x00, 0x00, 0x00, // 0x6c: <padding>
+
+ // 0x70: Callback mgr address.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
-uint64_t executeCompileCallback(JITCompileCallbackManagerBase *JCBM,
- TargetAddress CallbackID) {
- return JCBM->executeCompileCallback(CallbackID);
+ const unsigned ReentryFnAddrOffset = 0x3a;
+ const unsigned CallbackMgrAddrOffset = 0x70;
+
+ memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
+ memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn));
+ memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
+ sizeof(CallbackMgr));
}
-}
+void OrcX86_64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ unsigned NumTrampolines) {
-namespace llvm {
-namespace orc {
+ unsigned OffsetToPtr = NumTrampolines * TrampolineSize;
-const char* OrcX86_64::ResolverBlockName = "orc_resolver_block";
-
-void OrcX86_64::insertResolverBlock(
- Module &M, JITCompileCallbackManagerBase &JCBM) {
-
- // Trampoline code-sequence length, used to get trampoline address from return
- // address.
- const unsigned X86_64_TrampolineLength = 6;
-
- // List of x86-64 GPRs to save. Note - RBP saved separately below.
- std::array<const char *, 14> GPRs = {{
- "rax", "rbx", "rcx", "rdx",
- "rsi", "rdi", "r8", "r9",
- "r10", "r11", "r12", "r13",
- "r14", "r15"
- }};
-
- // Address of the executeCompileCallback function.
- uint64_t CallbackAddr =
- static_cast<uint64_t>(
- reinterpret_cast<uintptr_t>(executeCompileCallback));
-
- std::ostringstream AsmStream;
- Triple TT(M.getTargetTriple());
-
- // Switch to text section.
- if (TT.getOS() == Triple::Darwin)
- AsmStream << ".section __TEXT,__text,regular,pure_instructions\n"
- << ".align 4, 0x90\n";
- else
- AsmStream << ".text\n"
- << ".align 16, 0x90\n";
-
- // Bake in a pointer to the callback manager immediately before the
- // start of the resolver function.
- AsmStream << "jit_callback_manager_addr:\n"
- << " .quad " << &JCBM << "\n";
-
- // Start the resolver function.
- AsmStream << ResolverBlockName << ":\n"
- << " pushq %rbp\n"
- << " movq %rsp, %rbp\n";
-
- // Store the GPRs.
- for (const auto &GPR : GPRs)
- AsmStream << " pushq %" << GPR << "\n";
-
- // Store floating-point state with FXSAVE.
- // Note: We need to keep the stack 16-byte aligned, so if we've emitted an odd
- // number of 64-bit pushes so far (GPRs.size() plus 1 for RBP) then add
- // an extra 64 bits of padding to the FXSave area.
- unsigned Padding = (GPRs.size() + 1) % 2 ? 8 : 0;
- unsigned FXSaveSize = 512 + Padding;
- AsmStream << " subq $" << FXSaveSize << ", %rsp\n"
- << " fxsave64 (%rsp)\n"
-
- // Load callback manager address, compute trampoline address, call JIT.
- << " lea jit_callback_manager_addr(%rip), %rdi\n"
- << " movq (%rdi), %rdi\n"
- << " movq 0x8(%rbp), %rsi\n"
- << " subq $" << X86_64_TrampolineLength << ", %rsi\n"
- << " movabsq $" << CallbackAddr << ", %rax\n"
- << " callq *%rax\n"
-
- // Replace the return to the trampoline with the return address of the
- // compiled function body.
- << " movq %rax, 0x8(%rbp)\n"
-
- // Restore the floating point state.
- << " fxrstor64 (%rsp)\n"
- << " addq $" << FXSaveSize << ", %rsp\n";
-
- for (const auto &GPR : make_range(GPRs.rbegin(), GPRs.rend()))
- AsmStream << " popq %" << GPR << "\n";
-
- // Restore original RBP and return to compiled function body.
- AsmStream << " popq %rbp\n"
- << " retq\n";
-
- M.appendModuleInlineAsm(AsmStream.str());
-}
+ memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void*));
-OrcX86_64::LabelNameFtor
-OrcX86_64::insertCompileCallbackTrampolines(Module &M,
- TargetAddress ResolverBlockAddr,
- unsigned NumCalls,
- unsigned StartIndex) {
- const char *ResolverBlockPtrName = "Lorc_resolve_block_addr";
-
- std::ostringstream AsmStream;
- Triple TT(M.getTargetTriple());
-
- if (TT.getOS() == Triple::Darwin)
- AsmStream << ".section __TEXT,__text,regular,pure_instructions\n"
- << ".align 4, 0x90\n";
- else
- AsmStream << ".text\n"
- << ".align 16, 0x90\n";
-
- AsmStream << ResolverBlockPtrName << ":\n"
- << " .quad " << ResolverBlockAddr << "\n";
-
- auto GetLabelName =
- [=](unsigned I) {
- std::ostringstream LabelStream;
- LabelStream << "orc_jcc_" << (StartIndex + I);
- return LabelStream.str();
- };
+ uint64_t *Trampolines = reinterpret_cast<uint64_t*>(TrampolineMem);
+ uint64_t CallIndirPCRel = 0xf1c40000000015ff;
- for (unsigned I = 0; I < NumCalls; ++I)
- AsmStream << GetLabelName(I) << ":\n"
- << " callq *" << ResolverBlockPtrName << "(%rip)\n";
-
- M.appendModuleInlineAsm(AsmStream.str());
+ for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize)
+ Trampolines[I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16);
+}
- return GetLabelName;
+std::error_code OrcX86_64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
+ unsigned MinStubs,
+ void *InitialPtrVal) {
+ // Stub format is:
+ //
+ // .section __orc_stubs
+ // stub1:
+ // jmpq *ptr1(%rip)
+ // .byte 0xC4 ; <- Invalid opcode padding.
+ // .byte 0xF1
+ // stub2:
+ // jmpq *ptr2(%rip)
+ //
+ // ...
+ //
+ // .section __orc_ptrs
+ // ptr1:
+ // .quad 0x0
+ // ptr2:
+ // .quad 0x0
+ //
+ // ...
+
+ const unsigned StubSize = IndirectStubsInfo::StubSize;
+
+ // Emit at least MinStubs, rounded up to fill the pages allocated.
+ unsigned PageSize = sys::Process::getPageSize();
+ unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
+ unsigned NumStubs = (NumPages * PageSize) / StubSize;
+
+ // Allocate memory for stubs and pointers in one call.
+ std::error_code EC;
+ auto StubsMem =
+ sys::OwningMemoryBlock(
+ sys::Memory::allocateMappedMemory(2 * NumPages * PageSize, nullptr,
+ sys::Memory::MF_READ |
+ sys::Memory::MF_WRITE,
+ EC));
+
+ if (EC)
+ return EC;
+
+ // Create separate MemoryBlocks representing the stubs and pointers.
+ sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
+ sys::MemoryBlock PtrsBlock(static_cast<char*>(StubsMem.base()) +
+ NumPages * PageSize,
+ NumPages * PageSize);
+
+ // Populate the stubs page stubs and mark it executable.
+ uint64_t *Stub = reinterpret_cast<uint64_t*>(StubsBlock.base());
+ uint64_t PtrOffsetField =
+ static_cast<uint64_t>(NumPages * PageSize - 6) << 16;
+ for (unsigned I = 0; I < NumStubs; ++I)
+ Stub[I] = 0xF1C40000000025ff | PtrOffsetField;
+
+ if (auto EC = sys::Memory::protectMappedMemory(StubsBlock,
+ sys::Memory::MF_READ |
+ sys::Memory::MF_EXEC))
+ return EC;
+
+ // Initialize all pointers to point at FailureAddress.
+ void **Ptr = reinterpret_cast<void**>(PtrsBlock.base());
+ for (unsigned I = 0; I < NumStubs; ++I)
+ Ptr[I] = InitialPtrVal;
+
+ StubsInfo.NumStubs = NumStubs;
+ StubsInfo.StubsMem = std::move(StubsMem);
+
+ return std::error_code();
}
} // End namespace orc.
OpenPOWER on IntegriCloud