Skip to content

Commit 8b9ffd8

Browse files
authored
Merge pull request swiftlang#15438 from jckarter/property-descriptor-irgen
IRGen: Lower property descriptors.
2 parents d6894b8 + 02b23d0 commit 8b9ffd8

File tree

12 files changed

+737
-459
lines changed

12 files changed

+737
-459
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2478,7 +2478,7 @@ class KeyPathPatternComponent {
24782478
case Kind::OptionalChain:
24792479
case Kind::OptionalForce:
24802480
case Kind::OptionalWrap:
2481-
llvm_unreachable("not a computed property");
2481+
return {};
24822482
case Kind::GettableProperty:
24832483
case Kind::SettableProperty:
24842484
case Kind::External:

lib/IRGen/GenDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,12 @@ void IRGenerator::emitGlobalTopLevel() {
10901090
}
10911091
}
10921092

1093+
// Emit property descriptors.
1094+
for (auto &prop : PrimaryIGM->getSILModule().getPropertyList()) {
1095+
CurrentIGMPtr IGM = getGenModule(prop.getDecl()->getInnermostDeclContext());
1096+
IGM->emitSILProperty(&prop);
1097+
}
1098+
10931099
for (auto Iter : *this) {
10941100
IRGenModule *IGM = Iter.second;
10951101
IGM->finishEmitAfterTopLevel();

lib/IRGen/GenKeyPath.cpp

Lines changed: 517 additions & 403 deletions
Large diffs are not rendered by default.

lib/IRGen/GenType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,10 @@ void TypeConverter::pushGenericContext(CanGenericSignature signature) {
10771077
// Push the generic context down to the SIL TypeConverter, so we can share
10781078
// archetypes with SIL.
10791079
IGM.getSILTypes().pushGenericContext(signature);
1080+
1081+
// Clear the dependent type info cache since we have a new active signature
1082+
// now.
1083+
Types.DependentCache.clear();
10801084
}
10811085

10821086
void TypeConverter::popGenericContext(CanGenericSignature signature) {

lib/IRGen/GenType.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ class TypeConverter {
188188
NominalTypeDecl *D);
189189
friend void TypeConverter::addForwardDecl(TypeBase*, llvm::Type*);
190190
friend ArchetypeType *TypeConverter::getExemplarArchetype(ArchetypeType *t);
191+
friend void TypeConverter::pushGenericContext(CanGenericSignature signature);
191192
friend void TypeConverter::popGenericContext(CanGenericSignature signature);
192193

193194
#ifndef NDEBUG

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ namespace swift {
9292
struct SILDeclRef;
9393
class SILGlobalVariable;
9494
class SILModule;
95+
class SILProperty;
9596
class SILType;
9697
class SILWitnessTable;
9798
class SourceLoc;
@@ -1096,6 +1097,7 @@ private: \
10961097
void emitCoverageMapping();
10971098
void emitSILFunction(SILFunction *f);
10981099
void emitSILWitnessTable(SILWitnessTable *wt);
1100+
void emitSILProperty(SILProperty *prop);
10991101
void emitSILStaticInitializers();
11001102
llvm::Constant *emitFixedTypeLayout(CanType t, const FixedTypeInfo &ti);
11011103
void emitProtocolConformance(const NormalProtocolConformance *conformance);

lib/Parse/ParseStmt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
264264
Tok.isNot(tok::kw_sil_global) &&
265265
Tok.isNot(tok::kw_sil_witness_table) &&
266266
Tok.isNot(tok::kw_sil_default_witness_table) &&
267+
Tok.isNot(tok::kw_sil_property) &&
267268
(isConditionalBlock ||
268269
!isTerminatorForBraceItemListKind(Kind, Entries))) {
269270

lib/ParseSIL/ParseSIL.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5387,11 +5387,18 @@ bool SILParserTUState::parseSILProperty(Parser &P) {
53875387
generics = P.maybeParseGenericParams().getPtrOrNull();
53885388
patternEnv = handleSILGenericParams(P.Context, generics, &P.SF);
53895389

5390-
if (patternEnv->getGenericSignature()->getCanonicalSignature()
5391-
!= VD->getInnermostDeclContext()->getGenericSignatureOfContext()
5392-
->getCanonicalSignature()) {
5393-
P.diagnose(loc, diag::sil_property_generic_signature_mismatch);
5394-
return true;
5390+
if (patternEnv) {
5391+
if (patternEnv->getGenericSignature()->getCanonicalSignature()
5392+
!= VD->getInnermostDeclContext()->getGenericSignatureOfContext()
5393+
->getCanonicalSignature()) {
5394+
P.diagnose(loc, diag::sil_property_generic_signature_mismatch);
5395+
return true;
5396+
}
5397+
} else {
5398+
if (VD->getInnermostDeclContext()->getGenericSignatureOfContext()) {
5399+
P.diagnose(loc, diag::sil_property_generic_signature_mismatch);
5400+
return true;
5401+
}
53955402
}
53965403

53975404
Identifier ComponentKind;

lib/SILGen/SILGen.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,9 @@ static bool doesPropertyNeedDescriptor(AbstractStorageDecl *decl) {
12051205
}
12061206

12071207
void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) {
1208+
if (!M.getASTContext().LangOpts.EnableKeyPathResilience)
1209+
return;
1210+
12081211
// TODO: Key path code emission doesn't handle opaque values properly yet.
12091212
if (!SILModuleConventions(M).useLoweredAddresses())
12101213
return;

lib/SILOptimizer/IPO/DeadFunctionElimination.cpp

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -191,57 +191,56 @@ class FunctionLivenessComputation {
191191

192192
/// Marks the declarations referenced by a key path pattern as alive if they
193193
/// aren't yet.
194-
void ensureKeyPathComponentsAreAlive(KeyPathPattern *KP) {
195-
for (auto &component : KP->getComponents()) {
196-
switch (component.getKind()) {
197-
case KeyPathPatternComponent::Kind::SettableProperty:
198-
ensureAlive(component.getComputedPropertySetter());
199-
LLVM_FALLTHROUGH;
200-
case KeyPathPatternComponent::Kind::GettableProperty: {
201-
ensureAlive(component.getComputedPropertyGetter());
202-
auto id = component.getComputedPropertyId();
203-
switch (id.getKind()) {
204-
case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
205-
auto declRef = id.getDeclRef();
206-
if (declRef.isForeign) {
207-
// Nothing to do here: foreign functions aren't ours to be deleting.
208-
// (And even if they were, they're ObjC-dispatched and thus anchored
209-
// already: see isAnchorFunction)
194+
void
195+
ensureKeyPathComponentIsAlive(const KeyPathPatternComponent &component) {
196+
switch (component.getKind()) {
197+
case KeyPathPatternComponent::Kind::SettableProperty:
198+
ensureAlive(component.getComputedPropertySetter());
199+
LLVM_FALLTHROUGH;
200+
case KeyPathPatternComponent::Kind::GettableProperty: {
201+
ensureAlive(component.getComputedPropertyGetter());
202+
auto id = component.getComputedPropertyId();
203+
switch (id.getKind()) {
204+
case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
205+
auto declRef = id.getDeclRef();
206+
if (declRef.isForeign) {
207+
// Nothing to do here: foreign functions aren't ours to be deleting.
208+
// (And even if they were, they're ObjC-dispatched and thus anchored
209+
// already: see isAnchorFunction)
210+
} else {
211+
auto decl = cast<AbstractFunctionDecl>(declRef.getDecl());
212+
if (auto clas = dyn_cast<ClassDecl>(decl->getDeclContext())) {
213+
ensureAliveClassMethod(getMethodInfo(decl, /*witness*/ false),
214+
dyn_cast<FuncDecl>(decl),
215+
clas);
216+
} else if (isa<ProtocolDecl>(decl->getDeclContext())) {
217+
ensureAliveProtocolMethod(getMethodInfo(decl, /*witness*/ true));
210218
} else {
211-
auto decl = cast<AbstractFunctionDecl>(declRef.getDecl());
212-
if (auto clas = dyn_cast<ClassDecl>(decl->getDeclContext())) {
213-
ensureAliveClassMethod(getMethodInfo(decl, /*witness*/ false),
214-
dyn_cast<FuncDecl>(decl),
215-
clas);
216-
} else if (isa<ProtocolDecl>(decl->getDeclContext())) {
217-
ensureAliveProtocolMethod(getMethodInfo(decl, /*witness*/ true));
218-
} else {
219-
llvm_unreachable("key path keyed by a non-class, non-protocol method");
220-
}
219+
llvm_unreachable("key path keyed by a non-class, non-protocol method");
221220
}
222-
break;
223221
}
224-
case KeyPathPatternComponent::ComputedPropertyId::Function:
225-
ensureAlive(id.getFunction());
226-
break;
227-
case KeyPathPatternComponent::ComputedPropertyId::Property:
228-
break;
229-
}
230-
231-
if (auto equals = component.getSubscriptIndexEquals())
232-
ensureAlive(equals);
233-
if (auto hash = component.getSubscriptIndexHash())
234-
ensureAlive(hash);
235-
236-
continue;
222+
break;
237223
}
238-
case KeyPathPatternComponent::Kind::StoredProperty:
239-
case KeyPathPatternComponent::Kind::OptionalChain:
240-
case KeyPathPatternComponent::Kind::OptionalForce:
241-
case KeyPathPatternComponent::Kind::OptionalWrap:
242-
case KeyPathPatternComponent::Kind::External:
243-
continue;
224+
case KeyPathPatternComponent::ComputedPropertyId::Function:
225+
ensureAlive(id.getFunction());
226+
break;
227+
case KeyPathPatternComponent::ComputedPropertyId::Property:
228+
break;
244229
}
230+
231+
if (auto equals = component.getSubscriptIndexEquals())
232+
ensureAlive(equals);
233+
if (auto hash = component.getSubscriptIndexHash())
234+
ensureAlive(hash);
235+
236+
break;
237+
}
238+
case KeyPathPatternComponent::Kind::StoredProperty:
239+
case KeyPathPatternComponent::Kind::OptionalChain:
240+
case KeyPathPatternComponent::Kind::OptionalForce:
241+
case KeyPathPatternComponent::Kind::OptionalWrap:
242+
case KeyPathPatternComponent::Kind::External:
243+
break;
245244
}
246245
}
247246

@@ -367,7 +366,8 @@ class FunctionLivenessComputation {
367366
} else if (auto *FRI = dyn_cast<FunctionRefInst>(&I)) {
368367
ensureAlive(FRI->getReferencedFunction());
369368
} else if (auto *KPI = dyn_cast<KeyPathInst>(&I)) {
370-
ensureKeyPathComponentsAreAlive(KPI->getPattern());
369+
for (auto &component : KPI->getPattern()->getComponents())
370+
ensureKeyPathComponentIsAlive(component);
371371
}
372372
}
373373
}
@@ -510,8 +510,6 @@ class DeadFunctionElimination : FunctionLivenessComputation {
510510
mi->addWitnessFunction(F, nullptr);
511511
}
512512
}
513-
514-
515513
}
516514

517515
/// DeadFunctionElimination pass takes functions
@@ -600,6 +598,11 @@ class DeadFunctionElimination : FunctionLivenessComputation {
600598
}
601599
}
602600
}
601+
// Check property descriptor implementations.
602+
for (SILProperty &P : Module->getPropertyList()) {
603+
ensureKeyPathComponentIsAlive(P.getComponent());
604+
}
605+
603606
}
604607

605608
/// Removes all dead methods from vtables and witness tables.

0 commit comments

Comments
 (0)