diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/lib/ExecutionEngine/Orc | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/lib/ExecutionEngine/Orc')
24 files changed, 0 insertions, 6615 deletions
diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/gnu/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt deleted file mode 100644 index 9ca409f81cd..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -add_llvm_library(LLVMOrcJIT - CompileOnDemandLayer.cpp - Core.cpp - ExecutionUtils.cpp - IndirectionUtils.cpp - IRCompileLayer.cpp - IRTransformLayer.cpp - JITTargetMachineBuilder.cpp - LazyReexports.cpp - Legacy.cpp - Layer.cpp - LLJIT.cpp - NullResolver.cpp - ObjectTransformLayer.cpp - OrcABISupport.cpp - OrcCBindings.cpp - OrcError.cpp - OrcMCJITReplacement.cpp - RPCUtils.cpp - RTDyldObjectLinkingLayer.cpp - ThreadSafeModule.cpp - - ADDITIONAL_HEADER_DIRS - ${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/Orc - - DEPENDS - intrinsics_gen - ) - -target_link_libraries(LLVMOrcJIT - PRIVATE - LLVMBitReader - LLVMBitWriter - ) diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp deleted file mode 100644 index 241eb3600da..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp +++ /dev/null @@ -1,303 +0,0 @@ -//===----- CompileOnDemandLayer.cpp - Lazily emit IR on first call --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" - -using namespace llvm; -using namespace llvm::orc; - -static ThreadSafeModule extractSubModule(ThreadSafeModule &TSM, - StringRef Suffix, - GVPredicate ShouldExtract) { - - auto DeleteExtractedDefs = [](GlobalValue &GV) { - // Bump the linkage: this global will be provided by the external module. - GV.setLinkage(GlobalValue::ExternalLinkage); - - // Delete the definition in the source module. - if (isa<Function>(GV)) { - auto &F = cast<Function>(GV); - F.deleteBody(); - F.setPersonalityFn(nullptr); - } else if (isa<GlobalVariable>(GV)) { - cast<GlobalVariable>(GV).setInitializer(nullptr); - } else if (isa<GlobalAlias>(GV)) { - // We need to turn deleted aliases into function or variable decls based - // on the type of their aliasee. - auto &A = cast<GlobalAlias>(GV); - Constant *Aliasee = A.getAliasee(); - assert(A.hasName() && "Anonymous alias?"); - assert(Aliasee->hasName() && "Anonymous aliasee"); - std::string AliasName = A.getName(); - - if (isa<Function>(Aliasee)) { - auto *F = cloneFunctionDecl(*A.getParent(), *cast<Function>(Aliasee)); - A.replaceAllUsesWith(F); - A.eraseFromParent(); - F->setName(AliasName); - } else if (isa<GlobalVariable>(Aliasee)) { - auto *G = cloneGlobalVariableDecl(*A.getParent(), - *cast<GlobalVariable>(Aliasee)); - A.replaceAllUsesWith(G); - A.eraseFromParent(); - G->setName(AliasName); - } else - llvm_unreachable("Alias to unsupported type"); - } else - llvm_unreachable("Unsupported global type"); - }; - - auto NewTSMod = cloneToNewContext(TSM, ShouldExtract, DeleteExtractedDefs); - auto &M = *NewTSMod.getModule(); - M.setModuleIdentifier((M.getModuleIdentifier() + Suffix).str()); - - return NewTSMod; -} - -namespace llvm { -namespace orc { - -class PartitioningIRMaterializationUnit : public IRMaterializationUnit { -public: - PartitioningIRMaterializationUnit(ExecutionSession &ES, ThreadSafeModule TSM, - VModuleKey K, CompileOnDemandLayer &Parent) - : IRMaterializationUnit(ES, std::move(TSM), std::move(K)), - Parent(Parent) {} - - PartitioningIRMaterializationUnit( - ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags, - SymbolNameToDefinitionMap SymbolToDefinition, - CompileOnDemandLayer &Parent) - : IRMaterializationUnit(std::move(TSM), std::move(K), - std::move(SymbolFlags), - std::move(SymbolToDefinition)), - Parent(Parent) {} - -private: - void materialize(MaterializationResponsibility R) override { - Parent.emitPartition(std::move(R), std::move(TSM), - std::move(SymbolToDefinition)); - } - - void discard(const JITDylib &V, const SymbolStringPtr &Name) override { - // All original symbols were materialized by the CODLayer and should be - // final. The function bodies provided by M should never be overridden. - llvm_unreachable("Discard should never be called on an " - "ExtractingIRMaterializationUnit"); - } - - mutable std::mutex SourceModuleMutex; - CompileOnDemandLayer &Parent; -}; - -Optional<CompileOnDemandLayer::GlobalValueSet> -CompileOnDemandLayer::compileRequested(GlobalValueSet Requested) { - return std::move(Requested); -} - -Optional<CompileOnDemandLayer::GlobalValueSet> -CompileOnDemandLayer::compileWholeModule(GlobalValueSet Requested) { - return None; -} - -CompileOnDemandLayer::CompileOnDemandLayer( - ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr, - IndirectStubsManagerBuilder BuildIndirectStubsManager) - : IRLayer(ES), BaseLayer(BaseLayer), LCTMgr(LCTMgr), - BuildIndirectStubsManager(std::move(BuildIndirectStubsManager)) {} - -void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) { - this->Partition = std::move(Partition); -} - -void CompileOnDemandLayer::emit(MaterializationResponsibility R, - ThreadSafeModule TSM) { - assert(TSM.getModule() && "Null module"); - - auto &ES = getExecutionSession(); - auto &M = *TSM.getModule(); - - // First, do some cleanup on the module: - cleanUpModule(M); - - // Now sort the callables and non-callables, build re-exports and lodge the - // actual module with the implementation dylib. - auto &PDR = getPerDylibResources(R.getTargetJITDylib()); - - MangleAndInterner Mangle(ES, M.getDataLayout()); - SymbolAliasMap NonCallables; - SymbolAliasMap Callables; - for (auto &GV : M.global_values()) { - if (GV.isDeclaration() || GV.hasLocalLinkage() || GV.hasAppendingLinkage()) - continue; - - auto Name = Mangle(GV.getName()); - auto Flags = JITSymbolFlags::fromGlobalValue(GV); - if (Flags.isCallable()) - Callables[Name] = SymbolAliasMapEntry(Name, Flags); - else - NonCallables[Name] = SymbolAliasMapEntry(Name, Flags); - } - - // Create a partitioning materialization unit and lodge it with the - // implementation dylib. - if (auto Err = PDR.getImplDylib().define( - llvm::make_unique<PartitioningIRMaterializationUnit>( - ES, std::move(TSM), R.getVModuleKey(), *this))) { - ES.reportError(std::move(Err)); - R.failMaterialization(); - return; - } - - R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), true)); - R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), - std::move(Callables))); -} - -CompileOnDemandLayer::PerDylibResources & -CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) { - auto I = DylibResources.find(&TargetD); - if (I == DylibResources.end()) { - auto &ImplD = getExecutionSession().createJITDylib( - TargetD.getName() + ".impl", false); - TargetD.withSearchOrderDo([&](const JITDylibSearchList &TargetSearchOrder) { - auto NewSearchOrder = TargetSearchOrder; - assert(!NewSearchOrder.empty() && - NewSearchOrder.front().first == &TargetD && - NewSearchOrder.front().second == true && - "TargetD must be at the front of its own search order and match " - "non-exported symbol"); - NewSearchOrder.insert(std::next(NewSearchOrder.begin()), {&ImplD, true}); - ImplD.setSearchOrder(std::move(NewSearchOrder), false); - }); - PerDylibResources PDR(ImplD, BuildIndirectStubsManager()); - I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first; - } - - return I->second; -} - -void CompileOnDemandLayer::cleanUpModule(Module &M) { - for (auto &F : M.functions()) { - if (F.isDeclaration()) - continue; - - if (F.hasAvailableExternallyLinkage()) { - F.deleteBody(); - F.setPersonalityFn(nullptr); - continue; - } - } -} - -void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) { - // Expands the partition to ensure the following rules hold: - // (1) If any alias is in the partition, its aliasee is also in the partition. - // (2) If any aliasee is in the partition, its aliases are also in the - // partiton. - // (3) If any global variable is in the partition then all global variables - // are in the partition. - assert(!Partition.empty() && "Unexpected empty partition"); - - const Module &M = *(*Partition.begin())->getParent(); - bool ContainsGlobalVariables = false; - std::vector<const GlobalValue *> GVsToAdd; - - for (auto *GV : Partition) - if (isa<GlobalAlias>(GV)) - GVsToAdd.push_back( - cast<GlobalValue>(cast<GlobalAlias>(GV)->getAliasee())); - else if (isa<GlobalVariable>(GV)) - ContainsGlobalVariables = true; - - for (auto &A : M.aliases()) - if (Partition.count(cast<GlobalValue>(A.getAliasee()))) - GVsToAdd.push_back(&A); - - if (ContainsGlobalVariables) - for (auto &G : M.globals()) - GVsToAdd.push_back(&G); - - for (auto *GV : GVsToAdd) - Partition.insert(GV); -} - -void CompileOnDemandLayer::emitPartition( - MaterializationResponsibility R, ThreadSafeModule TSM, - IRMaterializationUnit::SymbolNameToDefinitionMap Defs) { - - // FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the - // extracted module key, extracted module, and source module key - // together. This could be used, for example, to provide a specific - // memory manager instance to the linking layer. - - auto &ES = getExecutionSession(); - - GlobalValueSet RequestedGVs; - for (auto &Name : R.getRequestedSymbols()) { - assert(Defs.count(Name) && "No definition for symbol"); - RequestedGVs.insert(Defs[Name]); - } - - auto GVsToExtract = Partition(RequestedGVs); - - // Take a 'None' partition to mean the whole module (as opposed to an empty - // partition, which means "materialize nothing"). Emit the whole module - // unmodified to the base layer. - if (GVsToExtract == None) { - Defs.clear(); - BaseLayer.emit(std::move(R), std::move(TSM)); - return; - } - - // If the partition is empty, return the whole module to the symbol table. - if (GVsToExtract->empty()) { - R.replace(llvm::make_unique<PartitioningIRMaterializationUnit>( - std::move(TSM), R.getSymbols(), std::move(Defs), *this)); - return; - } - - // Ok -- we actually need to partition the symbols. Promote the symbol - // linkages/names. - // FIXME: We apply this once per partitioning. It's safe, but overkill. - { - auto PromotedGlobals = PromoteSymbols(*TSM.getModule()); - if (!PromotedGlobals.empty()) { - MangleAndInterner Mangle(ES, TSM.getModule()->getDataLayout()); - SymbolFlagsMap SymbolFlags; - for (auto &GV : PromotedGlobals) - SymbolFlags[Mangle(GV->getName())] = - JITSymbolFlags::fromGlobalValue(*GV); - if (auto Err = R.defineMaterializing(SymbolFlags)) { - ES.reportError(std::move(Err)); - R.failMaterialization(); - return; - } - } - } - - expandPartition(*GVsToExtract); - - // Extract the requested partiton (plus any necessary aliases) and - // put the rest back into the impl dylib. - auto ShouldExtract = [&](const GlobalValue &GV) -> bool { - return GVsToExtract->count(&GV); - }; - - auto ExtractedTSM = extractSubModule(TSM, ".submodule", ShouldExtract); - R.replace(llvm::make_unique<PartitioningIRMaterializationUnit>( - ES, std::move(TSM), R.getVModuleKey(), *this)); - - BaseLayer.emit(std::move(R), std::move(ExtractedTSM)); -} - -} // end namespace orc -} // end namespace llvm diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/Core.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/Core.cpp deleted file mode 100644 index 73c0bcdf7d2..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ /dev/null @@ -1,2004 +0,0 @@ -//===--- Core.cpp - Core ORC APIs (MaterializationUnit, JITDylib, etc.) ---===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/Core.h" -#include "llvm/Config/llvm-config.h" -#include "llvm/ExecutionEngine/Orc/OrcError.h" -#include "llvm/IR/Mangler.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Format.h" - -#if LLVM_ENABLE_THREADS -#include <future> -#endif - -#define DEBUG_TYPE "orc" - -using namespace llvm; - -namespace { - -#ifndef NDEBUG - -cl::opt<bool> PrintHidden("debug-orc-print-hidden", cl::init(false), - cl::desc("debug print hidden symbols defined by " - "materialization units"), - cl::Hidden); - -cl::opt<bool> PrintCallable("debug-orc-print-callable", cl::init(false), - cl::desc("debug print callable symbols defined by " - "materialization units"), - cl::Hidden); - -cl::opt<bool> PrintData("debug-orc-print-data", cl::init(false), - cl::desc("debug print data symbols defined by " - "materialization units"), - cl::Hidden); - -#endif // NDEBUG - -// SetPrinter predicate that prints every element. -template <typename T> struct PrintAll { - bool operator()(const T &E) { return true; } -}; - -bool anyPrintSymbolOptionSet() { -#ifndef NDEBUG - return PrintHidden || PrintCallable || PrintData; -#else - return false; -#endif // NDEBUG -} - -bool flagsMatchCLOpts(const JITSymbolFlags &Flags) { -#ifndef NDEBUG - // Bail out early if this is a hidden symbol and we're not printing hiddens. - if (!PrintHidden && !Flags.isExported()) - return false; - - // Return true if this is callable and we're printing callables. - if (PrintCallable && Flags.isCallable()) - return true; - - // Return true if this is data and we're printing data. - if (PrintData && !Flags.isCallable()) - return true; - - // otherwise return false. - return false; -#else - return false; -#endif // NDEBUG -} - -// Prints a set of items, filtered by an user-supplied predicate. -template <typename Set, typename Pred = PrintAll<typename Set::value_type>> -class SetPrinter { -public: - SetPrinter(const Set &S, Pred ShouldPrint = Pred()) - : S(S), ShouldPrint(std::move(ShouldPrint)) {} - - void printTo(llvm::raw_ostream &OS) const { - bool PrintComma = false; - OS << "{"; - for (auto &E : S) { - if (ShouldPrint(E)) { - if (PrintComma) - OS << ','; - OS << ' ' << E; - PrintComma = true; - } - } - OS << " }"; - } - -private: - const Set &S; - mutable Pred ShouldPrint; -}; - -template <typename Set, typename Pred> -SetPrinter<Set, Pred> printSet(const Set &S, Pred P = Pred()) { - return SetPrinter<Set, Pred>(S, std::move(P)); -} - -// Render a SetPrinter by delegating to its printTo method. -template <typename Set, typename Pred> -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, - const SetPrinter<Set, Pred> &Printer) { - Printer.printTo(OS); - return OS; -} - -struct PrintSymbolFlagsMapElemsMatchingCLOpts { - bool operator()(const orc::SymbolFlagsMap::value_type &KV) { - return flagsMatchCLOpts(KV.second); - } -}; - -struct PrintSymbolMapElemsMatchingCLOpts { - bool operator()(const orc::SymbolMap::value_type &KV) { - return flagsMatchCLOpts(KV.second.getFlags()); - } -}; - -} // end anonymous namespace - -namespace llvm { -namespace orc { - - SymbolStringPool::PoolMapEntry SymbolStringPtr::Tombstone(0); - -char FailedToMaterialize::ID = 0; -char SymbolsNotFound::ID = 0; -char SymbolsCouldNotBeRemoved::ID = 0; - -RegisterDependenciesFunction NoDependenciesToRegister = - RegisterDependenciesFunction(); - -void MaterializationUnit::anchor() {} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) { - return OS << *Sym; -} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) { - return OS << printSet(Symbols, PrintAll<SymbolStringPtr>()); -} - -raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) { - if (Flags.isCallable()) - OS << "[Callable]"; - else - OS << "[Data]"; - if (Flags.isWeak()) - OS << "[Weak]"; - else if (Flags.isCommon()) - OS << "[Common]"; - - if (!Flags.isExported()) - OS << "[Hidden]"; - - return OS; -} - -raw_ostream &operator<<(raw_ostream &OS, const JITEvaluatedSymbol &Sym) { - return OS << format("0x%016" PRIx64, Sym.getAddress()) << " " - << Sym.getFlags(); -} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV) { - return OS << "(\"" << KV.first << "\", " << KV.second << ")"; -} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) { - return OS << "(\"" << KV.first << "\": " << KV.second << ")"; -} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) { - return OS << printSet(SymbolFlags, PrintSymbolFlagsMapElemsMatchingCLOpts()); -} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) { - return OS << printSet(Symbols, PrintSymbolMapElemsMatchingCLOpts()); -} - -raw_ostream &operator<<(raw_ostream &OS, - const SymbolDependenceMap::value_type &KV) { - return OS << "(" << KV.first << ", " << KV.second << ")"; -} - -raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) { - return OS << printSet(Deps, PrintAll<SymbolDependenceMap::value_type>()); -} - -raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) { - OS << "MU@" << &MU << " (\"" << MU.getName() << "\""; - if (anyPrintSymbolOptionSet()) - OS << ", " << MU.getSymbols(); - return OS << ")"; -} - -raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs) { - OS << "["; - if (!JDs.empty()) { - assert(JDs.front().first && "JITDylibList entries must not be null"); - OS << " (\"" << JDs.front().first->getName() << "\", " - << (JDs.front().second ? "true" : "false") << ")"; - for (auto &KV : make_range(std::next(JDs.begin()), JDs.end())) { - assert(KV.first && "JITDylibList entries must not be null"); - OS << ", (\"" << KV.first->getName() << "\", " - << (KV.second ? "true" : "false") << ")"; - } - } - OS << " ]"; - return OS; -} - -FailedToMaterialize::FailedToMaterialize(SymbolNameSet Symbols) - : Symbols(std::move(Symbols)) { - assert(!this->Symbols.empty() && "Can not fail to resolve an empty set"); -} - -std::error_code FailedToMaterialize::convertToErrorCode() const { - return orcError(OrcErrorCode::UnknownORCError); -} - -void FailedToMaterialize::log(raw_ostream &OS) const { - OS << "Failed to materialize symbols: " << Symbols; -} - -SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) - : Symbols(std::move(Symbols)) { - assert(!this->Symbols.empty() && "Can not fail to resolve an empty set"); -} - -std::error_code SymbolsNotFound::convertToErrorCode() const { - return orcError(OrcErrorCode::UnknownORCError); -} - -void SymbolsNotFound::log(raw_ostream &OS) const { - OS << "Symbols not found: " << Symbols; -} - -SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols) - : Symbols(std::move(Symbols)) { - assert(!this->Symbols.empty() && "Can not fail to resolve an empty set"); -} - -std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const { - return orcError(OrcErrorCode::UnknownORCError); -} - -void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const { - OS << "Symbols could not be removed: " << Symbols; -} - -AsynchronousSymbolQuery::AsynchronousSymbolQuery( - const SymbolNameSet &Symbols, SymbolsResolvedCallback NotifySymbolsResolved, - SymbolsReadyCallback NotifySymbolsReady) - : NotifySymbolsResolved(std::move(NotifySymbolsResolved)), - NotifySymbolsReady(std::move(NotifySymbolsReady)) { - NotYetResolvedCount = NotYetReadyCount = Symbols.size(); - - for (auto &S : Symbols) - ResolvedSymbols[S] = nullptr; -} - -void AsynchronousSymbolQuery::resolve(const SymbolStringPtr &Name, - JITEvaluatedSymbol Sym) { - auto I = ResolvedSymbols.find(Name); - assert(I != ResolvedSymbols.end() && - "Resolving symbol outside the requested set"); - assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name"); - I->second = std::move(Sym); - --NotYetResolvedCount; -} - -void AsynchronousSymbolQuery::handleFullyResolved() { - assert(NotYetResolvedCount == 0 && "Not fully resolved?"); - - if (!NotifySymbolsResolved) { - // handleFullyResolved may be called by handleFullyReady (see comments in - // that method), in which case this is a no-op, so bail out. - assert(!NotifySymbolsReady && - "NotifySymbolsResolved already called or an error occurred"); - return; - } - - auto TmpNotifySymbolsResolved = std::move(NotifySymbolsResolved); - NotifySymbolsResolved = SymbolsResolvedCallback(); - TmpNotifySymbolsResolved(std::move(ResolvedSymbols)); -} - -void AsynchronousSymbolQuery::notifySymbolReady() { - assert(NotYetReadyCount != 0 && "All symbols already emitted"); - --NotYetReadyCount; -} - -void AsynchronousSymbolQuery::handleFullyReady() { - assert(NotifySymbolsReady && - "NotifySymbolsReady already called or an error occurred"); - - auto TmpNotifySymbolsReady = std::move(NotifySymbolsReady); - NotifySymbolsReady = SymbolsReadyCallback(); - - if (NotYetResolvedCount == 0 && NotifySymbolsResolved) { - // The NotifyResolved callback of one query must have caused this query to - // become ready (i.e. there is still a handleFullyResolved callback waiting - // to be made back up the stack). Fold the handleFullyResolved call into - // this one before proceeding. This will cause the call further up the - // stack to become a no-op. - handleFullyResolved(); - } - - assert(QueryRegistrations.empty() && - "Query is still registered with some symbols"); - assert(!NotifySymbolsResolved && "Resolution not applied yet"); - TmpNotifySymbolsReady(Error::success()); -} - -bool AsynchronousSymbolQuery::canStillFail() { - return (NotifySymbolsResolved || NotifySymbolsReady); -} - -void AsynchronousSymbolQuery::handleFailed(Error Err) { - assert(QueryRegistrations.empty() && ResolvedSymbols.empty() && - NotYetResolvedCount == 0 && NotYetReadyCount == 0 && - "Query should already have been abandoned"); - if (NotifySymbolsResolved) { - NotifySymbolsResolved(std::move(Err)); - NotifySymbolsResolved = SymbolsResolvedCallback(); - } else { - assert(NotifySymbolsReady && "Failed after both callbacks issued?"); - NotifySymbolsReady(std::move(Err)); - } - NotifySymbolsReady = SymbolsReadyCallback(); -} - -void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD, - SymbolStringPtr Name) { - bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second; - (void)Added; - assert(Added && "Duplicate dependence notification?"); -} - -void AsynchronousSymbolQuery::removeQueryDependence( - JITDylib &JD, const SymbolStringPtr &Name) { - auto QRI = QueryRegistrations.find(&JD); - assert(QRI != QueryRegistrations.end() && - "No dependencies registered for JD"); - assert(QRI->second.count(Name) && "No dependency on Name in JD"); - QRI->second.erase(Name); - if (QRI->second.empty()) - QueryRegistrations.erase(QRI); -} - -void AsynchronousSymbolQuery::detach() { - ResolvedSymbols.clear(); - NotYetResolvedCount = 0; - NotYetReadyCount = 0; - for (auto &KV : QueryRegistrations) - KV.first->detachQueryHelper(*this, KV.second); - QueryRegistrations.clear(); -} - -MaterializationResponsibility::MaterializationResponsibility( - JITDylib &JD, SymbolFlagsMap SymbolFlags, VModuleKey K) - : JD(JD), SymbolFlags(std::move(SymbolFlags)), K(std::move(K)) { - assert(!this->SymbolFlags.empty() && "Materializing nothing?"); - -#ifndef NDEBUG - for (auto &KV : this->SymbolFlags) - KV.second |= JITSymbolFlags::Materializing; -#endif -} - -MaterializationResponsibility::~MaterializationResponsibility() { - assert(SymbolFlags.empty() && - "All symbols should have been explicitly materialized or failed"); -} - -SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const { - return JD.getRequestedSymbols(SymbolFlags); -} - -void MaterializationResponsibility::resolve(const SymbolMap &Symbols) { - LLVM_DEBUG(dbgs() << "In " << JD.getName() << " resolving " << Symbols - << "\n"); -#ifndef NDEBUG - for (auto &KV : Symbols) { - auto I = SymbolFlags.find(KV.first); - assert(I != SymbolFlags.end() && - "Resolving symbol outside this responsibility set"); - assert(I->second.isMaterializing() && "Duplicate resolution"); - I->second &= ~JITSymbolFlags::Materializing; - if (I->second.isWeak()) - assert(I->second == (KV.second.getFlags() | JITSymbolFlags::Weak) && - "Resolving symbol with incorrect flags"); - else - assert(I->second == KV.second.getFlags() && - "Resolving symbol with incorrect flags"); - } -#endif - - JD.resolve(Symbols); -} - -void MaterializationResponsibility::emit() { -#ifndef NDEBUG - for (auto &KV : SymbolFlags) - assert(!KV.second.isMaterializing() && - "Failed to resolve symbol before emission"); -#endif // NDEBUG - - JD.emit(SymbolFlags); - SymbolFlags.clear(); -} - -Error MaterializationResponsibility::defineMaterializing( - const SymbolFlagsMap &NewSymbolFlags) { - // Add the given symbols to this responsibility object. - // It's ok if we hit a duplicate here: In that case the new version will be - // discarded, and the JITDylib::defineMaterializing method will return a - // duplicate symbol error. - for (auto &KV : NewSymbolFlags) { - auto I = SymbolFlags.insert(KV).first; - (void)I; -#ifndef NDEBUG - I->second |= JITSymbolFlags::Materializing; -#endif - } - - return JD.defineMaterializing(NewSymbolFlags); -} - -void MaterializationResponsibility::failMaterialization() { - - SymbolNameSet FailedSymbols; - for (auto &KV : SymbolFlags) - FailedSymbols.insert(KV.first); - - JD.notifyFailed(FailedSymbols); - SymbolFlags.clear(); -} - -void MaterializationResponsibility::replace( - std::unique_ptr<MaterializationUnit> MU) { - for (auto &KV : MU->getSymbols()) - SymbolFlags.erase(KV.first); - - LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() { - dbgs() << "In " << JD.getName() << " replacing symbols with " << *MU - << "\n"; - });); - - JD.replace(std::move(MU)); -} - -MaterializationResponsibility -MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, - VModuleKey NewKey) { - - if (NewKey == VModuleKey()) - NewKey = K; - - SymbolFlagsMap DelegatedFlags; - - for (auto &Name : Symbols) { - auto I = SymbolFlags.find(Name); - assert(I != SymbolFlags.end() && - "Symbol is not tracked by this MaterializationResponsibility " - "instance"); - - DelegatedFlags[Name] = std::move(I->second); - SymbolFlags.erase(I); - } - - return MaterializationResponsibility(JD, std::move(DelegatedFlags), - std::move(NewKey)); -} - -void MaterializationResponsibility::addDependencies( - const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) { - assert(SymbolFlags.count(Name) && - "Symbol not covered by this MaterializationResponsibility instance"); - JD.addDependencies(Name, Dependencies); -} - -void MaterializationResponsibility::addDependenciesForAll( - const SymbolDependenceMap &Dependencies) { - for (auto &KV : SymbolFlags) - JD.addDependencies(KV.first, Dependencies); -} - -AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit( - SymbolMap Symbols, VModuleKey K) - : MaterializationUnit(extractFlags(Symbols), std::move(K)), - Symbols(std::move(Symbols)) {} - -StringRef AbsoluteSymbolsMaterializationUnit::getName() const { - return "<Absolute Symbols>"; -} - -void AbsoluteSymbolsMaterializationUnit::materialize( - MaterializationResponsibility R) { - R.resolve(Symbols); - R.emit(); -} - -void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD, - const SymbolStringPtr &Name) { - assert(Symbols.count(Name) && "Symbol is not part of this MU"); - Symbols.erase(Name); -} - -SymbolFlagsMap -AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) { - SymbolFlagsMap Flags; - for (const auto &KV : Symbols) - Flags[KV.first] = KV.second.getFlags(); - return Flags; -} - -ReExportsMaterializationUnit::ReExportsMaterializationUnit( - JITDylib *SourceJD, bool MatchNonExported, SymbolAliasMap Aliases, - VModuleKey K) - : MaterializationUnit(extractFlags(Aliases), std::move(K)), - SourceJD(SourceJD), MatchNonExported(MatchNonExported), - Aliases(std::move(Aliases)) {} - -StringRef ReExportsMaterializationUnit::getName() const { - return "<Reexports>"; -} - -void ReExportsMaterializationUnit::materialize( - MaterializationResponsibility R) { - - auto &ES = R.getTargetJITDylib().getExecutionSession(); - JITDylib &TgtJD = R.getTargetJITDylib(); - JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD; - - // Find the set of requested aliases and aliasees. Return any unrequested - // aliases back to the JITDylib so as to not prematurely materialize any - // aliasees. - auto RequestedSymbols = R.getRequestedSymbols(); - SymbolAliasMap RequestedAliases; - - for (auto &Name : RequestedSymbols) { - auto I = Aliases.find(Name); - assert(I != Aliases.end() && "Symbol not found in aliases map?"); - RequestedAliases[Name] = std::move(I->second); - Aliases.erase(I); - } - - if (!Aliases.empty()) { - if (SourceJD) - R.replace(reexports(*SourceJD, std::move(Aliases), MatchNonExported)); - else - R.replace(symbolAliases(std::move(Aliases))); - } - - // The OnResolveInfo struct will hold the aliases and responsibilty for each - // query in the list. - struct OnResolveInfo { - OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases) - : R(std::move(R)), Aliases(std::move(Aliases)) {} - - MaterializationResponsibility R; - SymbolAliasMap Aliases; - }; - - // Build a list of queries to issue. In each round we build the largest set of - // aliases that we can resolve without encountering a chain definition of the - // form Foo -> Bar, Bar -> Baz. Such a form would deadlock as the query would - // be waitin on a symbol that it itself had to resolve. Usually this will just - // involve one round and a single query. - - std::vector<std::pair<SymbolNameSet, std::shared_ptr<OnResolveInfo>>> - QueryInfos; - while (!RequestedAliases.empty()) { - SymbolNameSet ResponsibilitySymbols; - SymbolNameSet QuerySymbols; - SymbolAliasMap QueryAliases; - - // Collect as many aliases as we can without including a chain. - for (auto &KV : RequestedAliases) { - // Chain detected. Skip this symbol for this round. - if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) || - RequestedAliases.count(KV.second.Aliasee))) - continue; - - ResponsibilitySymbols.insert(KV.first); - QuerySymbols.insert(KV.second.Aliasee); - QueryAliases[KV.first] = std::move(KV.second); - } - - // Remove the aliases collected this round from the RequestedAliases map. - for (auto &KV : QueryAliases) - RequestedAliases.erase(KV.first); - - assert(!QuerySymbols.empty() && "Alias cycle detected!"); - - auto QueryInfo = std::make_shared<OnResolveInfo>( - R.delegate(ResponsibilitySymbols), std::move(QueryAliases)); - QueryInfos.push_back( - make_pair(std::move(QuerySymbols), std::move(QueryInfo))); - } - - // Issue the queries. - while (!QueryInfos.empty()) { - auto QuerySymbols = std::move(QueryInfos.back().first); - auto QueryInfo = std::move(QueryInfos.back().second); - - QueryInfos.pop_back(); - - auto RegisterDependencies = [QueryInfo, - &SrcJD](const SymbolDependenceMap &Deps) { - // If there were no materializing symbols, just bail out. - if (Deps.empty()) - return; - - // Otherwise the only deps should be on SrcJD. - assert(Deps.size() == 1 && Deps.count(&SrcJD) && - "Unexpected dependencies for reexports"); - - auto &SrcJDDeps = Deps.find(&SrcJD)->second; - SymbolDependenceMap PerAliasDepsMap; - auto &PerAliasDeps = PerAliasDepsMap[&SrcJD]; - - for (auto &KV : QueryInfo->Aliases) - if (SrcJDDeps.count(KV.second.Aliasee)) { - PerAliasDeps = {KV.second.Aliasee}; - QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap); - } - }; - - auto OnResolve = [QueryInfo](Expected<SymbolMap> Result) { - if (Result) { - SymbolMap ResolutionMap; - for (auto &KV : QueryInfo->Aliases) { - assert(Result->count(KV.second.Aliasee) && - "Result map missing entry?"); - ResolutionMap[KV.first] = JITEvaluatedSymbol( - (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags); - } - QueryInfo->R.resolve(ResolutionMap); - QueryInfo->R.emit(); - } else { - auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession(); - ES.reportError(Result.takeError()); - QueryInfo->R.failMaterialization(); - } - }; - - auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); }; - - ES.lookup(JITDylibSearchList({{&SrcJD, MatchNonExported}}), QuerySymbols, - std::move(OnResolve), std::move(OnReady), - std::move(RegisterDependencies)); - } -} - -void ReExportsMaterializationUnit::discard(const JITDylib &JD, - const SymbolStringPtr &Name) { - assert(Aliases.count(Name) && - "Symbol not covered by this MaterializationUnit"); - Aliases.erase(Name); -} - -SymbolFlagsMap -ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) { - SymbolFlagsMap SymbolFlags; - for (auto &KV : Aliases) - SymbolFlags[KV.first] = KV.second.AliasFlags; - - return SymbolFlags; -} - -Expected<SymbolAliasMap> -buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) { - auto Flags = SourceJD.lookupFlags(Symbols); - - if (Flags.size() != Symbols.size()) { - SymbolNameSet Unresolved = Symbols; - for (auto &KV : Flags) - Unresolved.erase(KV.first); - return make_error<SymbolsNotFound>(std::move(Unresolved)); - } - - SymbolAliasMap Result; - for (auto &Name : Symbols) { - assert(Flags.count(Name) && "Missing entry in flags map"); - Result[Name] = SymbolAliasMapEntry(Name, Flags[Name]); - } - - return Result; -} - -ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD, - bool MatchNonExported, - SymbolPredicate Allow) - : SourceJD(SourceJD), MatchNonExported(MatchNonExported), - Allow(std::move(Allow)) {} - -SymbolNameSet ReexportsGenerator::operator()(JITDylib &JD, - const SymbolNameSet &Names) { - orc::SymbolNameSet Added; - orc::SymbolAliasMap AliasMap; - - auto Flags = SourceJD.lookupFlags(Names); - - for (auto &KV : Flags) { - if (Allow && !Allow(KV.first)) - continue; - AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second); - Added.insert(KV.first); - } - - if (!Added.empty()) - cantFail(JD.define(reexports(SourceJD, AliasMap, MatchNonExported))); - - return Added; -} - -Error JITDylib::defineMaterializing(const SymbolFlagsMap &SymbolFlags) { - return ES.runSessionLocked([&]() -> Error { - std::vector<SymbolMap::iterator> AddedSyms; - - for (auto &KV : SymbolFlags) { - SymbolMap::iterator EntryItr; - bool Added; - - auto NewFlags = KV.second; - NewFlags |= JITSymbolFlags::Materializing; - - std::tie(EntryItr, Added) = Symbols.insert( - std::make_pair(KV.first, JITEvaluatedSymbol(0, NewFlags))); - - if (Added) - AddedSyms.push_back(EntryItr); - else { - // Remove any symbols already added. - for (auto &SI : AddedSyms) - Symbols.erase(SI); - - // FIXME: Return all duplicates. - return make_error<DuplicateDefinition>(*KV.first); - } - } - - return Error::success(); - }); -} - -void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) { - assert(MU != nullptr && "Can not replace with a null MaterializationUnit"); - - auto MustRunMU = - ES.runSessionLocked([&, this]() -> std::unique_ptr<MaterializationUnit> { - -#ifndef NDEBUG - for (auto &KV : MU->getSymbols()) { - auto SymI = Symbols.find(KV.first); - assert(SymI != Symbols.end() && "Replacing unknown symbol"); - assert(!SymI->second.getFlags().isLazy() && - SymI->second.getFlags().isMaterializing() && - "Can not replace symbol that is not materializing"); - assert(UnmaterializedInfos.count(KV.first) == 0 && - "Symbol being replaced should have no UnmaterializedInfo"); - } -#endif // NDEBUG - - // If any symbol has pending queries against it then we need to - // materialize MU immediately. - for (auto &KV : MU->getSymbols()) { - auto MII = MaterializingInfos.find(KV.first); - if (MII != MaterializingInfos.end()) { - if (!MII->second.PendingQueries.empty()) - return std::move(MU); - } - } - - // Otherwise, make MU responsible for all the symbols. - auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU)); - for (auto &KV : UMI->MU->getSymbols()) { - assert(!KV.second.isLazy() && - "Lazy flag should be managed internally."); - assert(!KV.second.isMaterializing() && - "Materializing flags should be managed internally."); - - auto SymI = Symbols.find(KV.first); - JITSymbolFlags ReplaceFlags = KV.second; - ReplaceFlags |= JITSymbolFlags::Lazy; - SymI->second = JITEvaluatedSymbol(SymI->second.getAddress(), - std::move(ReplaceFlags)); - UnmaterializedInfos[KV.first] = UMI; - } - - return nullptr; - }); - - if (MustRunMU) - ES.dispatchMaterialization(*this, std::move(MustRunMU)); -} - -SymbolNameSet -JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const { - return ES.runSessionLocked([&]() { - SymbolNameSet RequestedSymbols; - - for (auto &KV : SymbolFlags) { - assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?"); - assert(Symbols.find(KV.first)->second.getFlags().isMaterializing() && - "getRequestedSymbols can only be called for materializing " - "symbols"); - auto I = MaterializingInfos.find(KV.first); - if (I == MaterializingInfos.end()) - continue; - - if (!I->second.PendingQueries.empty()) - RequestedSymbols.insert(KV.first); - } - - return RequestedSymbols; - }); -} - -void JITDylib::addDependencies(const SymbolStringPtr &Name, - const SymbolDependenceMap &Dependencies) { - assert(Symbols.count(Name) && "Name not in symbol table"); - assert((Symbols[Name].getFlags().isLazy() || - Symbols[Name].getFlags().isMaterializing()) && - "Symbol is not lazy or materializing"); - - auto &MI = MaterializingInfos[Name]; - assert(!MI.IsEmitted && "Can not add dependencies to an emitted symbol"); - - for (auto &KV : Dependencies) { - assert(KV.first && "Null JITDylib in dependency?"); - auto &OtherJITDylib = *KV.first; - auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib]; - - for (auto &OtherSymbol : KV.second) { -#ifndef NDEBUG - // Assert that this symbol exists and has not been emitted already. - auto SymI = OtherJITDylib.Symbols.find(OtherSymbol); - assert(SymI != OtherJITDylib.Symbols.end() && - (SymI->second.getFlags().isLazy() || - SymI->second.getFlags().isMaterializing()) && - "Dependency on emitted symbol"); -#endif - - auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol]; - - if (OtherMI.IsEmitted) - transferEmittedNodeDependencies(MI, Name, OtherMI); - else if (&OtherJITDylib != this || OtherSymbol != Name) { - OtherMI.Dependants[this].insert(Name); - DepsOnOtherJITDylib.insert(OtherSymbol); - } - } - - if (DepsOnOtherJITDylib.empty()) - MI.UnemittedDependencies.erase(&OtherJITDylib); - } -} - -void JITDylib::resolve(const SymbolMap &Resolved) { - auto FullyResolvedQueries = ES.runSessionLocked([&, this]() { - AsynchronousSymbolQuerySet FullyResolvedQueries; - for (const auto &KV : Resolved) { - auto &Name = KV.first; - auto Sym = KV.second; - - assert(!Sym.getFlags().isLazy() && !Sym.getFlags().isMaterializing() && - "Materializing flags should be managed internally"); - - auto I = Symbols.find(Name); - - assert(I != Symbols.end() && "Symbol not found"); - assert(!I->second.getFlags().isLazy() && - I->second.getFlags().isMaterializing() && - "Symbol should be materializing"); - assert(I->second.getAddress() == 0 && "Symbol has already been resolved"); - - assert((Sym.getFlags() & ~JITSymbolFlags::Weak) == - (JITSymbolFlags::stripTransientFlags(I->second.getFlags()) & - ~JITSymbolFlags::Weak) && - "Resolved flags should match the declared flags"); - - // Once resolved, symbols can never be weak. - JITSymbolFlags ResolvedFlags = Sym.getFlags(); - ResolvedFlags &= ~JITSymbolFlags::Weak; - ResolvedFlags |= JITSymbolFlags::Materializing; - I->second = JITEvaluatedSymbol(Sym.getAddress(), ResolvedFlags); - - auto &MI = MaterializingInfos[Name]; - for (auto &Q : MI.PendingQueries) { - Q->resolve(Name, Sym); - if (Q->isFullyResolved()) - FullyResolvedQueries.insert(Q); - } - } - - return FullyResolvedQueries; - }); - - for (auto &Q : FullyResolvedQueries) { - assert(Q->isFullyResolved() && "Q not fully resolved"); - Q->handleFullyResolved(); - } -} - -void JITDylib::emit(const SymbolFlagsMap &Emitted) { - auto FullyReadyQueries = ES.runSessionLocked([&, this]() { - AsynchronousSymbolQuerySet ReadyQueries; - - for (const auto &KV : Emitted) { - const auto &Name = KV.first; - - auto MII = MaterializingInfos.find(Name); - assert(MII != MaterializingInfos.end() && - "Missing MaterializingInfo entry"); - - auto &MI = MII->second; - - // For each dependant, transfer this node's emitted dependencies to - // it. If the dependant node is ready (i.e. has no unemitted - // dependencies) then notify any pending queries. - for (auto &KV : MI.Dependants) { - auto &DependantJD = *KV.first; - for (auto &DependantName : KV.second) { - auto DependantMII = - DependantJD.MaterializingInfos.find(DependantName); - assert(DependantMII != DependantJD.MaterializingInfos.end() && - "Dependant should have MaterializingInfo"); - - auto &DependantMI = DependantMII->second; - - // Remove the dependant's dependency on this node. - assert(DependantMI.UnemittedDependencies[this].count(Name) && - "Dependant does not count this symbol as a dependency?"); - DependantMI.UnemittedDependencies[this].erase(Name); - if (DependantMI.UnemittedDependencies[this].empty()) - DependantMI.UnemittedDependencies.erase(this); - - // Transfer unemitted dependencies from this node to the dependant. - DependantJD.transferEmittedNodeDependencies(DependantMI, - DependantName, MI); - - // If the dependant is emitted and this node was the last of its - // unemitted dependencies then the dependant node is now ready, so - // notify any pending queries on the dependant node. - if (DependantMI.IsEmitted && - DependantMI.UnemittedDependencies.empty()) { - assert(DependantMI.Dependants.empty() && - "Dependants should be empty by now"); - for (auto &Q : DependantMI.PendingQueries) { - Q->notifySymbolReady(); - if (Q->isFullyReady()) - ReadyQueries.insert(Q); - Q->removeQueryDependence(DependantJD, DependantName); - } - - // Since this dependant is now ready, we erase its MaterializingInfo - // and update its materializing state. - assert(DependantJD.Symbols.count(DependantName) && - "Dependant has no entry in the Symbols table"); - auto &DependantSym = DependantJD.Symbols[DependantName]; - DependantSym.setFlags(DependantSym.getFlags() & - ~JITSymbolFlags::Materializing); - DependantJD.MaterializingInfos.erase(DependantMII); - } - } - } - MI.Dependants.clear(); - MI.IsEmitted = true; - - if (MI.UnemittedDependencies.empty()) { - for (auto &Q : MI.PendingQueries) { - Q->notifySymbolReady(); - if (Q->isFullyReady()) - ReadyQueries.insert(Q); - Q->removeQueryDependence(*this, Name); - } - assert(Symbols.count(Name) && - "Symbol has no entry in the Symbols table"); - auto &Sym = Symbols[Name]; - Sym.setFlags(Sym.getFlags() & ~JITSymbolFlags::Materializing); - MaterializingInfos.erase(MII); - } - } - - return ReadyQueries; - }); - - for (auto &Q : FullyReadyQueries) { - assert(Q->isFullyReady() && "Q is not fully ready"); - Q->handleFullyReady(); - } -} - -void JITDylib::notifyFailed(const SymbolNameSet &FailedSymbols) { - - // FIXME: This should fail any transitively dependant symbols too. - - auto FailedQueriesToNotify = ES.runSessionLocked([&, this]() { - AsynchronousSymbolQuerySet FailedQueries; - - for (auto &Name : FailedSymbols) { - auto I = Symbols.find(Name); - assert(I != Symbols.end() && "Symbol not present in this JITDylib"); - Symbols.erase(I); - - auto MII = MaterializingInfos.find(Name); - - // If we have not created a MaterializingInfo for this symbol yet then - // there is nobody to notify. - if (MII == MaterializingInfos.end()) - continue; - - // Copy all the queries to the FailedQueries list, then abandon them. - // This has to be a copy, and the copy has to come before the abandon - // operation: Each Q.detach() call will reach back into this - // PendingQueries list to remove Q. - for (auto &Q : MII->second.PendingQueries) - FailedQueries.insert(Q); - - for (auto &Q : FailedQueries) - Q->detach(); - - assert(MII->second.PendingQueries.empty() && - "Queries remain after symbol was failed"); - - MaterializingInfos.erase(MII); - } - - return FailedQueries; - }); - - for (auto &Q : FailedQueriesToNotify) - Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols)); -} - -void JITDylib::setSearchOrder(JITDylibSearchList NewSearchOrder, - bool SearchThisJITDylibFirst, - bool MatchNonExportedInThisDylib) { - if (SearchThisJITDylibFirst && NewSearchOrder.front().first != this) - NewSearchOrder.insert(NewSearchOrder.begin(), - {this, MatchNonExportedInThisDylib}); - - ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); }); -} - -void JITDylib::addToSearchOrder(JITDylib &JD, bool MatchNonExported) { - ES.runSessionLocked([&]() { - SearchOrder.push_back({&JD, MatchNonExported}); - }); -} - -void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD, - bool MatchNonExported) { - ES.runSessionLocked([&]() { - auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(), - [&](const JITDylibSearchList::value_type &KV) { - return KV.first == &OldJD; - }); - - if (I != SearchOrder.end()) - *I = {&NewJD, MatchNonExported}; - }); -} - -void JITDylib::removeFromSearchOrder(JITDylib &JD) { - ES.runSessionLocked([&]() { - auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(), - [&](const JITDylibSearchList::value_type &KV) { - return KV.first == &JD; - }); - if (I != SearchOrder.end()) - SearchOrder.erase(I); - }); -} - -Error JITDylib::remove(const SymbolNameSet &Names) { - return ES.runSessionLocked([&]() -> Error { - using SymbolMaterializerItrPair = - std::pair<SymbolMap::iterator, UnmaterializedInfosMap::iterator>; - std::vector<SymbolMaterializerItrPair> SymbolsToRemove; - SymbolNameSet Missing; - SymbolNameSet Materializing; - - for (auto &Name : Names) { - auto I = Symbols.find(Name); - - // Note symbol missing. - if (I == Symbols.end()) { - Missing.insert(Name); - continue; - } - - // Note symbol materializing. - if (I->second.getFlags().isMaterializing()) { - Materializing.insert(Name); - continue; - } - - auto UMII = I->second.getFlags().isLazy() ? UnmaterializedInfos.find(Name) - : UnmaterializedInfos.end(); - SymbolsToRemove.push_back(std::make_pair(I, UMII)); - } - - // If any of the symbols are not defined, return an error. - if (!Missing.empty()) - return make_error<SymbolsNotFound>(std::move(Missing)); - - // If any of the symbols are currently materializing, return an error. - if (!Materializing.empty()) - return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing)); - - // Remove the symbols. - for (auto &SymbolMaterializerItrPair : SymbolsToRemove) { - auto UMII = SymbolMaterializerItrPair.second; - - // If there is a materializer attached, call discard. - if (UMII != UnmaterializedInfos.end()) { - UMII->second->MU->doDiscard(*this, UMII->first); - UnmaterializedInfos.erase(UMII); - } - - auto SymI = SymbolMaterializerItrPair.first; - Symbols.erase(SymI); - } - - return Error::success(); - }); -} - -SymbolFlagsMap JITDylib::lookupFlags(const SymbolNameSet &Names) { - return ES.runSessionLocked([&, this]() { - SymbolFlagsMap Result; - auto Unresolved = lookupFlagsImpl(Result, Names); - if (DefGenerator && !Unresolved.empty()) { - auto NewDefs = DefGenerator(*this, Unresolved); - if (!NewDefs.empty()) { - auto Unresolved2 = lookupFlagsImpl(Result, NewDefs); - (void)Unresolved2; - assert(Unresolved2.empty() && - "All fallback defs should have been found by lookupFlagsImpl"); - } - }; - return Result; - }); -} - -SymbolNameSet JITDylib::lookupFlagsImpl(SymbolFlagsMap &Flags, - const SymbolNameSet &Names) { - SymbolNameSet Unresolved; - - for (auto &Name : Names) { - auto I = Symbols.find(Name); - - if (I == Symbols.end()) { - Unresolved.insert(Name); - continue; - } - - assert(!Flags.count(Name) && "Symbol already present in Flags map"); - Flags[Name] = JITSymbolFlags::stripTransientFlags(I->second.getFlags()); - } - - return Unresolved; -} - -void JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q, - SymbolNameSet &Unresolved, bool MatchNonExported, - MaterializationUnitList &MUs) { - assert(Q && "Query can not be null"); - - lodgeQueryImpl(Q, Unresolved, MatchNonExported, MUs); - if (DefGenerator && !Unresolved.empty()) { - auto NewDefs = DefGenerator(*this, Unresolved); - if (!NewDefs.empty()) { - for (auto &D : NewDefs) - Unresolved.erase(D); - lodgeQueryImpl(Q, NewDefs, MatchNonExported, MUs); - assert(NewDefs.empty() && - "All fallback defs should have been found by lookupImpl"); - } - } -} - -void JITDylib::lodgeQueryImpl( - std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved, - bool MatchNonExported, - std::vector<std::unique_ptr<MaterializationUnit>> &MUs) { - - std::vector<SymbolStringPtr> ToRemove; - for (auto Name : Unresolved) { - // Search for the name in Symbols. Skip it if not found. - auto SymI = Symbols.find(Name); - if (SymI == Symbols.end()) - continue; - - // If this is a non exported symbol and we're skipping those then skip it. - if (!SymI->second.getFlags().isExported() && !MatchNonExported) - continue; - - // If we matched against Name in JD, mark it to be removed from the Unresolved - // set. - ToRemove.push_back(Name); - - // If the symbol has an address then resolve it. - if (SymI->second.getAddress() != 0) - Q->resolve(Name, SymI->second); - - // If the symbol is lazy, get the MaterialiaztionUnit for it. - if (SymI->second.getFlags().isLazy()) { - assert(SymI->second.getAddress() == 0 && - "Lazy symbol should not have a resolved address"); - assert(!SymI->second.getFlags().isMaterializing() && - "Materializing and lazy should not both be set"); - auto UMII = UnmaterializedInfos.find(Name); - assert(UMII != UnmaterializedInfos.end() && - "Lazy symbol should have UnmaterializedInfo"); - auto MU = std::move(UMII->second->MU); - assert(MU != nullptr && "Materializer should not be null"); - - // Move all symbols associated with this MaterializationUnit into - // materializing state. - for (auto &KV : MU->getSymbols()) { - auto SymK = Symbols.find(KV.first); - auto Flags = SymK->second.getFlags(); - Flags &= ~JITSymbolFlags::Lazy; - Flags |= JITSymbolFlags::Materializing; - SymK->second.setFlags(Flags); - UnmaterializedInfos.erase(KV.first); - } - - // Add MU to the list of MaterializationUnits to be materialized. - MUs.push_back(std::move(MU)); - } else if (!SymI->second.getFlags().isMaterializing()) { - // The symbol is neither lazy nor materializing, so it must be - // ready. Notify the query and continue. - Q->notifySymbolReady(); - continue; - } - - // Add the query to the PendingQueries list. - assert(SymI->second.getFlags().isMaterializing() && - "By this line the symbol should be materializing"); - auto &MI = MaterializingInfos[Name]; - MI.PendingQueries.push_back(Q); - Q->addQueryDependence(*this, Name); - } - - // Remove any symbols that we found. - for (auto &Name : ToRemove) - Unresolved.erase(Name); -} - -SymbolNameSet JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, - SymbolNameSet Names) { - assert(Q && "Query can not be null"); - - ES.runOutstandingMUs(); - - LookupImplActionFlags ActionFlags = None; - std::vector<std::unique_ptr<MaterializationUnit>> MUs; - - SymbolNameSet Unresolved = std::move(Names); - ES.runSessionLocked([&, this]() { - ActionFlags = lookupImpl(Q, MUs, Unresolved); - if (DefGenerator && !Unresolved.empty()) { - assert(ActionFlags == None && - "ActionFlags set but unresolved symbols remain?"); - auto NewDefs = DefGenerator(*this, Unresolved); - if (!NewDefs.empty()) { - for (auto &D : NewDefs) - Unresolved.erase(D); - ActionFlags = lookupImpl(Q, MUs, NewDefs); - assert(NewDefs.empty() && - "All fallback defs should have been found by lookupImpl"); - } - } - }); - - assert((MUs.empty() || ActionFlags == None) && - "If action flags are set, there should be no work to do (so no MUs)"); - - if (ActionFlags & NotifyFullyResolved) - Q->handleFullyResolved(); - - if (ActionFlags & NotifyFullyReady) - Q->handleFullyReady(); - - // FIXME: Swap back to the old code below once RuntimeDyld works with - // callbacks from asynchronous queries. - // Add MUs to the OutstandingMUs list. - { - std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex); - for (auto &MU : MUs) - ES.OutstandingMUs.push_back(make_pair(this, std::move(MU))); - } - ES.runOutstandingMUs(); - - // Dispatch any required MaterializationUnits for materialization. - // for (auto &MU : MUs) - // ES.dispatchMaterialization(*this, std::move(MU)); - - return Unresolved; -} - -JITDylib::LookupImplActionFlags -JITDylib::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q, - std::vector<std::unique_ptr<MaterializationUnit>> &MUs, - SymbolNameSet &Unresolved) { - LookupImplActionFlags ActionFlags = None; - std::vector<SymbolStringPtr> ToRemove; - - for (auto Name : Unresolved) { - - // Search for the name in Symbols. Skip it if not found. - auto SymI = Symbols.find(Name); - if (SymI == Symbols.end()) - continue; - - // If we found Name, mark it to be removed from the Unresolved set. - ToRemove.push_back(Name); - - // If the symbol has an address then resolve it. - if (SymI->second.getAddress() != 0) { - Q->resolve(Name, SymI->second); - if (Q->isFullyResolved()) - ActionFlags |= NotifyFullyResolved; - } - - // If the symbol is lazy, get the MaterialiaztionUnit for it. - if (SymI->second.getFlags().isLazy()) { - assert(SymI->second.getAddress() == 0 && - "Lazy symbol should not have a resolved address"); - assert(!SymI->second.getFlags().isMaterializing() && - "Materializing and lazy should not both be set"); - auto UMII = UnmaterializedInfos.find(Name); - assert(UMII != UnmaterializedInfos.end() && - "Lazy symbol should have UnmaterializedInfo"); - auto MU = std::move(UMII->second->MU); - assert(MU != nullptr && "Materializer should not be null"); - - // Kick all symbols associated with this MaterializationUnit into - // materializing state. - for (auto &KV : MU->getSymbols()) { - auto SymK = Symbols.find(KV.first); - auto Flags = SymK->second.getFlags(); - Flags &= ~JITSymbolFlags::Lazy; - Flags |= JITSymbolFlags::Materializing; - SymK->second.setFlags(Flags); - UnmaterializedInfos.erase(KV.first); - } - - // Add MU to the list of MaterializationUnits to be materialized. - MUs.push_back(std::move(MU)); - } else if (!SymI->second.getFlags().isMaterializing()) { - // The symbol is neither lazy nor materializing, so it must be ready. - // Notify the query and continue. - Q->notifySymbolReady(); - if (Q->isFullyReady()) - ActionFlags |= NotifyFullyReady; - continue; - } - - // Add the query to the PendingQueries list. - assert(SymI->second.getFlags().isMaterializing() && - "By this line the symbol should be materializing"); - auto &MI = MaterializingInfos[Name]; - MI.PendingQueries.push_back(Q); - Q->addQueryDependence(*this, Name); - } - - // Remove any marked symbols from the Unresolved set. - for (auto &Name : ToRemove) - Unresolved.erase(Name); - - return ActionFlags; -} - -void JITDylib::dump(raw_ostream &OS) { - ES.runSessionLocked([&, this]() { - OS << "JITDylib \"" << JITDylibName << "\" (ES: " - << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n" - << "Search order: ["; - for (auto &KV : SearchOrder) - OS << " (\"" << KV.first->getName() << "\", " - << (KV.second ? "all" : "exported only") << ")"; - OS << " ]\n" - << "Symbol table:\n"; - - for (auto &KV : Symbols) { - OS << " \"" << *KV.first << "\": "; - if (auto Addr = KV.second.getAddress()) - OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags(); - else - OS << "<not resolved>"; - if (KV.second.getFlags().isLazy() || - KV.second.getFlags().isMaterializing()) { - OS << " ("; - if (KV.second.getFlags().isLazy()) { - auto I = UnmaterializedInfos.find(KV.first); - assert(I != UnmaterializedInfos.end() && - "Lazy symbol should have UnmaterializedInfo"); - OS << " Lazy (MU=" << I->second->MU.get() << ")"; - } - if (KV.second.getFlags().isMaterializing()) - OS << " Materializing"; - OS << ", " << KV.second.getFlags() << " )\n"; - } else - OS << "\n"; - } - - if (!MaterializingInfos.empty()) - OS << " MaterializingInfos entries:\n"; - for (auto &KV : MaterializingInfos) { - OS << " \"" << *KV.first << "\":\n" - << " IsEmitted = " << (KV.second.IsEmitted ? "true" : "false") - << "\n" - << " " << KV.second.PendingQueries.size() - << " pending queries: { "; - for (auto &Q : KV.second.PendingQueries) - OS << Q.get() << " "; - OS << "}\n Dependants:\n"; - for (auto &KV2 : KV.second.Dependants) - OS << " " << KV2.first->getName() << ": " << KV2.second << "\n"; - OS << " Unemitted Dependencies:\n"; - for (auto &KV2 : KV.second.UnemittedDependencies) - OS << " " << KV2.first->getName() << ": " << KV2.second << "\n"; - } - }); -} - -JITDylib::JITDylib(ExecutionSession &ES, std::string Name) - : ES(ES), JITDylibName(std::move(Name)) { - SearchOrder.push_back({this, true}); -} - -Error JITDylib::defineImpl(MaterializationUnit &MU) { - SymbolNameSet Duplicates; - SymbolNameSet MUDefsOverridden; - - struct ExistingDefOverriddenEntry { - SymbolMap::iterator ExistingDefItr; - JITSymbolFlags NewFlags; - }; - std::vector<ExistingDefOverriddenEntry> ExistingDefsOverridden; - - for (auto &KV : MU.getSymbols()) { - assert(!KV.second.isLazy() && "Lazy flag should be managed internally."); - assert(!KV.second.isMaterializing() && - "Materializing flags should be managed internally."); - - SymbolMap::iterator EntryItr; - bool Added; - - auto NewFlags = KV.second; - NewFlags |= JITSymbolFlags::Lazy; - - std::tie(EntryItr, Added) = Symbols.insert( - std::make_pair(KV.first, JITEvaluatedSymbol(0, NewFlags))); - - if (!Added) { - if (KV.second.isStrong()) { - if (EntryItr->second.getFlags().isStrong() || - (EntryItr->second.getFlags() & JITSymbolFlags::Materializing)) - Duplicates.insert(KV.first); - else - ExistingDefsOverridden.push_back({EntryItr, NewFlags}); - } else - MUDefsOverridden.insert(KV.first); - } - } - - if (!Duplicates.empty()) { - // We need to remove the symbols we added. - for (auto &KV : MU.getSymbols()) { - if (Duplicates.count(KV.first)) - continue; - - bool Found = false; - for (const auto &EDO : ExistingDefsOverridden) - if (EDO.ExistingDefItr->first == KV.first) - Found = true; - - if (!Found) - Symbols.erase(KV.first); - } - - // FIXME: Return all duplicates. - return make_error<DuplicateDefinition>(**Duplicates.begin()); - } - - // Update flags on existing defs and call discard on their materializers. - for (auto &EDO : ExistingDefsOverridden) { - assert(EDO.ExistingDefItr->second.getFlags().isLazy() && - !EDO.ExistingDefItr->second.getFlags().isMaterializing() && - "Overridden existing def should be in the Lazy state"); - - EDO.ExistingDefItr->second.setFlags(EDO.NewFlags); - - auto UMII = UnmaterializedInfos.find(EDO.ExistingDefItr->first); - assert(UMII != UnmaterializedInfos.end() && - "Overridden existing def should have an UnmaterializedInfo"); - - UMII->second->MU->doDiscard(*this, EDO.ExistingDefItr->first); - } - - // Discard overridden symbols povided by MU. - for (auto &Sym : MUDefsOverridden) - MU.doDiscard(*this, Sym); - - return Error::success(); -} - -void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q, - const SymbolNameSet &QuerySymbols) { - for (auto &QuerySymbol : QuerySymbols) { - assert(MaterializingInfos.count(QuerySymbol) && - "QuerySymbol does not have MaterializingInfo"); - auto &MI = MaterializingInfos[QuerySymbol]; - - auto IdenticalQuery = - [&](const std::shared_ptr<AsynchronousSymbolQuery> &R) { - return R.get() == &Q; - }; - - auto I = std::find_if(MI.PendingQueries.begin(), MI.PendingQueries.end(), - IdenticalQuery); - assert(I != MI.PendingQueries.end() && - "Query Q should be in the PendingQueries list for QuerySymbol"); - MI.PendingQueries.erase(I); - } -} - -void JITDylib::transferEmittedNodeDependencies( - MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName, - MaterializingInfo &EmittedMI) { - for (auto &KV : EmittedMI.UnemittedDependencies) { - auto &DependencyJD = *KV.first; - SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr; - - for (auto &DependencyName : KV.second) { - auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName]; - - // Do not add self dependencies. - if (&DependencyMI == &DependantMI) - continue; - - // If we haven't looked up the dependencies for DependencyJD yet, do it - // now and cache the result. - if (!UnemittedDependenciesOnDependencyJD) - UnemittedDependenciesOnDependencyJD = - &DependantMI.UnemittedDependencies[&DependencyJD]; - - DependencyMI.Dependants[this].insert(DependantName); - UnemittedDependenciesOnDependencyJD->insert(DependencyName); - } - } -} - -ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP) - : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) { - // Construct the main dylib. - JDs.push_back(std::unique_ptr<JITDylib>(new JITDylib(*this, "<main>"))); -} - -JITDylib &ExecutionSession::getMainJITDylib() { - return runSessionLocked([this]() -> JITDylib & { return *JDs.front(); }); -} - -JITDylib &ExecutionSession::createJITDylib(std::string Name, - bool AddToMainDylibSearchOrder) { - return runSessionLocked([&, this]() -> JITDylib & { - JDs.push_back( - std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name)))); - if (AddToMainDylibSearchOrder) - JDs.front()->addToSearchOrder(*JDs.back()); - return *JDs.back(); - }); -} - -void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) { - assert(!!Err && "Error should be in failure state"); - - bool SendErrorToQuery; - runSessionLocked([&]() { - Q.detach(); - SendErrorToQuery = Q.canStillFail(); - }); - - if (SendErrorToQuery) - Q.handleFailed(std::move(Err)); - else - reportError(std::move(Err)); -} - -Expected<SymbolMap> ExecutionSession::legacyLookup( - LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names, - bool WaitUntilReady, RegisterDependenciesFunction RegisterDependencies) { -#if LLVM_ENABLE_THREADS - // In the threaded case we use promises to return the results. - std::promise<SymbolMap> PromisedResult; - std::mutex ErrMutex; - Error ResolutionError = Error::success(); - std::promise<void> PromisedReady; - Error ReadyError = Error::success(); - auto OnResolve = [&](Expected<SymbolMap> R) { - if (R) - PromisedResult.set_value(std::move(*R)); - else { - { - ErrorAsOutParameter _(&ResolutionError); - std::lock_guard<std::mutex> Lock(ErrMutex); - ResolutionError = R.takeError(); - } - PromisedResult.set_value(SymbolMap()); - } - }; - - std::function<void(Error)> OnReady; - if (WaitUntilReady) { - OnReady = [&](Error Err) { - if (Err) { - ErrorAsOutParameter _(&ReadyError); - std::lock_guard<std::mutex> Lock(ErrMutex); - ReadyError = std::move(Err); - } - PromisedReady.set_value(); - }; - } else { - OnReady = [&](Error Err) { - if (Err) - reportError(std::move(Err)); - }; - } - -#else - SymbolMap Result; - Error ResolutionError = Error::success(); - Error ReadyError = Error::success(); - - auto OnResolve = [&](Expected<SymbolMap> R) { - ErrorAsOutParameter _(&ResolutionError); - if (R) - Result = std::move(*R); - else - ResolutionError = R.takeError(); - }; - - std::function<void(Error)> OnReady; - if (WaitUntilReady) { - OnReady = [&](Error Err) { - ErrorAsOutParameter _(&ReadyError); - if (Err) - ReadyError = std::move(Err); - }; - } else { - OnReady = [&](Error Err) { - if (Err) - reportError(std::move(Err)); - }; - } -#endif - - auto Query = std::make_shared<AsynchronousSymbolQuery>( - Names, std::move(OnResolve), std::move(OnReady)); - // FIXME: This should be run session locked along with the registration code - // and error reporting below. - SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names)); - - // If the query was lodged successfully then register the dependencies, - // otherwise fail it with an error. - if (UnresolvedSymbols.empty()) - RegisterDependencies(Query->QueryRegistrations); - else { - bool DeliverError = runSessionLocked([&]() { - Query->detach(); - return Query->canStillFail(); - }); - auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols)); - if (DeliverError) - Query->handleFailed(std::move(Err)); - else - reportError(std::move(Err)); - } - -#if LLVM_ENABLE_THREADS - auto ResultFuture = PromisedResult.get_future(); - auto Result = ResultFuture.get(); - - { - std::lock_guard<std::mutex> Lock(ErrMutex); - if (ResolutionError) { - // ReadyError will never be assigned. Consume the success value. - cantFail(std::move(ReadyError)); - return std::move(ResolutionError); - } - } - - if (WaitUntilReady) { - auto ReadyFuture = PromisedReady.get_future(); - ReadyFuture.get(); - - { - std::lock_guard<std::mutex> Lock(ErrMutex); - if (ReadyError) - return std::move(ReadyError); - } - } else - cantFail(std::move(ReadyError)); - - return std::move(Result); - -#else - if (ResolutionError) { - // ReadyError will never be assigned. Consume the success value. - cantFail(std::move(ReadyError)); - return std::move(ResolutionError); - } - - if (ReadyError) - return std::move(ReadyError); - - return Result; -#endif -} - -void ExecutionSession::lookup( - const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols, - SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady, - RegisterDependenciesFunction RegisterDependencies) { - - // lookup can be re-entered recursively if running on a single thread. Run any - // outstanding MUs in case this query depends on them, otherwise this lookup - // will starve waiting for a result from an MU that is stuck in the queue. - runOutstandingMUs(); - - auto Unresolved = std::move(Symbols); - std::map<JITDylib *, MaterializationUnitList> CollectedMUsMap; - auto Q = std::make_shared<AsynchronousSymbolQuery>( - Unresolved, std::move(OnResolve), std::move(OnReady)); - bool QueryIsFullyResolved = false; - bool QueryIsFullyReady = false; - bool QueryFailed = false; - - runSessionLocked([&]() { - for (auto &KV : SearchOrder) { - assert(KV.first && "JITDylibList entries must not be null"); - assert(!CollectedMUsMap.count(KV.first) && - "JITDylibList should not contain duplicate entries"); - - auto &JD = *KV.first; - auto MatchNonExported = KV.second; - JD.lodgeQuery(Q, Unresolved, MatchNonExported, CollectedMUsMap[&JD]); - } - - if (Unresolved.empty()) { - // Query lodged successfully. - - // Record whether this query is fully ready / resolved. We will use - // this to call handleFullyResolved/handleFullyReady outside the session - // lock. - QueryIsFullyResolved = Q->isFullyResolved(); - QueryIsFullyReady = Q->isFullyReady(); - - // Call the register dependencies function. - if (RegisterDependencies && !Q->QueryRegistrations.empty()) - RegisterDependencies(Q->QueryRegistrations); - } else { - // Query failed due to unresolved symbols. - QueryFailed = true; - - // Disconnect the query from its dependencies. - Q->detach(); - - // Replace the MUs. - for (auto &KV : CollectedMUsMap) - for (auto &MU : KV.second) - KV.first->replace(std::move(MU)); - } - }); - - if (QueryFailed) { - Q->handleFailed(make_error<SymbolsNotFound>(std::move(Unresolved))); - return; - } else { - if (QueryIsFullyResolved) - Q->handleFullyResolved(); - if (QueryIsFullyReady) - Q->handleFullyReady(); - } - - // Move the MUs to the OutstandingMUs list, then materialize. - { - std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex); - - for (auto &KV : CollectedMUsMap) - for (auto &MU : KV.second) - OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU))); - } - - runOutstandingMUs(); -} - -Expected<SymbolMap> ExecutionSession::lookup( - const JITDylibSearchList &SearchOrder, const SymbolNameSet &Symbols, - RegisterDependenciesFunction RegisterDependencies, bool WaitUntilReady) { -#if LLVM_ENABLE_THREADS - // In the threaded case we use promises to return the results. - std::promise<SymbolMap> PromisedResult; - std::mutex ErrMutex; - Error ResolutionError = Error::success(); - std::promise<void> PromisedReady; - Error ReadyError = Error::success(); - auto OnResolve = [&](Expected<SymbolMap> R) { - if (R) - PromisedResult.set_value(std::move(*R)); - else { - { - ErrorAsOutParameter _(&ResolutionError); - std::lock_guard<std::mutex> Lock(ErrMutex); - ResolutionError = R.takeError(); - } - PromisedResult.set_value(SymbolMap()); - } - }; - - std::function<void(Error)> OnReady; - if (WaitUntilReady) { - OnReady = [&](Error Err) { - if (Err) { - ErrorAsOutParameter _(&ReadyError); - std::lock_guard<std::mutex> Lock(ErrMutex); - ReadyError = std::move(Err); - } - PromisedReady.set_value(); - }; - } else { - OnReady = [&](Error Err) { - if (Err) - reportError(std::move(Err)); - }; - } - -#else - SymbolMap Result; - Error ResolutionError = Error::success(); - Error ReadyError = Error::success(); - - auto OnResolve = [&](Expected<SymbolMap> R) { - ErrorAsOutParameter _(&ResolutionError); - if (R) - Result = std::move(*R); - else - ResolutionError = R.takeError(); - }; - - std::function<void(Error)> OnReady; - if (WaitUntilReady) { - OnReady = [&](Error Err) { - ErrorAsOutParameter _(&ReadyError); - if (Err) - ReadyError = std::move(Err); - }; - } else { - OnReady = [&](Error Err) { - if (Err) - reportError(std::move(Err)); - }; - } -#endif - - // Perform the asynchronous lookup. - lookup(SearchOrder, Symbols, OnResolve, OnReady, RegisterDependencies); - -#if LLVM_ENABLE_THREADS - auto ResultFuture = PromisedResult.get_future(); - auto Result = ResultFuture.get(); - - { - std::lock_guard<std::mutex> Lock(ErrMutex); - if (ResolutionError) { - // ReadyError will never be assigned. Consume the success value. - cantFail(std::move(ReadyError)); - return std::move(ResolutionError); - } - } - - if (WaitUntilReady) { - auto ReadyFuture = PromisedReady.get_future(); - ReadyFuture.get(); - - { - std::lock_guard<std::mutex> Lock(ErrMutex); - if (ReadyError) - return std::move(ReadyError); - } - } else - cantFail(std::move(ReadyError)); - - return std::move(Result); - -#else - if (ResolutionError) { - // ReadyError will never be assigned. Consume the success value. - cantFail(std::move(ReadyError)); - return std::move(ResolutionError); - } - - if (ReadyError) - return std::move(ReadyError); - - return Result; -#endif -} - -Expected<JITEvaluatedSymbol> -ExecutionSession::lookup(const JITDylibSearchList &SearchOrder, - SymbolStringPtr Name) { - SymbolNameSet Names({Name}); - - if (auto ResultMap = lookup(SearchOrder, std::move(Names), - NoDependenciesToRegister, true)) { - assert(ResultMap->size() == 1 && "Unexpected number of results"); - assert(ResultMap->count(Name) && "Missing result for symbol"); - return std::move(ResultMap->begin()->second); - } else - return ResultMap.takeError(); -} - -Expected<JITEvaluatedSymbol> -ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, - SymbolStringPtr Name) { - SymbolNameSet Names({Name}); - - JITDylibSearchList FullSearchOrder; - FullSearchOrder.reserve(SearchOrder.size()); - for (auto *JD : SearchOrder) - FullSearchOrder.push_back({JD, false}); - - return lookup(FullSearchOrder, Name); -} - -Expected<JITEvaluatedSymbol> -ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name) { - return lookup(SearchOrder, intern(Name)); -} - -void ExecutionSession::dump(raw_ostream &OS) { - runSessionLocked([this, &OS]() { - for (auto &JD : JDs) - JD->dump(OS); - }); -} - -void ExecutionSession::runOutstandingMUs() { - while (1) { - std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU; - - { - std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex); - if (!OutstandingMUs.empty()) { - JITDylibAndMU = std::move(OutstandingMUs.back()); - OutstandingMUs.pop_back(); - } - } - - if (JITDylibAndMU.first) { - assert(JITDylibAndMU.second && "JITDylib, but no MU?"); - dispatchMaterialization(*JITDylibAndMU.first, - std::move(JITDylibAndMU.second)); - } else - break; - } -} - -MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL) - : ES(ES), DL(DL) {} - -SymbolStringPtr MangleAndInterner::operator()(StringRef Name) { - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, Name, DL); - } - return ES.intern(MangledName); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp deleted file mode 100644 index 7c3c50b4d6e..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ /dev/null @@ -1,232 +0,0 @@ -//===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" - -#include "llvm/IR/Constants.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/GlobalVariable.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { -namespace orc { - -CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) - : InitList( - GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), - I((InitList && End) ? InitList->getNumOperands() : 0) { -} - -bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const { - assert(InitList == Other.InitList && "Incomparable iterators."); - return I == Other.I; -} - -bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const { - return !(*this == Other); -} - -CtorDtorIterator& CtorDtorIterator::operator++() { - ++I; - return *this; -} - -CtorDtorIterator CtorDtorIterator::operator++(int) { - CtorDtorIterator Temp = *this; - ++I; - return Temp; -} - -CtorDtorIterator::Element CtorDtorIterator::operator*() const { - ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I)); - assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors"); - - Constant *FuncC = CS->getOperand(1); - Function *Func = nullptr; - - // Extract function pointer, pulling off any casts. - while (FuncC) { - if (Function *F = dyn_cast_or_null<Function>(FuncC)) { - Func = F; - break; - } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) { - if (CE->isCast()) - FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0)); - else - break; - } else { - // This isn't anything we recognize. Bail out with Func left set to null. - break; - } - } - - ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); - Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; - if (Data && !isa<GlobalValue>(Data)) - Data = nullptr; - return Element(Priority->getZExtValue(), Func, Data); -} - -iterator_range<CtorDtorIterator> getConstructors(const Module &M) { - const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors"); - return make_range(CtorDtorIterator(CtorsList, false), - CtorDtorIterator(CtorsList, true)); -} - -iterator_range<CtorDtorIterator> getDestructors(const Module &M) { - const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors"); - return make_range(CtorDtorIterator(DtorsList, false), - CtorDtorIterator(DtorsList, true)); -} - -void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) { - if (empty(CtorDtors)) - return; - - MangleAndInterner Mangle( - JD.getExecutionSession(), - (*CtorDtors.begin()).Func->getParent()->getDataLayout()); - - for (const auto &CtorDtor : CtorDtors) { - assert(CtorDtor.Func && CtorDtor.Func->hasName() && - "Ctor/Dtor function must be named to be runnable under the JIT"); - - // FIXME: Maybe use a symbol promoter here instead. - if (CtorDtor.Func->hasLocalLinkage()) { - CtorDtor.Func->setLinkage(GlobalValue::ExternalLinkage); - CtorDtor.Func->setVisibility(GlobalValue::HiddenVisibility); - } - - if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) { - dbgs() << " Skipping because why now?\n"; - continue; - } - - CtorDtorsByPriority[CtorDtor.Priority].push_back( - Mangle(CtorDtor.Func->getName())); - } -} - -Error CtorDtorRunner::run() { - using CtorDtorTy = void (*)(); - - SymbolNameSet Names; - - for (auto &KV : CtorDtorsByPriority) { - for (auto &Name : KV.second) { - auto Added = Names.insert(Name).second; - (void)Added; - assert(Added && "Ctor/Dtor names clashed"); - } - } - - auto &ES = JD.getExecutionSession(); - if (auto CtorDtorMap = - ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names), - NoDependenciesToRegister, true)) { - for (auto &KV : CtorDtorsByPriority) { - for (auto &Name : KV.second) { - assert(CtorDtorMap->count(Name) && "No entry for Name"); - auto CtorDtor = reinterpret_cast<CtorDtorTy>( - static_cast<uintptr_t>((*CtorDtorMap)[Name].getAddress())); - CtorDtor(); - } - } - return Error::success(); - } else - return CtorDtorMap.takeError(); - - CtorDtorsByPriority.clear(); - - return Error::success(); -} - -void LocalCXXRuntimeOverridesBase::runDestructors() { - auto& CXXDestructorDataPairs = DSOHandleOverride; - for (auto &P : CXXDestructorDataPairs) - P.first(P.second); - CXXDestructorDataPairs.clear(); -} - -int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor, - void *Arg, - void *DSOHandle) { - auto& CXXDestructorDataPairs = - *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle); - CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg)); - return 0; -} - -Error LocalCXXRuntimeOverrides::enable(JITDylib &JD, - MangleAndInterner &Mangle) { - SymbolMap RuntimeInterposes; - RuntimeInterposes[Mangle("__dso_handle")] = - JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride), - JITSymbolFlags::Exported); - RuntimeInterposes[Mangle("__cxa_atexit")] = - JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride), - JITSymbolFlags::Exported); - - return JD.define(absoluteSymbols(std::move(RuntimeInterposes))); -} - -DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator( - sys::DynamicLibrary Dylib, const DataLayout &DL, SymbolPredicate Allow) - : Dylib(std::move(Dylib)), Allow(std::move(Allow)), - GlobalPrefix(DL.getGlobalPrefix()) {} - -Expected<DynamicLibrarySearchGenerator> -DynamicLibrarySearchGenerator::Load(const char *FileName, const DataLayout &DL, - SymbolPredicate Allow) { - std::string ErrMsg; - auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg); - if (!Lib.isValid()) - return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); - return DynamicLibrarySearchGenerator(std::move(Lib), DL, std::move(Allow)); -} - -SymbolNameSet DynamicLibrarySearchGenerator:: -operator()(JITDylib &JD, const SymbolNameSet &Names) { - orc::SymbolNameSet Added; - orc::SymbolMap NewSymbols; - - bool HasGlobalPrefix = (GlobalPrefix != '\0'); - - for (auto &Name : Names) { - if ((*Name).empty()) - continue; - - if (Allow && !Allow(Name)) - continue; - - if (HasGlobalPrefix && (*Name).front() != GlobalPrefix) - continue; - - std::string Tmp((*Name).data() + (HasGlobalPrefix ? 1 : 0), (*Name).size()); - if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) { - Added.insert(Name); - NewSymbols[Name] = JITEvaluatedSymbol( - static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)), - JITSymbolFlags::Exported); - } - } - - // Add any new symbols to JD. Since the generator is only called for symbols - // that are not already defined, this will never trigger a duplicate - // definition error, so we can wrap this call in a 'cantFail'. - if (!NewSymbols.empty()) - cantFail(JD.define(absoluteSymbols(std::move(NewSymbols)))); - - return Added; -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp deleted file mode 100644 index d952d1be70d..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//===--------------- IRCompileLayer.cpp - IR Compiling Layer --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" - -namespace llvm { -namespace orc { - -IRCompileLayer::IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer, - CompileFunction Compile) - : IRLayer(ES), BaseLayer(BaseLayer), Compile(std::move(Compile)) {} - -void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) { - std::lock_guard<std::mutex> Lock(IRLayerMutex); - this->NotifyCompiled = std::move(NotifyCompiled); -} - -void IRCompileLayer::emit(MaterializationResponsibility R, - ThreadSafeModule TSM) { - assert(TSM.getModule() && "Module must not be null"); - - if (auto Obj = Compile(*TSM.getModule())) { - { - std::lock_guard<std::mutex> Lock(IRLayerMutex); - if (NotifyCompiled) - NotifyCompiled(R.getVModuleKey(), std::move(TSM)); - else - TSM = ThreadSafeModule(); - } - BaseLayer.emit(std::move(R), std::move(*Obj)); - } else { - R.failMaterialization(); - getExecutionSession().reportError(Obj.takeError()); - } -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp deleted file mode 100644 index 7bc0d696e3a..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===-------------- IRTransformLayer.cpp - IR Transform Layer -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" -#include "llvm/Support/MemoryBuffer.h" - -namespace llvm { -namespace orc { - -IRTransformLayer::IRTransformLayer(ExecutionSession &ES, - IRLayer &BaseLayer, - TransformFunction Transform) - : IRLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - -void IRTransformLayer::emit(MaterializationResponsibility R, - ThreadSafeModule TSM) { - assert(TSM.getModule() && "Module must not be null"); - - if (auto TransformedTSM = Transform(std::move(TSM), R)) - BaseLayer.emit(std::move(R), std::move(*TransformedTSM)); - else { - R.failMaterialization(); - getExecutionSession().reportError(TransformedTSM.takeError()); - } -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp deleted file mode 100644 index 82000ec5b32..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ /dev/null @@ -1,372 +0,0 @@ -//===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" -#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" -#include "llvm/IR/CallSite.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/Support/Format.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include <sstream> - -using namespace llvm; -using namespace llvm::orc; - -namespace { - -class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { -public: - using CompileFunction = JITCompileCallbackManager::CompileFunction; - - CompileCallbackMaterializationUnit(SymbolStringPtr Name, - CompileFunction Compile, VModuleKey K) - : MaterializationUnit(SymbolFlagsMap({{Name, JITSymbolFlags::Exported}}), - std::move(K)), - Name(std::move(Name)), Compile(std::move(Compile)) {} - - StringRef getName() const override { return "<Compile Callbacks>"; } - -private: - void materialize(MaterializationResponsibility R) override { - SymbolMap Result; - Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); - R.resolve(Result); - R.emit(); - } - - void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { - llvm_unreachable("Discard should never occur on a LMU?"); - } - - SymbolStringPtr Name; - CompileFunction Compile; -}; - -} // namespace - -namespace llvm { -namespace orc { - -void IndirectStubsManager::anchor() {} -void TrampolinePool::anchor() {} - -Expected<JITTargetAddress> -JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) { - if (auto TrampolineAddr = TP->getTrampoline()) { - auto CallbackName = - ES.intern(std::string("cc") + std::to_string(++NextCallbackId)); - - std::lock_guard<std::mutex> Lock(CCMgrMutex); - AddrToSymbol[*TrampolineAddr] = CallbackName; - cantFail(CallbacksJD.define( - llvm::make_unique<CompileCallbackMaterializationUnit>( - std::move(CallbackName), std::move(Compile), - ES.allocateVModule()))); - return *TrampolineAddr; - } else - return TrampolineAddr.takeError(); -} - -JITTargetAddress JITCompileCallbackManager::executeCompileCallback( - JITTargetAddress TrampolineAddr) { - SymbolStringPtr Name; - - { - std::unique_lock<std::mutex> Lock(CCMgrMutex); - auto I = AddrToSymbol.find(TrampolineAddr); - - // If this address is not associated with a compile callback then report an - // error to the execution session and return ErrorHandlerAddress to the - // callee. - if (I == AddrToSymbol.end()) { - Lock.unlock(); - std::string ErrMsg; - { - raw_string_ostream ErrMsgStream(ErrMsg); - ErrMsgStream << "No compile callback for trampoline at " - << format("0x%016" PRIx64, TrampolineAddr); - } - ES.reportError( - make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode())); - return ErrorHandlerAddress; - } else - Name = I->second; - } - - if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name)) - return Sym->getAddress(); - else { - llvm::dbgs() << "Didn't find callback.\n"; - // If anything goes wrong materializing Sym then report it to the session - // and return the ErrorHandlerAddress; - ES.reportError(Sym.takeError()); - return ErrorHandlerAddress; - } -} - -Expected<std::unique_ptr<JITCompileCallbackManager>> -createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, - JITTargetAddress ErrorHandlerAddress) { - switch (T.getArch()) { - default: - return make_error<StringError>( - std::string("No callback manager available for ") + T.str(), - inconvertibleErrorCode()); - case Triple::aarch64: { - typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } - - case Triple::x86: { - typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } - - case Triple::mips: { - typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Be> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } - case Triple::mipsel: { - typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Le> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } - - case Triple::mips64: - case Triple::mips64el: { - typedef orc::LocalJITCompileCallbackManager<orc::OrcMips64> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } - - case Triple::x86_64: { - if ( T.getOS() == Triple::OSType::Win32 ) { - typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } else { - typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT; - return CCMgrT::Create(ES, ErrorHandlerAddress); - } - } - - } -} - -std::function<std::unique_ptr<IndirectStubsManager>()> -createLocalIndirectStubsManagerBuilder(const Triple &T) { - switch (T.getArch()) { - default: - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcGenericABI>>(); - }; - - case Triple::aarch64: - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcAArch64>>(); - }; - - case Triple::x86: - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcI386>>(); - }; - - case Triple::mips: - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcMips32Be>>(); - }; - - case Triple::mipsel: - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcMips32Le>>(); - }; - - case Triple::mips64: - case Triple::mips64el: - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcMips64>>(); - }; - - case Triple::x86_64: - if (T.getOS() == Triple::OSType::Win32) { - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcX86_64_Win32>>(); - }; - } else { - return [](){ - return llvm::make_unique< - orc::LocalIndirectStubsManager<orc::OrcX86_64_SysV>>(); - }; - } - - } -} - -Constant* createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr) { - Constant *AddrIntVal = - ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr); - Constant *AddrPtrVal = - ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal, - PointerType::get(&FT, 0)); - return AddrPtrVal; -} - -GlobalVariable* createImplPointer(PointerType &PT, Module &M, - const Twine &Name, Constant *Initializer) { - auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage, - Initializer, Name, nullptr, - GlobalValue::NotThreadLocal, 0, true); - IP->setVisibility(GlobalValue::HiddenVisibility); - return IP; -} - -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(); - BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F); - IRBuilder<> Builder(EntryBlock); - LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer); - std::vector<Value*> CallArgs; - for (auto &A : F.args()) - CallArgs.push_back(&A); - CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs); - Call->setTailCall(); - Call->setAttributes(F.getAttributes()); - if (F.getReturnType()->isVoidTy()) - Builder.CreateRetVoid(); - else - Builder.CreateRet(Call); -} - -std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) { - std::vector<GlobalValue *> PromotedGlobals; - - for (auto &GV : M.global_values()) { - bool Promoted = true; - - // Rename if necessary. - if (!GV.hasName()) - GV.setName("__orc_anon." + Twine(NextId++)); - else if (GV.getName().startswith("\01L")) - GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++)); - else if (GV.hasLocalLinkage()) - GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++)); - else - Promoted = false; - - if (GV.hasLocalLinkage()) { - GV.setLinkage(GlobalValue::ExternalLinkage); - GV.setVisibility(GlobalValue::HiddenVisibility); - Promoted = true; - } - GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None); - - if (Promoted) - PromotedGlobals.push_back(&GV); - } - - return PromotedGlobals; -} - -Function* cloneFunctionDecl(Module &Dst, const Function &F, - ValueToValueMapTy *VMap) { - Function *NewF = - Function::Create(cast<FunctionType>(F.getValueType()), - F.getLinkage(), F.getName(), &Dst); - NewF->copyAttributesFrom(&F); - - if (VMap) { - (*VMap)[&F] = NewF; - auto NewArgI = NewF->arg_begin(); - for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE; - ++ArgI, ++NewArgI) - (*VMap)[&*ArgI] = &*NewArgI; - } - - return NewF; -} - -void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, - ValueMaterializer *Materializer, - Function *NewF) { - assert(!OrigF.isDeclaration() && "Nothing to move"); - if (!NewF) - NewF = cast<Function>(VMap[&OrigF]); - else - assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap."); - assert(NewF && "Function mapping missing from VMap."); - assert(NewF->getParent() != OrigF.getParent() && - "moveFunctionBody should only be used to move bodies between " - "modules."); - - SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned. - CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns, - "", nullptr, nullptr, Materializer); - OrigF.deleteBody(); -} - -GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, - ValueToValueMapTy *VMap) { - GlobalVariable *NewGV = new GlobalVariable( - Dst, GV.getValueType(), GV.isConstant(), - GV.getLinkage(), nullptr, GV.getName(), nullptr, - GV.getThreadLocalMode(), GV.getType()->getAddressSpace()); - NewGV->copyAttributesFrom(&GV); - if (VMap) - (*VMap)[&GV] = NewGV; - return NewGV; -} - -void moveGlobalVariableInitializer(GlobalVariable &OrigGV, - ValueToValueMapTy &VMap, - ValueMaterializer *Materializer, - GlobalVariable *NewGV) { - assert(OrigGV.hasInitializer() && "Nothing to move"); - if (!NewGV) - NewGV = cast<GlobalVariable>(VMap[&OrigGV]); - else - assert(VMap[&OrigGV] == NewGV && - "Incorrect global variable mapping in VMap."); - assert(NewGV->getParent() != OrigGV.getParent() && - "moveGlobalVariableInitializer should only be used to move " - "initializers between modules"); - - NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None, - 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; -} - -void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, - ValueToValueMapTy &VMap) { - auto *MFs = Src.getModuleFlagsMetadata(); - if (!MFs) - return; - for (auto *MF : MFs->operands()) - Dst.addModuleFlag(MapMetadata(MF, VMap)); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp deleted file mode 100644 index 4af09d196ff..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===----- JITTargetMachineBuilder.cpp - Build TargetMachines for JIT -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" - -#include "llvm/Support/TargetRegistry.h" - -namespace llvm { -namespace orc { - -JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT) - : TT(std::move(TT)) { - Options.EmulatedTLS = true; - Options.ExplicitEmulatedTLS = true; -} - -Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() { - // FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on, - // rather than a valid triple for the current process. - return JITTargetMachineBuilder(Triple(sys::getProcessTriple())); -} - -Expected<std::unique_ptr<TargetMachine>> -JITTargetMachineBuilder::createTargetMachine() { - - std::string ErrMsg; - auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg); - if (!TheTarget) - return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); - - auto *TM = - TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(), - Options, RM, CM, OptLevel, /*JIT*/ true); - if (!TM) - return make_error<StringError>("Could not allocate target machine", - inconvertibleErrorCode()); - - return std::unique_ptr<TargetMachine>(TM); -} - -JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures( - const std::vector<std::string> &FeatureVec) { - for (const auto &F : FeatureVec) - Features.AddFeature(F); - return *this; -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp deleted file mode 100644 index e2089f9106b..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/LLJIT.h" -#include "llvm/ExecutionEngine/Orc/OrcError.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/Mangler.h" - -namespace { - - // A SimpleCompiler that owns its TargetMachine. - class TMOwningSimpleCompiler : public llvm::orc::SimpleCompiler { - public: - TMOwningSimpleCompiler(std::unique_ptr<llvm::TargetMachine> TM) - : llvm::orc::SimpleCompiler(*TM), TM(std::move(TM)) {} - private: - // FIXME: shared because std::functions (and thus - // IRCompileLayer::CompileFunction) are not moveable. - std::shared_ptr<llvm::TargetMachine> TM; - }; - -} // end anonymous namespace - -namespace llvm { -namespace orc { - -LLJIT::~LLJIT() { - if (CompileThreads) - CompileThreads->wait(); -} - -Expected<std::unique_ptr<LLJIT>> -LLJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL, - unsigned NumCompileThreads) { - - if (NumCompileThreads == 0) { - // If NumCompileThreads == 0 then create a single-threaded LLJIT instance. - auto TM = JTMB.createTargetMachine(); - if (!TM) - return TM.takeError(); - return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(), - std::move(*TM), std::move(DL))); - } - - return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(), - std::move(JTMB), std::move(DL), - NumCompileThreads)); -} - -Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) { - auto InternedName = ES->intern(Name); - SymbolMap Symbols({{InternedName, Sym}}); - return Main.define(absoluteSymbols(std::move(Symbols))); -} - -Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { - assert(TSM && "Can not add null module"); - - if (auto Err = applyDataLayout(*TSM.getModule())) - return Err; - - return CompileLayer.add(JD, std::move(TSM), ES->allocateVModule()); -} - -Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { - assert(Obj && "Can not add null object"); - - return ObjLinkingLayer.add(JD, std::move(Obj), ES->allocateVModule()); -} - -Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD, - StringRef Name) { - return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name)); -} - -LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, - std::unique_ptr<TargetMachine> TM, DataLayout DL) - : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)), - ObjLinkingLayer( - *this->ES, - []() { return llvm::make_unique<SectionMemoryManager>(); }), - CompileLayer(*this->ES, ObjLinkingLayer, - TMOwningSimpleCompiler(std::move(TM))), - CtorRunner(Main), DtorRunner(Main) {} - -LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, - DataLayout DL, unsigned NumCompileThreads) - : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)), - ObjLinkingLayer( - *this->ES, - []() { return llvm::make_unique<SectionMemoryManager>(); }), - CompileLayer(*this->ES, ObjLinkingLayer, - ConcurrentIRCompiler(std::move(JTMB))), - CtorRunner(Main), DtorRunner(Main) { - assert(NumCompileThreads != 0 && - "Multithreaded LLJIT instance can not be created with 0 threads"); - - // Move modules to new contexts when they're emitted so that we can compile - // them in parallel. - CompileLayer.setCloneToNewContextOnEmit(true); - - // Create a thread pool to compile on and set the execution session - // dispatcher to use the thread pool. - CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads); - this->ES->setDispatchMaterialization( - [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) { - // FIXME: Switch to move capture once we have c++14. - auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU)); - auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); }; - CompileThreads->async(std::move(Work)); - }); -} - -std::string LLJIT::mangle(StringRef UnmangledName) { - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); - } - return MangledName; -} - -Error LLJIT::applyDataLayout(Module &M) { - if (M.getDataLayout().isDefault()) - M.setDataLayout(DL); - - if (M.getDataLayout() != DL) - return make_error<StringError>( - "Added modules have incompatible data layouts", - inconvertibleErrorCode()); - - return Error::success(); -} - -void LLJIT::recordCtorDtors(Module &M) { - CtorRunner.add(getConstructors(M)); - DtorRunner.add(getDestructors(M)); -} - -Expected<std::unique_ptr<LLLazyJIT>> -LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL, - JITTargetAddress ErrorAddr, unsigned NumCompileThreads) { - auto ES = llvm::make_unique<ExecutionSession>(); - - const Triple &TT = JTMB.getTargetTriple(); - - auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, ErrorAddr); - if (!LCTMgr) - return LCTMgr.takeError(); - - auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT); - if (!ISMBuilder) - return make_error<StringError>( - std::string("No indirect stubs manager builder for ") + TT.str(), - inconvertibleErrorCode()); - - if (NumCompileThreads == 0) { - auto TM = JTMB.createTargetMachine(); - if (!TM) - return TM.takeError(); - return std::unique_ptr<LLLazyJIT>( - new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL), - std::move(*LCTMgr), std::move(ISMBuilder))); - } - - return std::unique_ptr<LLLazyJIT>(new LLLazyJIT( - std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads, - std::move(*LCTMgr), std::move(ISMBuilder))); -} - -Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) { - assert(TSM && "Can not add null module"); - - if (auto Err = applyDataLayout(*TSM.getModule())) - return Err; - - recordCtorDtors(*TSM.getModule()); - - return CODLayer.add(JD, std::move(TSM), ES->allocateVModule()); -} - -LLLazyJIT::LLLazyJIT( - std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM, - DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr, - std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder) - : LLJIT(std::move(ES), std::move(TM), std::move(DL)), - LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer), - CODLayer(*this->ES, TransformLayer, *this->LCTMgr, - std::move(ISMBuilder)) {} - -LLLazyJIT::LLLazyJIT( - std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, - DataLayout DL, unsigned NumCompileThreads, - std::unique_ptr<LazyCallThroughManager> LCTMgr, - std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder) - : LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads), - LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer), - CODLayer(*this->ES, TransformLayer, *this->LCTMgr, - std::move(ISMBuilder)) { - CODLayer.setCloneToNewContextOnEmit(true); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/LLVMBuild.txt b/gnu/llvm/lib/ExecutionEngine/Orc/LLVMBuild.txt deleted file mode 100644 index 3f8fe9545fc..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/LLVMBuild.txt +++ /dev/null @@ -1,22 +0,0 @@ -;===- ./lib/ExecutionEngine/Orc/LLVMBuild.txt ----------------*- Conf -*--===; -; -; The LLVM Compiler Infrastructure -; -; This file is distributed under the University of Illinois Open Source -; License. See LICENSE.TXT for details. -; -;===------------------------------------------------------------------------===; -; -; This is an LLVMBuild description file for the components in this subdirectory. -; -; For more information on the LLVMBuild system, please see: -; -; http://llvm.org/docs/LLVMBuild.html -; -;===------------------------------------------------------------------------===; - -[component_0] -type = Library -name = OrcJIT -parent = ExecutionEngine -required_libraries = Core ExecutionEngine Object MC RuntimeDyld Support Target TransformUtils diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/Layer.cpp deleted file mode 100644 index 11af76825e9..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ /dev/null @@ -1,186 +0,0 @@ -//===-------------------- Layer.cpp - Layer interfaces --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/Layer.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Debug.h" - -#define DEBUG_TYPE "orc" - -namespace llvm { -namespace orc { - -IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {} -IRLayer::~IRLayer() {} - -Error IRLayer::add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K) { - return JD.define(llvm::make_unique<BasicIRLayerMaterializationUnit>( - *this, std::move(K), std::move(TSM))); -} - -IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES, - ThreadSafeModule TSM, VModuleKey K) - : MaterializationUnit(SymbolFlagsMap(), std::move(K)), TSM(std::move(TSM)) { - - assert(this->TSM && "Module must not be null"); - - MangleAndInterner Mangle(ES, this->TSM.getModule()->getDataLayout()); - for (auto &G : this->TSM.getModule()->global_values()) { - if (G.hasName() && !G.isDeclaration() && !G.hasLocalLinkage() && - !G.hasAvailableExternallyLinkage() && !G.hasAppendingLinkage()) { - auto MangledName = Mangle(G.getName()); - SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); - SymbolToDefinition[MangledName] = &G; - } - } -} - -IRMaterializationUnit::IRMaterializationUnit( - ThreadSafeModule TSM, VModuleKey K, SymbolFlagsMap SymbolFlags, - SymbolNameToDefinitionMap SymbolToDefinition) - : MaterializationUnit(std::move(SymbolFlags), std::move(K)), - TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {} - -StringRef IRMaterializationUnit::getName() const { - if (TSM.getModule()) - return TSM.getModule()->getModuleIdentifier(); - return "<null module>"; -} - -void IRMaterializationUnit::discard(const JITDylib &JD, - const SymbolStringPtr &Name) { - LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() { - dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@" - << this << " (" << getName() << ")\n"; - });); - - auto I = SymbolToDefinition.find(Name); - assert(I != SymbolToDefinition.end() && - "Symbol not provided by this MU, or previously discarded"); - assert(!I->second->isDeclaration() && - "Discard should only apply to definitions"); - I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); - SymbolToDefinition.erase(I); -} - -BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( - IRLayer &L, VModuleKey K, ThreadSafeModule TSM) - : IRMaterializationUnit(L.getExecutionSession(), std::move(TSM), - std::move(K)), - L(L), K(std::move(K)) {} - -void BasicIRLayerMaterializationUnit::materialize( - MaterializationResponsibility R) { - - // Throw away the SymbolToDefinition map: it's not usable after we hand - // off the module. - SymbolToDefinition.clear(); - - // If cloneToNewContextOnEmit is set, clone the module now. - if (L.getCloneToNewContextOnEmit()) - TSM = cloneToNewContext(TSM); - -#ifndef NDEBUG - auto &ES = R.getTargetJITDylib().getExecutionSession(); -#endif // NDEBUG - - auto Lock = TSM.getContextLock(); - LLVM_DEBUG(ES.runSessionLocked([&]() { - dbgs() << "Emitting, for " << R.getTargetJITDylib().getName() << ", " - << *this << "\n"; - });); - L.emit(std::move(R), std::move(TSM)); - LLVM_DEBUG(ES.runSessionLocked([&]() { - dbgs() << "Finished emitting, for " << R.getTargetJITDylib().getName() - << ", " << *this << "\n"; - });); -} - -ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} - -ObjectLayer::~ObjectLayer() {} - -Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O, - VModuleKey K) { - auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(K), - std::move(O)); - if (!ObjMU) - return ObjMU.takeError(); - return JD.define(std::move(*ObjMU)); -} - -Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> -BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, VModuleKey K, - std::unique_ptr<MemoryBuffer> O) { - auto SymbolFlags = - getObjectSymbolFlags(L.getExecutionSession(), O->getMemBufferRef()); - - if (!SymbolFlags) - return SymbolFlags.takeError(); - - return std::unique_ptr<BasicObjectLayerMaterializationUnit>( - new BasicObjectLayerMaterializationUnit(L, K, std::move(O), - std::move(*SymbolFlags))); -} - -BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( - ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O, - SymbolFlagsMap SymbolFlags) - : MaterializationUnit(std::move(SymbolFlags), std::move(K)), L(L), - O(std::move(O)) {} - -StringRef BasicObjectLayerMaterializationUnit::getName() const { - if (O) - return O->getBufferIdentifier(); - return "<null object>"; -} - -void BasicObjectLayerMaterializationUnit::materialize( - MaterializationResponsibility R) { - L.emit(std::move(R), std::move(O)); -} - -void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD, - const SymbolStringPtr &Name) { - // FIXME: Support object file level discard. This could be done by building a - // filter to pass to the object layer along with the object itself. -} - -Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES, - MemoryBufferRef ObjBuffer) { - auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); - - if (!Obj) - return Obj.takeError(); - - SymbolFlagsMap SymbolFlags; - for (auto &Sym : (*Obj)->symbols()) { - // Skip symbols not defined in this object file. - if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) - continue; - - // Skip symbols that are not global. - if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) - continue; - - auto Name = Sym.getName(); - if (!Name) - return Name.takeError(); - auto InternedName = ES.intern(*Name); - auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); - if (!SymFlags) - return SymFlags.takeError(); - SymbolFlags[InternedName] = std::move(*SymFlags); - } - - return SymbolFlags; -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp deleted file mode 100644 index 55f4a7c5afc..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ /dev/null @@ -1,208 +0,0 @@ -//===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/LazyReexports.h" - -#include "llvm/ADT/Triple.h" -#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" - -#define DEBUG_TYPE "orc" - -namespace llvm { -namespace orc { - -void LazyCallThroughManager::NotifyResolvedFunction::anchor() {} - -LazyCallThroughManager::LazyCallThroughManager( - ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, - std::unique_ptr<TrampolinePool> TP) - : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(std::move(TP)) {} - -Expected<JITTargetAddress> LazyCallThroughManager::getCallThroughTrampoline( - JITDylib &SourceJD, SymbolStringPtr SymbolName, - std::shared_ptr<NotifyResolvedFunction> NotifyResolved) { - std::lock_guard<std::mutex> Lock(LCTMMutex); - auto Trampoline = TP->getTrampoline(); - - if (!Trampoline) - return Trampoline.takeError(); - - Reexports[*Trampoline] = std::make_pair(&SourceJD, std::move(SymbolName)); - Notifiers[*Trampoline] = std::move(NotifyResolved); - return *Trampoline; -} - -JITTargetAddress -LazyCallThroughManager::callThroughToSymbol(JITTargetAddress TrampolineAddr) { - JITDylib *SourceJD = nullptr; - SymbolStringPtr SymbolName; - - { - std::lock_guard<std::mutex> Lock(LCTMMutex); - auto I = Reexports.find(TrampolineAddr); - if (I == Reexports.end()) - return ErrorHandlerAddr; - SourceJD = I->second.first; - SymbolName = I->second.second; - } - - auto LookupResult = ES.lookup(JITDylibSearchList({{SourceJD, true}}), - {SymbolName}, NoDependenciesToRegister, true); - - if (!LookupResult) { - ES.reportError(LookupResult.takeError()); - return ErrorHandlerAddr; - } - - assert(LookupResult->size() == 1 && "Unexpected number of results"); - assert(LookupResult->count(SymbolName) && "Unexpected result"); - - auto ResolvedAddr = LookupResult->begin()->second.getAddress(); - - std::shared_ptr<NotifyResolvedFunction> NotifyResolved = nullptr; - { - std::lock_guard<std::mutex> Lock(LCTMMutex); - auto I = Notifiers.find(TrampolineAddr); - if (I != Notifiers.end()) { - NotifyResolved = I->second; - Notifiers.erase(I); - } - } - - if (NotifyResolved) { - if (auto Err = (*NotifyResolved)(*SourceJD, SymbolName, ResolvedAddr)) { - ES.reportError(std::move(Err)); - return ErrorHandlerAddr; - } - } - - return ResolvedAddr; -} - -Expected<std::unique_ptr<LazyCallThroughManager>> -createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, - JITTargetAddress ErrorHandlerAddr) { - switch (T.getArch()) { - default: - return make_error<StringError>( - std::string("No callback manager available for ") + T.str(), - inconvertibleErrorCode()); - - case Triple::aarch64: - return LocalLazyCallThroughManager::Create<OrcAArch64>(ES, - ErrorHandlerAddr); - - case Triple::x86: - return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr); - - case Triple::mips: - return LocalLazyCallThroughManager::Create<OrcMips32Be>(ES, - ErrorHandlerAddr); - - case Triple::mipsel: - return LocalLazyCallThroughManager::Create<OrcMips32Le>(ES, - ErrorHandlerAddr); - - case Triple::mips64: - case Triple::mips64el: - return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr); - - case Triple::x86_64: - if (T.getOS() == Triple::OSType::Win32) - return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>( - ES, ErrorHandlerAddr); - else - return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>( - ES, ErrorHandlerAddr); - } -} - -LazyReexportsMaterializationUnit::LazyReexportsMaterializationUnit( - LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, - JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K) - : MaterializationUnit(extractFlags(CallableAliases), std::move(K)), - LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD), - CallableAliases(std::move(CallableAliases)), - NotifyResolved(LazyCallThroughManager::createNotifyResolvedFunction( - [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName, - JITTargetAddress ResolvedAddr) { - return ISManager.updatePointer(*SymbolName, ResolvedAddr); - })) {} - -StringRef LazyReexportsMaterializationUnit::getName() const { - return "<Lazy Reexports>"; -} - -void LazyReexportsMaterializationUnit::materialize( - MaterializationResponsibility R) { - auto RequestedSymbols = R.getRequestedSymbols(); - - SymbolAliasMap RequestedAliases; - for (auto &RequestedSymbol : RequestedSymbols) { - auto I = CallableAliases.find(RequestedSymbol); - assert(I != CallableAliases.end() && "Symbol not found in alias map?"); - RequestedAliases[I->first] = std::move(I->second); - CallableAliases.erase(I); - } - - if (!CallableAliases.empty()) - R.replace(lazyReexports(LCTManager, ISManager, SourceJD, - std::move(CallableAliases))); - - IndirectStubsManager::StubInitsMap StubInits; - for (auto &Alias : RequestedAliases) { - - auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline( - SourceJD, Alias.second.Aliasee, NotifyResolved); - - if (!CallThroughTrampoline) { - SourceJD.getExecutionSession().reportError( - CallThroughTrampoline.takeError()); - R.failMaterialization(); - return; - } - - StubInits[*Alias.first] = - std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags); - } - - if (auto Err = ISManager.createStubs(StubInits)) { - SourceJD.getExecutionSession().reportError(std::move(Err)); - R.failMaterialization(); - return; - } - - SymbolMap Stubs; - for (auto &Alias : RequestedAliases) - Stubs[Alias.first] = ISManager.findStub(*Alias.first, false); - - R.resolve(Stubs); - R.emit(); -} - -void LazyReexportsMaterializationUnit::discard(const JITDylib &JD, - const SymbolStringPtr &Name) { - assert(CallableAliases.count(Name) && - "Symbol not covered by this MaterializationUnit"); - CallableAliases.erase(Name); -} - -SymbolFlagsMap -LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) { - SymbolFlagsMap SymbolFlags; - for (auto &KV : Aliases) { - assert(KV.second.AliasFlags.isCallable() && - "Lazy re-exports must be callable symbols"); - SymbolFlags[KV.first] = KV.second.AliasFlags; - } - return SymbolFlags; -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/Legacy.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/Legacy.cpp deleted file mode 100644 index ddb72544b77..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/Legacy.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//===------- Legacy.cpp - Adapters for ExecutionEngine API interop --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/Legacy.h" - -namespace llvm { -namespace orc { - -void SymbolResolver::anchor() {} - -JITSymbolResolverAdapter::JITSymbolResolverAdapter( - ExecutionSession &ES, SymbolResolver &R, MaterializationResponsibility *MR) - : ES(ES), R(R), MR(MR) {} - -void JITSymbolResolverAdapter::lookup(const LookupSet &Symbols, - OnResolvedFunction OnResolved) { - SymbolNameSet InternedSymbols; - for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); - - auto OnResolvedWithUnwrap = [OnResolved](Expected<SymbolMap> InternedResult) { - if (!InternedResult) { - OnResolved(InternedResult.takeError()); - return; - } - - LookupResult Result; - for (auto &KV : *InternedResult) - Result[*KV.first] = std::move(KV.second); - OnResolved(Result); - }; - - auto Q = std::make_shared<AsynchronousSymbolQuery>( - InternedSymbols, OnResolvedWithUnwrap, - [this](Error Err) { ES.reportError(std::move(Err)); }); - - auto Unresolved = R.lookup(Q, InternedSymbols); - if (Unresolved.empty()) { - if (MR) - MR->addDependenciesForAll(Q->QueryRegistrations); - } else - ES.legacyFailQuery(*Q, make_error<SymbolsNotFound>(std::move(Unresolved))); -} - -Expected<JITSymbolResolverAdapter::LookupSet> -JITSymbolResolverAdapter::getResponsibilitySet(const LookupSet &Symbols) { - SymbolNameSet InternedSymbols; - for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); - - auto InternedResult = R.getResponsibilitySet(InternedSymbols); - LookupSet Result; - for (auto &S : InternedResult) { - ResolvedStrings.insert(S); - Result.insert(*S); - } - - return Result; -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp deleted file mode 100644 index 922fc6f021c..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//===---------- NullResolver.cpp - Reject symbol lookup requests ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/NullResolver.h" - -#include "llvm/Support/ErrorHandling.h" - -namespace llvm { -namespace orc { - -SymbolNameSet NullResolver::getResponsibilitySet(const SymbolNameSet &Symbols) { - return Symbols; -} - -SymbolNameSet -NullResolver::lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, - SymbolNameSet Symbols) { - assert(Symbols.empty() && "Null resolver: Symbols must be empty"); - return Symbols; -} - -JITSymbol NullLegacyResolver::findSymbol(const std::string &Name) { - llvm_unreachable("Unexpected cross-object symbol reference"); -} - -JITSymbol -NullLegacyResolver::findSymbolInLogicalDylib(const std::string &Name) { - llvm_unreachable("Unexpected cross-object symbol reference"); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp deleted file mode 100644 index 825f5320473..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===---------- ObjectTransformLayer.cpp - Object Transform Layer ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" -#include "llvm/Support/MemoryBuffer.h" - -namespace llvm { -namespace orc { - -ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES, - ObjectLayer &BaseLayer, - TransformFunction Transform) - : ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - -void ObjectTransformLayer::emit(MaterializationResponsibility R, - std::unique_ptr<MemoryBuffer> O) { - assert(O && "Module must not be null"); - - if (auto TransformedObj = Transform(std::move(O))) - BaseLayer.emit(std::move(R), std::move(*TransformedObj)); - else { - R.failMaterialization(); - getExecutionSession().reportError(TransformedObj.takeError()); - } -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp deleted file mode 100644 index aa405554242..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp +++ /dev/null @@ -1,984 +0,0 @@ -//===------------- OrcABISupport.cpp - ABI specific support code ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/OrcABISupport.h" -#include "llvm/Support/Process.h" - -namespace llvm { -namespace orc { - -void OrcAArch64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn, - void *CallbackMgr) { - - const uint32_t ResolverCode[] = { - // resolver_entry: - 0xa9bf47fd, // 0x000: stp x29, x17, [sp, #-16]! - 0x910003fd, // 0x004: mov x29, sp - 0xa9bf73fb, // 0x008: stp x27, x28, [sp, #-16]! - 0xa9bf6bf9, // 0x00c: stp x25, x26, [sp, #-16]! - 0xa9bf63f7, // 0x010: stp x23, x24, [sp, #-16]! - 0xa9bf5bf5, // 0x014: stp x21, x22, [sp, #-16]! - 0xa9bf53f3, // 0x018: stp x19, x20, [sp, #-16]! - 0xa9bf3fee, // 0x01c: stp x14, x15, [sp, #-16]! - 0xa9bf37ec, // 0x020: stp x12, x13, [sp, #-16]! - 0xa9bf2fea, // 0x024: stp x10, x11, [sp, #-16]! - 0xa9bf27e8, // 0x028: stp x8, x9, [sp, #-16]! - 0xa9bf1fe6, // 0x02c: stp x6, x7, [sp, #-16]! - 0xa9bf17e4, // 0x030: stp x4, x5, [sp, #-16]! - 0xa9bf0fe2, // 0x034: stp x2, x3, [sp, #-16]! - 0xa9bf07e0, // 0x038: stp x0, x1, [sp, #-16]! - 0xadbf7ffe, // 0x03c: stp q30, q31, [sp, #-32]! - 0xadbf77fc, // 0x040: stp q28, q29, [sp, #-32]! - 0xadbf6ffa, // 0x044: stp q26, q27, [sp, #-32]! - 0xadbf67f8, // 0x048: stp q24, q25, [sp, #-32]! - 0xadbf5ff6, // 0x04c: stp q22, q23, [sp, #-32]! - 0xadbf57f4, // 0x050: stp q20, q21, [sp, #-32]! - 0xadbf4ff2, // 0x054: stp q18, q19, [sp, #-32]! - 0xadbf47f0, // 0x058: stp q16, q17, [sp, #-32]! - 0xadbf3fee, // 0x05c: stp q14, q15, [sp, #-32]! - 0xadbf37ec, // 0x060: stp q12, q13, [sp, #-32]! - 0xadbf2fea, // 0x064: stp q10, q11, [sp, #-32]! - 0xadbf27e8, // 0x068: stp q8, q9, [sp, #-32]! - 0xadbf1fe6, // 0x06c: stp q6, q7, [sp, #-32]! - 0xadbf17e4, // 0x070: stp q4, q5, [sp, #-32]! - 0xadbf0fe2, // 0x074: stp q2, q3, [sp, #-32]! - 0xadbf07e0, // 0x078: stp q0, q1, [sp, #-32]! - 0x580004e0, // 0x07c: ldr x0, Lcallbackmgr - 0xaa1e03e1, // 0x080: mov x1, x30 - 0xd1003021, // 0x084: sub x1, x1, #12 - 0x58000442, // 0x088: ldr x2, Lreentry_fn_ptr - 0xd63f0040, // 0x08c: blr x2 - 0xaa0003f1, // 0x090: mov x17, x0 - 0xacc107e0, // 0x094: ldp q0, q1, [sp], #32 - 0xacc10fe2, // 0x098: ldp q2, q3, [sp], #32 - 0xacc117e4, // 0x09c: ldp q4, q5, [sp], #32 - 0xacc11fe6, // 0x0a0: ldp q6, q7, [sp], #32 - 0xacc127e8, // 0x0a4: ldp q8, q9, [sp], #32 - 0xacc12fea, // 0x0a8: ldp q10, q11, [sp], #32 - 0xacc137ec, // 0x0ac: ldp q12, q13, [sp], #32 - 0xacc13fee, // 0x0b0: ldp q14, q15, [sp], #32 - 0xacc147f0, // 0x0b4: ldp q16, q17, [sp], #32 - 0xacc14ff2, // 0x0b8: ldp q18, q19, [sp], #32 - 0xacc157f4, // 0x0bc: ldp q20, q21, [sp], #32 - 0xacc15ff6, // 0x0c0: ldp q22, q23, [sp], #32 - 0xacc167f8, // 0x0c4: ldp q24, q25, [sp], #32 - 0xacc16ffa, // 0x0c8: ldp q26, q27, [sp], #32 - 0xacc177fc, // 0x0cc: ldp q28, q29, [sp], #32 - 0xacc17ffe, // 0x0d0: ldp q30, q31, [sp], #32 - 0xa8c107e0, // 0x0d4: ldp x0, x1, [sp], #16 - 0xa8c10fe2, // 0x0d8: ldp x2, x3, [sp], #16 - 0xa8c117e4, // 0x0dc: ldp x4, x5, [sp], #16 - 0xa8c11fe6, // 0x0e0: ldp x6, x7, [sp], #16 - 0xa8c127e8, // 0x0e4: ldp x8, x9, [sp], #16 - 0xa8c12fea, // 0x0e8: ldp x10, x11, [sp], #16 - 0xa8c137ec, // 0x0ec: ldp x12, x13, [sp], #16 - 0xa8c13fee, // 0x0f0: ldp x14, x15, [sp], #16 - 0xa8c153f3, // 0x0f4: ldp x19, x20, [sp], #16 - 0xa8c15bf5, // 0x0f8: ldp x21, x22, [sp], #16 - 0xa8c163f7, // 0x0fc: ldp x23, x24, [sp], #16 - 0xa8c16bf9, // 0x100: ldp x25, x26, [sp], #16 - 0xa8c173fb, // 0x104: ldp x27, x28, [sp], #16 - 0xa8c17bfd, // 0x108: ldp x29, x30, [sp], #16 - 0xd65f0220, // 0x10c: ret x17 - 0x01234567, // 0x110: Lreentry_fn_ptr: - 0xdeadbeef, // 0x114: .quad 0 - 0x98765432, // 0x118: Lcallbackmgr: - 0xcafef00d // 0x11c: .quad 0 - }; - - const unsigned ReentryFnAddrOffset = 0x110; - const unsigned CallbackMgrAddrOffset = 0x118; - - memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); - memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); - memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, - sizeof(CallbackMgr)); -} - -void OrcAArch64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, - unsigned NumTrampolines) { - - unsigned OffsetToPtr = alignTo(NumTrampolines * TrampolineSize, 8); - - memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void *)); - - // OffsetToPtr is actually the offset from the PC for the 2nd instruction, so - // subtract 32-bits. - OffsetToPtr -= 4; - - uint32_t *Trampolines = reinterpret_cast<uint32_t *>(TrampolineMem); - - for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) { - Trampolines[3 * I + 0] = 0xaa1e03f1; // mov x17, x30 - Trampolines[3 * I + 1] = 0x58000010 | (OffsetToPtr << 3); // adr x16, Lptr - Trampolines[3 * I + 2] = 0xd63f0200; // blr x16 - } - -} - -Error OrcAArch64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, - unsigned MinStubs, - void *InitialPtrVal) { - // Stub format is: - // - // .section __orc_stubs - // stub1: - // ldr x0, ptr1 ; PC-rel load of ptr1 - // br x0 ; Jump to resolver - // stub2: - // ldr x0, ptr2 ; PC-rel load of ptr2 - // br x0 ; Jump to resolver - // - // ... - // - // .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 errorCodeToError(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) - << 3; - - for (unsigned I = 0; I < NumStubs; ++I) - Stub[I] = 0xd61f020058000010 | PtrOffsetField; - - if (auto EC = sys::Memory::protectMappedMemory( - StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) - return errorCodeToError(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 = IndirectStubsInfo(NumStubs, std::move(StubsMem)); - - return Error::success(); -} - -void OrcX86_64_Base::writeTrampolines(uint8_t *TrampolineMem, - void *ResolverAddr, - unsigned NumTrampolines) { - - unsigned OffsetToPtr = NumTrampolines * TrampolineSize; - - memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void *)); - - uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineMem); - uint64_t CallIndirPCRel = 0xf1c40000000015ff; - - for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) - Trampolines[I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16); -} - -Error OrcX86_64_Base::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 errorCodeToError(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 errorCodeToError(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 = IndirectStubsInfo(NumStubs, std::move(StubsMem)); - - return Error::success(); -} - -void OrcX86_64_SysV::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 0x208, %rsp - 0x48, 0x0f, 0xae, 0x04, 0x24, // 0x21: fxsave64 (%rsp) - 0x48, 0xbf, // 0x26: movabsq <CBMgr>, %rdi - - // 0x28: Callback manager addr. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x48, 0x8b, 0x75, 0x08, // 0x30: movq 8(%rbp), %rsi - 0x48, 0x83, 0xee, 0x06, // 0x34: subq $6, %rsi - 0x48, 0xb8, // 0x38: movabsq <REntry>, %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 0x208, %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 - }; - - const unsigned ReentryFnAddrOffset = 0x3a; - const unsigned CallbackMgrAddrOffset = 0x28; - - memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); - memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); - memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, - sizeof(CallbackMgr)); -} - -void OrcX86_64_Win32::writeResolverCode(uint8_t *ResolverMem, - JITReentryFn ReentryFn, - void *CallbackMgr) { - - // resolverCode is similar to OrcX86_64 with differences specific to windows x64 calling convention: - // arguments go into rcx, rdx and come in reverse order, shadow space allocation on stack - 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 0x208, %rsp - 0x48, 0x0f, 0xae, 0x04, 0x24, // 0x21: fxsave64 (%rsp) - - 0x48, 0xb9, // 0x26: movabsq <CBMgr>, %rcx - // 0x28: Callback manager addr. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x48, 0x8B, 0x55, 0x08, // 0x30: mov rdx, [rbp+0x8] - 0x48, 0x83, 0xea, 0x06, // 0x34: sub rdx, 0x6 - - 0x48, 0xb8, // 0x38: movabsq <REntry>, %rax - // 0x3a: JIT re-entry fn addr: - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - // 0x42: sub rsp, 0x20 (Allocate shadow space) - 0x48, 0x83, 0xEC, 0x20, - 0xff, 0xd0, // 0x46: callq *%rax - - // 0x48: add rsp, 0x20 (Free shadow space) - 0x48, 0x83, 0xC4, 0x20, - - 0x48, 0x89, 0x45, 0x08, // 0x4C: movq %rax, 8(%rbp) - 0x48, 0x0f, 0xae, 0x0c, 0x24, // 0x50: fxrstor64 (%rsp) - 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00, // 0x55: addq 0x208, %rsp - 0x41, 0x5f, // 0x5C: popq %r15 - 0x41, 0x5e, // 0x5E: popq %r14 - 0x41, 0x5d, // 0x60: popq %r13 - 0x41, 0x5c, // 0x62: popq %r12 - 0x41, 0x5b, // 0x64: popq %r11 - 0x41, 0x5a, // 0x66: popq %r10 - 0x41, 0x59, // 0x68: popq %r9 - 0x41, 0x58, // 0x6a: popq %r8 - 0x5f, // 0x6c: popq %rdi - 0x5e, // 0x6d: popq %rsi - 0x5a, // 0x6e: popq %rdx - 0x59, // 0x6f: popq %rcx - 0x5b, // 0x70: popq %rbx - 0x58, // 0x71: popq %rax - 0x5d, // 0x72: popq %rbp - 0xc3, // 0x73: retq - }; - - - const unsigned ReentryFnAddrOffset = 0x3a; - const unsigned CallbackMgrAddrOffset = 0x28; - - memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); - memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); - memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, - sizeof(CallbackMgr)); -} - -void OrcI386::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn, - void *CallbackMgr) { - - const uint8_t ResolverCode[] = { - // resolver_entry: - 0x55, // 0x00: pushl %ebp - 0x89, 0xe5, // 0x01: movl %esp, %ebp - 0x54, // 0x03: pushl %esp - 0x83, 0xe4, 0xf0, // 0x04: andl $-0x10, %esp - 0x50, // 0x07: pushl %eax - 0x53, // 0x08: pushl %ebx - 0x51, // 0x09: pushl %ecx - 0x52, // 0x0a: pushl %edx - 0x56, // 0x0b: pushl %esi - 0x57, // 0x0c: pushl %edi - 0x81, 0xec, 0x18, 0x02, 0x00, 0x00, // 0x0d: subl $0x218, %esp - 0x0f, 0xae, 0x44, 0x24, 0x10, // 0x13: fxsave 0x10(%esp) - 0x8b, 0x75, 0x04, // 0x18: movl 0x4(%ebp), %esi - 0x83, 0xee, 0x05, // 0x1b: subl $0x5, %esi - 0x89, 0x74, 0x24, 0x04, // 0x1e: movl %esi, 0x4(%esp) - 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, - 0x00, // 0x22: movl <cbmgr>, (%esp) - 0xb8, 0x00, 0x00, 0x00, 0x00, // 0x29: movl <reentry>, %eax - 0xff, 0xd0, // 0x2e: calll *%eax - 0x89, 0x45, 0x04, // 0x30: movl %eax, 0x4(%ebp) - 0x0f, 0xae, 0x4c, 0x24, 0x10, // 0x33: fxrstor 0x10(%esp) - 0x81, 0xc4, 0x18, 0x02, 0x00, 0x00, // 0x38: addl $0x218, %esp - 0x5f, // 0x3e: popl %edi - 0x5e, // 0x3f: popl %esi - 0x5a, // 0x40: popl %edx - 0x59, // 0x41: popl %ecx - 0x5b, // 0x42: popl %ebx - 0x58, // 0x43: popl %eax - 0x8b, 0x65, 0xfc, // 0x44: movl -0x4(%ebp), %esp - 0x5d, // 0x48: popl %ebp - 0xc3 // 0x49: retl - }; - - const unsigned ReentryFnAddrOffset = 0x2a; - const unsigned CallbackMgrAddrOffset = 0x25; - - memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); - memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); - memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, - sizeof(CallbackMgr)); -} - -void OrcI386::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, - unsigned NumTrampolines) { - - uint64_t CallRelImm = 0xF1C4C400000000e8; - uint64_t Resolver = reinterpret_cast<uint64_t>(ResolverAddr); - uint64_t ResolverRel = - Resolver - reinterpret_cast<uint64_t>(TrampolineMem) - 5; - - uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineMem); - for (unsigned I = 0; I < NumTrampolines; ++I, ResolverRel -= TrampolineSize) - Trampolines[I] = CallRelImm | (ResolverRel << 8); -} - -Error OrcI386::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, - unsigned MinStubs, void *InitialPtrVal) { - // Stub format is: - // - // .section __orc_stubs - // stub1: - // jmpq *ptr1 - // .byte 0xC4 ; <- Invalid opcode padding. - // .byte 0xF1 - // stub2: - // jmpq *ptr2 - // - // ... - // - // .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 errorCodeToError(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 PtrAddr = reinterpret_cast<uint64_t>(PtrsBlock.base()); - for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 4) - Stub[I] = 0xF1C40000000025ff | (PtrAddr << 16); - - if (auto EC = sys::Memory::protectMappedMemory( - StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) - return errorCodeToError(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 = IndirectStubsInfo(NumStubs, std::move(StubsMem)); - - return Error::success(); -} - -void OrcMips32_Base::writeResolverCode(uint8_t *ResolverMem, - JITReentryFn ReentryFn, - void *CallbackMgr, bool isBigEndian) { - - const uint32_t ResolverCode[] = { - // resolver_entry: - 0x27bdff98, // 0x00: addiu $sp,$sp,-104 - 0xafa20000, // 0x04: sw $v0,0($sp) - 0xafa30004, // 0x08: sw $v1,4($sp) - 0xafa40008, // 0x0c: sw $a0,8($sp) - 0xafa5000c, // 0x10: sw $a1,12($sp) - 0xafa60010, // 0x14: sw $a2,16($sp) - 0xafa70014, // 0x18: sw $a3,20($sp) - 0xafb00018, // 0x1c: sw $s0,24($sp) - 0xafb1001c, // 0x20: sw $s1,28($sp) - 0xafb20020, // 0x24: sw $s2,32($sp) - 0xafb30024, // 0x28: sw $s3,36($sp) - 0xafb40028, // 0x2c: sw $s4,40($sp) - 0xafb5002c, // 0x30: sw $s5,44($sp) - 0xafb60030, // 0x34: sw $s6,48($sp) - 0xafb70034, // 0x38: sw $s7,52($sp) - 0xafa80038, // 0x3c: sw $t0,56($sp) - 0xafa9003c, // 0x40: sw $t1,60($sp) - 0xafaa0040, // 0x44: sw $t2,64($sp) - 0xafab0044, // 0x48: sw $t3,68($sp) - 0xafac0048, // 0x4c: sw $t4,72($sp) - 0xafad004c, // 0x50: sw $t5,76($sp) - 0xafae0050, // 0x54: sw $t6,80($sp) - 0xafaf0054, // 0x58: sw $t7,84($sp) - 0xafb80058, // 0x5c: sw $t8,88($sp) - 0xafb9005c, // 0x60: sw $t9,92($sp) - 0xafbe0060, // 0x64: sw $fp,96($sp) - 0xafbf0064, // 0x68: sw $ra,100($sp) - - // Callback manager addr. - 0x00000000, // 0x6c: lui $a0,callbackmgr - 0x00000000, // 0x70: addiu $a0,$a0,callbackmgr - - 0x03e02825, // 0x74: move $a1, $ra - 0x24a5ffec, // 0x78: addiu $a1,$a1,-20 - - // JIT re-entry fn addr: - 0x00000000, // 0x7c: lui $t9,reentry - 0x00000000, // 0x80: addiu $t9,$t9,reentry - - 0x0320f809, // 0x84: jalr $t9 - 0x00000000, // 0x88: nop - 0x8fbf0064, // 0x8c: lw $ra,100($sp) - 0x8fbe0060, // 0x90: lw $fp,96($sp) - 0x8fb9005c, // 0x94: lw $t9,92($sp) - 0x8fb80058, // 0x98: lw $t8,88($sp) - 0x8faf0054, // 0x9c: lw $t7,84($sp) - 0x8fae0050, // 0xa0: lw $t6,80($sp) - 0x8fad004c, // 0xa4: lw $t5,76($sp) - 0x8fac0048, // 0xa8: lw $t4,72($sp) - 0x8fab0044, // 0xac: lw $t3,68($sp) - 0x8faa0040, // 0xb0: lw $t2,64($sp) - 0x8fa9003c, // 0xb4: lw $t1,60($sp) - 0x8fa80038, // 0xb8: lw $t0,56($sp) - 0x8fb70034, // 0xbc: lw $s7,52($sp) - 0x8fb60030, // 0xc0: lw $s6,48($sp) - 0x8fb5002c, // 0xc4: lw $s5,44($sp) - 0x8fb40028, // 0xc8: lw $s4,40($sp) - 0x8fb30024, // 0xcc: lw $s3,36($sp) - 0x8fb20020, // 0xd0: lw $s2,32($sp) - 0x8fb1001c, // 0xd4: lw $s1,28($sp) - 0x8fb00018, // 0xd8: lw $s0,24($sp) - 0x8fa70014, // 0xdc: lw $a3,20($sp) - 0x8fa60010, // 0xe0: lw $a2,16($sp) - 0x8fa5000c, // 0xe4: lw $a1,12($sp) - 0x8fa40008, // 0xe8: lw $a0,8($sp) - 0x27bd0068, // 0xec: addiu $sp,$sp,104 - 0x0300f825, // 0xf0: move $ra, $t8 - 0x03200008, // 0xf4: jr $t9 - 0x00000000, // 0xf8: move $t9, $v0/v1 - }; - - const unsigned ReentryFnAddrOffset = 0x7c; // JIT re-entry fn addr lui - const unsigned CallbackMgrAddrOffset = 0x6c; // Callback manager addr lui - const unsigned Offsett = 0xf8; - - memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); - - // Depending on endian return value will be in v0 or v1. - uint32_t MoveVxT9 = isBigEndian ? 0x0060c825 : 0x0040c825; - memcpy(ResolverMem + Offsett, &MoveVxT9, sizeof(MoveVxT9)); - - uint64_t CallMgrAddr = reinterpret_cast<uint64_t>(CallbackMgr); - uint32_t CallMgrLUi = 0x3c040000 | (((CallMgrAddr + 0x8000) >> 16) & 0xFFFF); - uint32_t CallMgrADDiu = 0x24840000 | ((CallMgrAddr) & 0xFFFF); - memcpy(ResolverMem + CallbackMgrAddrOffset, &CallMgrLUi, sizeof(CallMgrLUi)); - memcpy(ResolverMem + CallbackMgrAddrOffset + 4, &CallMgrADDiu, - sizeof(CallMgrADDiu)); - - uint64_t ReentryAddr = reinterpret_cast<uint64_t>(ReentryFn); - uint32_t ReentryLUi = 0x3c190000 | (((ReentryAddr + 0x8000) >> 16) & 0xFFFF); - uint32_t ReentryADDiu = 0x27390000 | ((ReentryAddr) & 0xFFFF); - memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryLUi, sizeof(ReentryLUi)); - memcpy(ResolverMem + ReentryFnAddrOffset + 4, &ReentryADDiu, - sizeof(ReentryADDiu)); -} - -void OrcMips32_Base::writeTrampolines(uint8_t *TrampolineMem, - void *ResolverAddr, - unsigned NumTrampolines) { - - uint32_t *Trampolines = reinterpret_cast<uint32_t *>(TrampolineMem); - uint64_t ResolveAddr = reinterpret_cast<uint64_t>(ResolverAddr); - uint32_t RHiAddr = ((ResolveAddr + 0x8000) >> 16); - - for (unsigned I = 0; I < NumTrampolines; ++I) { - Trampolines[5 * I + 0] = 0x03e0c025; // move $t8,$ra - Trampolines[5 * I + 1] = 0x3c190000 | (RHiAddr & 0xFFFF); // lui $t9,resolveAddr - Trampolines[5 * I + 2] = 0x27390000 | (ResolveAddr & 0xFFFF); // addiu $t9,$t9,resolveAddr - Trampolines[5 * I + 3] = 0x0320f809; // jalr $t9 - Trampolines[5 * I + 4] = 0x00000000; // nop - } -} - -Error OrcMips32_Base::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, - unsigned MinStubs, - void *InitialPtrVal) { - // Stub format is: - // - // .section __orc_stubs - // stub1: - // lui $t9, ptr1 - // lw $t9, %lo(ptr1)($t9) - // jr $t9 - // stub2: - // lui $t9, ptr2 - // lw $t9,%lo(ptr1)($t9) - // jr $t9 - // - // ... - // - // .section __orc_ptrs - // ptr1: - // .word 0x0 - // ptr2: - // .word 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 errorCodeToError(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. - uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlock.base()); - uint64_t PtrAddr = reinterpret_cast<uint64_t>(Stub) + NumPages * PageSize; - - for (unsigned I = 0; I < NumStubs; ++I) { - uint32_t HiAddr = ((PtrAddr + 0x8000) >> 16); - Stub[4 * I + 0] = 0x3c190000 | (HiAddr & 0xFFFF); // lui $t9,ptr1 - Stub[4 * I + 1] = 0x8f390000 | (PtrAddr & 0xFFFF); // lw $t9,%lo(ptr1)($t9) - Stub[4 * I + 2] = 0x03200008; // jr $t9 - Stub[4 * I + 3] = 0x00000000; // nop - PtrAddr += 4; - } - - if (auto EC = sys::Memory::protectMappedMemory( - StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) - return errorCodeToError(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 = IndirectStubsInfo(NumStubs, std::move(StubsMem)); - - return Error::success(); -} - -void OrcMips64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn, - void *CallbackMgr) { - - const uint32_t ResolverCode[] = { - //resolver_entry: - 0x67bdff30, // 0x00: daddiu $sp,$sp,-208 - 0xffa20000, // 0x04: sd v0,0(sp) - 0xffa30008, // 0x08: sd v1,8(sp) - 0xffa40010, // 0x0c: sd a0,16(sp) - 0xffa50018, // 0x10: sd a1,24(sp) - 0xffa60020, // 0x14: sd a2,32(sp) - 0xffa70028, // 0x18: sd a3,40(sp) - 0xffa80030, // 0x1c: sd a4,48(sp) - 0xffa90038, // 0x20: sd a5,56(sp) - 0xffaa0040, // 0x24: sd a6,64(sp) - 0xffab0048, // 0x28: sd a7,72(sp) - 0xffac0050, // 0x2c: sd t0,80(sp) - 0xffad0058, // 0x30: sd t1,88(sp) - 0xffae0060, // 0x34: sd t2,96(sp) - 0xffaf0068, // 0x38: sd t3,104(sp) - 0xffb00070, // 0x3c: sd s0,112(sp) - 0xffb10078, // 0x40: sd s1,120(sp) - 0xffb20080, // 0x44: sd s2,128(sp) - 0xffb30088, // 0x48: sd s3,136(sp) - 0xffb40090, // 0x4c: sd s4,144(sp) - 0xffb50098, // 0x50: sd s5,152(sp) - 0xffb600a0, // 0x54: sd s6,160(sp) - 0xffb700a8, // 0x58: sd s7,168(sp) - 0xffb800b0, // 0x5c: sd t8,176(sp) - 0xffb900b8, // 0x60: sd t9,184(sp) - 0xffbe00c0, // 0x64: sd fp,192(sp) - 0xffbf00c8, // 0x68: sd ra,200(sp) - - // Callback manager addr. - 0x00000000, // 0x6c: lui $a0,heighest(callbackmgr) - 0x00000000, // 0x70: daddiu $a0,$a0,heigher(callbackmgr) - 0x00000000, // 0x74: dsll $a0,$a0,16 - 0x00000000, // 0x78: daddiu $a0,$a0,hi(callbackmgr) - 0x00000000, // 0x7c: dsll $a0,$a0,16 - 0x00000000, // 0x80: daddiu $a0,$a0,lo(callbackmgr) - - 0x03e02825, // 0x84: move $a1, $ra - 0x64a5ffdc, // 0x88: daddiu $a1,$a1,-36 - - // JIT re-entry fn addr: - 0x00000000, // 0x8c: lui $t9,reentry - 0x00000000, // 0x90: daddiu $t9,$t9,reentry - 0x00000000, // 0x94: dsll $t9,$t9, - 0x00000000, // 0x98: daddiu $t9,$t9, - 0x00000000, // 0x9c: dsll $t9,$t9, - 0x00000000, // 0xa0: daddiu $t9,$t9, - 0x0320f809, // 0xa4: jalr $t9 - 0x00000000, // 0xa8: nop - 0xdfbf00c8, // 0xac: ld ra, 200(sp) - 0xdfbe00c0, // 0xb0: ld fp, 192(sp) - 0xdfb900b8, // 0xb4: ld t9, 184(sp) - 0xdfb800b0, // 0xb8: ld t8, 176(sp) - 0xdfb700a8, // 0xbc: ld s7, 168(sp) - 0xdfb600a0, // 0xc0: ld s6, 160(sp) - 0xdfb50098, // 0xc4: ld s5, 152(sp) - 0xdfb40090, // 0xc8: ld s4, 144(sp) - 0xdfb30088, // 0xcc: ld s3, 136(sp) - 0xdfb20080, // 0xd0: ld s2, 128(sp) - 0xdfb10078, // 0xd4: ld s1, 120(sp) - 0xdfb00070, // 0xd8: ld s0, 112(sp) - 0xdfaf0068, // 0xdc: ld t3, 104(sp) - 0xdfae0060, // 0xe0: ld t2, 96(sp) - 0xdfad0058, // 0xe4: ld t1, 88(sp) - 0xdfac0050, // 0xe8: ld t0, 80(sp) - 0xdfab0048, // 0xec: ld a7, 72(sp) - 0xdfaa0040, // 0xf0: ld a6, 64(sp) - 0xdfa90038, // 0xf4: ld a5, 56(sp) - 0xdfa80030, // 0xf8: ld a4, 48(sp) - 0xdfa70028, // 0xfc: ld a3, 40(sp) - 0xdfa60020, // 0x100: ld a2, 32(sp) - 0xdfa50018, // 0x104: ld a1, 24(sp) - 0xdfa40010, // 0x108: ld a0, 16(sp) - 0xdfa30008, // 0x10c: ld v1, 8(sp) - 0x67bd00d0, // 0x110: daddiu $sp,$sp,208 - 0x0300f825, // 0x114: move $ra, $t8 - 0x03200008, // 0x118: jr $t9 - 0x0040c825, // 0x11c: move $t9, $v0 - }; - - const unsigned ReentryFnAddrOffset = 0x8c; // JIT re-entry fn addr lui - const unsigned CallbackMgrAddrOffset = 0x6c; // Callback manager addr lui - - memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); - - uint64_t CallMgrAddr = reinterpret_cast<uint64_t>(CallbackMgr); - - uint32_t CallMgrLUi = - 0x3c040000 | (((CallMgrAddr + 0x800080008000) >> 48) & 0xFFFF); - uint32_t CallMgrDADDiu = - 0x64840000 | (((CallMgrAddr + 0x80008000) >> 32) & 0xFFFF); - uint32_t CallMgrDSLL = 0x00042438; - uint32_t CallMgrDADDiu2 = - 0x64840000 | ((((CallMgrAddr + 0x8000) >> 16) & 0xFFFF)); - uint32_t CallMgrDSLL2 = 0x00042438; - uint32_t CallMgrDADDiu3 = 0x64840000 | ((CallMgrAddr)&0xFFFF); - - memcpy(ResolverMem + CallbackMgrAddrOffset, &CallMgrLUi, sizeof(CallMgrLUi)); - memcpy(ResolverMem + (CallbackMgrAddrOffset + 4), &CallMgrDADDiu, - sizeof(CallMgrDADDiu)); - memcpy(ResolverMem + (CallbackMgrAddrOffset + 8), &CallMgrDSLL, - sizeof(CallMgrDSLL)); - memcpy(ResolverMem + (CallbackMgrAddrOffset + 12), &CallMgrDADDiu2, - sizeof(CallMgrDADDiu2)); - memcpy(ResolverMem + (CallbackMgrAddrOffset + 16), &CallMgrDSLL2, - sizeof(CallMgrDSLL2)); - memcpy(ResolverMem + (CallbackMgrAddrOffset + 20), &CallMgrDADDiu3, - sizeof(CallMgrDADDiu3)); - - uint64_t ReentryAddr = reinterpret_cast<uint64_t>(ReentryFn); - - uint32_t ReentryLUi = - 0x3c190000 | (((ReentryAddr + 0x800080008000) >> 48) & 0xFFFF); - - uint32_t ReentryDADDiu = - 0x67390000 | (((ReentryAddr + 0x80008000) >> 32) & 0xFFFF); - - uint32_t ReentryDSLL = 0x0019cc38; - - uint32_t ReentryDADDiu2 = - 0x67390000 | (((ReentryAddr + 0x8000) >> 16) & 0xFFFF); - - uint32_t ReentryDSLL2 = 0x0019cc38; - - uint32_t ReentryDADDiu3 = 0x67390000 | ((ReentryAddr)&0xFFFF); - - memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryLUi, sizeof(ReentryLUi)); - memcpy(ResolverMem + (ReentryFnAddrOffset + 4), &ReentryDADDiu, - sizeof(ReentryDADDiu)); - memcpy(ResolverMem + (ReentryFnAddrOffset + 8), &ReentryDSLL, - sizeof(ReentryDSLL)); - memcpy(ResolverMem + (ReentryFnAddrOffset + 12), &ReentryDADDiu2, - sizeof(ReentryDADDiu2)); - memcpy(ResolverMem + (ReentryFnAddrOffset + 16), &ReentryDSLL2, - sizeof(ReentryDSLL2)); - memcpy(ResolverMem + (ReentryFnAddrOffset + 20), &ReentryDADDiu3, - sizeof(ReentryDADDiu3)); -} - -void OrcMips64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, - unsigned NumTrampolines) { - - uint32_t *Trampolines = reinterpret_cast<uint32_t *>(TrampolineMem); - uint64_t ResolveAddr = reinterpret_cast<uint64_t>(ResolverAddr); - - uint64_t HeighestAddr = ((ResolveAddr + 0x800080008000) >> 48); - uint64_t HeigherAddr = ((ResolveAddr + 0x80008000) >> 32); - uint64_t HiAddr = ((ResolveAddr + 0x8000) >> 16); - - for (unsigned I = 0; I < NumTrampolines; ++I) { - Trampolines[10 * I + 0] = 0x03e0c025; // move $t8,$ra - Trampolines[10 * I + 1] = 0x3c190000 | (HeighestAddr & 0xFFFF); // lui $t9,resolveAddr - Trampolines[10 * I + 2] = 0x67390000 | (HeigherAddr & 0xFFFF); // daddiu $t9,$t9,%higher(resolveAddr) - Trampolines[10 * I + 3] = 0x0019cc38; // dsll $t9,$t9,16 - Trampolines[10 * I + 4] = 0x67390000 | (HiAddr & 0xFFFF); // daddiu $t9,$t9,%hi(ptr) - Trampolines[10 * I + 5] = 0x0019cc38; // dsll $t9,$t9,16 - Trampolines[10 * I + 6] = 0x67390000 | (ResolveAddr & 0xFFFF); // daddiu $t9,$t9,%lo(ptr) - Trampolines[10 * I + 7] = 0x0320f809; // jalr $t9 - Trampolines[10 * I + 8] = 0x00000000; // nop - Trampolines[10 * I + 9] = 0x00000000; // nop - } -} - -Error OrcMips64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, - unsigned MinStubs, - void *InitialPtrVal) { - // Stub format is: - // - // .section __orc_stubs - // stub1: - // lui $t9,ptr1 - // dsll $t9,$t9,16 - // daddiu $t9,$t9,%hi(ptr) - // dsll $t9,$t9,16 - // ld $t9,%lo(ptr) - // jr $t9 - // stub2: - // lui $t9,ptr1 - // dsll $t9,$t9,16 - // daddiu $t9,$t9,%hi(ptr) - // dsll $t9,$t9,16 - // ld $t9,%lo(ptr) - // jr $t9 - // - // ... - // - // .section __orc_ptrs - // ptr1: - // .dword 0x0 - // ptr2: - // .dword 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 errorCodeToError(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. - uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlock.base()); - uint64_t PtrAddr = reinterpret_cast<uint64_t>(PtrsBlock.base()); - - for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 8) { - uint64_t HeighestAddr = ((PtrAddr + 0x800080008000) >> 48); - uint64_t HeigherAddr = ((PtrAddr + 0x80008000) >> 32); - uint64_t HiAddr = ((PtrAddr + 0x8000) >> 16); - Stub[8 * I + 0] = 0x3c190000 | (HeighestAddr & 0xFFFF); // lui $t9,ptr1 - Stub[8 * I + 1] = 0x67390000 | (HeigherAddr & 0xFFFF); // daddiu $t9,$t9,%higher(ptr) - Stub[8 * I + 2] = 0x0019cc38; // dsll $t9,$t9,16 - Stub[8 * I + 3] = 0x67390000 | (HiAddr & 0xFFFF); // daddiu $t9,$t9,%hi(ptr) - Stub[8 * I + 4] = 0x0019cc38; // dsll $t9,$t9,16 - Stub[8 * I + 5] = 0xdf390000 | (PtrAddr & 0xFFFF); // ld $t9,%lo(ptr) - Stub[8 * I + 6] = 0x03200008; // jr $t9 - Stub[8 * I + 7] = 0x00000000; // nop - } - - if (auto EC = sys::Memory::protectMappedMemory( - StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) - return errorCodeToError(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 = IndirectStubsInfo(NumStubs, std::move(StubsMem)); - - return Error::success(); -} -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp deleted file mode 100644 index 6dea64a6e78..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//===----------- 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" -#include "llvm/ExecutionEngine/JITEventListener.h" - -using namespace llvm; - -LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) { - TargetMachine *TM2(unwrap(TM)); - - Triple T(TM2->getTargetTriple()); - - auto IndirectStubsMgrBuilder = - orc::createLocalIndirectStubsManagerBuilder(T); - - OrcCBindingsStack *JITStack = - new OrcCBindingsStack(*TM2, std::move(IndirectStubsMgrBuilder)); - - return wrap(JITStack); -} - -const char *LLVMOrcGetErrorMsg(LLVMOrcJITStackRef JITStack) { - OrcCBindingsStack &J = *unwrap(JITStack); - return J.getErrorMessage().c_str(); -} - -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; } - -LLVMErrorRef LLVMOrcCreateLazyCompileCallback( - LLVMOrcJITStackRef JITStack, LLVMOrcTargetAddress *RetAddr, - LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - if (auto Addr = J.createLazyCompileCallback(Callback, CallbackCtx)) { - *RetAddr = *Addr; - return LLVMErrorSuccess; - } else - return wrap(Addr.takeError()); -} - -LLVMErrorRef LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack, - const char *StubName, - LLVMOrcTargetAddress InitAddr) { - OrcCBindingsStack &J = *unwrap(JITStack); - return wrap(J.createIndirectStub(StubName, InitAddr)); -} - -LLVMErrorRef LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, - const char *StubName, - LLVMOrcTargetAddress NewAddr) { - OrcCBindingsStack &J = *unwrap(JITStack); - return wrap(J.setIndirectStubPointer(StubName, NewAddr)); -} - -LLVMErrorRef LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMModuleRef Mod, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::unique_ptr<Module> M(unwrap(Mod)); - if (auto Handle = - J.addIRModuleEager(std::move(M), SymbolResolver, SymbolResolverCtx)) { - *RetHandle = *Handle; - return LLVMErrorSuccess; - } else - return wrap(Handle.takeError()); -} - -LLVMErrorRef LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMModuleRef Mod, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::unique_ptr<Module> M(unwrap(Mod)); - if (auto Handle = - J.addIRModuleLazy(std::move(M), SymbolResolver, SymbolResolverCtx)) { - *RetHandle = *Handle; - return LLVMErrorSuccess; - } else - return wrap(Handle.takeError()); -} - -LLVMErrorRef LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMMemoryBufferRef Obj, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::unique_ptr<MemoryBuffer> O(unwrap(Obj)); - if (auto Handle = - J.addObject(std::move(O), SymbolResolver, SymbolResolverCtx)) { - *RetHandle = *Handle; - return LLVMErrorSuccess; - } else - return wrap(Handle.takeError()); -} - -LLVMErrorRef LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle H) { - OrcCBindingsStack &J = *unwrap(JITStack); - return wrap(J.removeModule(H)); -} - -LLVMErrorRef LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack, - LLVMOrcTargetAddress *RetAddr, - const char *SymbolName) { - OrcCBindingsStack &J = *unwrap(JITStack); - if (auto Addr = J.findSymbolAddress(SymbolName, true)) { - *RetAddr = *Addr; - return LLVMErrorSuccess; - } else - return wrap(Addr.takeError()); -} - -LLVMErrorRef LLVMOrcGetSymbolAddressIn(LLVMOrcJITStackRef JITStack, - LLVMOrcTargetAddress *RetAddr, - LLVMOrcModuleHandle H, - const char *SymbolName) { - OrcCBindingsStack &J = *unwrap(JITStack); - if (auto Addr = J.findSymbolAddressIn(H, SymbolName, true)) { - *RetAddr = *Addr; - return LLVMErrorSuccess; - } else - return wrap(Addr.takeError()); -} - -LLVMErrorRef LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) { - auto *J = unwrap(JITStack); - auto Err = J->shutdown(); - delete J; - return wrap(std::move(Err)); -} - -void LLVMOrcRegisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L) -{ - unwrap(JITStack)->RegisterJITEventListener(unwrap(L)); -} - -void LLVMOrcUnregisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L) -{ - unwrap(JITStack)->UnregisterJITEventListener(unwrap(L)); -} diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h deleted file mode 100644 index 817a4b89bfb..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ /dev/null @@ -1,533 +0,0 @@ -//===- 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-c/OrcBindings.h" -#include "llvm-c/TargetMachine.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/JITEventListener.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/LambdaResolver.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/CBindingWrapping.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include <algorithm> -#include <cstdint> -#include <functional> -#include <map> -#include <memory> -#include <set> -#include <string> -#include <vector> - -namespace llvm { - -class OrcCBindingsStack; - -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef) -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) - -namespace detail { - -// FIXME: Kill this off once the Layer concept becomes an interface. -class GenericLayer { -public: - virtual ~GenericLayer() = default; - - virtual JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) = 0; - virtual Error removeModule(orc::VModuleKey K) = 0; - }; - - template <typename LayerT> class GenericLayerImpl : public GenericLayer { - public: - GenericLayerImpl(LayerT &Layer) : Layer(Layer) {} - - JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) override { - return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - Error removeModule(orc::VModuleKey K) override { - return Layer.removeModule(K); - } - - private: - LayerT &Layer; - }; - - template <> - class GenericLayerImpl<orc::LegacyRTDyldObjectLinkingLayer> : public GenericLayer { - private: - using LayerT = orc::LegacyRTDyldObjectLinkingLayer; - public: - GenericLayerImpl(LayerT &Layer) : Layer(Layer) {} - - JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) override { - return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - Error removeModule(orc::VModuleKey K) override { - return Layer.removeObject(K); - } - - private: - LayerT &Layer; - }; - - template <typename LayerT> - std::unique_ptr<GenericLayerImpl<LayerT>> createGenericLayer(LayerT &Layer) { - return llvm::make_unique<GenericLayerImpl<LayerT>>(Layer); - } - -} // end namespace detail - -class OrcCBindingsStack { -public: - - using CompileCallbackMgr = orc::JITCompileCallbackManager; - using ObjLayerT = orc::LegacyRTDyldObjectLinkingLayer; - using CompileLayerT = orc::LegacyIRCompileLayer<ObjLayerT, orc::SimpleCompiler>; - using CODLayerT = - orc::LegacyCompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>; - - using CallbackManagerBuilder = - std::function<std::unique_ptr<CompileCallbackMgr>()>; - - using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT; - -private: - - using OwningObject = object::OwningBinary<object::ObjectFile>; - - class CBindingsResolver : public orc::SymbolResolver { - public: - CBindingsResolver(OrcCBindingsStack &Stack, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) - : Stack(Stack), ExternalResolver(std::move(ExternalResolver)), - ExternalResolverCtx(std::move(ExternalResolverCtx)) {} - - orc::SymbolNameSet - getResponsibilitySet(const orc::SymbolNameSet &Symbols) override { - orc::SymbolNameSet Result; - - for (auto &S : Symbols) { - if (auto Sym = findSymbol(*S)) { - if (!Sym.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym.takeError()) { - Stack.reportError(std::move(Err)); - return orc::SymbolNameSet(); - } - } - - return Result; - } - - orc::SymbolNameSet - lookup(std::shared_ptr<orc::AsynchronousSymbolQuery> Query, - orc::SymbolNameSet Symbols) override { - orc::SymbolNameSet UnresolvedSymbols; - - for (auto &S : Symbols) { - if (auto Sym = findSymbol(*S)) { - if (auto Addr = Sym.getAddress()) { - Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - Query->notifySymbolReady(); - } else { - Stack.ES.legacyFailQuery(*Query, Addr.takeError()); - return orc::SymbolNameSet(); - } - } else if (auto Err = Sym.takeError()) { - Stack.ES.legacyFailQuery(*Query, std::move(Err)); - return orc::SymbolNameSet(); - } else - UnresolvedSymbols.insert(S); - } - - if (Query->isFullyResolved()) - Query->handleFullyResolved(); - - if (Query->isFullyReady()) - Query->handleFullyReady(); - - return UnresolvedSymbols; - } - - private: - JITSymbol findSymbol(const std::string &Name) { - // Search order: - // 1. JIT'd symbols. - // 2. Runtime overrides. - // 3. External resolver (if present). - - if (Stack.CODLayer) { - if (auto Sym = Stack.CODLayer->findSymbol(Name, true)) - return Sym; - else if (auto Err = Sym.takeError()) - return Sym.takeError(); - } else { - if (auto Sym = Stack.CompileLayer.findSymbol(Name, true)) - return Sym; - else if (auto Err = Sym.takeError()) - return Sym.takeError(); - } - - if (auto Sym = Stack.CXXRuntimeOverrides.searchOverrides(Name)) - return Sym; - - if (ExternalResolver) - return JITSymbol(ExternalResolver(Name.c_str(), ExternalResolverCtx), - JITSymbolFlags::Exported); - - return JITSymbol(nullptr); - } - - OrcCBindingsStack &Stack; - LLVMOrcSymbolResolverFn ExternalResolver; - void *ExternalResolverCtx = nullptr; - }; - -public: - OrcCBindingsStack(TargetMachine &TM, - IndirectStubsManagerBuilder IndirectStubsMgrBuilder) - : CCMgr(createCompileCallbackManager(TM, ES)), DL(TM.createDataLayout()), - IndirectStubsMgr(IndirectStubsMgrBuilder()), - ObjectLayer(ES, - [this](orc::VModuleKey K) { - auto ResolverI = Resolvers.find(K); - assert(ResolverI != Resolvers.end() && - "No resolver for module K"); - auto Resolver = std::move(ResolverI->second); - Resolvers.erase(ResolverI); - return ObjLayerT::Resources{ - std::make_shared<SectionMemoryManager>(), Resolver}; - }, - nullptr, - [this](orc::VModuleKey K, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { - this->notifyFinalized(K, Obj, LoadedObjInfo); - }, - [this](orc::VModuleKey K, const object::ObjectFile &Obj) { - this->notifyFreed(K, Obj); - }), - CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)), - CODLayer(createCODLayer(ES, CompileLayer, CCMgr.get(), - std::move(IndirectStubsMgrBuilder), Resolvers)), - CXXRuntimeOverrides( - [this](const std::string &S) { return mangle(S); }) {} - - Error shutdown() { - // Run any destructors registered with __cxa_atexit. - CXXRuntimeOverrides.runDestructors(); - // Run any IR destructors. - for (auto &DtorRunner : IRStaticDestructorRunners) - if (auto Err = DtorRunner.runViaLayer(*this)) - return Err; - return Error::success(); - } - - 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(JITTargetAddress Addr) { - return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); - } - - Expected<JITTargetAddress> - createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback, - void *CallbackCtx) { - auto WrappedCallback = [=]() -> JITTargetAddress { - return Callback(wrap(this), CallbackCtx); - }; - - return CCMgr->getCompileCallback(std::move(WrappedCallback)); - } - - Error createIndirectStub(StringRef StubName, JITTargetAddress Addr) { - return IndirectStubsMgr->createStub(StubName, Addr, - JITSymbolFlags::Exported); - } - - Error setIndirectStubPointer(StringRef Name, JITTargetAddress Addr) { - return IndirectStubsMgr->updatePointer(Name, Addr); - } - - template <typename LayerT> - Expected<orc::VModuleKey> - addIRModule(LayerT &Layer, std::unique_ptr<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())); - - // Add the module to the JIT. - auto K = ES.allocateVModule(); - Resolvers[K] = std::make_shared<CBindingsResolver>(*this, ExternalResolver, - ExternalResolverCtx); - if (auto Err = Layer.addModule(K, std::move(M))) - return std::move(Err); - - KeyLayers[K] = detail::createGenericLayer(Layer); - - // Run the static constructors, and save the static destructor runner for - // execution when the JIT is torn down. - orc::LegacyCtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), K); - if (auto Err = CtorRunner.runViaLayer(*this)) - return std::move(Err); - - IRStaticDestructorRunners.emplace_back(std::move(DtorNames), K); - - return K; - } - - Expected<orc::VModuleKey> - addIRModuleEager(std::unique_ptr<Module> M, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - return addIRModule(CompileLayer, std::move(M), - llvm::make_unique<SectionMemoryManager>(), - std::move(ExternalResolver), ExternalResolverCtx); - } - - Expected<orc::VModuleKey> - addIRModuleLazy(std::unique_ptr<Module> M, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - if (!CODLayer) - return make_error<StringError>("Can not add lazy module: No compile " - "callback manager available", - inconvertibleErrorCode()); - - return addIRModule(*CODLayer, std::move(M), - llvm::make_unique<SectionMemoryManager>(), - std::move(ExternalResolver), ExternalResolverCtx); - } - - Error removeModule(orc::VModuleKey K) { - // FIXME: Should error release the module key? - if (auto Err = KeyLayers[K]->removeModule(K)) - return Err; - ES.releaseVModule(K); - KeyLayers.erase(K); - return Error::success(); - } - - Expected<orc::VModuleKey> addObject(std::unique_ptr<MemoryBuffer> ObjBuffer, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - if (auto Obj = object::ObjectFile::createObjectFile( - ObjBuffer->getMemBufferRef())) { - - auto K = ES.allocateVModule(); - Resolvers[K] = std::make_shared<CBindingsResolver>( - *this, ExternalResolver, ExternalResolverCtx); - - if (auto Err = ObjectLayer.addObject(K, std::move(ObjBuffer))) - return std::move(Err); - - KeyLayers[K] = detail::createGenericLayer(ObjectLayer); - - return K; - } else - return Obj.takeError(); - } - - JITSymbol findSymbol(const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly)) - return Sym; - if (CODLayer) - return CODLayer->findSymbol(mangle(Name), ExportedSymbolsOnly); - return CompileLayer.findSymbol(mangle(Name), ExportedSymbolsOnly); - } - - JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - assert(KeyLayers.count(K) && "looking up symbol in unknown module"); - return KeyLayers[K]->findSymbolIn(K, mangle(Name), ExportedSymbolsOnly); - } - - Expected<JITTargetAddress> findSymbolAddress(const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) { - // Successful lookup, non-null symbol: - if (auto AddrOrErr = Sym.getAddress()) - return *AddrOrErr; - else - return AddrOrErr.takeError(); - } else if (auto Err = Sym.takeError()) { - // Lookup failure - report error. - return std::move(Err); - } - - // No symbol not found. Return 0. - return 0; - } - - Expected<JITTargetAddress> findSymbolAddressIn(orc::VModuleKey K, - const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = findSymbolIn(K, Name, ExportedSymbolsOnly)) { - // Successful lookup, non-null symbol: - if (auto AddrOrErr = Sym.getAddress()) - return *AddrOrErr; - else - return AddrOrErr.takeError(); - } else if (auto Err = Sym.takeError()) { - // Lookup failure - report error. - return std::move(Err); - } - - // Symbol not found. Return 0. - return 0; - } - - const std::string &getErrorMessage() const { return ErrMsg; } - - void RegisterJITEventListener(JITEventListener *L) { - if (!L) - return; - EventListeners.push_back(L); - } - - void UnregisterJITEventListener(JITEventListener *L) { - if (!L) - return; - - auto I = find(reverse(EventListeners), L); - if (I != EventListeners.rend()) { - std::swap(*I, EventListeners.back()); - EventListeners.pop_back(); - } - } - -private: - using ResolverMap = - std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>>; - - static std::unique_ptr<CompileCallbackMgr> - createCompileCallbackManager(TargetMachine &TM, orc::ExecutionSession &ES) { - auto CCMgr = createLocalCompileCallbackManager(TM.getTargetTriple(), ES, 0); - if (!CCMgr) { - // FIXME: It would be good if we could report this somewhere, but we do - // have an instance yet. - logAllUnhandledErrors(CCMgr.takeError(), errs(), "ORC error: "); - return nullptr; - } - return std::move(*CCMgr); - } - - static std::unique_ptr<CODLayerT> - createCODLayer(orc::ExecutionSession &ES, CompileLayerT &CompileLayer, - CompileCallbackMgr *CCMgr, - IndirectStubsManagerBuilder IndirectStubsMgrBuilder, - ResolverMap &Resolvers) { - // If there is no compile callback manager available we can not create a - // compile on demand layer. - if (!CCMgr) - return nullptr; - - return llvm::make_unique<CODLayerT>( - ES, CompileLayer, - [&Resolvers](orc::VModuleKey K) { - auto ResolverI = Resolvers.find(K); - assert(ResolverI != Resolvers.end() && "No resolver for module K"); - return ResolverI->second; - }, - [&Resolvers](orc::VModuleKey K, - std::shared_ptr<orc::SymbolResolver> Resolver) { - assert(!Resolvers.count(K) && "Resolver already present"); - Resolvers[K] = std::move(Resolver); - }, - [](Function &F) { return std::set<Function *>({&F}); }, *CCMgr, - std::move(IndirectStubsMgrBuilder), false); - } - - void reportError(Error Err) { - // FIXME: Report errors on the execution session. - logAllUnhandledErrors(std::move(Err), errs(), "ORC error: "); - }; - - void notifyFinalized(orc::VModuleKey K, - const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { - uint64_t Key = static_cast<uint64_t>( - reinterpret_cast<uintptr_t>(Obj.getData().data())); - for (auto &Listener : EventListeners) - Listener->notifyObjectLoaded(Key, Obj, LoadedObjInfo); - } - - void notifyFreed(orc::VModuleKey K, const object::ObjectFile &Obj) { - uint64_t Key = static_cast<uint64_t>( - reinterpret_cast<uintptr_t>(Obj.getData().data())); - for (auto &Listener : EventListeners) - Listener->notifyFreeingObject(Key); - } - - orc::ExecutionSession ES; - std::unique_ptr<CompileCallbackMgr> CCMgr; - - std::vector<JITEventListener *> EventListeners; - - DataLayout DL; - SectionMemoryManager CCMgrMemMgr; - - std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr; - - ObjLayerT ObjectLayer; - CompileLayerT CompileLayer; - std::unique_ptr<CODLayerT> CODLayer; - - std::map<orc::VModuleKey, std::unique_ptr<detail::GenericLayer>> KeyLayers; - - orc::LegacyLocalCXXRuntimeOverrides CXXRuntimeOverrides; - std::vector<orc::LegacyCtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners; - std::string ErrMsg; - - ResolverMap Resolvers; -}; - -} // end namespace llvm - -#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcError.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/OrcError.cpp deleted file mode 100644 index f4102b359a6..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcError.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//===---------------- OrcError.cpp - Error codes for ORC ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Error codes for ORC. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/OrcError.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" - -using namespace llvm; -using namespace llvm::orc; - -namespace { - -// FIXME: This class is only here to support the transition to llvm::Error. It -// will be removed once this transition is complete. Clients should prefer to -// deal with the Error value directly, rather than converting to error_code. -class OrcErrorCategory : public std::error_category { -public: - const char *name() const noexcept override { return "orc"; } - - std::string message(int condition) const override { - switch (static_cast<OrcErrorCode>(condition)) { - case OrcErrorCode::UnknownORCError: - return "Unknown ORC error"; - case OrcErrorCode::DuplicateDefinition: - return "Duplicate symbol definition"; - case OrcErrorCode::JITSymbolNotFound: - return "JIT symbol not found"; - case OrcErrorCode::RemoteAllocatorDoesNotExist: - return "Remote allocator does not exist"; - case OrcErrorCode::RemoteAllocatorIdAlreadyInUse: - return "Remote allocator Id already in use"; - case OrcErrorCode::RemoteMProtectAddrUnrecognized: - return "Remote mprotect call references unallocated memory"; - case OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist: - return "Remote indirect stubs owner does not exist"; - case OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse: - return "Remote indirect stubs owner Id already in use"; - case OrcErrorCode::RPCConnectionClosed: - return "RPC connection closed"; - case OrcErrorCode::RPCCouldNotNegotiateFunction: - return "Could not negotiate RPC function"; - case OrcErrorCode::RPCResponseAbandoned: - return "RPC response abandoned"; - case OrcErrorCode::UnexpectedRPCCall: - return "Unexpected RPC call"; - case OrcErrorCode::UnexpectedRPCResponse: - return "Unexpected RPC response"; - case OrcErrorCode::UnknownErrorCodeFromRemote: - return "Unknown error returned from remote RPC function " - "(Use StringError to get error message)"; - case OrcErrorCode::UnknownResourceHandle: - return "Unknown resource handle"; - } - llvm_unreachable("Unhandled error code"); - } -}; - -static ManagedStatic<OrcErrorCategory> OrcErrCat; -} - -namespace llvm { -namespace orc { - -char DuplicateDefinition::ID = 0; -char JITSymbolNotFound::ID = 0; - -std::error_code orcError(OrcErrorCode ErrCode) { - typedef std::underlying_type<OrcErrorCode>::type UT; - return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat); -} - - -DuplicateDefinition::DuplicateDefinition(std::string SymbolName) - : SymbolName(std::move(SymbolName)) {} - -std::error_code DuplicateDefinition::convertToErrorCode() const { - return orcError(OrcErrorCode::DuplicateDefinition); -} - -void DuplicateDefinition::log(raw_ostream &OS) const { - OS << "Duplicate definition of symbol '" << SymbolName << "'"; -} - -const std::string &DuplicateDefinition::getSymbolName() const { - return SymbolName; -} - -JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName) - : SymbolName(std::move(SymbolName)) {} - -std::error_code JITSymbolNotFound::convertToErrorCode() const { - typedef std::underlying_type<OrcErrorCode>::type UT; - return std::error_code(static_cast<UT>(OrcErrorCode::JITSymbolNotFound), - *OrcErrCat); -} - -void JITSymbolNotFound::log(raw_ostream &OS) const { - OS << "Could not find symbol '" << SymbolName << "'"; -} - -const std::string &JITSymbolNotFound::getSymbolName() const { - return SymbolName; -} - -} -} diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp deleted file mode 100644 index 617bc2fc64b..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "OrcMCJITReplacement.h" -#include "llvm/ExecutionEngine/GenericValue.h" - -namespace { - -static struct RegisterJIT { - RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); } -} JITRegistrator; - -} - -extern "C" void LLVMLinkInOrcMCJITReplacement() {} - -namespace llvm { -namespace orc { - -GenericValue -OrcMCJITReplacement::runFunction(Function *F, - ArrayRef<GenericValue> ArgValues) { - assert(F && "Function *F was null at entry to run()"); - - void *FPtr = getPointerToFunction(F); - assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); - FunctionType *FTy = F->getFunctionType(); - Type *RetTy = FTy->getReturnType(); - - assert((FTy->getNumParams() == ArgValues.size() || - (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && - "Wrong number of arguments passed into function!"); - assert(FTy->getNumParams() == ArgValues.size() && - "This doesn't support passing arguments through varargs (yet)!"); - - // Handle some common cases first. These cases correspond to common `main' - // prototypes. - if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { - switch (ArgValues.size()) { - case 3: - if (FTy->getParamType(0)->isIntegerTy(32) && - FTy->getParamType(1)->isPointerTy() && - FTy->getParamType(2)->isPointerTy()) { - int (*PF)(int, char **, const char **) = - (int (*)(int, char **, const char **))(intptr_t)FPtr; - - // Call the function. - GenericValue rv; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), - (char **)GVTOP(ArgValues[1]), - (const char **)GVTOP(ArgValues[2]))); - return rv; - } - break; - case 2: - if (FTy->getParamType(0)->isIntegerTy(32) && - FTy->getParamType(1)->isPointerTy()) { - int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr; - - // Call the function. - GenericValue rv; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), - (char **)GVTOP(ArgValues[1]))); - return rv; - } - break; - case 1: - if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) { - GenericValue rv; - int (*PF)(int) = (int (*)(int))(intptr_t)FPtr; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); - return rv; - } - break; - } - } - - // Handle cases where no arguments are passed first. - if (ArgValues.empty()) { - GenericValue rv; - switch (RetTy->getTypeID()) { - default: - llvm_unreachable("Unknown return type for function call!"); - case Type::IntegerTyID: { - unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); - if (BitWidth == 1) - rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 8) - rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 16) - rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 32) - rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 64) - rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)()); - else - llvm_unreachable("Integer types > 64 bits not supported"); - return rv; - } - case Type::VoidTyID: - rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)()); - return rv; - case Type::FloatTyID: - rv.FloatVal = ((float (*)())(intptr_t)FPtr)(); - return rv; - case Type::DoubleTyID: - rv.DoubleVal = ((double (*)())(intptr_t)FPtr)(); - return rv; - case Type::X86_FP80TyID: - case Type::FP128TyID: - case Type::PPC_FP128TyID: - llvm_unreachable("long double not supported yet"); - case Type::PointerTyID: - return PTOGV(((void *(*)())(intptr_t)FPtr)()); - } - } - - llvm_unreachable("Full-featured argument passing not supported yet!"); -} - -void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) { - auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors; - - for (auto &KV : CtorDtorsMap) - cantFail(LegacyCtorDtorRunner<LazyEmitLayerT>(std::move(KV.second), KV.first) - .runViaLayer(LazyEmitLayer)); - - CtorDtorsMap.clear(); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/gnu/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h deleted file mode 100644 index 36e7e83a8ba..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ /dev/null @@ -1,505 +0,0 @@ -//===- OrcMCJITReplacement.h - Orc based MCJIT replacement ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Orc based MCJIT replacement. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H -#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" -#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" -#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/Object/Archive.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include <algorithm> -#include <cassert> -#include <cstddef> -#include <cstdint> -#include <map> -#include <memory> -#include <set> -#include <string> -#include <vector> - -namespace llvm { - -class ObjectCache; - -namespace orc { - -class OrcMCJITReplacement : public ExecutionEngine { - - // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that - // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are - // expecting - see finalizeMemory. - class MCJITReplacementMemMgr : public MCJITMemoryManager { - public: - MCJITReplacementMemMgr(OrcMCJITReplacement &M, - std::shared_ptr<MCJITMemoryManager> ClientMM) - : M(M), ClientMM(std::move(ClientMM)) {} - - uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, - StringRef SectionName) override { - uint8_t *Addr = - ClientMM->allocateCodeSection(Size, Alignment, SectionID, - SectionName); - M.SectionsAllocatedSinceLastLoad.insert(Addr); - return Addr; - } - - uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName, - bool IsReadOnly) override { - uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID, - SectionName, IsReadOnly); - M.SectionsAllocatedSinceLastLoad.insert(Addr); - return Addr; - } - - void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, - uintptr_t RODataSize, uint32_t RODataAlign, - uintptr_t RWDataSize, - uint32_t RWDataAlign) override { - return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign, - RODataSize, RODataAlign, - RWDataSize, RWDataAlign); - } - - bool needsToReserveAllocationSpace() override { - return ClientMM->needsToReserveAllocationSpace(); - } - - void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override { - return ClientMM->registerEHFrames(Addr, LoadAddr, Size); - } - - void deregisterEHFrames() override { - return ClientMM->deregisterEHFrames(); - } - - void notifyObjectLoaded(RuntimeDyld &RTDyld, - const object::ObjectFile &O) override { - return ClientMM->notifyObjectLoaded(RTDyld, O); - } - - void notifyObjectLoaded(ExecutionEngine *EE, - const object::ObjectFile &O) override { - return ClientMM->notifyObjectLoaded(EE, O); - } - - bool finalizeMemory(std::string *ErrMsg = nullptr) override { - // Each set of objects loaded will be finalized exactly once, but since - // symbol lookup during relocation may recursively trigger the - // loading/relocation of other modules, and since we're forwarding all - // finalizeMemory calls to a single underlying memory manager, we need to - // defer forwarding the call on until all necessary objects have been - // loaded. Otherwise, during the relocation of a leaf object, we will end - // up finalizing memory, causing a crash further up the stack when we - // attempt to apply relocations to finalized memory. - // To avoid finalizing too early, look at how many objects have been - // loaded but not yet finalized. This is a bit of a hack that relies on - // the fact that we're lazily emitting object files: The only way you can - // get more than one set of objects loaded but not yet finalized is if - // they were loaded during relocation of another set. - if (M.UnfinalizedSections.size() == 1) - return ClientMM->finalizeMemory(ErrMsg); - return false; - } - - private: - OrcMCJITReplacement &M; - std::shared_ptr<MCJITMemoryManager> ClientMM; - }; - - class LinkingORCResolver : public orc::SymbolResolver { - public: - LinkingORCResolver(OrcMCJITReplacement &M) : M(M) {} - - SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) override { - SymbolNameSet Result; - - for (auto &S : Symbols) { - if (auto Sym = M.findMangledSymbol(*S)) { - if (!Sym.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym.takeError()) { - M.reportError(std::move(Err)); - return SymbolNameSet(); - } else { - if (auto Sym2 = M.ClientResolver->findSymbolInLogicalDylib(*S)) { - if (!Sym2.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym2.takeError()) { - M.reportError(std::move(Err)); - return SymbolNameSet(); - } else - Result.insert(S); - } - } - - return Result; - } - - SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, - SymbolNameSet Symbols) override { - SymbolNameSet UnresolvedSymbols; - bool NewSymbolsResolved = false; - - for (auto &S : Symbols) { - if (auto Sym = M.findMangledSymbol(*S)) { - if (auto Addr = Sym.getAddress()) { - Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - Query->notifySymbolReady(); - NewSymbolsResolved = true; - } else { - M.ES.legacyFailQuery(*Query, Addr.takeError()); - return SymbolNameSet(); - } - } else if (auto Err = Sym.takeError()) { - M.ES.legacyFailQuery(*Query, std::move(Err)); - return SymbolNameSet(); - } else { - if (auto Sym2 = M.ClientResolver->findSymbol(*S)) { - if (auto Addr = Sym2.getAddress()) { - Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym2.getFlags())); - Query->notifySymbolReady(); - NewSymbolsResolved = true; - } else { - M.ES.legacyFailQuery(*Query, Addr.takeError()); - return SymbolNameSet(); - } - } else if (auto Err = Sym2.takeError()) { - M.ES.legacyFailQuery(*Query, std::move(Err)); - return SymbolNameSet(); - } else - UnresolvedSymbols.insert(S); - } - } - - if (NewSymbolsResolved && Query->isFullyResolved()) - Query->handleFullyResolved(); - - if (NewSymbolsResolved && Query->isFullyReady()) - Query->handleFullyReady(); - - return UnresolvedSymbols; - } - - private: - OrcMCJITReplacement &M; - }; - -private: - static ExecutionEngine * - createOrcMCJITReplacement(std::string *ErrorMsg, - std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<LegacyJITSymbolResolver> Resolver, - std::unique_ptr<TargetMachine> TM) { - return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver), - std::move(TM)); - } - - void reportError(Error Err) { - logAllUnhandledErrors(std::move(Err), errs(), "MCJIT error: "); - } - -public: - OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<LegacyJITSymbolResolver> ClientResolver, - std::unique_ptr<TargetMachine> TM) - : ExecutionEngine(TM->createDataLayout()), - TM(std::move(TM)), - MemMgr( - std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))), - Resolver(std::make_shared<LinkingORCResolver>(*this)), - ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this), - NotifyFinalized(*this), - ObjectLayer( - ES, - [this](VModuleKey K) { - return ObjectLayerT::Resources{this->MemMgr, this->Resolver}; - }, - NotifyObjectLoaded, NotifyFinalized), - CompileLayer(ObjectLayer, SimpleCompiler(*this->TM), - [this](VModuleKey K, std::unique_ptr<Module> M) { - Modules.push_back(std::move(M)); - }), - LazyEmitLayer(CompileLayer) {} - - static void Register() { - OrcMCJITReplacementCtor = createOrcMCJITReplacement; - } - - 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()); - } else { - assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch"); - } - - // Rename, bump linkage and record 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; - { - unsigned CtorId = 0, DtorId = 0; - for (auto Ctor : orc::getConstructors(*M)) { - std::string NewCtorName = ("__ORCstatic_ctor." + Twine(CtorId++)).str(); - Ctor.Func->setName(NewCtorName); - Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); - Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); - CtorNames.push_back(mangle(NewCtorName)); - } - for (auto Dtor : orc::getDestructors(*M)) { - std::string NewDtorName = ("__ORCstatic_dtor." + Twine(DtorId++)).str(); - dbgs() << "Found dtor: " << NewDtorName << "\n"; - Dtor.Func->setName(NewDtorName); - Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); - Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); - DtorNames.push_back(mangle(NewDtorName)); - } - } - - auto K = ES.allocateVModule(); - - UnexecutedConstructors[K] = std::move(CtorNames); - UnexecutedDestructors[K] = std::move(DtorNames); - - cantFail(LazyEmitLayer.addModule(K, std::move(M))); - } - - void addObjectFile(std::unique_ptr<object::ObjectFile> O) override { - cantFail(ObjectLayer.addObject( - ES.allocateVModule(), MemoryBuffer::getMemBufferCopy(O->getData()))); - } - - void addObjectFile(object::OwningBinary<object::ObjectFile> O) override { - std::unique_ptr<object::ObjectFile> Obj; - std::unique_ptr<MemoryBuffer> ObjBuffer; - std::tie(Obj, ObjBuffer) = O.takeBinary(); - cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(ObjBuffer))); - } - - void addArchive(object::OwningBinary<object::Archive> A) override { - Archives.push_back(std::move(A)); - } - - bool removeModule(Module *M) override { - auto I = Modules.begin(); - for (auto E = Modules.end(); I != E; ++I) - if (I->get() == M) - break; - if (I == Modules.end()) - return false; - Modules.erase(I); - return true; - } - - uint64_t getSymbolAddress(StringRef Name) { - return cantFail(findSymbol(Name).getAddress()); - } - - JITSymbol findSymbol(StringRef Name) { - return findMangledSymbol(mangle(Name)); - } - - void finalizeObject() override { - // This is deprecated - Aim to remove in ExecutionEngine. - // REMOVE IF POSSIBLE - Doesn't make sense for New JIT. - } - - void mapSectionAddress(const void *LocalAddress, - uint64_t TargetAddress) override { - for (auto &P : UnfinalizedSections) - if (P.second.count(LocalAddress)) - ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress); - } - - uint64_t getGlobalValueAddress(const std::string &Name) override { - return getSymbolAddress(Name); - } - - uint64_t getFunctionAddress(const std::string &Name) override { - return getSymbolAddress(Name); - } - - void *getPointerToFunction(Function *F) override { - uint64_t FAddr = getSymbolAddress(F->getName()); - return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr)); - } - - void *getPointerToNamedFunction(StringRef Name, - bool AbortOnFailure = true) override { - uint64_t Addr = getSymbolAddress(Name); - if (!Addr && AbortOnFailure) - llvm_unreachable("Missing symbol!"); - return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr)); - } - - GenericValue runFunction(Function *F, - ArrayRef<GenericValue> ArgValues) override; - - void setObjectCache(ObjectCache *NewCache) override { - CompileLayer.getCompiler().setObjectCache(NewCache); - } - - void setProcessAllSections(bool ProcessAllSections) override { - ObjectLayer.setProcessAllSections(ProcessAllSections); - } - - void runStaticConstructorsDestructors(bool isDtors) override; - -private: - JITSymbol findMangledSymbol(StringRef Name) { - if (auto Sym = LazyEmitLayer.findSymbol(Name, false)) - return Sym; - if (auto Sym = ClientResolver->findSymbol(Name)) - return Sym; - if (auto Sym = scanArchives(Name)) - return Sym; - - return nullptr; - } - - JITSymbol scanArchives(StringRef Name) { - for (object::OwningBinary<object::Archive> &OB : Archives) { - object::Archive *A = OB.getBinary(); - // Look for our symbols in each Archive - auto OptionalChildOrErr = A->findSym(Name); - if (!OptionalChildOrErr) - report_fatal_error(OptionalChildOrErr.takeError()); - auto &OptionalChild = *OptionalChildOrErr; - if (OptionalChild) { - // FIXME: Support nested archives? - Expected<std::unique_ptr<object::Binary>> ChildBinOrErr = - OptionalChild->getAsBinary(); - if (!ChildBinOrErr) { - // TODO: Actually report errors helpfully. - consumeError(ChildBinOrErr.takeError()); - continue; - } - std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get(); - if (ChildBin->isObject()) { - cantFail(ObjectLayer.addObject( - ES.allocateVModule(), - MemoryBuffer::getMemBufferCopy(ChildBin->getData()))); - if (auto Sym = ObjectLayer.findSymbol(Name, true)) - return Sym; - } - } - } - return nullptr; - } - - class NotifyObjectLoadedT { - public: - using LoadedObjInfoListT = - std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>; - - NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {} - - void operator()(VModuleKey K, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &Info) const { - M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad); - M.SectionsAllocatedSinceLastLoad = SectionAddrSet(); - M.MemMgr->notifyObjectLoaded(&M, Obj); - } - private: - OrcMCJITReplacement &M; - }; - - class NotifyFinalizedT { - public: - NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {} - - void operator()(VModuleKey K, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &Info) { - M.UnfinalizedSections.erase(K); - } - - private: - OrcMCJITReplacement &M; - }; - - std::string mangle(StringRef Name) { - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout()); - } - return MangledName; - } - - using ObjectLayerT = LegacyRTDyldObjectLinkingLayer; - using CompileLayerT = LegacyIRCompileLayer<ObjectLayerT, orc::SimpleCompiler>; - using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>; - - ExecutionSession ES; - - std::unique_ptr<TargetMachine> TM; - std::shared_ptr<MCJITReplacementMemMgr> MemMgr; - std::shared_ptr<LinkingORCResolver> Resolver; - std::shared_ptr<LegacyJITSymbolResolver> ClientResolver; - Mangler Mang; - - // IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr - // delete blocks in LocalModules refer to the ShouldDelete map, so - // LocalModules needs to be destructed before ShouldDelete. - std::map<Module*, bool> ShouldDelete; - - NotifyObjectLoadedT NotifyObjectLoaded; - NotifyFinalizedT NotifyFinalized; - - ObjectLayerT ObjectLayer; - CompileLayerT CompileLayer; - LazyEmitLayerT LazyEmitLayer; - - std::map<VModuleKey, std::vector<std::string>> UnexecutedConstructors; - std::map<VModuleKey, std::vector<std::string>> UnexecutedDestructors; - - // We need to store ObjLayerT::ObjSetHandles for each of the object sets - // that have been emitted but not yet finalized so that we can forward the - // mapSectionAddress calls appropriately. - using SectionAddrSet = std::set<const void *>; - SectionAddrSet SectionsAllocatedSinceLastLoad; - std::map<VModuleKey, SectionAddrSet> UnfinalizedSections; - - std::vector<object::OwningBinary<object::Archive>> Archives; -}; - -} // end namespace orc - -} // end namespace llvm - -#endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp deleted file mode 100644 index 2a7ab5ca818..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/RPCUtils.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===--------------- RPCUtils.cpp - RPCUtils implementation ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// RPCUtils implementation. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/RPCUtils.h" - -char llvm::orc::rpc::RPCFatalError::ID = 0; -char llvm::orc::rpc::ConnectionClosed::ID = 0; -char llvm::orc::rpc::ResponseAbandoned::ID = 0; -char llvm::orc::rpc::CouldNotNegotiate::ID = 0; - -namespace llvm { -namespace orc { -namespace rpc { - -std::error_code ConnectionClosed::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCConnectionClosed); -} - -void ConnectionClosed::log(raw_ostream &OS) const { - OS << "RPC connection already closed"; -} - -std::error_code ResponseAbandoned::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCResponseAbandoned); -} - -void ResponseAbandoned::log(raw_ostream &OS) const { - OS << "RPC response abandoned"; -} - -CouldNotNegotiate::CouldNotNegotiate(std::string Signature) - : Signature(std::move(Signature)) {} - -std::error_code CouldNotNegotiate::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCCouldNotNegotiateFunction); -} - -void CouldNotNegotiate::log(raw_ostream &OS) const { - OS << "Could not negotiate RPC function " << Signature; -} - - -} // end namespace rpc -} // end namespace orc -} // end namespace llvm diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp deleted file mode 100644 index 299d76183cd..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ /dev/null @@ -1,216 +0,0 @@ -//===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" - -namespace { - -using namespace llvm; -using namespace llvm::orc; - -class JITDylibSearchOrderResolver : public JITSymbolResolver { -public: - JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {} - - void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) { - auto &ES = MR.getTargetJITDylib().getExecutionSession(); - SymbolNameSet InternedSymbols; - - // Intern the requested symbols: lookup takes interned strings. - for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); - - // Build an OnResolve callback to unwrap the interned strings and pass them - // to the OnResolved callback. - // FIXME: Switch to move capture of OnResolved once we have c++14. - auto OnResolvedWithUnwrap = - [OnResolved](Expected<SymbolMap> InternedResult) { - if (!InternedResult) { - OnResolved(InternedResult.takeError()); - return; - } - - LookupResult Result; - for (auto &KV : *InternedResult) - Result[*KV.first] = std::move(KV.second); - OnResolved(Result); - }; - - // We're not waiting for symbols to be ready. Just log any errors. - auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); }; - - // Register dependencies for all symbols contained in this set. - auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) { - MR.addDependenciesForAll(Deps); - }; - - JITDylibSearchList SearchOrder; - MR.getTargetJITDylib().withSearchOrderDo( - [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; }); - ES.lookup(SearchOrder, InternedSymbols, OnResolvedWithUnwrap, OnReady, - RegisterDependencies); - } - - Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) { - LookupSet Result; - - for (auto &KV : MR.getSymbols()) { - if (Symbols.count(*KV.first)) - Result.insert(*KV.first); - } - - return Result; - } - -private: - MaterializationResponsibility &MR; -}; - -} // end anonymous namespace - -namespace llvm { -namespace orc { - -RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer( - ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager, - NotifyLoadedFunction NotifyLoaded, NotifyEmittedFunction NotifyEmitted) - : ObjectLayer(ES), GetMemoryManager(GetMemoryManager), - NotifyLoaded(std::move(NotifyLoaded)), - NotifyEmitted(std::move(NotifyEmitted)) {} - -void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, - std::unique_ptr<MemoryBuffer> O) { - assert(O && "Object must not be null"); - - // This method launches an asynchronous link step that will fulfill our - // materialization responsibility. We need to switch R to be heap - // allocated before that happens so it can live as long as the asynchronous - // link needs it to (i.e. it must be able to outlive this method). - auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R)); - - auto &ES = getExecutionSession(); - - auto Obj = object::ObjectFile::createObjectFile(*O); - - if (!Obj) { - getExecutionSession().reportError(Obj.takeError()); - SharedR->failMaterialization(); - return; - } - - // Collect the internal symbols from the object file: We will need to - // filter these later. - auto InternalSymbols = std::make_shared<std::set<StringRef>>(); - { - for (auto &Sym : (*Obj)->symbols()) { - if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) { - if (auto SymName = Sym.getName()) - InternalSymbols->insert(*SymName); - else { - ES.reportError(SymName.takeError()); - R.failMaterialization(); - return; - } - } - } - } - - auto K = R.getVModuleKey(); - RuntimeDyld::MemoryManager *MemMgr = nullptr; - - // Create a record a memory manager for this object. - { - auto Tmp = GetMemoryManager(); - std::lock_guard<std::mutex> Lock(RTDyldLayerMutex); - MemMgrs.push_back(std::move(Tmp)); - MemMgr = MemMgrs.back().get(); - } - - JITDylibSearchOrderResolver Resolver(*SharedR); - - /* Thoughts on proper cross-dylib weak symbol handling: - * - * Change selection of canonical defs to be a manually triggered process, and - * add a 'canonical' bit to symbol definitions. When canonical def selection - * is triggered, sweep the JITDylibs to mark defs as canonical, discard - * duplicate defs. - */ - jitLinkForORC( - **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections, - [this, K, SharedR, &Obj, InternalSymbols]( - std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, - std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) { - return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo), - ResolvedSymbols, *InternalSymbols); - }, - [this, K, SharedR](Error Err) { - onObjEmit(K, *SharedR, std::move(Err)); - }); -} - -Error RTDyldObjectLinkingLayer::onObjLoad( - VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj, - std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, - std::map<StringRef, JITEvaluatedSymbol> Resolved, - std::set<StringRef> &InternalSymbols) { - SymbolFlagsMap ExtraSymbolsToClaim; - SymbolMap Symbols; - for (auto &KV : Resolved) { - // Scan the symbols and add them to the Symbols map for resolution. - - // We never claim internal symbols. - if (InternalSymbols.count(KV.first)) - continue; - - auto InternedName = getExecutionSession().intern(KV.first); - auto Flags = KV.second.getFlags(); - - // Override object flags and claim responsibility for symbols if - // requested. - if (OverrideObjectFlags || AutoClaimObjectSymbols) { - auto I = R.getSymbols().find(InternedName); - - if (OverrideObjectFlags && I != R.getSymbols().end()) - Flags = JITSymbolFlags::stripTransientFlags(I->second); - else if (AutoClaimObjectSymbols && I == R.getSymbols().end()) - ExtraSymbolsToClaim[InternedName] = Flags; - } - - Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags); - } - - if (!ExtraSymbolsToClaim.empty()) - if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim)) - return Err; - - R.resolve(Symbols); - - if (NotifyLoaded) - NotifyLoaded(K, Obj, *LoadedObjInfo); - - return Error::success(); -} - -void RTDyldObjectLinkingLayer::onObjEmit(VModuleKey K, - MaterializationResponsibility &R, - Error Err) { - if (Err) { - getExecutionSession().reportError(std::move(Err)); - R.failMaterialization(); - return; - } - - R.emit(); - - if (NotifyEmitted) - NotifyEmitted(K); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/ThreadSafeModule.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/ThreadSafeModule.cpp deleted file mode 100644 index 9525b168fbd..00000000000 --- a/gnu/llvm/lib/ExecutionEngine/Orc/ThreadSafeModule.cpp +++ /dev/null @@ -1,65 +0,0 @@ -//===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities -//h-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" -#include "llvm/Bitcode/BitcodeReader.h" -#include "llvm/Bitcode/BitcodeWriter.h" -#include "llvm/Transforms/Utils/Cloning.h" - -namespace llvm { -namespace orc { - -ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM, - GVPredicate ShouldCloneDef, - GVModifier UpdateClonedDefSource) { - assert(TSM && "Can not clone null module"); - - if (!ShouldCloneDef) - ShouldCloneDef = [](const GlobalValue &) { return true; }; - - auto Lock = TSM.getContextLock(); - - SmallVector<char, 1> ClonedModuleBuffer; - - { - std::set<GlobalValue *> ClonedDefsInSrc; - ValueToValueMapTy VMap; - auto Tmp = CloneModule(*TSM.getModule(), VMap, [&](const GlobalValue *GV) { - if (ShouldCloneDef(*GV)) { - ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV)); - return true; - } - return false; - }); - - if (UpdateClonedDefSource) - for (auto *GV : ClonedDefsInSrc) - UpdateClonedDefSource(*GV); - - BitcodeWriter BCWriter(ClonedModuleBuffer); - - BCWriter.writeModule(*Tmp); - BCWriter.writeSymtab(); - BCWriter.writeStrtab(); - } - - MemoryBufferRef ClonedModuleBufferRef( - StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), - "cloned module buffer"); - ThreadSafeContext NewTSCtx(llvm::make_unique<LLVMContext>()); - - auto ClonedModule = - cantFail(parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext())); - ClonedModule->setModuleIdentifier(TSM.getModule()->getName()); - return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx)); -} - -} // end namespace orc -} // end namespace llvm |
