17#define DEBUG_TYPE "orc"
23constexpr StringRef ReentryFnName =
"__orc_rt_reenter";
24constexpr StringRef ReentrySectionName =
"__orc_stubs";
30 :
public ObjectLinkingLayer::Plugin {
35 Config.PreFixupPasses.push_back(
51 std::shared_ptr<std::vector<ExecutorSymbolDef>> Addrs) {
52 std::lock_guard<std::mutex> Lock(M);
53 assert(!PendingAddrs.count(&
G) &&
"Duplicate registration");
54 PendingAddrs[&
G] = std::move(Addrs);
58 std::shared_ptr<std::vector<ExecutorSymbolDef>> Addrs;
60 std::lock_guard<std::mutex> Lock(M);
61 auto I = PendingAddrs.find(&
G);
62 if (
I == PendingAddrs.end())
64 Addrs = std::move(
I->second);
65 PendingAddrs.erase(
I);
68 auto *Sec =
G.findSectionByName(ReentrySectionName);
69 assert(Sec &&
"Reentry graph missing reentry section");
70 assert(!Sec->empty() &&
"Reentry graph is empty");
72 for (
auto *
Sym : Sec->symbols())
91 switch (TT.getArch()) {
99 return make_error<StringError>(
"JITLinkReentryTrampolines: architecture " +
100 TT.getArchName() +
" not supported",
104 return std::make_unique<JITLinkReentryTrampolines>(ObjLinkingLayer,
105 std::move(EmitTrampoline));
110 : ObjLinkingLayer(ObjLinkingLayer),
111 EmitTrampoline(
std::
move(EmitTrampoline)) {
112 auto TAS = std::make_shared<TrampolineAddrScraperPlugin>();
113 TrampolineAddrScraper = TAS.get();
114 ObjLinkingLayer.
addPlugin(std::move(TAS));
118 size_t NumTrampolines,
121 if (NumTrampolines == 0)
122 return OnTrampolinesReady(std::vector<ExecutorSymbolDef>());
126 Triple TT = ES.getTargetTriple();
128 auto ReentryGraphSym =
129 ES.intern((
"__orc_reentry_graph_#" +
Twine(++ReentryGraphIdx)).str());
131 auto G = std::make_unique<jitlink::LinkGraph>(
132 (*ReentryGraphSym).str(), ES.getSymbolStringPool(), TT,
133 TT.isArch64Bit() ? 8 : 4,
137 auto &ReentryFnSym =
G->addExternalSymbol(ReentryFnName, 0,
false);
139 auto &ReentrySection =
142 for (
size_t I = 0;
I != NumTrampolines; ++
I)
143 EmitTrampoline(*
G, ReentrySection, ReentryFnSym).setLive(
true);
145 auto &FirstBlock = **ReentrySection.blocks().begin();
146 G->addDefinedSymbol(FirstBlock, 0, *ReentryGraphSym, FirstBlock.getSize(),
147 Linkage::Strong, Scope::SideEffectsOnly,
true,
true);
149 auto TrampolineAddrs = std::make_shared<std::vector<ExecutorSymbolDef>>();
153 if (
auto Err = ObjLinkingLayer.
add(std::move(RT), std::move(
G)))
154 return OnTrampolinesReady(std::move(Err));
162 [OnTrampolinesReady = std::move(OnTrampolinesReady),
166 OnTrampolinesReady(std::move(*TrampolineAddrs));
168 OnTrampolinesReady(
Result.takeError());
179 return JLT.takeError();
184 OnTrampolinesReady)
mutable {
185 JLT->emit(std::move(RT), NumTrampolines, std::move(OnTrampolinesReady));
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Flags for symbols in the JIT.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
bool hasName() const
Returns true if this symbol has a name.
const Triple & getTargetTriple() const
Return the triple for the executor.
Represents a JIT'd dynamic library.
void registerGraph(LinkGraph &G, std::shared_ptr< std::vector< ExecutorSymbolDef > > Addrs)
Error notifyFailed(MaterializationResponsibility &MR) override
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) override
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
Error recordTrampolineAddrs(LinkGraph &G)
JITLinkReentryTrampolines(ObjectLinkingLayer &ObjLinkingLayer, EmitTrampolineFn EmitTrampoline)
void emit(ResourceTrackerSP RT, size_t NumTrampolines, OnTrampolinesReadyFn OnTrampolinesReady)
static Expected< std::unique_ptr< JITLinkReentryTrampolines > > Create(ObjectLinkingLayer &ObjLinkingLayer)
Create trampolines using the default reentry trampoline function for the session triple.
static Expected< std::unique_ptr< LazyReexportsManager > > Create(EmitTrampolinesFn EmitTrampolines, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD)
Create a LazyReexportsManager that uses the ORC runtime for reentry.
ExecutionSession & getExecutionSession()
LinkGraphLinkingLayer & addPlugin(std::shared_ptr< Plugin > P)
Add a plugin.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
An ObjectLayer implementation built on JITLink.
virtual Error add(ResourceTrackerSP RT, std::unique_ptr< MemoryBuffer > O, MaterializationUnit::Interface I)
Adds a MaterializationUnit for the object file in the given memory buffer to the JITDylib for the giv...
Base class for managing redirectable symbols in which a call gets redirected to another symbol in run...
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Symbol & createAnonymousReentryTrampoline(LinkGraph &G, Section &TrampolineSection, Symbol &ReentrySymbol)
Symbol & createAnonymousReentryTrampoline(LinkGraph &G, Section &TrampolineSection, Symbol &ReentrySymbol)
const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
Expected< std::unique_ptr< LazyReexportsManager > > createJITLinkLazyReexportsManager(ObjectLinkingLayer &ObjLinkingLayer, RedirectableSymbolManager &RSMgr, JITDylib &PlatformJD)
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
@ Ready
Emitted to memory, but waiting on transitive dependencies.
This is an optimization pass for GlobalISel generic memory operations.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...