Skip to content

Commit ebe8733

Browse files
authored
[ORC] Merge MaterializationResponsibility notifyEmitted and addDependencies
Removes the MaterializationResponsibility::addDependencies and addDependenciesForAll methods, and transfers dependency registration to the notifyEmitted operation. The new dependency registration allows dependencies to be specified for arbitrary subsets of the MaterializationResponsibility's symbols (rather than just single symbols or all symbols) via an array of SymbolDependenceGroups (pairs of symbol sets and corresponding dependencies for that set). This patch aims to both improve emission performance and simplify dependence tracking. By eliminating some states (e.g. symbols having registered dependencies but not yet being resolved or emitted) we make some errors impossible by construction, and reduce the number of error cases that we need to check. NonOwningSymbolStringPtrs are used for dependence tracking under the session lock, which should reduce ref-counting operations, and intra-emit dependencies are resolved outside the session lock, which should provide better performance when JITing concurrently (since some dependence tracking can happen in parallel). The Orc C API is updated to account for this change, with the LLVMOrcMaterializationResponsibilityNotifyEmitted API being modified and the LLVMOrcMaterializationResponsibilityAddDependencies and LLVMOrcMaterializationResponsibilityAddDependenciesForAll operations being removed.
1 parent 9107904 commit ebe8733

File tree

16 files changed

+1101
-757
lines changed

16 files changed

+1101
-757
lines changed

llvm/include/llvm-c/Orc.h

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ typedef struct {
181181
*/
182182
typedef LLVMOrcCDependenceMapPair *LLVMOrcCDependenceMapPairs;
183183

184+
/**
185+
* A set of symbols that share dependencies.
186+
*/
187+
typedef struct {
188+
LLVMOrcCSymbolsList Symbols;
189+
LLVMOrcCDependenceMapPairs Dependencies;
190+
size_t NumDependencies;
191+
} LLVMOrcCSymbolDependenceGroup;
192+
184193
/**
185194
* Lookup kind. This can be used by definition generators when deciding whether
186195
* to produce a definition for a requested symbol.
@@ -808,6 +817,19 @@ LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyResolved(
808817
* that all symbols covered by this MaterializationResponsibility instance
809818
* have been emitted.
810819
*
820+
* This function takes ownership of the symbols in the Dependencies struct.
821+
* This allows the following pattern...
822+
*
823+
* LLVMOrcSymbolStringPoolEntryRef Names[] = {...};
824+
* LLVMOrcCDependenceMapPair Dependence = {JD, {Names, sizeof(Names)}}
825+
* LLVMOrcMaterializationResponsibilityAddDependencies(JD, Name, &Dependence,
826+
* 1);
827+
*
828+
* ... without requiring cleanup of the elements of the Names array afterwards.
829+
*
830+
* The client is still responsible for deleting the Dependencies.Names arrays,
831+
* and the Dependencies array itself.
832+
*
811833
* This method will return an error if any symbols being resolved have been
812834
* moved to the error state due to the failure of a dependency. If this
813835
* method returns an error then clients should log it and call
@@ -817,7 +839,8 @@ LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyResolved(
817839
* LLVMErrorSuccess.
818840
*/
819841
LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyEmitted(
820-
LLVMOrcMaterializationResponsibilityRef MR);
842+
LLVMOrcMaterializationResponsibilityRef MR,
843+
LLVMOrcCSymbolDependenceGroup *SymbolDepGroups, size_t NumSymbolDepGroups);
821844

