Skip to content

Commit 0c3a9d8

Browse files
committed
IRGen: Replace FulfillmentKey with GenericRequirement
1 parent 65d2d4d commit 0c3a9d8

File tree

5 files changed

+57
-25
lines changed

5 files changed

+57
-25
lines changed

include/swift/IRGen/GenericRequirement.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
#ifndef SWIFT_AST_GENERIC_REQUIREMENT_H
1414
#define SWIFT_AST_GENERIC_REQUIREMENT_H
1515

16+
#include "swift/AST/Decl.h"
1617
#include "swift/AST/Type.h"
18+
#include "llvm/Support/raw_ostream.h"
1719

1820
namespace swift {
1921

@@ -64,6 +66,7 @@ class GenericRequirement {
6466
}
6567

6668
static GenericRequirement forShape(CanType type) {
69+
assert(type->isParameterPack());
6770
return GenericRequirement(Kind::Shape, type, nullptr);
6871
}
6972

@@ -83,6 +86,20 @@ class GenericRequirement {
8386
assert(proto != nullptr);
8487
return GenericRequirement(Kind::WitnessTable, type, proto);
8588
}
89+
90+
void dump(llvm::raw_ostream &out) const {
91+
switch (kind) {
92+
case Kind::Shape:
93+
out << "shape: " << type;
94+
break;
95+
case Kind::Metadata:
96+
out << "metadata: " << type;
97+
break;
98+
case Kind::WitnessTable:
99+
out << "witness_table: " << type << " : " << proto->getName();
100+
break;
101+
}
102+
}
86103
};
87104

88105
} // end namespace swift

lib/IRGen/Fulfillment.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ bool FulfillmentMap::searchTypeMetadata(IRGenModule &IGM, CanType type,
150150
}
151151

