Skip to content

Commit f588f2f

Browse files
authored
Merge pull request swiftlang#33650 from jckarter/global_init_mangling
Remove hardcoded symbol name parsing from SILOptimizer passes
2 parents f3cebd2 + 0bef4a6 commit f588f2f

35 files changed

+180
-93
lines changed

docs/ABI/Mangling.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ Globals
176176
global ::= global 'MJ' // noncanonical specialized generic type metadata instantiation cache associated with global
177177
global ::= global 'MN' // noncanonical specialized generic type metadata for global
178178

179+
#if SWIFT_RUNTIME_VERSION >= 5.4
180+
global ::= context (decl-name '_')+ 'WZ' // global variable one-time initialization function
181+
global ::= context (decl-name '_')+ 'Wz' // global variable one-time initialization token
182+
#endif
183+
179184
A direct symbol resolves directly to the address of an object. An
180185
indirect symbol resolves to the address of a pointer to the object.
181186
They are distinct manglings to make a certain class of bugs

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ class ASTMangler : public Mangler {
146146

147147
std::string mangleGlobalVariableFull(const VarDecl *decl);
148148

149-
std::string mangleGlobalInit(const VarDecl *decl, int counter,
149+
std::string mangleGlobalInit(const PatternBindingDecl *decl,
150+
unsigned entry,
150151
bool isInitFunc);
151152

152153
std::string mangleReabstractionThunkHelper(CanSILFunctionType ThunkType,

include/swift/Demangling/DemangleNodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ NODE(CanonicalSpecializedGenericTypeMetadataAccessFunction)
294294
NODE(MetadataInstantiationCache)
295295
NODE(NoncanonicalSpecializedGenericTypeMetadata)
296296
NODE(NoncanonicalSpecializedGenericTypeMetadataCache)
297+
NODE(GlobalVariableOnceFunction)
298+
NODE(GlobalVariableOnceToken)
299+
NODE(GlobalVariableOnceDeclList)
297300

298301
#undef CONTEXT_NODE
299302
#undef NODE

include/swift/SIL/SILFunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class SILFunction
121121
enum class Purpose : uint8_t {
122122
None,
123123
GlobalInit,
124+
GlobalInitOnceFunction,
124125
LazyPropertyGetter
125126
};
126127

@@ -832,6 +833,10 @@ class SILFunction
832833
/// function itself does not need this attribute. It is private and only
833834
/// called within the addressor.
834835
bool isGlobalInit() const { return specialPurpose == Purpose::GlobalInit; }
836+
837+
bool isGlobalInitOnceFunction() const {
838+
return specialPurpose == Purpose::GlobalInitOnceFunction;
839+
}
835840

836841
bool isLazyPropertyGetter() const {
837842
return specialPurpose == Purpose::LazyPropertyGetter;

lib/AST/ASTMangler.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -336,21 +336,29 @@ std::string ASTMangler::mangleKeyPathHashHelper(ArrayRef<CanType> indices,
336336
return finalize();
337337
}
338338

339-
std::string ASTMangler::mangleGlobalInit(const VarDecl *decl, int counter,
339+
std::string ASTMangler::mangleGlobalInit(const PatternBindingDecl *pd,
340+
unsigned pbdEntry,
340341
bool isInitFunc) {
341-
auto topLevelContext = decl->getDeclContext()->getModuleScopeContext();
342-
auto fileUnit = cast<FileUnit>(topLevelContext);
343-
Identifier discriminator = fileUnit->getDiscriminatorForPrivateValue(decl);
344-
assert(!discriminator.empty());
345-
assert(!isNonAscii(discriminator.str()) &&
346-
"discriminator contains non-ASCII characters");
347-
assert(!clang::isDigit(discriminator.str().front()) &&
348-
"not a valid identifier");
349-
350-
Buffer << "globalinit_";
351-
appendIdentifier(discriminator.str());
352-
Buffer << (isInitFunc ? "_func" : "_token");
353-
Buffer << counter;
342+
beginMangling();
343+
344+
Pattern *pattern = pd->getPattern(pbdEntry);
345+
bool first = true;
346+
pattern->forEachVariable([&](VarDecl *D) {
347+
if (first) {
348+
appendContextOf(D);
349+
first = false;
350+
}
351+
appendDeclName(D);
352+
appendListSeparator();
353+
});
354+
assert(!first && "no variables in pattern binding?!");
355+
356+
if (isInitFunc) {
357+
appendOperator("WZ");
358+
} else {
359+
appendOperator("Wz");
360+
}
361+
354362
return finalize();
355363
}
356364

lib/Demangling/Demangler.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2669,7 +2669,7 @@ NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) {
26692669
}
26702670

26712671
NodePointer Demangler::demangleWitness() {
2672-
switch (nextChar()) {
2672+
switch (char c = nextChar()) {
26732673
case 'C':
26742674
return createWithChild(Node::Kind::EnumCase,
26752675
popNode(isEntity));
@@ -2811,6 +2811,30 @@ NodePointer Demangler::demangleWitness() {
28112811
return nullptr;
28122812
}
28132813
}
2814+
case 'Z':
2815+
case 'z': {
2816+
auto declList = createNode(Node::Kind::GlobalVariableOnceDeclList);
2817+
std::vector<NodePointer> vars;
2818+
while (auto sig = popNode(Node::Kind::FirstElementMarker)) {
2819+
auto identifier = popNode(isDeclName);
2820+
if (!identifier)
2821+
return nullptr;
2822+
vars.push_back(identifier);
2823+
}
2824+
for (auto i = vars.rbegin(); i != vars.rend(); ++i) {
2825+
declList->addChild(*i, *this);
2826+
}
2827+
2828+
auto context = popContext();
2829+
if (!context)
2830+
return nullptr;
2831+
Node::Kind kind = c == 'Z'
2832+
? Node::Kind::GlobalVariableOnceFunction
2833+
: Node::Kind::GlobalVariableOnceToken;
2834+
return createWithChildren(kind,
2835+
context,
2836+
declList);
2837+
}
28142838
default:
28152839
return nullptr;
28162840
}

lib/Demangling/NodePrinter.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,9 @@ class NodePrinter {
552552
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
553553
case Node::Kind::NoncanonicalSpecializedGenericTypeMetadata:
554554
case Node::Kind::NoncanonicalSpecializedGenericTypeMetadataCache:
555+
case Node::Kind::GlobalVariableOnceDeclList:
556+
case Node::Kind::GlobalVariableOnceFunction:
557+
case Node::Kind::GlobalVariableOnceToken:
555558
return false;
556559
}
557560
printer_unreachable("bad node kind");
@@ -2466,6 +2469,28 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
24662469
Printer << "cache variable for noncanonical specialized generic type metadata for ";
24672470
print(Node->getChild(0));
24682471
return nullptr;
2472+
case Node::Kind::GlobalVariableOnceToken:
2473+
case Node::Kind::GlobalVariableOnceFunction:
2474+
Printer << (kind == Node::Kind::GlobalVariableOnceToken
2475+
? "one-time initialization token for "
2476+
: "one-time initialization function for ");
2477+
printContext(Node->getChild(0));
2478+
print(Node->getChild(1));
2479+
return nullptr;
2480+
case Node::Kind::GlobalVariableOnceDeclList:
2481+
if (Node->getNumChildren() == 1) {
2482+
print(Node->getChild(0));
2483+
} else {
2484+
Printer << '(';
2485+
for (unsigned i = 0, e = Node->getNumChildren(); i < e; ++i) {
2486+
if (i != 0) {
2487+
Printer << ", ";
2488+
}
2489+
print(Node->getChild(i));
2490+
}
2491+
Printer << ')';
2492+
}
2493+
return nullptr;
24692494
}
24702495
printer_unreachable("bad node kind!");
24712496
}

lib/Demangling/OldRemangler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,6 +2139,15 @@ void Remangler::mangleAccessorFunctionReference(Node *node) {
21392139
void Remangler::mangleMetadataInstantiationCache(Node *node) {
21402140
unreachable("unsupported");
21412141
}
2142+
void Remangler::mangleGlobalVariableOnceToken(Node *node) {
2143+
unreachable("unsupported");
2144+
}
2145+
void Remangler::mangleGlobalVariableOnceFunction(Node *node) {
2146+
unreachable("unsupported");
2147+
}
2148+
void Remangler::mangleGlobalVariableOnceDeclList(Node *node) {
2149+
unreachable("unsupported");
2150+
}
21422151

21432152
void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) {
21442153
Buffer << "MM";

lib/Demangling/Remangler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,6 +2566,23 @@ void Remangler::mangleNoncanonicalSpecializedGenericTypeMetadataCache(Node *node
25662566
Buffer << "MJ";
25672567
}
25682568

2569+
void Remangler::mangleGlobalVariableOnceToken(Node *node) {
2570+
mangleChildNodes(node);
2571+
Buffer << "Wz";
2572+
}
2573+
2574+
void Remangler::mangleGlobalVariableOnceFunction(Node *node) {
2575+
mangleChildNodes(node);
2576+
Buffer << "WZ";
2577+
}
2578+
2579+
void Remangler::mangleGlobalVariableOnceDeclList(Node *node) {
2580+
for (unsigned i = 0, e = node->getNumChildren(); i < e; ++i) {
2581+
mangle(node->getChild(i));
2582+
Buffer << '_';
2583+
}
2584+
}
2585+
25692586
} // anonymous namespace
25702587

25712588
/// The top-level interface to the remangler.

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ SILFunction *swift::findInitializer(SILFunction *AddrF,
272272
if (!CallToOnce)
273273
return nullptr;
274274
SILFunction *callee = getCalleeOfOnceCall(CallToOnce);
275-
if (!callee->getName().startswith("globalinit_"))
275+
if (!callee->isGlobalInitOnceFunction())
276276
return nullptr;
277277
return callee;
278278
}

0 commit comments

Comments
 (0)