Skip to content

Commit 41aebf8

Browse files
committed
IRGen: Simplify NominalMetadataVisitor's treatment of generic requirements
We don't need to substitute the superclass type as we walk up a class hierarchy, or look up the generic parameters and conformances to check if they're concrete, since we're always just emitting null pointers in place of the generic parameters and requirements, to be filled at runtime. Also, don't leave space for generic parameters and requirements from Objective-C superclasses, since that's not how they're represented.
1 parent fbba4a7 commit 41aebf8

7 files changed

+43
-62
lines changed

lib/IRGen/ClassMetadataVisitor.h

+11-14
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ template <class Impl> class ClassMetadataVisitor
7676
asImpl().addIVarDestroyer();
7777

7878
// Class members.
79-
addClassMembers(Target, Target->getDeclaredTypeInContext());
79+
addClassMembers(Target);
8080
}
8181

8282
/// Notes the beginning of the field offset vector for a particular ancestor
@@ -89,11 +89,13 @@ template <class Impl> class ClassMetadataVisitor
8989

9090
private:
9191
/// Add fields associated with the given class and its bases.
92-
void addClassMembers(ClassDecl *theClass, Type type) {
92+
void addClassMembers(ClassDecl *theClass) {
9393
// Visit the superclass first.
94-
if (Type superclass = type->getSuperclass()) {
95-
auto *superclassDecl = superclass->getClassOrBoundGenericClass();
96-
if (IGM.isResilient(superclassDecl, ResilienceExpansion::Maximal)) {
94+
if (auto *superclassDecl = theClass->getSuperclassDecl()) {
95+
if (superclassDecl->hasClangNode()) {
96+
// Nothing to do; Objective-C classes do not add new members to
97+
// Swift class metadata.
98+
} else if (IGM.isResilient(superclassDecl, ResilienceExpansion::Maximal)) {
9799
// Runtime metadata instantiation will initialize our field offset
98100
// vector and vtable entries.
99101
//
@@ -104,7 +106,7 @@ template <class Impl> class ClassMetadataVisitor
104106
// NB: We don't apply superclass substitutions to members because we want
105107
// consistent metadata layout between generic superclasses and concrete
106108
// subclasses.
107-
addClassMembers(superclassDecl, superclass);
109+
addClassMembers(superclassDecl);
108110
}
109111
}
110112

@@ -114,7 +116,7 @@ template <class Impl> class ClassMetadataVisitor
114116

115117
// Add space for the generic parameters, if applicable.
116118
// This must always be the first item in the immediate members.
117-
asImpl().addGenericFields(theClass, type, theClass);
119+
asImpl().addGenericFields(theClass, theClass);
118120

119121
// Add vtable entries.
120122
asImpl().addVTableEntries(theClass);
@@ -192,13 +194,8 @@ class ClassMetadataScanner : public ClassMetadataVisitor<Impl> {
192194
addPointer();
193195
}
194196
}
195-
void addGenericArgument(CanType argument, ClassDecl *forClass) {
196-
addPointer();
197-
}
198-
void addGenericWitnessTable(CanType argument, ProtocolConformanceRef conf,
199-
ClassDecl *forClass) {
200-
addPointer();
201-
}
197+
void addGenericArgument(ClassDecl *forClass) { addPointer(); }
198+
void addGenericWitnessTable(ClassDecl *forClass) { addPointer(); }
202199
void addPlaceholder(MissingMemberDecl *MMD) {
203200
for (auto i : range(MMD->getNumberOfVTableEntries())) {
204201
(void)i;

lib/IRGen/EnumMetadataVisitor.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ template <class Impl> class EnumMetadataVisitor
5555

5656
// Generic arguments.
5757
// This must always be the first piece of trailing data.
58-
asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
58+
asImpl().addGenericFields(Target);
5959

6060
// Reserve a word to cache the payload size if the type has dynamic layout.
6161
auto &strategy = getEnumImplStrategy(IGM,
62-
Target->DeclContext::getDeclaredTypeInContext()->getCanonicalType());
62+
Target->getDeclaredTypeInContext()->getCanonicalType());
6363
if (strategy.needsPayloadSizeInMetadata())
6464
asImpl().addPayloadSize();
6565
}
@@ -82,10 +82,8 @@ class EnumMetadataScanner : public EnumMetadataVisitor<Impl> {
8282
void addMetadataFlags() { addPointer(); }
8383
void addValueWitnessTable() { addPointer(); }
8484
void addNominalTypeDescriptor() { addPointer(); }
85-
void addGenericArgument(CanType argument) { addPointer(); }
86-
void addGenericWitnessTable(CanType argument, ProtocolConformanceRef conf) {
87-
addPointer();
88-
}
85+
void addGenericArgument() { addPointer(); }
86+
void addGenericWitnessTable() { addPointer(); }
8987
void addPayloadSize() { addPointer(); }
9088
void noteStartOfTypeSpecificMembers() {}
9189

lib/IRGen/GenMeta.cpp

+14-17
Original file line numberDiff line numberDiff line change
@@ -1929,13 +1929,12 @@ namespace {
19291929
void emitInitializeMethodOverrides(IRGenFunction &IGF,
19301930
llvm::Value *metadata) {}
19311931

1932-
void addGenericArgument(CanType argTy, ClassDecl *forClass) {
1933-
B.addNullPointer(IGM.TypeMetadataPtrTy);
1932+
void addGenericArgument(ClassDecl *forClass) {
1933+
llvm_unreachable("Fixed class metadata cannot have generic parameters");
19341934
}
19351935

1936-
void addGenericWitnessTable(CanType argTy, ProtocolConformanceRef conf,
1937-
ClassDecl *forClass) {
1938-
B.addNullPointer(IGM.WitnessTablePtrTy);
1936+
void addGenericWitnessTable(ClassDecl *forClass) {
1937+
llvm_unreachable("Fixed class metadata cannot have generic requirements");
19391938
}
19401939
};
19411940

@@ -1986,10 +1985,9 @@ namespace {
19861985
}
19871986
}
19881987

1989-
void addGenericArgument(CanType argTy, ClassDecl *forClass) {}
1988+
void addGenericArgument(ClassDecl *forClass) {}
19901989

1991-
void addGenericWitnessTable(CanType argTy, ProtocolConformanceRef conf,
1992-
ClassDecl *forClass) {}
1990+
void addGenericWitnessTable(ClassDecl *forClass) {}
19931991
};
19941992

19951993
/// Base class for laying out class metadata.
@@ -2275,13 +2273,12 @@ namespace {
22752273

22762274
void addMethodOverride(SILDeclRef baseRef, SILDeclRef declRef) {}
22772275

2278-
void addGenericArgument(CanType argTy, ClassDecl *forClass) {
2279-
Members.addGenericArgument(argTy, forClass);
2276+
void addGenericArgument(ClassDecl *forClass) {
2277+
Members.addGenericArgument(forClass);
22802278
}
22812279

2282-
void addGenericWitnessTable(CanType argTy, ProtocolConformanceRef conf,
2283-
ClassDecl *forClass) {
2284-
Members.addGenericWitnessTable(argTy, conf, forClass);
2280+
void addGenericWitnessTable(ClassDecl *forClass) {
2281+
Members.addGenericWitnessTable(forClass);
22852282
}
22862283

22872284
protected:
@@ -3036,11 +3033,11 @@ namespace {
30363033
B.addAlignmentPadding(super::IGM.getPointerAlignment());
30373034
}
30383035

3039-
void addGenericArgument(CanType type) {
3036+
void addGenericArgument() {
30403037
B.addNullPointer(IGM.TypeMetadataPtrTy);
30413038
}
30423039

3043-
void addGenericWitnessTable(CanType type, ProtocolConformanceRef conf) {
3040+
void addGenericWitnessTable() {
30443041
B.addNullPointer(IGM.WitnessTablePtrTy);
30453042
}
30463043

@@ -3287,11 +3284,11 @@ namespace {
32873284
B.add(emitNominalTypeDescriptor());
32883285
}
32893286

3290-
void addGenericArgument(CanType type) {
3287+
void addGenericArgument() {
32913288
B.addNullPointer(IGM.TypeMetadataPtrTy);
32923289
}
32933290

3294-
void addGenericWitnessTable(CanType type, ProtocolConformanceRef conf) {
3291+
void addGenericWitnessTable() {
32953292
B.addNullPointer(IGM.WitnessTablePtrTy);
32963293
}
32973294

lib/IRGen/GenProto.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -3004,8 +3004,7 @@ NecessaryBindings::forFunctionInvocations(IRGenModule &IGM,
30043004
}
30053005

30063006
/// The information we need to record in generic type metadata
3007-
/// is the information in the type's generic signature, minus the
3008-
/// information recoverable from the type's parent type. This is
3007+
/// is the information in the type's generic signature. This is
30093008
/// simply the information that would be passed to a generic function
30103009
/// that takes the (thick) parent metatype as an argument.
30113010
GenericTypeRequirements::GenericTypeRequirements(IRGenModule &IGM,

lib/IRGen/MetadataLayout.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -313,19 +313,18 @@ ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
313313
super::noteStartOfGenericRequirements(forClass);
314314
}
315315

316-
void addGenericWitnessTable(CanType argType, ProtocolConformanceRef conf,
317-
ClassDecl *forClass) {
316+
void addGenericWitnessTable(ClassDecl *forClass) {
318317
if (forClass == Target) {
319318
Layout.NumImmediateMembers++;
320319
}
321-
super::addGenericWitnessTable(argType, conf, forClass);
320+
super::addGenericWitnessTable(forClass);
322321
}
323322

324-
void addGenericArgument(CanType argType, ClassDecl *forClass) {
323+
void addGenericArgument(ClassDecl *forClass) {
325324
if (forClass == Target) {
326325
Layout.NumImmediateMembers++;
327326
}
328-
super::addGenericArgument(argType, forClass);
327+
super::addGenericArgument(forClass);
329328
}
330329

331330
void addMethod(SILDeclRef fn) {

lib/IRGen/NominalMetadataVisitor.h

+6-13
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,21 @@ template <class Impl> class NominalMetadataVisitor {
5656
/// fields. e.g., if B<T> extends A<T>, the witness for T in A's
5757
/// section should be enough.
5858
template <class... T>
59-
void addGenericFields(NominalTypeDecl *typeDecl, Type type,
60-
T &&...args) {
59+
void addGenericFields(NominalTypeDecl *typeDecl, T &&...args) {
6160
// The archetype order here needs to be consistent with
6261
// NominalTypeDescriptorBase::addGenericParams.
6362

6463
// Note that we intentionally don't std::forward 'args'.
6564
asImpl().noteStartOfGenericRequirements(args...);
6665

6766
GenericTypeRequirements requirements(IGM, typeDecl);
68-
if (requirements.empty()) return;
69-
70-
auto subs = type->getContextSubstitutionMap(IGM.getSwiftModule(),
71-
typeDecl);
72-
requirements.enumerateFulfillments(IGM, subs,
73-
[&](unsigned reqtIndex, CanType argType,
74-
Optional<ProtocolConformanceRef> conf) {
75-
if (conf) {
76-
asImpl().addGenericWitnessTable(argType, *conf, args...);
67+
for (auto reqt : requirements.getRequirements()) {
68+
if (reqt.Protocol) {
69+
asImpl().addGenericWitnessTable(args...);
7770
} else {
78-
asImpl().addGenericArgument(argType, args...);
71+
asImpl().addGenericArgument(args...);
7972
}
80-
});
73+
}
8174

8275
asImpl().noteEndOfGenericRequirements(args...);
8376
}

lib/IRGen/StructMetadataVisitor.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ template <class Impl> class StructMetadataVisitor
5353

5454
// Generic arguments.
5555
// This must always be the first piece of trailing data.
56-
asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
56+
asImpl().addGenericFields(Target);
5757

5858
// Struct field offsets.
5959
asImpl().noteStartOfFieldOffsets();
@@ -87,10 +87,8 @@ class StructMetadataScanner : public StructMetadataVisitor<Impl> {
8787
void addValueWitnessTable() { addPointer(); }
8888
void addNominalTypeDescriptor() { addPointer(); }
8989
void addFieldOffset(VarDecl *) { addInt32(); }
90-
void addGenericArgument(CanType argument) { addPointer(); }
91-
void addGenericWitnessTable(CanType argument, ProtocolConformanceRef conf) {
92-
addPointer();
93-
}
90+
void addGenericArgument() { addPointer(); }
91+
void addGenericWitnessTable() { addPointer(); }
9492
void noteStartOfTypeSpecificMembers() {}
9593

9694
void noteEndOfFieldOffsets() {

0 commit comments

Comments
 (0)