152152
// Add the fulfillment.
153-
hadFulfillment |= addFulfillment({type, nullptr},
153+
hadFulfillment |= addFulfillment(GenericRequirement::forMetadata(type),
154154
source, std::move(path), metadataState);
155155
return hadFulfillment;
156156
}
@@ -251,8 +251,9 @@ bool FulfillmentMap::searchWitnessTable(
251251
// If we're not limiting the set of interesting conformances, or if
252252
// this is an interesting conformance, record it.
253253
if (!interestingConformances || interestingConformances->count(protocol)) {
254-
hadFulfillment |= addFulfillment({type, protocol}, source,
255-
std::move(path), MetadataState::Complete);
254+
hadFulfillment |= addFulfillment(
255+
GenericRequirement::forWitnessTable(type, protocol), source,
256+
std::move(path), MetadataState::Complete);
256257
}
257258

258259
return hadFulfillment;
@@ -315,7 +316,7 @@ bool FulfillmentMap::searchNominalTypeMetadata(IRGenModule &IGM,
315316
}
316317

317318
/// Testify that there's a fulfillment at the given path.
318-
bool FulfillmentMap::addFulfillment(FulfillmentKey key,
319+
bool FulfillmentMap::addFulfillment(GenericRequirement key,
319320
unsigned source,
320321
MetadataPath &&path,
321322
MetadataState metadataState) {
@@ -360,10 +361,8 @@ static StringRef getStateName(MetadataState state) {
360361
void FulfillmentMap::dump() const {
361362
auto &out = llvm::errs();
362363
for (auto &entry : Fulfillments) {
363-
out << "(" << entry.first.first;
364-
if (auto proto = entry.first.second) {
365-
out << ", " << proto->getNameStr();
366-
}
364+
out << "(";
365+
entry.first.dump(out);
367366
out << ") => " << getStateName(entry.second.getState())
368367
<< " at sources[" << entry.second.SourceIndex
369368
<< "]." << entry.second.Path << "\n";

lib/IRGen/Fulfillment.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/DenseMap.h"
2222
#include "swift/AST/Types.h"
2323
#include "swift/AST/GenericSignature.h"
24+
#include "swift/IRGen/GenericRequirement.h"
2425
#include "MetadataPath.h"
2526

2627
namespace swift {
@@ -48,9 +49,7 @@ struct Fulfillment {
4849
};
4950

5051
class FulfillmentMap {
51-
using FulfillmentKey = std::pair<Type, ProtocolDecl*>;
52-
53-
llvm::DenseMap<FulfillmentKey, Fulfillment> Fulfillments;
52+
llvm::DenseMap<GenericRequirement, Fulfillment> Fulfillments;
5453

5554
public:
5655
struct InterestingKeysCallback {
@@ -115,25 +114,28 @@ class FulfillmentMap {
115114
///
116115
/// \return true if the fulfillment was added, which won't happen if there's
117116
/// already a fulfillment that was at least as good
118-
bool addFulfillment(FulfillmentKey key, unsigned source,
117+
bool addFulfillment(GenericRequirement key, unsigned source,
119118
MetadataPath &&path, MetadataState state);
120119

121-
const Fulfillment *getTypeMetadata(CanType type) const {
122-
auto it = Fulfillments.find({type, nullptr});
120+
const Fulfillment *getFulfillment(GenericRequirement key) const {
121+
auto it = Fulfillments.find(key);
123122
if (it != Fulfillments.end()) {
124123
return &it->second;
125124
} else {
126125
return nullptr;
127126
}
128127
}
129128

129+
const Fulfillment *getShape(CanType type) const {
130+
return getFulfillment(GenericRequirement::forShape(type));
131+
}
132+
133+
const Fulfillment *getTypeMetadata(CanType type) const {
134+
return getFulfillment(GenericRequirement::forMetadata(type));
135+
}
136+
130137
const Fulfillment *getWitnessTable(CanType type, ProtocolDecl *proto) const {
131-
auto it = Fulfillments.find({type, proto});
132-
if (it != Fulfillments.end()) {
133-
return &it->second;
134-
} else {
135-
return nullptr;
136-
}
138+
return getFulfillment(GenericRequirement::forWitnessTable(type, proto));
137139
}
138140

139141
void dump() const;

lib/IRGen/GenProto.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ void PolymorphicConvention::addPseudogenericFulfillments() {
246246
reqt.getTypeParameter(), erasedTypeParam);
247247

248248
MetadataPath path;
249-
Fulfillments.addFulfillment({reqt.getTypeParameter(), reqt.getProtocol()},
249+
Fulfillments.addFulfillment(reqt,
250250
Sources.size() - 1, std::move(path),
251251
MetadataState::Complete);
252252
});
@@ -257,6 +257,17 @@ irgen::enumerateGenericSignatureRequirements(CanGenericSignature signature,
257257
const RequirementCallback &callback) {
258258
if (!signature) return;
259259

260+
// Get all unique pack generic parameter shapes.
261+
SmallSetVector<CanType, 2> packs;
262+
for (auto gp : signature.getGenericParams()) {
263+
if (gp->isParameterPack()) {
264+
packs.insert(signature->getReducedShape(gp)->getCanonicalType());
265+
}
266+
}
267+
268+
for (auto type : packs)
269+
callback(GenericRequirement::forShape(type));
270+
260271
// Get all of the type metadata.
261272
signature->forEachParam([&](GenericTypeParamType *gp, bool canonical) {
262273
if (canonical)
@@ -442,15 +453,15 @@ void PolymorphicConvention::considerParameter(SILParameterInfo param,
442453

443454
void PolymorphicConvention::addSelfMetadataFulfillment(CanType arg) {
444455
unsigned source = Sources.size() - 1;
445-
Fulfillments.addFulfillment({arg, nullptr},
456+
Fulfillments.addFulfillment(GenericRequirement::forMetadata(arg),
446457
source, MetadataPath(), MetadataState::Complete);
447458
}
448459

449460
void PolymorphicConvention::addSelfWitnessTableFulfillment(
450461
CanType arg, ProtocolConformanceRef conformance) {
451462
auto proto = conformance.getRequirement();
452463
unsigned source = Sources.size() - 1;
453-
Fulfillments.addFulfillment({arg, proto},
464+
Fulfillments.addFulfillment(GenericRequirement::forWitnessTable(arg, proto),
454465
source, MetadataPath(), MetadataState::Complete);
455466

456467
if (conformance.isConcrete()) {

lib/IRGen/LocalTypeData.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,12 +542,13 @@ addAbstractForFulfillments(IRGenFunction &IGF, FulfillmentMap &&fulfillments,
542542
};
543543

544544
for (auto &fulfillment : fulfillments) {
545-
CanType type = CanType(fulfillment.first.first);
545+
CanType type = fulfillment.first.getTypeParameter();
546546
LocalTypeDataKind localDataKind;
547547

548548
// For now, ignore witness-table fulfillments when they're not for
549549
// archetypes.
550-
if (ProtocolDecl *protocol = fulfillment.first.second) {
550+
if (fulfillment.first.isWitnessTable()) {
551+
ProtocolDecl *protocol = fulfillment.first.getProtocol();
551552
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
552553
auto conformsTo = archetype->getConformsTo();
553554
auto it = std::find(conformsTo.begin(), conformsTo.end(), protocol);
@@ -558,6 +559,8 @@ addAbstractForFulfillments(IRGenFunction &IGF, FulfillmentMap &&fulfillments,
558559
}
559560

560561
} else {
562+
assert(fulfillment.first.isMetadata());
563+
561564
// Ignore type metadata fulfillments for non-dependent types that
562565
// we can produce very cheaply. We don't want to end up emitting
563566
// the type metadata for Int by chasing through N layers of metadata

0 commit comments

Comments
 (0)