aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine/Orc/Core.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /include/llvm/ExecutionEngine/Orc/Core.h
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/Core.h')
-rw-r--r--include/llvm/ExecutionEngine/Orc/Core.h228
1 files changed, 145 insertions, 83 deletions
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));
}