diff options
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc')
30 files changed, 934 insertions, 454 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 884878925cde..5f593a27cad6 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -1,9 +1,8 @@ //===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -265,13 +264,26 @@ public: std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>; /// Construct a compile-on-demand layer instance. - LegacyCompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer, - SymbolResolverGetter GetSymbolResolver, - SymbolResolverSetter SetSymbolResolver, - PartitioningFtor Partition, - CompileCallbackMgrT &CallbackMgr, - IndirectStubsManagerBuilderT CreateIndirectStubsManager, - bool CloneStubsIntoPartitions = true) + LLVM_ATTRIBUTE_DEPRECATED( + LegacyCompileOnDemandLayer( + ExecutionSession &ES, BaseLayerT &BaseLayer, + SymbolResolverGetter GetSymbolResolver, + SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, + CompileCallbackMgrT &CallbackMgr, + IndirectStubsManagerBuilderT CreateIndirectStubsManager, + bool CloneStubsIntoPartitions = true), + "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " + "use " + "the ORCv2 LegacyCompileOnDemandLayer instead"); + + /// Legacy layer constructor with deprecation acknowledgement. + LegacyCompileOnDemandLayer( + ORCv1DeprecationAcknowledgement, ExecutionSession &ES, + BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver, + SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, + CompileCallbackMgrT &CallbackMgr, + IndirectStubsManagerBuilderT CreateIndirectStubsManager, + bool CloneStubsIntoPartitions = true) : ES(ES), BaseLayer(BaseLayer), GetSymbolResolver(std::move(GetSymbolResolver)), SetSymbolResolver(std::move(SetSymbolResolver)), @@ -730,8 +742,24 @@ private: bool CloneStubsIntoPartitions; }; -} // end namespace orc +template <typename BaseLayerT, typename CompileCallbackMgrT, + typename IndirectStubsMgrT> +LegacyCompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT, IndirectStubsMgrT>:: + LegacyCompileOnDemandLayer( + ExecutionSession &ES, BaseLayerT &BaseLayer, + SymbolResolverGetter GetSymbolResolver, + SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, + CompileCallbackMgrT &CallbackMgr, + IndirectStubsManagerBuilderT CreateIndirectStubsManager, + bool CloneStubsIntoPartitions) + : ES(ES), BaseLayer(BaseLayer), + GetSymbolResolver(std::move(GetSymbolResolver)), + SetSymbolResolver(std::move(SetSymbolResolver)), + Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr), + CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)), + CloneStubsIntoPartitions(CloneStubsIntoPartitions) {} +} // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/include/llvm/ExecutionEngine/Orc/CompileUtils.h index f34f88311ba5..eb6d84e8cbb4 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileUtils.h +++ b/include/llvm/ExecutionEngine/Orc/CompileUtils.h @@ -1,9 +1,8 @@ //===- CompileUtils.h - Utilities for compiling IR in the JIT ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,28 +13,21 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H -#include "llvm/ADT/SmallVector.h" -#include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SmallVectorMemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include <algorithm> #include <memory> namespace llvm { class MCContext; +class MemoryBuffer; class Module; +class ObjectCache; +class TargetMachine; namespace orc { +class JITTargetMachineBuilder; + /// Simple compile functor: Takes a single IR module and returns an ObjectFile. /// This compiler supports a single compilation thread and LLVMContext only. /// For multithreaded compilation, use ConcurrentIRCompiler below. @@ -51,56 +43,32 @@ public: void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } /// Compile a Module to an ObjectFile. - CompileResult operator()(Module &M) { - CompileResult CachedObject = tryToLoadFromObjectCache(M); - if (CachedObject) - return CachedObject; - - SmallVector<char, 0> ObjBufferSV; - - { - raw_svector_ostream ObjStream(ObjBufferSV); - - legacy::PassManager PM; - MCContext *Ctx; - if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) - llvm_unreachable("Target does not support MC emission."); - PM.run(M); - } - - auto ObjBuffer = - llvm::make_unique<SmallVectorMemoryBuffer>(std::move(ObjBufferSV)); - auto Obj = - object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - - if (Obj) { - notifyObjectCompiled(M, *ObjBuffer); - return std::move(ObjBuffer); - } - - // TODO: Actually report errors helpfully. - consumeError(Obj.takeError()); - return nullptr; - } + CompileResult operator()(Module &M); private: - - CompileResult tryToLoadFromObjectCache(const Module &M) { - if (!ObjCache) - return CompileResult(); - - return ObjCache->getObject(&M); - } - - void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) { - if (ObjCache) - ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); - } + CompileResult tryToLoadFromObjectCache(const Module &M); + void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer); TargetMachine &TM; ObjectCache *ObjCache = nullptr; }; +/// A SimpleCompiler that owns its TargetMachine. +/// +/// This convenient for clients who don't want to own their TargetMachines, +/// e.g. LLJIT. +class TMOwningSimpleCompiler : public SimpleCompiler { +public: + TMOwningSimpleCompiler(std::unique_ptr<TargetMachine> TM, + ObjectCache *ObjCache = nullptr) + : SimpleCompiler(*TM, ObjCache), TM(std::move(TM)) {} + +private: + // FIXME: shared because std::functions (and consequently + // IRCompileLayer::CompileFunction) are not moveable. + std::shared_ptr<llvm::TargetMachine> TM; +}; + /// A thread-safe version of SimpleCompiler. /// /// This class creates a new TargetMachine and SimpleCompiler instance for each @@ -108,16 +76,11 @@ private: class ConcurrentIRCompiler { public: ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, - ObjectCache *ObjCache = nullptr) - : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} + ObjectCache *ObjCache = nullptr); void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; } - std::unique_ptr<MemoryBuffer> operator()(Module &M) { - auto TM = cantFail(JTMB.createTargetMachine()); - SimpleCompiler C(*TM, ObjCache); - return C(M); - } + std::unique_ptr<MemoryBuffer> operator()(Module &M); private: JITTargetMachineBuilder JTMB; diff --git a/include/llvm/ExecutionEngine/Orc/Core.h b/include/llvm/ExecutionEngine/Orc/Core.h index 39d306e0bd4c..94a5618233e4 100644 --- a/include/llvm/ExecutionEngine/Orc/Core.h +++ b/include/llvm/ExecutionEngine/Orc/Core.h @@ -1,9 +1,8 @@ //===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -17,6 +16,7 @@ #include "llvm/ADT/BitmaskEnum.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h" +#include "llvm/ExecutionEngine/OrcV1Deprecation.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" @@ -34,6 +34,7 @@ class ExecutionSession; class MaterializationUnit; class MaterializationResponsibility; class JITDylib; +enum class SymbolState : uint8_t; /// VModuleKey provides a unique identifier (allocated and managed by /// ExecutionSessions) for a module added to the JIT. @@ -57,6 +58,18 @@ using SymbolDependenceMap = DenseMap<JITDylib *, SymbolNameSet>; /// A list of (JITDylib*, bool) pairs. using JITDylibSearchList = std::vector<std::pair<JITDylib *, bool>>; +struct SymbolAliasMapEntry { + SymbolAliasMapEntry() = default; + SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags) + : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {} + + SymbolStringPtr Aliasee; + JITSymbolFlags AliasFlags; +}; + +/// A map of Symbols to (Symbol, Flags) pairs. +using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>; + /// Render a SymbolStringPtr. raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym); @@ -88,12 +101,15 @@ raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU); /// Render a JITDylibSearchList. raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs); +/// Render a SymbolAliasMap. +raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases); + +/// Render a SymbolState. +raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S); + /// Callback to notify client that symbols have been resolved. using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>; -/// Callback to notify client that symbols are ready for execution. -using SymbolsReadyCallback = std::function<void(Error)>; - /// Callback to register the dependencies for a given query. using RegisterDependenciesFunction = std::function<void(const SymbolDependenceMap &)>; @@ -175,7 +191,7 @@ public: /// Note: The returned flags may have transient flags (Lazy, Materializing) /// set. These should be stripped with JITSymbolFlags::stripTransientFlags /// before using. - const SymbolFlagsMap &getSymbols() { return SymbolFlags; } + const SymbolFlagsMap &getSymbols() const { return SymbolFlags; } /// Returns the names of any symbols covered by this /// MaterializationResponsibility object that have queries pending. This @@ -189,12 +205,12 @@ public: /// symbols must be ones covered by this MaterializationResponsibility /// instance. Individual calls to this method may resolve a subset of the /// symbols, but all symbols must have been resolved prior to calling emit. - void resolve(const SymbolMap &Symbols); + void notifyResolved(const SymbolMap &Symbols); /// Notifies the target JITDylib (and any pending queries on that JITDylib) /// that all symbols covered by this MaterializationResponsibility instance /// have been emitted. - void emit(); + void notifyEmitted(); /// Adds new symbols to the JITDylib and this responsibility instance. /// JITDylib entries start out in the materializing state. @@ -334,18 +350,6 @@ absoluteSymbols(SymbolMap Symbols, VModuleKey K = VModuleKey()) { std::move(Symbols), std::move(K)); } -struct SymbolAliasMapEntry { - SymbolAliasMapEntry() = default; - SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags) - : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {} - - SymbolStringPtr Aliasee; - JITSymbolFlags AliasFlags; -}; - -/// A map of Symbols to (Symbol, Flags) pairs. -using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>; - /// A materialization unit for symbol aliases. Allows existing symbols to be /// aliased with alternate flags. class ReExportsMaterializationUnit : public MaterializationUnit { @@ -419,7 +423,7 @@ public: ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported = false, SymbolPredicate Allow = SymbolPredicate()); - SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names); + Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names); private: JITDylib &SourceJD; @@ -427,6 +431,15 @@ private: SymbolPredicate Allow; }; +/// Represents the state that a symbol has reached during materialization. +enum class SymbolState : uint8_t { + Invalid, /// No symbol should be in this state. + NeverSearched, /// Added to the symbol table, never queried. + Materializing, /// Queried, materialization begun. + Resolved, /// Assigned address, still materializing. + Ready = 0x3f /// Ready and safe for clients to access. +}; + /// A symbol query that returns results via a callback when results are /// ready. /// @@ -437,38 +450,30 @@ class AsynchronousSymbolQuery { friend class JITSymbolResolverAdapter; public: - - /// Create a query for the given symbols, notify-resolved and - /// notify-ready callbacks. + /// Create a query for the given symbols. The NotifyComplete + /// callback will be called once all queried symbols reach the given + /// minimum state. AsynchronousSymbolQuery(const SymbolNameSet &Symbols, - SymbolsResolvedCallback NotifySymbolsResolved, - SymbolsReadyCallback NotifySymbolsReady); + SymbolState RequiredState, + SymbolsResolvedCallback NotifyComplete); - /// Set the resolved symbol information for the given symbol name. - void resolve(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym); + /// Notify the query that a requested symbol has reached the required state. + void notifySymbolMetRequiredState(const SymbolStringPtr &Name, + JITEvaluatedSymbol Sym); /// Returns true if all symbols covered by this query have been /// resolved. - bool isFullyResolved() const { return NotYetResolvedCount == 0; } + bool isComplete() const { return OutstandingSymbolsCount == 0; } - /// Call the NotifySymbolsResolved callback. + /// Call the NotifyComplete callback. /// - /// This should only be called if all symbols covered by the query have been - /// resolved. - void handleFullyResolved(); - - /// Notify the query that a requested symbol is ready for execution. - void notifySymbolReady(); - - /// Returns true if all symbols covered by this query are ready. - bool isFullyReady() const { return NotYetReadyCount == 0; } - - /// Calls the NotifySymbolsReady callback. - /// - /// This should only be called if all symbols covered by this query are ready. - void handleFullyReady(); + /// This should only be called if all symbols covered by the query have + /// reached the specified state. + void handleComplete(); private: + SymbolState getRequiredState() { return RequiredState; } + void addQueryDependence(JITDylib &JD, SymbolStringPtr Name); void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name); @@ -479,12 +484,11 @@ private: void detach(); - SymbolsResolvedCallback NotifySymbolsResolved; - SymbolsReadyCallback NotifySymbolsReady; + SymbolsResolvedCallback NotifyComplete; SymbolDependenceMap QueryRegistrations; SymbolMap ResolvedSymbols; - size_t NotYetResolvedCount; - size_t NotYetReadyCount; + size_t OutstandingSymbolsCount; + SymbolState RequiredState; }; /// A symbol table that supports asynchoronous symbol queries. @@ -498,7 +502,7 @@ class JITDylib { friend class ExecutionSession; friend class MaterializationResponsibility; public: - using GeneratorFunction = std::function<SymbolNameSet( + using GeneratorFunction = std::function<Expected<SymbolNameSet>( JITDylib &Parent, const SymbolNameSet &Names)>; using AsynchronousSymbolQuerySet = @@ -596,7 +600,7 @@ public: /// Search the given JITDylib for the symbols in Symbols. If found, store /// the flags for each symbol in Flags. Returns any unresolved symbols. - SymbolFlagsMap lookupFlags(const SymbolNameSet &Names); + Expected<SymbolFlagsMap> lookupFlags(const SymbolNameSet &Names); /// Dump current JITDylib state to OS. void dump(raw_ostream &OS); @@ -609,8 +613,8 @@ public: /// and the query will not be applied. The Query is not failed and can be /// re-used in a subsequent lookup once the symbols have been added, or /// manually failed. - SymbolNameSet legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, - SymbolNameSet Names); + Expected<SymbolNameSet> + legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names); private: using AsynchronousSymbolQueryList = @@ -627,40 +631,92 @@ private: DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>; struct MaterializingInfo { - AsynchronousSymbolQueryList PendingQueries; SymbolDependenceMap Dependants; SymbolDependenceMap UnemittedDependencies; bool IsEmitted = false; + + void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q); + void removeQuery(const AsynchronousSymbolQuery &Q); + AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState); + AsynchronousSymbolQueryList takeAllQueries(); + bool hasQueriesPending() const { return !PendingQueries.empty(); } + const AsynchronousSymbolQueryList &pendingQueries() const { + return PendingQueries; + } + + private: + AsynchronousSymbolQueryList PendingQueries; }; using MaterializingInfosMap = DenseMap<SymbolStringPtr, MaterializingInfo>; - using LookupImplActionFlags = enum { - None = 0, - NotifyFullyResolved = 1 << 0U, - NotifyFullyReady = 1 << 1U, - LLVM_MARK_AS_BITMASK_ENUM(NotifyFullyReady) + class SymbolTableEntry { + public: + SymbolTableEntry() = default; + SymbolTableEntry(JITSymbolFlags Flags) + : Flags(Flags), State(static_cast<uint8_t>(SymbolState::NeverSearched)), + MaterializerAttached(false), PendingRemoval(false) {} + + JITTargetAddress getAddress() const { return Addr; } + JITSymbolFlags getFlags() const { return Flags; } + SymbolState getState() const { return static_cast<SymbolState>(State); } + + bool isInMaterializationPhase() const { + return getState() == SymbolState::Materializing || + getState() == SymbolState::Resolved; + } + + bool hasMaterializerAttached() const { return MaterializerAttached; } + bool isPendingRemoval() const { return PendingRemoval; } + + void setAddress(JITTargetAddress Addr) { this->Addr = Addr; } + void setFlags(JITSymbolFlags Flags) { this->Flags = Flags; } + void setState(SymbolState State) { + assert(static_cast<uint8_t>(State) < (1 << 6) && + "State does not fit in bitfield"); + this->State = static_cast<uint8_t>(State); + } + + void setMaterializerAttached(bool MaterializerAttached) { + this->MaterializerAttached = MaterializerAttached; + } + + void setPendingRemoval(bool PendingRemoval) { + this->PendingRemoval = PendingRemoval; + } + + JITEvaluatedSymbol getSymbol() const { + return JITEvaluatedSymbol(Addr, Flags); + } + + private: + JITTargetAddress Addr = 0; + JITSymbolFlags Flags; + uint8_t State : 6; + uint8_t MaterializerAttached : 1; + uint8_t PendingRemoval : 1; }; + using SymbolTable = DenseMap<SymbolStringPtr, SymbolTableEntry>; + JITDylib(ExecutionSession &ES, std::string Name); Error defineImpl(MaterializationUnit &MU); - SymbolNameSet lookupFlagsImpl(SymbolFlagsMap &Flags, - const SymbolNameSet &Names); + Expected<SymbolNameSet> lookupFlagsImpl(SymbolFlagsMap &Flags, + const SymbolNameSet &Names); - void lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q, - SymbolNameSet &Unresolved, bool MatchNonExported, - MaterializationUnitList &MUs); + Error lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q, + SymbolNameSet &Unresolved, bool MatchNonExported, + MaterializationUnitList &MUs); void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved, bool MatchNonExported, MaterializationUnitList &MUs); - LookupImplActionFlags - lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q, - std::vector<std::unique_ptr<MaterializationUnit>> &MUs, - SymbolNameSet &Unresolved); + bool lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q, + std::vector<std::unique_ptr<MaterializationUnit>> &MUs, + SymbolNameSet &Unresolved); void detachQueryHelper(AsynchronousSymbolQuery &Q, const SymbolNameSet &QuerySymbols); @@ -686,7 +742,7 @@ private: ExecutionSession &ES; std::string JITDylibName; - SymbolMap Symbols; + SymbolTable Symbols; UnmaterializedInfosMap UnmaterializedInfos; MaterializingInfosMap MaterializingInfos; GeneratorFunction DefGenerator; @@ -727,7 +783,15 @@ public: /// the ExecutionSession. JITDylib &getMainJITDylib(); + /// Return a pointer to the "name" JITDylib. + /// Ownership of JITDylib remains within Execution Session + JITDylib *getJITDylibByName(StringRef Name); + /// Add a new JITDylib to this ExecutionSession. + /// + /// The JITDylib Name is required to be unique. Clients should verify that + /// names are not being re-used (e.g. by calling getJITDylibByName) if names + /// are based on user input. JITDylib &createJITDylib(std::string Name, bool AddToMainDylibSearchOrder = true); @@ -769,7 +833,7 @@ public: /// Do not use -- this will be removed soon. Expected<SymbolMap> legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names, - bool WaiUntilReady, + SymbolState RequiredState, RegisterDependenciesFunction RegisterDependencies); /// Search the given JITDylib list for the given symbols. @@ -779,11 +843,8 @@ public: /// (hidden visibility) symbols in that dylib (true means match against /// non-exported symbols, false means do not match). /// - /// The OnResolve callback will be called once all requested symbols are - /// resolved, or if an error occurs prior to resolution. - /// - /// The OnReady callback will be called once all requested symbols are ready, - /// or if an error occurs after resolution but before all symbols are ready. + /// The NotifyComplete callback will be called once all requested symbols + /// reach the required state. /// /// If all symbols are found, the RegisterDependencies function will be called /// while the session lock is held. This gives clients a chance to register @@ -795,7 +856,7 @@ public: /// client to get an address to call) then the value NoDependenciesToRegister /// can be used. void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols, - SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady, + SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies); /// Blocking version of lookup above. Returns the resolved symbol map. @@ -807,9 +868,9 @@ public: /// error will be reported via reportErrors. Expected<SymbolMap> lookup(const JITDylibSearchList &SearchOrder, const SymbolNameSet &Symbols, + SymbolState RequiredState = SymbolState::Ready, RegisterDependenciesFunction RegisterDependencies = - NoDependenciesToRegister, - bool WaitUntilReady = true); + NoDependenciesToRegister); /// Convenience version of blocking lookup. /// Searches each of the JITDylibs in the search order in turn for the given @@ -832,10 +893,11 @@ public: /// Materialize the given unit. void dispatchMaterialization(JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) { - LLVM_DEBUG(runSessionLocked([&]() { - dbgs() << "Compiling, for " << JD.getName() << ", " << *MU - << "\n"; - });); + LLVM_DEBUG({ + runSessionLocked([&]() { + dbgs() << "Dispatching " << *MU << " for " << JD.getName() << "\n"; + }); + }); DispatchMaterialization(JD, std::move(MU)); } diff --git a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index 88559f822e5d..75865920c741 100644 --- a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -1,9 +1,8 @@ //===- ExecutionUtils.h - Utilities for executing code in Orc ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -98,7 +97,14 @@ class LegacyCtorDtorRunner { public: /// Construct a CtorDtorRunner for the given range using the given /// name mangling function. - LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames, VModuleKey K) + LLVM_ATTRIBUTE_DEPRECATED( + LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames, + VModuleKey K), + "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. " + "Please use the ORCv2 CtorDtorRunner utility instead"); + + LegacyCtorDtorRunner(ORCv1DeprecationAcknowledgement, + std::vector<std::string> CtorDtorNames, VModuleKey K) : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} /// Run the recorded constructors/destructors through the given JIT @@ -129,6 +135,11 @@ private: orc::VModuleKey K; }; +template <typename JITLayerT> +LegacyCtorDtorRunner<JITLayerT>::LegacyCtorDtorRunner( + std::vector<std::string> CtorDtorNames, VModuleKey K) + : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} + class CtorDtorRunner { public: CtorDtorRunner(JITDylib &JD) : JD(JD) {} @@ -181,7 +192,14 @@ class LegacyLocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase { public: /// Create a runtime-overrides class. template <typename MangleFtorT> - LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle) { + LLVM_ATTRIBUTE_DEPRECATED( + LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle), + "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. " + "Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"); + + template <typename MangleFtorT> + LegacyLocalCXXRuntimeOverrides(ORCv1DeprecationAcknowledgement, + const MangleFtorT &Mangle) { addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride)); addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride)); } @@ -202,6 +220,13 @@ private: StringMap<JITTargetAddress> CXXRuntimeOverrides; }; +template <typename MangleFtorT> +LegacyLocalCXXRuntimeOverrides::LegacyLocalCXXRuntimeOverrides( + const MangleFtorT &Mangle) { + addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride)); + addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride)); +} + class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase { public: Error enable(JITDylib &JD, MangleAndInterner &Mangler); @@ -218,28 +243,29 @@ public: /// Create a DynamicLibrarySearchGenerator that searches for symbols in the /// given sys::DynamicLibrary. + /// /// If the Allow predicate is given then only symbols matching the predicate - /// will be searched for in the DynamicLibrary. If the predicate is not given - /// then all symbols will be searched for. - DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, const DataLayout &DL, + /// will be searched for. If the predicate is not given then all symbols will + /// be searched for. + DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow = SymbolPredicate()); /// Permanently loads the library at the given path and, on success, returns /// a DynamicLibrarySearchGenerator that will search it for symbol definitions /// in the library. On failure returns the reason the library failed to load. static Expected<DynamicLibrarySearchGenerator> - Load(const char *FileName, const DataLayout &DL, + Load(const char *FileName, char GlobalPrefix, SymbolPredicate Allow = SymbolPredicate()); /// Creates a DynamicLibrarySearchGenerator that searches for symbols in /// the current process. static Expected<DynamicLibrarySearchGenerator> - GetForCurrentProcess(const DataLayout &DL, + GetForCurrentProcess(char GlobalPrefix, SymbolPredicate Allow = SymbolPredicate()) { - return Load(nullptr, DL, std::move(Allow)); + return Load(nullptr, GlobalPrefix, std::move(Allow)); } - SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names); + Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names); private: sys::DynamicLibrary Dylib; diff --git a/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h index a8a88d7cb2d2..a4e43d4e1c9c 100644 --- a/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h @@ -1,9 +1,8 @@ //===- GlobalMappingLayer.h - Run all IR through a functor ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index 30d71e69cd70..52223a83ad42 100644 --- a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -1,9 +1,8 @@ //===- IRCompileLayer.h -- Eagerly compile IR for JIT -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -64,8 +63,18 @@ public: /// Construct an LegacyIRCompileLayer with the given BaseLayer, which must /// implement the ObjectLayer concept. + LLVM_ATTRIBUTE_DEPRECATED( + LegacyIRCompileLayer( + BaseLayerT &BaseLayer, CompileFtor Compile, + NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()), + "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " + "use " + "the ORCv2 IRCompileLayer instead"); + + /// Legacy layer constructor with deprecation acknowledgement. LegacyIRCompileLayer( - BaseLayerT &BaseLayer, CompileFtor Compile, + ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer, + CompileFtor Compile, NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()) : BaseLayer(BaseLayer), Compile(std::move(Compile)), NotifyCompiled(std::move(NotifyCompiled)) {} @@ -123,8 +132,14 @@ private: NotifyCompiledCallback NotifyCompiled; }; -} // end namespace orc +template <typename BaseLayerT, typename CompileFtor> +LegacyIRCompileLayer<BaseLayerT, CompileFtor>::LegacyIRCompileLayer( + BaseLayerT &BaseLayer, CompileFtor Compile, + NotifyCompiledCallback NotifyCompiled) + : BaseLayer(BaseLayer), Compile(std::move(Compile)), + NotifyCompiled(std::move(NotifyCompiled)) {} +} // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 49e65b9f2a80..1b4c8b6cd95f 100644 --- a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -1,9 +1,8 @@ //===- IRTransformLayer.h - Run all IR through a functor --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -57,9 +56,17 @@ class LegacyIRTransformLayer { public: /// Construct an LegacyIRTransformLayer with the given BaseLayer - LegacyIRTransformLayer(BaseLayerT &BaseLayer, - TransformFtor Transform = TransformFtor()) - : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} + LLVM_ATTRIBUTE_DEPRECATED( + LegacyIRTransformLayer(BaseLayerT &BaseLayer, + TransformFtor Transform = TransformFtor()), + "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " + "use " + "the ORCv2 IRTransformLayer instead"); + + /// Legacy layer constructor with deprecation acknowledgement. + LegacyIRTransformLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer, + TransformFtor Transform = TransformFtor()) + : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} /// Apply the transform functor to the module, then add the module to /// the layer below, along with the memory manager and symbol resolver. @@ -109,6 +116,11 @@ private: TransformFtor Transform; }; +template <typename BaseLayerT, typename TransformFtor> +LegacyIRTransformLayer<BaseLayerT, TransformFtor>::LegacyIRTransformLayer( + BaseLayerT &BaseLayer, TransformFtor Transform) + : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} + } // end namespace orc } // end namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index c2527802f6a7..a7ed5372d1e4 100644 --- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -1,9 +1,8 @@ //===- IndirectionUtils.h - Utilities for adding indirections ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -147,13 +146,13 @@ private: std::error_code EC; auto TrampolineBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( - sys::Process::getPageSize(), nullptr, + sys::Process::getPageSizeEstimate(), nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); if (EC) return errorCodeToError(EC); unsigned NumTrampolines = - (sys::Process::getPageSize() - ORCABI::PointerSize) / + (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) / ORCABI::TrampolineSize; uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base()); diff --git a/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h b/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h index eb9b6bf2dea6..bcbd72e68f15 100644 --- a/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h +++ b/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h @@ -1,9 +1,8 @@ //===- JITTargetMachineBuilder.h - Build TargetMachines for JIT -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/LLJIT.h b/include/llvm/ExecutionEngine/Orc/LLJIT.h index ce3e5d519c73..0aac1916423f 100644 --- a/include/llvm/ExecutionEngine/Orc/LLJIT.h +++ b/include/llvm/ExecutionEngine/Orc/LLJIT.h @@ -1,9 +1,8 @@ //===----- LLJIT.h -- An ORC-based JIT for compiling LLVM IR ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for 3Bdetails. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -21,35 +20,49 @@ #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" #include "llvm/Support/ThreadPool.h" namespace llvm { namespace orc { +class LLJITBuilderState; +class LLLazyJITBuilderState; + /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT. +/// +/// Create instances using LLJITBuilder. class LLJIT { + template <typename, typename, typename> friend class LLJITBuilderSetters; + public: + static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S); /// Destruct this instance. If a multi-threaded instance, waits for all /// compile threads to complete. ~LLJIT(); - /// Create an LLJIT instance. - /// If NumCompileThreads is not equal to zero, creates a multi-threaded - /// LLJIT with the given number of compile threads. - static Expected<std::unique_ptr<LLJIT>> - Create(JITTargetMachineBuilder JTMB, DataLayout DL, - unsigned NumCompileThreads = 0); - /// Returns the ExecutionSession for this instance. ExecutionSession &getExecutionSession() { return *ES; } + /// Returns a reference to the DataLayout for this instance. + const DataLayout &getDataLayout() const { return DL; } + /// Returns a reference to the JITDylib representing the JIT'd main program. JITDylib &getMainJITDylib() { return Main; } + /// Returns the JITDylib with the given name, or nullptr if no JITDylib with + /// that name exists. + JITDylib *getJITDylibByName(StringRef Name) { + return ES->getJITDylibByName(Name); + } + /// Create a new JITDylib with the given name and return a reference to it. + /// + /// JITDylib names must be unique. If the given name is derived from user + /// input or elsewhere in the environment then the client should check + /// (e.g. by calling getJITDylibByName) that the given name is not already in + /// use. JITDylib &createJITDylib(std::string Name) { return ES->createJITDylib(std::move(Name)); } @@ -57,8 +70,6 @@ public: /// Convenience method for defining an absolute symbol. Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address); - /// Convenience method for defining an - /// Adds an IR module to the given JITDylib. Error addIRModule(JITDylib &JD, ThreadSafeModule TSM); @@ -104,17 +115,17 @@ public: Error runDestructors() { return DtorRunner.run(); } /// Returns a reference to the ObjLinkingLayer - RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; } + ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; } protected: + static std::unique_ptr<ObjectLayer> + createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES); - /// Create an LLJIT instance with a single compile thread. - LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM, - DataLayout DL); + static Expected<IRCompileLayer::CompileFunction> + createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB); - /// Create an LLJIT instance with multiple compile threads. - LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, - DataLayout DL, unsigned NumCompileThreads); + /// Create an LLJIT instance with a single compile thread. + LLJIT(LLJITBuilderState &S, Error &Err); std::string mangle(StringRef UnmangledName); @@ -128,8 +139,8 @@ protected: DataLayout DL; std::unique_ptr<ThreadPool> CompileThreads; - RTDyldObjectLinkingLayer ObjLinkingLayer; - IRCompileLayer CompileLayer; + std::unique_ptr<ObjectLayer> ObjLinkingLayer; + std::unique_ptr<IRCompileLayer> CompileLayer; CtorDtorRunner CtorRunner, DtorRunner; }; @@ -137,25 +148,20 @@ protected: /// An extended version of LLJIT that supports lazy function-at-a-time /// compilation of LLVM IR. class LLLazyJIT : public LLJIT { -public: + template <typename, typename, typename> friend class LLJITBuilderSetters; - /// Create an LLLazyJIT instance. - /// If NumCompileThreads is not equal to zero, creates a multi-threaded - /// LLLazyJIT with the given number of compile threads. - static Expected<std::unique_ptr<LLLazyJIT>> - Create(JITTargetMachineBuilder JTMB, DataLayout DL, - JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0); +public: /// Set an IR transform (e.g. pass manager pipeline) to run on each function /// when it is compiled. void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) { - TransformLayer.setTransform(std::move(Transform)); + TransformLayer->setTransform(std::move(Transform)); } /// Sets the partition function. void setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) { - CODLayer.setPartitionFunction(std::move(Partition)); + CODLayer->setPartitionFunction(std::move(Partition)); } /// Add a module to be lazily compiled to JITDylib JD. @@ -169,24 +175,160 @@ public: private: // Create a single-threaded LLLazyJIT instance. - 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); + LLLazyJIT(LLLazyJITBuilderState &S, Error &Err); + + std::unique_ptr<LazyCallThroughManager> LCTMgr; + std::unique_ptr<IRTransformLayer> TransformLayer; + std::unique_ptr<CompileOnDemandLayer> CODLayer; +}; + +class LLJITBuilderState { +public: + using ObjectLinkingLayerCreator = + std::function<std::unique_ptr<ObjectLayer>(ExecutionSession &)>; + + using CompileFunctionCreator = + std::function<Expected<IRCompileLayer::CompileFunction>( + JITTargetMachineBuilder JTMB)>; + + std::unique_ptr<ExecutionSession> ES; + Optional<JITTargetMachineBuilder> JTMB; + ObjectLinkingLayerCreator CreateObjectLinkingLayer; + CompileFunctionCreator CreateCompileFunction; + unsigned NumCompileThreads = 0; - // Create a multi-threaded LLLazyJIT instance. - LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, - DataLayout DL, unsigned NumCompileThreads, - std::unique_ptr<LazyCallThroughManager> LCTMgr, - std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder); + /// Called prior to JIT class construcion to fix up defaults. + Error prepareForConstruction(); +}; + +template <typename JITType, typename SetterImpl, typename State> +class LLJITBuilderSetters { +public: + /// Set the JITTargetMachineBuilder for this instance. + /// + /// If this method is not called, JITTargetMachineBuilder::detectHost will be + /// used to construct a default target machine builder for the host platform. + SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) { + impl().JTMB = std::move(JTMB); + return impl(); + } + + /// Return a reference to the JITTargetMachineBuilder. + /// + Optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() { + return impl().JTMB; + } + /// Set an ObjectLinkingLayer creation function. + /// + /// If this method is not called, a default creation function will be used + /// that will construct an RTDyldObjectLinkingLayer. + SetterImpl &setObjectLinkingLayerCreator( + LLJITBuilderState::ObjectLinkingLayerCreator CreateObjectLinkingLayer) { + impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer); + return impl(); + } + + /// Set a CompileFunctionCreator. + /// + /// If this method is not called, a default creation function wil be used + /// that will construct a basic IR compile function that is compatible with + /// the selected number of threads (SimpleCompiler for '0' compile threads, + /// ConcurrentIRCompiler otherwise). + SetterImpl &setCompileFunctionCreator( + LLJITBuilderState::CompileFunctionCreator CreateCompileFunction) { + impl().CreateCompileFunction = std::move(CreateCompileFunction); + return impl(); + } + + /// Set the number of compile threads to use. + /// + /// If set to zero, compilation will be performed on the execution thread when + /// JITing in-process. If set to any other number N, a thread pool of N + /// threads will be created for compilation. + /// + /// If this method is not called, behavior will be as if it were called with + /// a zero argument. + SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) { + impl().NumCompileThreads = NumCompileThreads; + return impl(); + } + + /// Create an instance of the JIT. + Expected<std::unique_ptr<JITType>> create() { + if (auto Err = impl().prepareForConstruction()) + return std::move(Err); + + Error Err = Error::success(); + std::unique_ptr<JITType> J(new JITType(impl(), Err)); + if (Err) + return std::move(Err); + return std::move(J); + } + +protected: + SetterImpl &impl() { return static_cast<SetterImpl &>(*this); } +}; + +/// Constructs LLJIT instances. +class LLJITBuilder + : public LLJITBuilderState, + public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {}; + +class LLLazyJITBuilderState : public LLJITBuilderState { + friend class LLLazyJIT; + +public: + using IndirectStubsManagerBuilderFunction = + std::function<std::unique_ptr<IndirectStubsManager>()>; + + Triple TT; + JITTargetAddress LazyCompileFailureAddr = 0; std::unique_ptr<LazyCallThroughManager> LCTMgr; - std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder; + IndirectStubsManagerBuilderFunction ISMBuilder; + + Error prepareForConstruction(); +}; + +template <typename JITType, typename SetterImpl, typename State> +class LLLazyJITBuilderSetters + : public LLJITBuilderSetters<JITType, SetterImpl, State> { +public: + /// Set the address in the target address to call if a lazy compile fails. + /// + /// If this method is not called then the value will default to 0. + SetterImpl &setLazyCompileFailureAddr(JITTargetAddress Addr) { + this->impl().LazyCompileFailureAddr = Addr; + return this->impl(); + } + + /// Set the lazy-callthrough manager. + /// + /// If this method is not called then a default, in-process lazy callthrough + /// manager for the host platform will be used. + SetterImpl & + setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) { + this->impl().LCTMgr = std::move(LCTMgr); + return this->impl(); + } - IRTransformLayer TransformLayer; - CompileOnDemandLayer CODLayer; + /// Set the IndirectStubsManager builder function. + /// + /// If this method is not called then a default, in-process + /// IndirectStubsManager builder for the host platform will be used. + SetterImpl &setIndirectStubsManagerBuilder( + LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) { + this->impl().ISMBuilder = std::move(ISMBuilder); + return this->impl(); + } }; +/// Constructs LLLazyJIT instances. +class LLLazyJITBuilder + : public LLLazyJITBuilderState, + public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder, + LLLazyJITBuilderState> {}; + } // End namespace orc } // End namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/include/llvm/ExecutionEngine/Orc/LambdaResolver.h index 7b6f3d2f92ab..855e31b33549 100644 --- a/include/llvm/ExecutionEngine/Orc/LambdaResolver.h +++ b/include/llvm/ExecutionEngine/Orc/LambdaResolver.h @@ -1,9 +1,8 @@ //===- LambdaResolverMM - Redirect symbol lookup via a functor --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -25,7 +24,15 @@ namespace orc { template <typename DylibLookupFtorT, typename ExternalLookupFtorT> class LambdaResolver : public LegacyJITSymbolResolver { public: - LambdaResolver(DylibLookupFtorT DylibLookupFtor, + LLVM_ATTRIBUTE_DEPRECATED( + LambdaResolver(DylibLookupFtorT DylibLookupFtor, + ExternalLookupFtorT ExternalLookupFtor), + "ORCv1 utilities (including resolvers) are deprecated and will be " + "removed " + "in the next release. Please use ORCv2 (see docs/ORCv2.rst)"); + + LambdaResolver(ORCv1DeprecationAcknowledgement, + DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor) : DylibLookupFtor(DylibLookupFtor), ExternalLookupFtor(ExternalLookupFtor) {} @@ -43,6 +50,12 @@ private: ExternalLookupFtorT ExternalLookupFtor; }; +template <typename DylibLookupFtorT, typename ExternalLookupFtorT> +LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>::LambdaResolver( + DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor) + : DylibLookupFtor(DylibLookupFtor), ExternalLookupFtor(ExternalLookupFtor) { +} + template <typename DylibLookupFtorT, typename ExternalLookupFtorT> std::shared_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>> @@ -53,6 +66,17 @@ createLambdaResolver(DylibLookupFtorT DylibLookupFtor, std::move(ExternalLookupFtor)); } +template <typename DylibLookupFtorT, typename ExternalLookupFtorT> +std::shared_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>> +createLambdaResolver(ORCv1DeprecationAcknowledgement, + DylibLookupFtorT DylibLookupFtor, + ExternalLookupFtorT ExternalLookupFtor) { + using LR = LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>; + return make_unique<LR>(AcknowledgeORCv1Deprecation, + std::move(DylibLookupFtor), + std::move(ExternalLookupFtor)); +} + } // end namespace orc } // end namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/Layer.h b/include/llvm/ExecutionEngine/Orc/Layer.h index cd797445a2e6..8f9bd704395e 100644 --- a/include/llvm/ExecutionEngine/Orc/Layer.h +++ b/include/llvm/ExecutionEngine/Orc/Layer.h @@ -1,9 +1,8 @@ //===---------------- Layer.h -- Layer interfaces --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 46761b0ca7e1..16202d89f861 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -1,9 +1,8 @@ //===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -35,8 +34,8 @@ namespace orc { /// Lazy-emitting IR layer. /// -/// This layer accepts LLVM IR Modules (via addModule), but does not -/// immediately emit them the layer below. Instead, emissing to the base layer +/// This layer accepts LLVM IR Modules (via addModule) but does not +/// immediately emit them the layer below. Instead, emission to the base layer /// is deferred until the first time the client requests the address (via /// JITSymbol::getAddress) for a symbol contained in this layer. template <typename BaseLayerT> class LazyEmittingLayer { @@ -197,7 +196,14 @@ private: public: /// Construct a lazy emitting layer. - LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} + LLVM_ATTRIBUTE_DEPRECATED( + LazyEmittingLayer(BaseLayerT &BaseLayer), + "ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use " + "ORCv2, where lazy emission is the default"); + + /// Construct a lazy emitting layer. + LazyEmittingLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer) + : BaseLayer(BaseLayer) {} /// Add the given module to the lazy emitting layer. Error addModule(VModuleKey K, std::unique_ptr<Module> M) { @@ -255,6 +261,10 @@ public: } }; +template <typename BaseLayerT> +LazyEmittingLayer<BaseLayerT>::LazyEmittingLayer(BaseLayerT &BaseLayer) + : BaseLayer(BaseLayer) {} + } // end namespace orc } // end namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/include/llvm/ExecutionEngine/Orc/LazyReexports.h index b5041325bce2..9fdd1d15f782 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyReexports.h +++ b/include/llvm/ExecutionEngine/Orc/LazyReexports.h @@ -1,9 +1,8 @@ //===------ LazyReexports.h -- Utilities for lazy reexports -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/Legacy.h b/include/llvm/ExecutionEngine/Orc/Legacy.h index 4c6162ac4b8b..f9cbbf6ff180 100644 --- a/include/llvm/ExecutionEngine/Orc/Legacy.h +++ b/include/llvm/ExecutionEngine/Orc/Legacy.h @@ -1,9 +1,8 @@ //===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -149,8 +148,8 @@ lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, for (auto &S : Symbols) { if (JITSymbol Sym = FindSymbol(*S)) { if (auto Addr = Sym.getAddress()) { - Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - Query.notifySymbolReady(); + Query.notifySymbolMetRequiredState( + S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); NewSymbolsResolved = true; } else { ES.legacyFailQuery(Query, Addr.takeError()); @@ -163,11 +162,8 @@ lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, SymbolsNotFound.insert(S); } - if (NewSymbolsResolved && Query.isFullyResolved()) - Query.handleFullyResolved(); - - if (NewSymbolsResolved && Query.isFullyReady()) - Query.handleFullyReady(); + if (NewSymbolsResolved && Query.isComplete()) + Query.handleComplete(); return SymbolsNotFound; } diff --git a/include/llvm/ExecutionEngine/Orc/NullResolver.h b/include/llvm/ExecutionEngine/Orc/NullResolver.h index 03fefb69a928..ffa37a13d064 100644 --- a/include/llvm/ExecutionEngine/Orc/NullResolver.h +++ b/include/llvm/ExecutionEngine/Orc/NullResolver.h @@ -1,9 +1,8 @@ //===------ NullResolver.h - Reject symbol lookup requests ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h new file mode 100644 index 000000000000..c1e7d27f446e --- /dev/null +++ b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -0,0 +1,165 @@ +//===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Contains the definition for an JITLink-based, in-process object linking +// layer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H +#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/JITLink/JITLink.h" +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Layer.h" +#include "llvm/Support/Error.h" +#include <algorithm> +#include <cassert> +#include <functional> +#include <list> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +namespace llvm { + +namespace jitlink { +class EHFrameRegistrar; +} // namespace jitlink + +namespace object { +class ObjectFile; +} // namespace object + +namespace orc { + +class ObjectLinkingLayerJITLinkContext; + +/// An ObjectLayer implementation built on JITLink. +/// +/// Clients can use this class to add relocatable object files to an +/// ExecutionSession, and it typically serves as the base layer (underneath +/// a compiling layer like IRCompileLayer) for the rest of the JIT. +class ObjectLinkingLayer : public ObjectLayer { + friend class ObjectLinkingLayerJITLinkContext; + +public: + /// Plugin instances can be added to the ObjectLinkingLayer to receive + /// callbacks when code is loaded or emitted, and when JITLink is being + /// configured. + class Plugin { + public: + virtual ~Plugin(); + virtual void modifyPassConfig(MaterializationResponsibility &MR, + const Triple &TT, + jitlink::PassConfiguration &Config) {} + virtual void notifyLoaded(MaterializationResponsibility &MR) {} + virtual Error notifyEmitted(MaterializationResponsibility &MR) { + return Error::success(); + } + virtual Error notifyRemovingModule(VModuleKey K) { + return Error::success(); + } + virtual Error notifyRemovingAllModules() { return Error::success(); } + }; + + /// Construct an ObjectLinkingLayer with the given NotifyLoaded, + /// and NotifyEmitted functors. + ObjectLinkingLayer(ExecutionSession &ES, + jitlink::JITLinkMemoryManager &MemMgr); + + /// Destruct an ObjectLinkingLayer. + ~ObjectLinkingLayer(); + + /// Add a pass-config modifier. + ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) { + std::lock_guard<std::mutex> Lock(LayerMutex); + Plugins.push_back(std::move(P)); + return *this; + } + + /// Emit the object. + void emit(MaterializationResponsibility R, + std::unique_ptr<MemoryBuffer> O) override; + + /// Instructs this ObjectLinkingLayer instance to override the symbol flags + /// found in the AtomGraph with the flags supplied by the + /// MaterializationResponsibility instance. This is a workaround to support + /// symbol visibility in COFF, which does not use the libObject's + /// SF_Exported flag. Use only when generating / adding COFF object files. + /// + /// FIXME: We should be able to remove this if/when COFF properly tracks + /// exported symbols. + ObjectLinkingLayer & + setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) { + this->OverrideObjectFlags = OverrideObjectFlags; + return *this; + } + + /// If set, this ObjectLinkingLayer instance will claim responsibility + /// for any symbols provided by a given object file that were not already in + /// the MaterializationResponsibility instance. Setting this flag allows + /// higher-level program representations (e.g. LLVM IR) to be added based on + /// only a subset of the symbols they provide, without having to write + /// intervening layers to scan and add the additional symbols. This trades + /// diagnostic quality for convenience however: If all symbols are enumerated + /// up-front then clashes can be detected and reported early (and usually + /// deterministically). If this option is set, clashes for the additional + /// symbols may not be detected until late, and detection may depend on + /// the flow of control through JIT'd code. Use with care. + ObjectLinkingLayer & + setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) { + this->AutoClaimObjectSymbols = AutoClaimObjectSymbols; + return *this; + } + +private: + using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>; + + void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, + jitlink::PassConfiguration &PassConfig); + void notifyLoaded(MaterializationResponsibility &MR); + Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc); + + Error removeModule(VModuleKey K); + Error removeAllModules(); + + mutable std::mutex LayerMutex; + jitlink::JITLinkMemoryManager &MemMgr; + bool OverrideObjectFlags = false; + bool AutoClaimObjectSymbols = false; + DenseMap<VModuleKey, AllocPtr> TrackedAllocs; + std::vector<AllocPtr> UntrackedAllocs; + std::vector<std::unique_ptr<Plugin>> Plugins; +}; + +class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin { +public: + EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar); + Error notifyEmitted(MaterializationResponsibility &MR) override; + void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, + jitlink::PassConfiguration &PassConfig) override; + Error notifyRemovingModule(VModuleKey K) override; + Error notifyRemovingAllModules() override; + +private: + jitlink::EHFrameRegistrar &Registrar; + DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks; + DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs; + std::vector<JITTargetAddress> UntrackedEHFrameAddrs; +}; + +} // end namespace orc +} // end namespace llvm + +#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index 44d6b490e19d..eac1cc3e097a 100644 --- a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -1,9 +1,8 @@ //===- ObjectTransformLayer.h - Run all objects through functor -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -49,7 +48,16 @@ template <typename BaseLayerT, typename TransformFtor> class LegacyObjectTransformLayer { public: /// Construct an ObjectTransformLayer with the given BaseLayer - LegacyObjectTransformLayer(BaseLayerT &BaseLayer, + LLVM_ATTRIBUTE_DEPRECATED( + LegacyObjectTransformLayer(BaseLayerT &BaseLayer, + TransformFtor Transform = TransformFtor()), + "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " + "use " + "the ORCv2 ObjectTransformLayer instead"); + + /// Legacy layer constructor with deprecation acknowledgement. + LegacyObjectTransformLayer(ORCv1DeprecationAcknowledgement, + BaseLayerT &BaseLayer, TransformFtor Transform = TransformFtor()) : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} @@ -108,6 +116,11 @@ private: TransformFtor Transform; }; +template <typename BaseLayerT, typename TransformFtor> +LegacyObjectTransformLayer<BaseLayerT, TransformFtor>:: + LegacyObjectTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform) + : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} + } // end namespace orc } // end namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/include/llvm/ExecutionEngine/Orc/OrcABISupport.h index a70fc373713d..38246bc480b6 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcABISupport.h +++ b/include/llvm/ExecutionEngine/Orc/OrcABISupport.h @@ -1,9 +1,8 @@ //===- OrcABISupport.h - ABI support code -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/OrcError.h b/include/llvm/ExecutionEngine/Orc/OrcError.h index dc60e8d74e97..e5d6a3eca85f 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcError.h +++ b/include/llvm/ExecutionEngine/Orc/OrcError.h @@ -1,9 +1,8 @@ //===------ OrcError.h - Reject symbol lookup requests ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h index 3e07f5cf3742..8b875b7906e1 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h @@ -1,9 +1,8 @@ //===- OrcRemoteTargetClient.h - Orc Remote-target Client -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h index 8db9e317a18a..e7b598d8f812 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h @@ -1,9 +1,8 @@ //===- OrcRemoteTargetRPCAPI.h - Orc Remote-target RPC API ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h index acbc1682fa5d..4c8e2ea1a7be 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h @@ -1,9 +1,8 @@ //===- OrcRemoteTargetServer.h - Orc Remote-target Server -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -300,13 +299,13 @@ private: std::error_code EC; auto TrampolineBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( - sys::Process::getPageSize(), nullptr, + sys::Process::getPageSizeEstimate(), nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); if (EC) return errorCodeToError(EC); uint32_t NumTrampolines = - (sys::Process::getPageSize() - TargetT::PointerSize) / + (sys::Process::getPageSizeEstimate() - TargetT::PointerSize) / TargetT::TrampolineSize; uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base()); @@ -336,7 +335,7 @@ private: handleGetRemoteInfo() { std::string ProcessTriple = sys::getProcessTriple(); uint32_t PointerSize = TargetT::PointerSize; - uint32_t PageSize = sys::Process::getPageSize(); + uint32_t PageSize = sys::Process::getPageSizeEstimate(); uint32_t TrampolineSize = TargetT::TrampolineSize; uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize; LLVM_DEBUG(dbgs() << " Remote info:\n" diff --git a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h index 1e5f6ced597a..07c7471afc6a 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h +++ b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h @@ -1,9 +1,8 @@ //===- llvm/ExecutionEngine/Orc/RPCSerialization.h --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -128,123 +127,85 @@ template <typename T> class RPCTypeName<Expected<T>> { public: static const char* getName() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << "Expected<" << RPCTypeNameSequence<T>() << ">"; + return Name; + }(); return Name.data(); } - -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename T> -std::mutex RPCTypeName<Expected<T>>::NameMutex; - -template <typename T> -std::string RPCTypeName<Expected<T>>::Name; - template <typename T1, typename T2> class RPCTypeName<std::pair<T1, T2>> { public: static const char* getName() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << "std::pair<" << RPCTypeNameSequence<T1, T2>() << ">"; + return Name; + }(); return Name.data(); } -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename T1, typename T2> -std::mutex RPCTypeName<std::pair<T1, T2>>::NameMutex; -template <typename T1, typename T2> -std::string RPCTypeName<std::pair<T1, T2>>::Name; - template <typename... ArgTs> class RPCTypeName<std::tuple<ArgTs...>> { public: static const char* getName() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << "std::tuple<" << RPCTypeNameSequence<ArgTs...>() << ">"; + return Name; + }(); return Name.data(); } -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename... ArgTs> -std::mutex RPCTypeName<std::tuple<ArgTs...>>::NameMutex; -template <typename... ArgTs> -std::string RPCTypeName<std::tuple<ArgTs...>>::Name; - template <typename T> class RPCTypeName<std::vector<T>> { public: static const char*getName() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << "std::vector<" << RPCTypeName<T>::getName() << ">"; + return Name; + }(); return Name.data(); } - -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename T> -std::mutex RPCTypeName<std::vector<T>>::NameMutex; -template <typename T> -std::string RPCTypeName<std::vector<T>>::Name; - template <typename T> class RPCTypeName<std::set<T>> { public: static const char *getName() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << "std::set<" << RPCTypeName<T>::getName() << ">"; + return Name; + }(); return Name.data(); } - -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename T> std::mutex RPCTypeName<std::set<T>>::NameMutex; -template <typename T> std::string RPCTypeName<std::set<T>>::Name; - template <typename K, typename V> class RPCTypeName<std::map<K, V>> { public: static const char *getName() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << "std::map<" << RPCTypeNameSequence<K, V>() << ">"; + return Name; + }(); return Name.data(); } - -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename K, typename V> -std::mutex RPCTypeName<std::map<K, V>>::NameMutex; -template <typename K, typename V> std::string RPCTypeName<std::map<K, V>>::Name; - /// The SerializationTraits<ChannelT, T> class describes how to serialize and /// deserialize an instance of type T to/from an abstract channel of type /// ChannelT. It also provides a representation of the type's name via the diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h index 953b73e10e43..3b11e1b283de 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/include/llvm/ExecutionEngine/Orc/RPCUtils.h @@ -1,9 +1,8 @@ -//===------- RPCUTils.h - Utilities for building RPC APIs -------*- C++ -*-===// +//===- RPCUtils.h - Utilities for building RPC APIs -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -152,25 +151,17 @@ public: /// Returns the full function prototype as a string. static const char *getPrototype() { - std::lock_guard<std::mutex> Lock(NameMutex); - if (Name.empty()) + static std::string Name = [] { + std::string Name; raw_string_ostream(Name) << RPCTypeName<RetT>::getName() << " " << DerivedFunc::getName() << "(" << llvm::orc::rpc::RPCTypeNameSequence<ArgTs...>() << ")"; + return Name; + }(); return Name.data(); } - -private: - static std::mutex NameMutex; - static std::string Name; }; -template <typename DerivedFunc, typename RetT, typename... ArgTs> -std::mutex Function<DerivedFunc, RetT(ArgTs...)>::NameMutex; - -template <typename DerivedFunc, typename RetT, typename... ArgTs> -std::string Function<DerivedFunc, RetT(ArgTs...)>::Name; - /// Allocates RPC function ids during autonegotiation. /// Specializations of this class must provide four members: /// diff --git a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 6f90f0380d95..d9535ce5f21f 100644 --- a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -1,9 +1,8 @@ //===- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -44,22 +43,34 @@ public: const RuntimeDyld::LoadedObjectInfo &)>; /// Functor for receiving finalization notifications. - using NotifyEmittedFunction = std::function<void(VModuleKey)>; + using NotifyEmittedFunction = + std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>; using GetMemoryManagerFunction = std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>; /// Construct an ObjectLinkingLayer with the given NotifyLoaded, /// and NotifyEmitted functors. - RTDyldObjectLinkingLayer( - ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager, - NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(), - NotifyEmittedFunction NotifyEmitted = NotifyEmittedFunction()); + RTDyldObjectLinkingLayer(ExecutionSession &ES, + GetMemoryManagerFunction GetMemoryManager); /// Emit the object. void emit(MaterializationResponsibility R, std::unique_ptr<MemoryBuffer> O) override; + /// Set the NotifyLoaded callback. + RTDyldObjectLinkingLayer &setNotifyLoaded(NotifyLoadedFunction NotifyLoaded) { + this->NotifyLoaded = std::move(NotifyLoaded); + return *this; + } + + /// Set the NotifyEmitted callback. + RTDyldObjectLinkingLayer & + setNotifyEmitted(NotifyEmittedFunction NotifyEmitted) { + this->NotifyEmitted = std::move(NotifyEmitted); + return *this; + } + /// Set the 'ProcessAllSections' flag. /// /// If set to true, all sections in each object file will be allocated using @@ -109,7 +120,8 @@ private: std::map<StringRef, JITEvaluatedSymbol> Resolved, std::set<StringRef> &InternalSymbols); - void onObjEmit(VModuleKey K, MaterializationResponsibility &R, Error Err); + void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer, + MaterializationResponsibility &R, Error Err); mutable std::mutex RTDyldLayerMutex; GetMemoryManagerFunction GetMemoryManager; @@ -341,17 +353,27 @@ public: /// Construct an ObjectLinkingLayer with the given NotifyLoaded, /// and NotifyFinalized functors. + LLVM_ATTRIBUTE_DEPRECATED( + LegacyRTDyldObjectLinkingLayer( + ExecutionSession &ES, ResourcesGetter GetResources, + NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), + NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), + NotifyFreedFtor NotifyFreed = NotifyFreedFtor()), + "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " + "use " + "ORCv2 (see docs/ORCv2.rst)"); + + // Legacy layer constructor with deprecation acknowledgement. LegacyRTDyldObjectLinkingLayer( - ExecutionSession &ES, ResourcesGetter GetResources, + ORCv1DeprecationAcknowledgement, ExecutionSession &ES, + ResourcesGetter GetResources, NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), NotifyFreedFtor NotifyFreed = NotifyFreedFtor()) : ES(ES), GetResources(std::move(GetResources)), NotifyLoaded(std::move(NotifyLoaded)), NotifyFinalized(std::move(NotifyFinalized)), - NotifyFreed(std::move(NotifyFreed)), - ProcessAllSections(false) { - } + NotifyFreed(std::move(NotifyFreed)), ProcessAllSections(false) {} /// Set the 'ProcessAllSections' flag. /// diff --git a/include/llvm/ExecutionEngine/Orc/RawByteChannel.h b/include/llvm/ExecutionEngine/Orc/RawByteChannel.h index db810f4ef2e5..46b7c59450e6 100644 --- a/include/llvm/ExecutionEngine/Orc/RawByteChannel.h +++ b/include/llvm/ExecutionEngine/Orc/RawByteChannel.h @@ -1,9 +1,8 @@ //===- llvm/ExecutionEngine/Orc/RawByteChannel.h ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h b/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h index 955e77607a18..b87cf697a81e 100644 --- a/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h +++ b/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h @@ -1,9 +1,8 @@ //===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,9 +13,10 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H #define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include <map> namespace llvm { @@ -313,7 +313,14 @@ public: /// /// The ReportError functor can be used locally log errors that are intended /// to be sent sent - RemoteObjectClientLayer(RPCEndpoint &Remote, + LLVM_ATTRIBUTE_DEPRECATED( + RemoteObjectClientLayer(RPCEndpoint &Remote, + std::function<void(Error)> ReportError), + "ORCv1 layers (including RemoteObjectClientLayer) are deprecated. Please " + "use " + "ORCv2 (see docs/ORCv2.rst)"); + + RemoteObjectClientLayer(ORCv1DeprecationAcknowledgement, RPCEndpoint &Remote, std::function<void(Error)> ReportError) : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) { using ThisT = RemoteObjectClientLayer<RPCEndpoint>; @@ -418,11 +425,18 @@ public: /// Create a RemoteObjectServerLayer with the given base layer (which must be /// an object layer), RPC endpoint, and error reporter function. - RemoteObjectServerLayer(BaseLayerT &BaseLayer, - RPCEndpoint &Remote, + LLVM_ATTRIBUTE_DEPRECATED( + RemoteObjectServerLayer(BaseLayerT &BaseLayer, RPCEndpoint &Remote, + std::function<void(Error)> ReportError), + "ORCv1 layers (including RemoteObjectServerLayer) are deprecated. Please " + "use " + "ORCv2 (see docs/ORCv2.rst)"); + + RemoteObjectServerLayer(ORCv1DeprecationAcknowledgement, + BaseLayerT &BaseLayer, RPCEndpoint &Remote, std::function<void(Error)> ReportError) - : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)), - BaseLayer(BaseLayer), HandleIdMgr(1) { + : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)), + BaseLayer(BaseLayer), HandleIdMgr(1) { using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>; Remote.template addHandler<AddObject>(*this, &ThisT::addObject); @@ -463,6 +477,7 @@ private: assert(!BaseLayerHandles.count(Id) && "Id already in use?"); auto Resolver = createLambdaResolver( + AcknowledgeORCv1Deprecation, [this, Id](const std::string &Name) { return lookup(Id, Name); }, [this, Id](const std::string &Name) { return lookupInLogicalDylib(Id, Name); @@ -523,6 +538,31 @@ private: std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles; }; +template <typename RPCEndpoint> +RemoteObjectClientLayer<RPCEndpoint>::RemoteObjectClientLayer( + RPCEndpoint &Remote, std::function<void(Error)> ReportError) + : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) { + using ThisT = RemoteObjectClientLayer<RPCEndpoint>; + Remote.template addHandler<Lookup>(*this, &ThisT::lookup); + Remote.template addHandler<LookupInLogicalDylib>( + *this, &ThisT::lookupInLogicalDylib); +} + +template <typename BaseLayerT, typename RPCEndpoint> +RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>::RemoteObjectServerLayer( + BaseLayerT &BaseLayer, RPCEndpoint &Remote, + std::function<void(Error)> ReportError) + : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)), + BaseLayer(BaseLayer), HandleIdMgr(1) { + using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>; + + Remote.template addHandler<AddObject>(*this, &ThisT::addObject); + Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject); + Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol); + Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn); + Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize); +} + } // end namespace orc } // end namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h index 717076e25609..c354f6c3559c 100644 --- a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h +++ b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h @@ -1,9 +1,8 @@ //===- SymbolStringPool.h - Multi-threaded pool for JIT symbols -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -51,25 +50,20 @@ private: class SymbolStringPtr { friend class SymbolStringPool; friend struct DenseMapInfo<SymbolStringPtr>; - friend bool operator==(const SymbolStringPtr &LHS, - const SymbolStringPtr &RHS); - friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS); - - static SymbolStringPool::PoolMapEntry Tombstone; public: SymbolStringPtr() = default; SymbolStringPtr(const SymbolStringPtr &Other) : S(Other.S) { - if (S) + if (isRealPoolEntry(S)) ++S->getValue(); } SymbolStringPtr& operator=(const SymbolStringPtr &Other) { - if (S) + if (isRealPoolEntry(S)) --S->getValue(); S = Other.S; - if (S) + if (isRealPoolEntry(S)) ++S->getValue(); return *this; } @@ -79,7 +73,7 @@ public: } SymbolStringPtr& operator=(SymbolStringPtr &&Other) { - if (S) + if (isRealPoolEntry(S)) --S->getValue(); S = nullptr; std::swap(S, Other.S); @@ -87,34 +81,64 @@ public: } ~SymbolStringPtr() { - if (S) + if (isRealPoolEntry(S)) --S->getValue(); } StringRef operator*() const { return S->first(); } + friend bool operator==(const SymbolStringPtr &LHS, + const SymbolStringPtr &RHS) { + return LHS.S == RHS.S; + } + + friend bool operator!=(const SymbolStringPtr &LHS, + const SymbolStringPtr &RHS) { + return !(LHS == RHS); + } + + friend bool operator<(const SymbolStringPtr &LHS, + const SymbolStringPtr &RHS) { + return LHS.S < RHS.S; + } + private: + using PoolEntryPtr = SymbolStringPool::PoolMapEntry *; SymbolStringPtr(SymbolStringPool::PoolMapEntry *S) : S(S) { - if (S) + if (isRealPoolEntry(S)) ++S->getValue(); } - SymbolStringPool::PoolMapEntry *S = nullptr; -}; + // Returns false for null, empty, and tombstone values, true otherwise. + bool isRealPoolEntry(PoolEntryPtr P) { + return ((reinterpret_cast<uintptr_t>(P) - 1) & InvalidPtrMask) != + InvalidPtrMask; + } -inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) { - return LHS.S == RHS.S; -} + static SymbolStringPtr getEmptyVal() { + return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(EmptyBitPattern)); + } -inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) { - return !(LHS == RHS); -} + static SymbolStringPtr getTombstoneVal() { + return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(TombstoneBitPattern)); + } -inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) { - return LHS.S < RHS.S; -} + constexpr static uintptr_t EmptyBitPattern = + std::numeric_limits<uintptr_t>::max() + << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable; + + constexpr static uintptr_t TombstoneBitPattern = + (std::numeric_limits<uintptr_t>::max() - 1) + << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable; + + constexpr static uintptr_t InvalidPtrMask = + (std::numeric_limits<uintptr_t>::max() - 3) + << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable; + + PoolEntryPtr S = nullptr; +}; inline SymbolStringPool::~SymbolStringPool() { #ifndef NDEBUG @@ -151,16 +175,15 @@ template <> struct DenseMapInfo<orc::SymbolStringPtr> { static orc::SymbolStringPtr getEmptyKey() { - return orc::SymbolStringPtr(); + return orc::SymbolStringPtr::getEmptyVal(); } static orc::SymbolStringPtr getTombstoneKey() { - return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone); + return orc::SymbolStringPtr::getTombstoneVal(); } - static unsigned getHashValue(orc::SymbolStringPtr V) { - uintptr_t IV = reinterpret_cast<uintptr_t>(V.S); - return unsigned(IV) ^ unsigned(IV >> 9); + static unsigned getHashValue(const orc::SymbolStringPtr &V) { + return DenseMapInfo<orc::SymbolStringPtr::PoolEntryPtr>::getHashValue(V.S); } static bool isEqual(const orc::SymbolStringPtr &LHS, diff --git a/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h index bf946de532d3..5787500387c4 100644 --- a/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h +++ b/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h @@ -1,9 +1,8 @@ //===----------- ThreadSafeModule.h -- Layer interfaces ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // |