Skip to content

Commit bc119d0

Browse files
committed
SILGen: Emit inlinable keypath thunks from inlinable contexts
It's still not resilient because we emit direct references to stored properties, but its progress.
1 parent 89950fe commit bc119d0

File tree

13 files changed

+173
-95
lines changed

13 files changed

+173
-95
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,19 @@ class ASTMangler : public Mangler {
137137
std::string mangleKeyPathGetterThunkHelper(const AbstractStorageDecl *property,
138138
GenericSignature *signature,
139139
CanType baseType,
140-
ArrayRef<CanType> subs);
140+
SubstitutionMap subs,
141+
ResilienceExpansion expansion);
141142
std::string mangleKeyPathSetterThunkHelper(const AbstractStorageDecl *property,
142143
GenericSignature *signature,
143144
CanType baseType,
144-
ArrayRef<CanType> subs);
145+
SubstitutionMap subs,
146+
ResilienceExpansion expansion);
145147
std::string mangleKeyPathEqualsHelper(ArrayRef<CanType> indices,
146-
GenericSignature *signature);
148+
GenericSignature *signature,
149+
ResilienceExpansion expansion);
147150
std::string mangleKeyPathHashHelper(ArrayRef<CanType> indices,
148-
GenericSignature *signature);
151+
GenericSignature *signature,
152+
ResilienceExpansion expansion);
149153

150154
std::string mangleTypeForDebugger(Type decl, const DeclContext *DC);
151155

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ NODE(SILBoxMutableField)
183183
NODE(SILBoxImmutableField)
184184
CONTEXT_NODE(Setter)
185185
NODE(SpecializationPassID)
186-
NODE(SpecializationIsFragile)
186+
NODE(IsSerialized)
187187
CONTEXT_NODE(Static)
188188
CONTEXT_NODE(Structure)
189189
CONTEXT_NODE(Subscript)

lib/AST/ASTMangler.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ std::string ASTMangler::mangleKeyPathGetterThunkHelper(
267267
const AbstractStorageDecl *property,
268268
GenericSignature *signature,
269269
CanType baseType,
270-
ArrayRef<CanType> subs) {
270+
SubstitutionMap subs,
271+
ResilienceExpansion expansion) {
271272
beginMangling();
272273
appendEntity(property);
273274
if (signature)
@@ -276,19 +277,22 @@ std::string ASTMangler::mangleKeyPathGetterThunkHelper(
276277
if (isa<SubscriptDecl>(property)) {
277278
// Subscripts can be generic, and different key paths could capture the same
278279
// subscript at different generic arguments.
279-
for (auto &sub : subs) {
280-
appendType(sub);
280+
for (auto sub : subs.getReplacementTypes()) {
281+
appendType(sub->mapTypeOutOfContext()->getCanonicalType());
281282
}
282283
}
283284
appendOperator("TK");
285+
if (expansion == ResilienceExpansion::Minimal)
286+
appendOperator("q");
284287
return finalize();
285288
}
286289

287290
std::string ASTMangler::mangleKeyPathSetterThunkHelper(
288291
const AbstractStorageDecl *property,
289292
GenericSignature *signature,
290293
CanType baseType,
291-
ArrayRef<CanType> subs) {
294+
SubstitutionMap subs,
295+
ResilienceExpansion expansion) {
292296
beginMangling();
293297
appendEntity(property);
294298
if (signature)
@@ -297,33 +301,41 @@ std::string ASTMangler::mangleKeyPathSetterThunkHelper(
297301
if (isa<SubscriptDecl>(property)) {
298302
// Subscripts can be generic, and different key paths could capture the same
299303
// subscript at different generic arguments.
300-
for (auto &sub : subs) {
301-
appendType(sub);
304+
for (auto sub : subs.getReplacementTypes()) {
305+
appendType(sub->mapTypeOutOfContext()->getCanonicalType());
302306
}
303307
}
304308
appendOperator("Tk");
309+
if (expansion == ResilienceExpansion::Minimal)
310+
appendOperator("q");
305311
return finalize();
306312
}
307313

308314
std::string ASTMangler::mangleKeyPathEqualsHelper(ArrayRef<CanType> indices,
309-
GenericSignature *signature) {
315+
GenericSignature *signature,
316+
ResilienceExpansion expansion) {
310317
beginMangling();
311318
for (auto &index : indices)
312319
appendType(index);
313320
if (signature)
314321
appendGenericSignature(signature);
315322
appendOperator("TH");
323+
if (expansion == ResilienceExpansion::Minimal)
324+
appendOperator("q");
316325
return finalize();
317326
}
318327

319328
std::string ASTMangler::mangleKeyPathHashHelper(ArrayRef<CanType> indices,
320-
GenericSignature *signature) {
329+
GenericSignature *signature,
330+
ResilienceExpansion expansion) {
321331
beginMangling();
322332
for (auto &index : indices)
323333
appendType(index);
324334
if (signature)
325335
appendGenericSignature(signature);
326336
appendOperator("Th");
337+
if (expansion == ResilienceExpansion::Minimal)
338+
appendOperator("q");
327339
return finalize();
328340
}
329341

lib/Demangling/Demangler.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,9 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
19971997
case 'k': {
19981998
auto nodeKind = c == 'K' ? Node::Kind::KeyPathGetterThunkHelper
19991999
: Node::Kind::KeyPathSetterThunkHelper;
2000+
2001+
bool isSerialized = nextIf('q');
2002+
20002003
std::vector<NodePointer> types;
20012004
auto node = popNode();
20022005
if (!node || node->getKind() != Node::Kind::Type)
@@ -2022,6 +2025,10 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20222025
for (auto i = types.rbegin(), e = types.rend(); i != e; ++i) {
20232026
result->addChild(*i, *this);
20242027
}
2028+
2029+
if (isSerialized)
2030+
result->addChild(createNode(Node::Kind::IsSerialized), *this);
2031+
20252032
return result;
20262033
}
20272034
case 'l': {
@@ -2060,6 +2067,9 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20602067
case 'h': {
20612068
auto nodeKind = c == 'H' ? Node::Kind::KeyPathEqualsThunkHelper
20622069
: Node::Kind::KeyPathHashThunkHelper;
2070+
2071+
bool isSerialized = nextIf('q');
2072+
20632073
NodePointer genericSig = nullptr;
20642074
std::vector<NodePointer> types;
20652075

@@ -2089,6 +2099,10 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
20892099
}
20902100
if (genericSig)
20912101
result->addChild(genericSig, *this);
2102+
2103+
if (isSerialized)
2104+
result->addChild(createNode(Node::Kind::IsSerialized), *this);
2105+
20922106
return result;
20932107
}
20942108
case 'v': {
@@ -2344,15 +2358,15 @@ NodePointer Demangler::addFuncSpecParamNumber(NodePointer Param,
23442358
}
23452359

23462360
NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) {
2347-
bool isFragile = nextIf('q');
2361+
bool isSerialized = nextIf('q');
23482362

23492363
int PassID = (int)nextChar() - '0';
23502364
if (PassID < 0 || PassID > 9)
23512365
return nullptr;
23522366

23532367
NodePointer SpecNd = createNode(SpecKind);
2354-
if (isFragile)
2355-
SpecNd->addChild(createNode(Node::Kind::SpecializationIsFragile),
2368+
if (isSerialized)
2369+
SpecNd->addChild(createNode(Node::Kind::IsSerialized),
23562370
*this);
23572371

23582372
SpecNd->addChild(createNode(Node::Kind::SpecializationPassID, PassID),

lib/Demangling/NodePrinter.cpp

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ class NodePrinter {
435435
case Node::Kind::SILBoxLayout:
436436
case Node::Kind::SILBoxMutableField:
437437
case Node::Kind::SILBoxImmutableField:
438-
case Node::Kind::SpecializationIsFragile:
438+
case Node::Kind::IsSerialized:
439439
case Node::Kind::SpecializationPassID:
440440
case Node::Kind::Static:
441441
case Node::Kind::Subscript:
@@ -894,7 +894,7 @@ void NodePrinter::printSpecializationPrefix(NodePointer node,
894894
// information that is useful to our users.
895895
break;
896896

897-
case Node::Kind::SpecializationIsFragile:
897+
case Node::Kind::IsSerialized:
898898
Printer << Separator;
899899
Separator = ", ";
900900
print(node->getChild(i));
@@ -1238,8 +1238,8 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
12381238
case Node::Kind::InlinedGenericFunction:
12391239
printSpecializationPrefix(Node, "inlined generic function");
12401240
return nullptr;
1241-
case Node::Kind::SpecializationIsFragile:
1242-
Printer << "preserving fragile attribute";
1241+
case Node::Kind::IsSerialized:
1242+
Printer << "serialized";
12431243
return nullptr;
12441244
case Node::Kind::GenericSpecializationParam:
12451245
print(Node->getChild(0));
@@ -1448,25 +1448,19 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
14481448
}
14491449
return nullptr;
14501450
case Node::Kind::KeyPathGetterThunkHelper:
1451-
Printer << "key path getter for ";
1452-
print(Node->getChild(0));
1453-
Printer << " : ";
1454-
if (Node->getNumChildren() == 2) {
1455-
print(Node->getChild(1));
1456-
} else {
1457-
print(Node->getChild(1));
1458-
print(Node->getChild(2));
1459-
}
1460-
return nullptr;
14611451
case Node::Kind::KeyPathSetterThunkHelper:
1462-
Printer << "key path setter for ";
1452+
if (Node->getKind() == Node::Kind::KeyPathGetterThunkHelper)
1453+
Printer << "key path getter for ";
1454+
else
1455+
Printer << "key path setter for ";
1456+
14631457
print(Node->getChild(0));
14641458
Printer << " : ";
1465-
if (Node->getNumChildren() == 2) {
1466-
print(Node->getChild(1));
1467-
} else {
1468-
print(Node->getChild(1));
1469-
print(Node->getChild(2));
1459+
for (unsigned index = 1; index < Node->getNumChildren(); ++index) {
1460+
auto Child = Node->getChild(index);
1461+
if (Child->getKind() == Node::Kind::IsSerialized)
1462+
Printer << ", ";
1463+
print(Child);
14701464
}
14711465
return nullptr;
14721466
case Node::Kind::KeyPathEqualsThunkHelper:
@@ -1475,16 +1469,23 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
14751469
<< (Node->getKind() == Node::Kind::KeyPathEqualsThunkHelper
14761470
? "equality" : "hash")
14771471
<< " operator for ";
1478-
1479-
auto lastChild = Node->getChild(Node->getNumChildren() - 1);
1480-
auto lastType = Node->getNumChildren();
1472+
1473+
unsigned lastChildIndex = Node->getNumChildren();
1474+
auto lastChild = Node->getChild(lastChildIndex - 1);
1475+
bool isSerialized = false;
1476+
if (lastChild->getKind() == Node::Kind::IsSerialized) {
1477+
isSerialized = true;
1478+
lastChildIndex--;
1479+
lastChild = Node->getChild(lastChildIndex - 1);
1480+
}
1481+
14811482
if (lastChild->getKind() == Node::Kind::DependentGenericSignature) {
14821483
print(lastChild);
1483-
lastType--;
1484+
lastChildIndex--;
14841485
}
1485-
1486+
14861487
Printer << "(";
1487-
for (unsigned i = 0; i < lastType; ++i) {
1488+
for (unsigned i = 0; i < lastChildIndex; ++i) {
14881489
if (i != 0)
14891490
Printer << ", ";
14901491
print(Node->getChild(i));

lib/Demangling/OldDemangler.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,9 +688,9 @@ class OldDemangler {
688688
Node::Kind::GenericSpecializationNotReAbstracted :
689689
Node::Kind::GenericSpecialization);
690690

691-
// Create a node if the specialization is externally inlinable.
691+
// Create a node if the specialization is serialized.
692692
if (Mangled.nextIf("q")) {
693-
auto kind = Node::Kind::SpecializationIsFragile;
693+
auto kind = Node::Kind::IsSerialized;
694694
spec->addChild(Factory.createNode(kind), Factory);
695695
}
696696

@@ -705,9 +705,9 @@ class OldDemangler {
705705
auto spec =
706706
Factory.createNode(Node::Kind::FunctionSignatureSpecialization);
707707

708-
// Create a node if the specialization is externally inlinable.
708+
// Create a node if the specialization is serialized.
709709
if (Mangled.nextIf("q")) {
710-
auto kind = Node::Kind::SpecializationIsFragile;
710+
auto kind = Node::Kind::IsSerialized;
711711
spec->addChild(Factory.createNode(kind), Factory);
712712
}
713713

lib/Demangling/OldRemangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ void Remangler::mangleSpecializationPassID(Node *node) {
586586
Out << node->getIndex();
587587
}
588588

589-
void Remangler::mangleSpecializationIsFragile(Node *node) {
589+
void Remangler::mangleIsSerialized(Node *node) {
590590
Out << "q";
591591
}
592592

lib/Demangling/Remangler.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ class Remangler {
284284
void mangleAbstractStorage(Node *node, StringRef accessorCode);
285285
void mangleAnyProtocolConformance(Node *node);
286286

287+
void mangleKeyPathThunkHelper(Node *node, StringRef op);
288+
287289
#define NODE(ID) \
288290
void mangle##ID(Node *node);
289291
#define CONTEXT_NODE(ID) \
@@ -1819,24 +1821,30 @@ void Remangler::mangleReadAccessor(Node *node) {
18191821
mangleAbstractStorage(node->getFirstChild(), "r");
18201822
}
18211823

1824+
void Remangler::mangleKeyPathThunkHelper(Node *node, StringRef op) {
1825+
for (NodePointer Child : *node)
1826+
if (Child->getKind() != Node::Kind::IsSerialized)
1827+
mangle(Child);
1828+
Buffer << op;
1829+
for (NodePointer Child : *node)
1830+
if (Child->getKind() == Node::Kind::IsSerialized)
1831+
mangle(Child);
1832+
}
1833+
18221834
void Remangler::mangleKeyPathGetterThunkHelper(Node *node) {
1823-
mangleChildNodes(node);
1824-
Buffer << "TK";
1835+
mangleKeyPathThunkHelper(node, "TK");
18251836
}
18261837

18271838
void Remangler::mangleKeyPathSetterThunkHelper(Node *node) {
1828-
mangleChildNodes(node);
1829-
Buffer << "Tk";
1839+
mangleKeyPathThunkHelper(node, "Tk");
18301840
}
18311841

18321842
void Remangler::mangleKeyPathEqualsThunkHelper(Node *node) {
1833-
mangleChildNodes(node);
1834-
Buffer << "TH";
1843+
mangleKeyPathThunkHelper(node, "TH");
18351844
}
18361845

18371846
void Remangler::mangleKeyPathHashThunkHelper(Node *node) {
1838-
mangleChildNodes(node);
1839-
Buffer << "Th";
1847+
mangleKeyPathThunkHelper(node, "Th");
18401848
}
18411849

18421850
void Remangler::mangleReturnType(Node *node) {
@@ -1863,7 +1871,7 @@ void Remangler::mangleSpecializationPassID(Node *node) {
18631871
Buffer << node->getIndex();
18641872
}
18651873

1866-
void Remangler::mangleSpecializationIsFragile(Node *node) {
1874+
void Remangler::mangleIsSerialized(Node *node) {
18671875
Buffer << 'q';
18681876
}
18691877

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,6 +1455,7 @@ void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) {
14551455

14561456
auto component = emitKeyPathComponentForDecl(SILLocation(decl),
14571457
genericEnv,
1458+
ResilienceExpansion::Maximal,
14581459
baseOperand, needsGenericContext,
14591460
subs, decl, {},
14601461
baseTy->getCanonicalType(),

lib/SILGen/SILGen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
346346
KeyPathPatternComponent
347347
emitKeyPathComponentForDecl(SILLocation loc,
348348
GenericEnvironment *genericEnv,
349+
ResilienceExpansion expansion,
349350
unsigned &baseOperand,
350351
bool &needsGenericContext,
351352
SubstitutionMap subs,

0 commit comments

Comments
 (0)