Skip to content

Commit 3705ff3

Browse files
committed
[ORC] Replace ORC's baked-in dependence tracking with WaitingOnGraph.
WaitingOnGraph tracks waiting-on relationships between nodes (intended to represent symbols in an ORC program) in order to identify nodes that are *Ready* (i.e. are not waiting on any other nodes) or have *Failed* (are waiting on some node that cannot be produced). WaitingOnGraph replaces ORC's baked-in data structures that were tracking the same information (EmissionDepUnit, EmissionDepUnitInfo, ...). Isolating this information in a separate data structure simplifies the code, allows us to unit test it, and simplifies performance testing. The WaitingOnGraph uses several techniques to improve performance relative to the old data structures, including symbol coalescing ("SuperNodes") and symbol keys that don't perform unnecessary reference counting (NonOwningSymbolStringPtr). This commit includes unit tests for common dependence-tracking issues that have led to ORC bugs in the past.
1 parent ca4df68 commit 3705ff3

File tree

7 files changed

+1429
-737
lines changed

7 files changed

+1429
-737
lines changed

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

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
2727
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
2828
#include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
29+
#include "llvm/ExecutionEngine/Orc/WaitingOnGraph.h"
2930
#include "llvm/Support/Compiler.h"
3031
#include "llvm/Support/Debug.h"
3132
#include "llvm/Support/ExtensibleRTTI.h"
@@ -49,6 +50,9 @@ class InProgressLookupState;
4950

5051
enum class SymbolState : uint8_t;
5152

53+
using WaitingOnGraph =
54+
detail::WaitingOnGraph<JITDylib *, NonOwningSymbolStringPtr>;
55+
5256
using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>;
5357
using JITDylibSP = IntrusiveRefCntPtr<JITDylib>;
5458

@@ -1131,20 +1135,6 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
11311135
using UnmaterializedInfosList =
11321136
std::vector<std::shared_ptr<UnmaterializedInfo>>;
11331137

1134-
struct EmissionDepUnit {
1135-
EmissionDepUnit(JITDylib &JD) : JD(&JD) {}
1136-
1137-
JITDylib *JD = nullptr;
1138-
DenseMap<NonOwningSymbolStringPtr, JITSymbolFlags> Symbols;
1139-
DenseMap<JITDylib *, DenseSet<NonOwningSymbolStringPtr>> Dependencies;
1140-
};
1141-
1142-
struct EmissionDepUnitInfo {
1143-
std::shared_ptr<EmissionDepUnit> EDU;
1144-
DenseSet<EmissionDepUnit *> IntraEmitUsers;
1145-
DenseMap<JITDylib *, DenseSet<NonOwningSymbolStringPtr>> NewDeps;
1146-
};
1147-
11481138
// Information about not-yet-ready symbol.
11491139
// * DefiningEDU will point to the EmissionDepUnit that defines the symbol.
11501140
// * DependantEDUs will hold pointers to any EmissionDepUnits currently
@@ -1154,9 +1144,6 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
11541144
struct MaterializingInfo {
11551145
friend class ExecutionSession;
11561146

1157-
std::shared_ptr<EmissionDepUnit> DefiningEDU;
1158-
DenseSet<EmissionDepUnit *> DependantEDUs;
1159-
11601147
LLVM_ABI void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
11611148
LLVM_ABI void removeQuery(const AsynchronousSymbolQuery &Q);
11621149
LLVM_ABI AsynchronousSymbolQueryList
@@ -1778,30 +1765,26 @@ class ExecutionSession {
17781765
LLVM_ABI Error OL_notifyResolved(MaterializationResponsibility &MR,
17791766
const SymbolMap &Symbols);
17801767

1781-
using EDUInfosMap =
1782-
DenseMap<JITDylib::EmissionDepUnit *, JITDylib::EmissionDepUnitInfo>;
1783-
1784-
template <typename HandleNewDepFn>
1785-
void propagateExtraEmitDeps(std::deque<JITDylib::EmissionDepUnit *> Worklist,
1786-
EDUInfosMap &EDUInfos,
1787-
HandleNewDepFn HandleNewDep);
1788-
EDUInfosMap simplifyDepGroups(MaterializationResponsibility &MR,
1789-
ArrayRef<SymbolDependenceGroup> EmittedDeps);
1790-
void IL_makeEDUReady(std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
1791-
JITDylib::AsynchronousSymbolQuerySet &Queries);
1792-
void IL_makeEDUEmitted(std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
1793-
JITDylib::AsynchronousSymbolQuerySet &Queries);
1794-
bool IL_removeEDUDependence(JITDylib::EmissionDepUnit &EDU, JITDylib &DepJD,
1795-
NonOwningSymbolStringPtr DepSym,
1796-
EDUInfosMap &EDUInfos);
1797-
1798-
static Error makeJDClosedError(JITDylib::EmissionDepUnit &EDU,
1799-
JITDylib &ClosedJD);
1800-
static Error makeUnsatisfiedDepsError(JITDylib::EmissionDepUnit &EDU,
1801-
JITDylib &BadJD, SymbolNameSet BadDeps);
1802-
1803-
Expected<JITDylib::AsynchronousSymbolQuerySet>
1804-
IL_emit(MaterializationResponsibility &MR, EDUInfosMap EDUInfos);
1768+
// FIXME: We should be able to derive FailedSymsForQuery from each query once
1769+
// we fix how the detach operation works.
1770+
struct EmitQueries {
1771+
JITDylib::AsynchronousSymbolQuerySet Updated;
1772+
JITDylib::AsynchronousSymbolQuerySet Failed;
1773+
DenseMap<AsynchronousSymbolQuery *, std::shared_ptr<SymbolDependenceMap>>
1774+
FailedSymsForQuery;
1775+
};
1776+
1777+
WaitingOnGraph::ExternalState
1778+
IL_getSymbolState(JITDylib *JD, NonOwningSymbolStringPtr Name);
1779+
1780+
template <typename UpdateSymbolFn, typename UpdateQueryFn>
1781+
void IL_collectQueries(JITDylib::AsynchronousSymbolQuerySet &Qs,
1782+
WaitingOnGraph::ContainerElementsMap &QualifiedSymbols,
1783+
UpdateSymbolFn &&UpdateSymbol,
1784+
UpdateQueryFn &&UpdateQuery);
1785+
1786+
Expected<EmitQueries> IL_emit(MaterializationResponsibility &MR,
1787+
WaitingOnGraph::SimplifyResult SR);
18051788
LLVM_ABI Error OL_notifyEmitted(MaterializationResponsibility &MR,
18061789
ArrayRef<SymbolDependenceGroup> EmittedDeps);
18071790

@@ -1830,6 +1813,7 @@ class ExecutionSession {
18301813
std::vector<ResourceManager *> ResourceManagers;
18311814

18321815
std::vector<JITDylibSP> JDs;
1816+
WaitingOnGraph G;
18331817

18341818
// FIXME: Remove this (and runOutstandingMUs) once the linking layer works
18351819
// with callbacks from asynchronous queries.

0 commit comments

Comments
 (0)