Skip to content

Commit 49bc191

Browse files
committed
IRGen: Simplify enumerateFulfillments()
1 parent fa541fa commit 49bc191

File tree

6 files changed

+51
-113
lines changed

6 files changed

+51
-113
lines changed

lib/IRGen/Fulfillment.cpp

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -279,38 +279,39 @@ bool FulfillmentMap::searchNominalTypeMetadata(IRGenModule &IGM,
279279

280280
bool hadFulfillment = false;
281281

282+
auto subs = type->getContextSubstitutionMap(IGM.getSwiftModule(), nominal);
283+
282284
GenericTypeRequirements requirements(IGM, nominal);
283-
requirements.enumerateFulfillments(
284-
IGM, type->getContextSubstitutionMap(IGM.getSwiftModule(), nominal),
285-
[&](unsigned reqtIndex, CanType arg, ProtocolConformanceRef conf) {
286-
// Skip uninteresting type arguments.
287-
if (!keys.hasInterestingType(arg))
288-
return;
289-
290-
// If the fulfilled value is type metadata, refine the path.
291-
if (conf.isInvalid()) {
292-
auto argState =
293-
getPresumedMetadataStateForTypeArgument(metadataState);
294-
MetadataPath argPath = path;
295-
argPath.addNominalTypeArgumentComponent(reqtIndex);
296-
hadFulfillment |= searchTypeMetadata(
297-
IGM, arg, IsExact, argState, source, std::move(argPath), keys);
298-
return;
299-
}
300-
301-
// Otherwise, it's a conformance.
302-
303-
// Ignore it unless the type itself is interesting.
304-
if (!keys.isInterestingType(arg))
305-
return;
306-
307-
// Refine the path.
308-
MetadataPath argPath = path;
309-
argPath.addNominalTypeArgumentConformanceComponent(reqtIndex);
310-
311-
hadFulfillment |= searchWitnessTable(IGM, arg, conf.getRequirement(),
312-
source, std::move(argPath), keys);
313-
});
285+
286+
for (unsigned reqtIndex : indices(requirements.getRequirements())) {
287+
auto requirement = requirements.getRequirements()[reqtIndex];
288+
auto arg = requirement.getTypeParameter().subst(subs)->getCanonicalType();
289+
290+
// Skip uninteresting type arguments.
291+
if (!keys.hasInterestingType(arg))
292+
continue;
293+
294+
// If the fulfilled value is type metadata, refine the path.
295+
if (requirement.isMetadata()) {
296+
auto argState =
297+
getPresumedMetadataStateForTypeArgument(metadataState);
298+
MetadataPath argPath = path;
299+
argPath.addNominalTypeArgumentComponent(reqtIndex);
300+
hadFulfillment |= searchTypeMetadata(
301+
IGM, arg, IsExact, argState, source, std::move(argPath), keys);
302+
continue;
303+
}
304+
305+
// Otherwise, it's a conformance.
306+
assert(requirement.isWitnessTable());
307+
308+
// Refine the path.
309+
MetadataPath argPath = path;
310+
argPath.addNominalTypeArgumentConformanceComponent(reqtIndex);
311+
312+
hadFulfillment |= searchWitnessTable(IGM, arg, requirement.getProtocol(),
313+
source, std::move(argPath), keys);
314+
}
314315

315316
return hadFulfillment;
316317
}