822845
/**
823846
* Attempt to claim responsibility for new definitions. This method can be
@@ -870,38 +893,6 @@ LLVMErrorRef LLVMOrcMaterializationResponsibilityDelegate(
870893
LLVMOrcSymbolStringPoolEntryRef *Symbols, size_t NumSymbols,
871894
LLVMOrcMaterializationResponsibilityRef *Result);
872895

873-
/**
874-
* Adds dependencies to a symbol that the MaterializationResponsibility is
875-
* responsible for.
876-
*
877-
* This function takes ownership of Dependencies struct. The Names
878-
* array have been retained for this function. This allows the following
879-
* pattern...
880-
*
881-
* LLVMOrcSymbolStringPoolEntryRef Names[] = {...};
882-
* LLVMOrcCDependenceMapPair Dependence = {JD, {Names, sizeof(Names)}}
883-
* LLVMOrcMaterializationResponsibilityAddDependencies(JD, Name, &Dependence,
884-
* 1);
885-
*
886-
* ... without requiring cleanup of the elements of the Names array afterwards.
887-
*
888-
* The client is still responsible for deleting the Dependencies.Names array
889-
* itself.
890-
*/
891-
void LLVMOrcMaterializationResponsibilityAddDependencies(
892-
LLVMOrcMaterializationResponsibilityRef MR,
893-
LLVMOrcSymbolStringPoolEntryRef Name,
894-
LLVMOrcCDependenceMapPairs Dependencies, size_t NumPairs);
895-
896-
/**
897-
* Adds dependencies to all symbols that the MaterializationResponsibility is
898-
* responsible for. See LLVMOrcMaterializationResponsibilityAddDependencies for
899-
* notes about memory responsibility.
900-
*/
901-
void LLVMOrcMaterializationResponsibilityAddDependenciesForAll(
902-
LLVMOrcMaterializationResponsibilityRef MR,
903-
LLVMOrcCDependenceMapPairs Dependencies, size_t NumPairs);
904-
905896
/**
906897
* Create a "bare" JITDylib.
907898
*

llvm/include/llvm/ExecutionEngine/Orc/Core.h

Lines changed: 95 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,27 @@ class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
436436
std::shared_ptr<SymbolDependenceMap> Symbols;
437437
};
438438

439+
/// Used to report failure due to unsatisfiable symbol dependencies.
440+
class UnsatisfiedSymbolDependencies
441+
: public ErrorInfo<UnsatisfiedSymbolDependencies> {
442+
public:
443+
static char ID;
444+
445+
UnsatisfiedSymbolDependencies(std::shared_ptr<SymbolStringPool> SSP,
446+
JITDylibSP JD, SymbolNameSet FailedSymbols,
447+
SymbolDependenceMap BadDeps,
448+
std::string Explanation);
449+
std::error_code convertToErrorCode() const override;
450+
void log(raw_ostream &OS) const override;
451+
452+
private:
453+
std::shared_ptr<SymbolStringPool> SSP;
454+
JITDylibSP JD;
455+
SymbolNameSet FailedSymbols;
456+
SymbolDependenceMap BadDeps;
457+
std::string Explanation;
458+
};
459+
439460
/// Used to notify clients when symbols can not be found during a lookup.
440461
class SymbolsNotFound : public ErrorInfo<SymbolsNotFound> {
441462
public:
@@ -517,6 +538,13 @@ class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions
517538
SymbolNameVector Symbols;
518539
};
519540

541+
/// A set of symbols and the their dependencies. Used to describe dependencies
542+
/// for the MaterializationResponsibility::notifyEmitted operation.
543+
struct SymbolDependenceGroup {
544+
SymbolNameSet Symbols;
545+
SymbolDependenceMap Dependencies;
546+
};
547+
520548
/// Tracks responsibility for materialization, and mediates interactions between
521549
/// MaterializationUnits and JDs.
522550
///
@@ -587,13 +615,22 @@ class MaterializationResponsibility {
587615
/// that all symbols covered by this MaterializationResponsibility instance
588616
/// have been emitted.
589617
///
618+
/// The DepGroups array describes the dependencies of symbols being emitted on
619+
/// symbols that are outside this MaterializationResponsibility object. Each
620+
/// group consists of a pair of a set of symbols and a SymbolDependenceMap
621+
/// that describes the dependencies for the symbols in the first set. The
622+
/// elements of DepGroups must be non-overlapping (no symbol should appear in
623+
/// more than one of hte symbol sets), but do not have to be exhaustive. Any
624+
/// symbol in this MaterializationResponsibility object that is not covered
625+
/// by an entry will be treated as having no dependencies.
626+
///
590627
/// This method will return an error if any symbols being resolved have been
591628
/// moved to the error state due to the failure of a dependency. If this
592629
/// method returns an error then clients should log it and call
593630
/// failMaterialize. If no dependencies have been registered for the
594631
/// symbols covered by this MaterializationResponsibility then this method
595632
/// is guaranteed to return Error::success() and can be wrapped with cantFail.
596-
Error notifyEmitted();
633+
Error notifyEmitted(ArrayRef<SymbolDependenceGroup> DepGroups);
597634

598635
/// Attempt to claim responsibility for new definitions. This method can be
599636
/// used to claim responsibility for symbols that are added to a
@@ -628,12 +665,6 @@ class MaterializationResponsibility {
628665
Expected<std::unique_ptr<MaterializationResponsibility>>
629666
delegate(const SymbolNameSet &Symbols);
630667

631-
void addDependencies(const SymbolStringPtr &Name,
632-
const SymbolDependenceMap &Dependencies);
633-
634-
/// Add dependencies that apply to all symbols covered by this instance.
635-
void addDependenciesForAll(const SymbolDependenceMap &Dependencies);
636-
637668
private:
638669
/// Create a MaterializationResponsibility for the given JITDylib and
639670
/// initial symbols.
@@ -1185,9 +1216,29 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
11851216
using UnmaterializedInfosList =
11861217
std::vector<std::shared_ptr<UnmaterializedInfo>>;
11871218

1219+
struct EmissionDepUnit {
1220+
EmissionDepUnit(JITDylib &JD) : JD(&JD) {}
1221+
1222+
JITDylib *JD = nullptr;
1223+
DenseMap<NonOwningSymbolStringPtr, JITSymbolFlags> Symbols;
1224+
DenseMap<JITDylib *, DenseSet<NonOwningSymbolStringPtr>> Dependencies;
1225+
};
1226+
1227+
struct EmissionDepUnitInfo {
1228+
std::shared_ptr<EmissionDepUnit> EDU;
1229+
DenseSet<EmissionDepUnit *> IntraEmitUsers;
1230+
DenseMap<JITDylib *, DenseSet<NonOwningSymbolStringPtr>> NewDeps;
1231+
};
1232+
1233+
// Information about not-yet-ready symbol.
1234+
// * DefiningEDU will point to the EmissionDepUnit that defines the symbol.
1235+
// * DependantEDUs will hold pointers to any EmissionDepUnits currently
1236+
// waiting on this symbol.
1237+
// * Pending queries holds any not-yet-completed queries that include this
1238+
// symbol.
11881239
struct MaterializingInfo {
1189-
SymbolDependenceMap Dependants;
1190-
SymbolDependenceMap UnemittedDependencies;
1240+
std::shared_ptr<EmissionDepUnit> DefiningEDU;
1241+
DenseSet<EmissionDepUnit *> DependantEDUs;
11911242

11921243
void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
11931244
void removeQuery(const AsynchronousSymbolQuery &Q);
@@ -1278,17 +1329,8 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
12781329

12791330
Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved);
12801331

1281-
Error emit(MaterializationResponsibility &MR, const SymbolFlagsMap &Emitted);
1282-
12831332
void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
12841333

1285-
using FailedSymbolsWorklist =
1286-
std::vector<std::pair<JITDylib *, SymbolStringPtr>>;
1287-
1288-
static std::pair<AsynchronousSymbolQuerySet,
1289-
std::shared_ptr<SymbolDependenceMap>>
1290-
failSymbols(FailedSymbolsWorklist);
1291-
12921334
ExecutionSession &ES;
12931335
enum { Open, Closing, Closed } State = Open;
12941336
std::mutex GeneratorsMutex;
@@ -1767,19 +1809,45 @@ class ExecutionSession {
17671809
SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
17681810
Error OL_notifyResolved(MaterializationResponsibility &MR,
17691811
const SymbolMap &Symbols);
1770-
Error OL_notifyEmitted(MaterializationResponsibility &MR);
1812+
1813+
using EDUInfosMap =
1814+
DenseMap<JITDylib::EmissionDepUnit *, JITDylib::EmissionDepUnitInfo>;
1815+
1816+
template <typename HandleNewDepFn>
1817+
void propagateExtraEmitDeps(std::deque<JITDylib::EmissionDepUnit *> Worklist,
1818+
EDUInfosMap &EDUInfos,
1819+
HandleNewDepFn HandleNewDep);
1820+
EDUInfosMap simplifyDepGroups(MaterializationResponsibility &MR,
1821+
ArrayRef<SymbolDependenceGroup> EmittedDeps);
1822+
void IL_makeEDUReady(std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
1823+
JITDylib::AsynchronousSymbolQuerySet &Queries);
1824+
void IL_makeEDUEmitted(std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
1825+
JITDylib::AsynchronousSymbolQuerySet &Queries);
1826+
bool IL_removeEDUDependence(JITDylib::EmissionDepUnit &EDU, JITDylib &DepJD,
1827+
NonOwningSymbolStringPtr DepSym,
1828+
EDUInfosMap &EDUInfos);
1829+
1830+
static Error makeJDClosedError(JITDylib::EmissionDepUnit &EDU,
1831+
JITDylib &ClosedJD);
1832+
static Error makeUnsatisfiedDepsError(JITDylib::EmissionDepUnit &EDU,
1833+
JITDylib &BadJD, SymbolNameSet BadDeps);
1834+
1835+
Expected<JITDylib::AsynchronousSymbolQuerySet>
1836+
IL_emit(MaterializationResponsibility &MR, EDUInfosMap EDUInfos);
1837+
Error OL_notifyEmitted(MaterializationResponsibility &MR,
1838+
ArrayRef<SymbolDependenceGroup> EmittedDeps);
1839+
17711840
Error OL_defineMaterializing(MaterializationResponsibility &MR,
17721841
SymbolFlagsMap SymbolFlags);
1842+
1843+
std::pair<JITDylib::AsynchronousSymbolQuerySet,
1844+
std::shared_ptr<SymbolDependenceMap>>
1845+
IL_failSymbols(JITDylib &JD, const SymbolNameVector &SymbolsToFail);
17731846
void OL_notifyFailed(MaterializationResponsibility &MR);
17741847
Error OL_replace(MaterializationResponsibility &MR,
17751848
std::unique_ptr<MaterializationUnit> MU);
17761849
Expected<std::unique_ptr<MaterializationResponsibility>>
17771850
OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
1778-
void OL_addDependencies(MaterializationResponsibility &MR,
1779-
const SymbolStringPtr &Name,
1780-
const SymbolDependenceMap &Dependencies);
1781-
void OL_addDependenciesForAll(MaterializationResponsibility &MR,
1782-
const SymbolDependenceMap &Dependencies);
17831851

17841852
#ifndef NDEBUG
17851853
void dumpDispatchInfo(Task &T);
@@ -1965,8 +2033,9 @@ inline Error MaterializationResponsibility::notifyResolved(
19652033
return getExecutionSession().OL_notifyResolved(*this, Symbols);
19662034
}
19672035

1968-
inline Error MaterializationResponsibility::notifyEmitted() {
1969-
return getExecutionSession().OL_notifyEmitted(*this);
2036+
inline Error MaterializationResponsibility::notifyEmitted(
2037+
ArrayRef<SymbolDependenceGroup> EmittedDeps) {
2038+
return getExecutionSession().OL_notifyEmitted(*this, EmittedDeps);
19702039
}
19712040

19722041
inline Error MaterializationResponsibility::defineMaterializing(
@@ -1989,16 +2058,6 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
19892058
return getExecutionSession().OL_delegate(*this, Symbols);
19902059
}
19912060

1992-
inline void MaterializationResponsibility::addDependencies(
1993-
const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
1994-
getExecutionSession().OL_addDependencies(*this, Name, Dependencies);
1995-
}
1996-
1997-
inline void MaterializationResponsibility::addDependenciesForAll(
1998-
const SymbolDependenceMap &Dependencies) {
1999-
getExecutionSession().OL_addDependenciesForAll(*this, Dependencies);
2000-
}
2001-
20022061
} // End namespace orc
20032062
} // End namespace llvm
20042063

llvm/include/llvm/ExecutionEngine/Orc/DebugUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ namespace orc {
3232
/// Render a SymbolStringPtr.
3333
raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
3434

35+
/// Render a NonOwningSymbolStringPtr.
36+
raw_ostream &operator<<(raw_ostream &OS, NonOwningSymbolStringPtr Sym);
37+
3538
/// Render a SymbolNameSet.
3639
raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
3740

llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class RTDyldObjectLinkingLayer
137137
object::OwningBinary<object::ObjectFile> O,
138138
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
139139
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
140-
Error Err);
140+
std::unique_ptr<SymbolDependenceMap> Deps, Error Err);
141141

142142
Error handleRemoveResources(JITDylib &JD, ResourceKey K) override;
143143
void handleTransferResources(JITDylib &JD, ResourceKey DstKey,

0 commit comments

Comments
 (0)