[ORC][JITLink] Add jitlink::Scope::SideEffectsOnly, use it in ORC Platforms.

SideEffectsOnly is a new jitlink::Scope value that corresponds to the
JITSymbolFlags::MaterializationSideEffectsOnly flag: Symbols with this scope
can be looked up (and form part of the initial interface of a LinkGraph) but
never actually resolve to an address (so can only be looked up with a
WeaklyReferencedSymbol lookup).

Previously ObjectLinkingLayer implicitly treated JITLink symbols as having this
scope, regardless of a Symbol's actual scope, if the
MaterializationSideEffectsOnly flag was set on the corresponding symbol in the
MaterializationResponsibility object. Using an explicit scope in JITLink for
this (1) allows JITLink plugins to identify and correctly handle
side-effects-only symbols, and (2) allows raw LinkGraphs to define
side-effects-only symbols without clients having to manually modify their
`MaterializationUnit::Interface`.
This commit is contained in:
Lang Hames
2024-12-03 15:30:24 +11:00
parent 6ef4990daa
commit aba6bb0820
5 changed files with 14 additions and 11 deletions

View File

@@ -393,10 +393,13 @@ const char *getLinkageName(Linkage L);
/// Defines the scope in which this symbol should be visible:
/// Default -- Visible in the public interface of the linkage unit.
/// Hidden -- Visible within the linkage unit, but not exported from it.
/// SideEffectsOnly -- Like hidden, but symbol can only be looked up once
/// to trigger materialization of the containing graph.
/// Local -- Visible only within the LinkGraph.
enum class Scope : uint8_t {
Default,
Hidden,
SideEffectsOnly,
Local
};

View File

@@ -76,7 +76,7 @@ public:
// Init symbol is __ImageBase symbol.
auto &ImageBaseSymbol = G->addDefinedSymbol(
HeaderBlock, 0, *R->getInitializerSymbol(), HeaderBlock.getSize(),
jitlink::Linkage::Strong, jitlink::Scope::Default, false, true);
jitlink::Linkage::Strong, jitlink::Scope::SideEffectsOnly, false, true);
addImageBaseRelocationEdge(HeaderBlock, ImageBaseSymbol);

View File

@@ -197,7 +197,7 @@ public:
8, 0);
auto &DSOHandleSymbol = G->addDefinedSymbol(
DSOHandleBlock, 0, *R->getInitializerSymbol(), DSOHandleBlock.getSize(),
jitlink::Linkage::Strong, jitlink::Scope::Default, false, true);
jitlink::Linkage::Strong, jitlink::Scope::SideEffectsOnly, false, true);
DSOHandleBlock.addEdge(EdgeKind, 0, DSOHandleSymbol, 0);
ENP.getObjectLinkingLayer().emit(std::move(R), std::move(G));

View File

@@ -1001,9 +1001,9 @@ Error MachOPlatform::MachOPlatformPlugin::preserveImportantSections(
// to the first block.
if (!InitSym) {
auto &B = **InitSection->blocks().begin();
InitSym = &G.addDefinedSymbol(B, 0, *InitSymName, B.getSize(),
jitlink::Linkage::Strong,
jitlink::Scope::Default, false, true);
InitSym = &G.addDefinedSymbol(
B, 0, *InitSymName, B.getSize(), jitlink::Linkage::Strong,
jitlink::Scope::SideEffectsOnly, false, true);
}
// Add keep-alive edges to anonymous symbols in all other init blocks.

View File

@@ -65,6 +65,8 @@ JITSymbolFlags getJITSymbolFlagsForSymbol(Symbol &Sym) {
if (Sym.getScope() == Scope::Default)
Flags |= JITSymbolFlags::Exported;
else if (Sym.getScope() == Scope::SideEffectsOnly)
Flags |= JITSymbolFlags::MaterializationSideEffectsOnly;
if (Sym.isCallable())
Flags |= JITSymbolFlags::Callable;
@@ -236,7 +238,7 @@ public:
SymbolMap InternedResult;
for (auto *Sym : G.defined_symbols())
if (Sym->getScope() != Scope::Local) {
if (Sym->getScope() < Scope::SideEffectsOnly) {
auto InternedName = ES.intern(Sym->getName());
auto Ptr = getJITSymbolPtrForSymbol(*Sym, G.getTargetTriple());
auto Flags = getJITSymbolFlagsForSymbol(*Sym);
@@ -249,7 +251,7 @@ public:
}
for (auto *Sym : G.absolute_symbols())
if (Sym->getScope() != Scope::Local) {
if (Sym->getScope() < Scope::SideEffectsOnly) {
auto InternedName = ES.intern(Sym->getName());
auto Ptr = getJITSymbolPtrForSymbol(*Sym, G.getTargetTriple());
auto Flags = getJITSymbolFlagsForSymbol(*Sym);
@@ -281,11 +283,9 @@ public:
// If this is a materialization-side-effects only symbol then bump
// the counter and remove in from the result, otherwise make sure that
// it's defined.
if (Flags.hasMaterializationSideEffectsOnly()) {
if (Flags.hasMaterializationSideEffectsOnly())
++NumMaterializationSideEffectsOnlySymbols;
InternedResult.erase(Sym);
continue;
} else if (I == InternedResult.end())
else if (I == InternedResult.end())
MissingSymbols.push_back(Sym);
else if (Layer.OverrideObjectFlags)
I->second.setFlags(Flags);