lib/IRGen/GenProto.cpp

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3154,8 +3154,7 @@ void EmitPolymorphicArguments::emit(SubstitutionMap subs,
31543154
// For now, treat all archetypes independently.
31553155
enumerateUnfulfilledRequirements([&](GenericRequirement requirement) {
31563156
llvm::Value *requiredValue =
3157-
emitGenericRequirementFromSubstitutions(IGF, Generics,
3158-
requirement, subs);
3157+
emitGenericRequirementFromSubstitutions(IGF, requirement, subs);
31593158
out.add(requiredValue);
31603159
});
31613160

@@ -3277,7 +3276,6 @@ GenericTypeRequirements::GenericTypeRequirements(IRGenModule &IGM,
32773276

32783277
// Construct a representative function type.
32793278
auto generics = ncGenerics.getCanonicalSignature();
3280-
Generics = generics;
32813279
auto fnType = SILFunctionType::get(generics, SILFunctionType::ExtInfo(),
32823280
SILCoroutineKind::None,
32833281
/*callee*/ ParameterConvention::Direct_Unowned,
@@ -3297,35 +3295,14 @@ GenericTypeRequirements::GenericTypeRequirements(IRGenModule &IGM,
32973295
// We do not need to consider extra sources.
32983296
}
32993297

3300-
void
3301-
GenericTypeRequirements::enumerateFulfillments(IRGenModule &IGM,
3302-
SubstitutionMap subs,
3303-
FulfillmentCallback callback) {
3304-
if (empty()) return;
3305-
3306-
for (auto reqtIndex : indices(getRequirements())) {
3307-
auto &reqt = getRequirements()[reqtIndex];
3308-
CanType type = reqt.getTypeParameter().subst(subs)->getCanonicalType();
3309-
if (reqt.isWitnessTable()) {
3310-
auto conformance =
3311-
subs.lookupConformance(reqt.getTypeParameter(), reqt.getProtocol());
3312-
callback(reqtIndex, type, conformance);
3313-
} else {
3314-
assert(reqt.isMetadata());
3315-
callback(reqtIndex, type, ProtocolConformanceRef::forInvalid());
3316-
}
3317-
}
3318-
}
3319-
33203298
void GenericTypeRequirements::emitInitOfBuffer(IRGenFunction &IGF,
33213299
SubstitutionMap subs,
33223300
Address buffer) {
33233301
if (Requirements.empty()) return;
33243302

33253303
emitInitOfGenericRequirementsBuffer(IGF, Requirements, buffer,
33263304
[&](GenericRequirement requirement) {
3327-
return emitGenericRequirementFromSubstitutions(IGF, Generics,
3328-
requirement, subs);
3305+
return emitGenericRequirementFromSubstitutions(IGF, requirement, subs);
33293306
});
33303307
}
33313308

@@ -3358,7 +3335,6 @@ void irgen::emitInitOfGenericRequirementsBuffer(IRGenFunction &IGF,
33583335

33593336
llvm::Value *
33603337
irgen::emitGenericRequirementFromSubstitutions(IRGenFunction &IGF,
3361-
CanGenericSignature generics,
33623338
GenericRequirement requirement,
33633339
SubstitutionMap subs) {
33643340
CanType depTy = requirement.getTypeParameter();

lib/IRGen/GenericArguments.h

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,7 @@ struct GenericArguments {
5050
SmallVector<llvm::Value *, 8> Values;
5151
SmallVector<llvm::Type *, 8> Types;
5252

53-
static unsigned getNumGenericArguments(IRGenModule &IGM,
54-
NominalTypeDecl *nominal) {
55-
GenericTypeRequirements requirements(IGM, nominal);
56-
return requirements.getNumTypeRequirements();
57-
}
58-
59-
void collectTypes(IRGenModule &IGM, NominalTypeDecl *nominal) {
53+
void collectTypes(IRGenModule &IGM, NominalTypeDecl *nominal) {
6054
GenericTypeRequirements requirements(IGM, nominal);
6155
collectTypes(IGM, requirements);
6256
}
@@ -87,15 +81,10 @@ struct GenericArguments {
8781
void collect(IRGenFunction &IGF, SubstitutionMap subs) {
8882
GenericTypeRequirements requirements(IGF.IGM, subs.getGenericSignature());
8983

90-
requirements.enumerateFulfillments(
91-
IGF.IGM, subs,
92-
[&](unsigned reqtIndex, CanType type, ProtocolConformanceRef conf) {
93-
if (conf) {
94-
Values.push_back(emitWitnessTableRef(IGF, type, conf));
95-
} else {
96-
Values.push_back(IGF.emitAbstractTypeMetadataRef(type));
97-
}
98-
});
84+
for (auto requirement : requirements.getRequirements()) {
85+
Values.push_back(emitGenericRequirementFromSubstitutions(
86+
IGF, requirement, subs));
87+
}
9988

10089
collectTypes(IGF.IGM, requirements);
10190
assert(Types.size() == Values.size());

lib/IRGen/GenericRequirement.h

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ void enumerateGenericSignatureRequirements(CanGenericSignature signature,
5454
/// value.
5555
llvm::Value *
5656
emitGenericRequirementFromSubstitutions(IRGenFunction &IGF,
57-
CanGenericSignature signature,
5857
GenericRequirement requirement,
5958
SubstitutionMap subs);
6059

@@ -86,15 +85,10 @@ void bindFromGenericRequirementsBuffer(IRGenFunction &IGF,
8685
/// A class describing the layout of the generic requirements of a
8786
/// nominal type metadata.
8887
///
89-
/// The generic requirements are always laid out as a sequence of type
90-
/// metadata (corresponding to the type parameters of the context established
91-
/// by the type, minus anything fulfillable from its parent type metadata)
92-
/// followed by a sequence of protocol witness tables (corresponding to the
93-
/// root conformances of the context established by the type, again minus
94-
/// anything fulfillable from its parent type metadata).
88+
/// The generic requirements are always laid out as a sequence of shape
89+
/// parameters, followed by type metadata and witness tables.
9590
class GenericTypeRequirements {
9691
llvm::SmallVector<GenericRequirement, 4> Requirements;
97-
CanGenericSignature Generics;
9892

9993
public:
10094
GenericTypeRequirements(IRGenModule &IGM, NominalTypeDecl *decl);
@@ -105,38 +99,8 @@ class GenericTypeRequirements {
10599
return Requirements;
106100
}
107101

108-
/// Return the number of entries required in order to store this data.
109-
unsigned getStorageSizeInWords() const {
110-
return Requirements.size();
111-
}
112-
113-
/// Return the number of type metadata requirements.
114-
unsigned getNumTypeRequirements() const {
115-
unsigned count = 0;
116-
for (auto i = Requirements.begin(), e = Requirements.end(); i != e; ++i) {
117-
if (i->isMetadata()) {
118-
count++;
119-
} else {
120-
#ifndef NDEBUG
121-
// Assert that the rest of the requirements are conformance
122-
// requirements.
123-
for (++i; i != e; ++i) {
124-
assert(i->isWitnessTable() && "type requirement followed conformance!");
125-
}
126-
#endif
127-
break;
128-
}
129-
}
130-
return count;
131-
}
132-
133102
bool empty() const { return Requirements.empty(); }
134103

135-
using FulfillmentCallback = llvm::function_ref<void(
136-
unsigned requirementIndex, CanType type, ProtocolConformanceRef conf)>;
137-
void enumerateFulfillments(IRGenModule &IGM, SubstitutionMap subs,
138-
FulfillmentCallback callback);
139-
140104
void emitInitOfBuffer(IRGenFunction &IGF, SubstitutionMap subs,
141105
Address buffer);
142106

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6543,8 +6543,7 @@ void IRGenSILFunction::visitKeyPathInst(swift::KeyPathInst *I) {
65436543
if (!I->getSubstitutions().empty()) {
65446544
emitInitOfGenericRequirementsBuffer(*this, requirements, argsBuf,
65456545
[&](GenericRequirement reqt) -> llvm::Value * {
6546-
return emitGenericRequirementFromSubstitutions(*this, sig,
6547-
reqt, subs);
6546+
return emitGenericRequirementFromSubstitutions(*this, reqt, subs);
65486547
});
65496548
}
65506549

test/IRGen/variadic_generic_types.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,12 @@ struct G<T...> {
1717
callee()
1818
}
1919
}
20+
21+
func blackHole<T>(_: T) {}
22+
23+
blackHole(G< >.self)
24+
blackHole(G<Int, String>.self)
25+
26+
func genericMetadata<T...>(_: T...) {
27+
blackHole(G<T... >.self)
28+
}

0 commit comments

Comments
 (0)