Skip to content

Commit c2d5d60

Browse files
committed
[IRGen] Prepare to lazily emit prespecializations.
Added worklist of prespecializations awaiting lazy emission to IRGenModule. Added map from type decl to list of bound types for which prespecializations will be emitted. For now, no specializations are emitted.
1 parent 9ea71d1 commit c2d5d60

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,7 @@ void IRGenerator::emitTypeMetadataRecords() {
11291129
/// else) that we require.
11301130
void IRGenerator::emitLazyDefinitions() {
11311131
while (!LazyTypeMetadata.empty() ||
1132+
!LazySpecializedTypeMetadataRecords.empty() ||
11321133
!LazyTypeContextDescriptors.empty() ||
11331134
!LazyOpaqueTypeDescriptors.empty() ||
11341135
!LazyFieldDescriptors.empty() ||
@@ -1145,6 +1146,11 @@ void IRGenerator::emitLazyDefinitions() {
11451146
CurrentIGMPtr IGM = getGenModule(type->getDeclContext());
11461147
emitLazyTypeMetadata(*IGM.get(), type);
11471148
}
1149+
while (!LazySpecializedTypeMetadataRecords.empty()) {
1150+
CanType type = LazySpecializedTypeMetadataRecords.pop_back_val();
1151+
auto *nominal = type->getNominalOrBoundGenericNominal();
1152+
CurrentIGMPtr IGM = getGenModule(nominal->getDeclContext());
1153+
}
11481154
while (!LazyTypeContextDescriptors.empty()) {
11491155
NominalTypeDecl *type = LazyTypeContextDescriptors.pop_back_val();
11501156
auto &entry = LazyTypeGlobals.find(type)->second;
@@ -1362,6 +1368,18 @@ void IRGenerator::noteUseOfFieldDescriptor(NominalTypeDecl *type) {
13621368
LazyFieldDescriptors.push_back(type);
13631369
}
13641370

1371+
void IRGenerator::noteUseOfSpecializedGenericTypeMetadata(CanType type) {
1372+
auto key = type->getAnyNominal();
1373+
assert(key);
1374+
auto &enqueuedSpecializedTypes = this->SpecializationsForGenericTypes[key];
1375+
if (llvm::all_of(enqueuedSpecializedTypes,
1376+
[&](CanType enqueued) { return enqueued != type; })) {
1377+
assert(!FinishedEmittingLazyDefinitions);
1378+
this->LazySpecializedTypeMetadataRecords.push_back(type);
1379+
enqueuedSpecializedTypes.push_back(type);
1380+
}
1381+
}
1382+
13651383
void IRGenerator::noteUseOfOpaqueTypeDescriptor(OpaqueTypeDecl *opaque) {
13661384
if (!opaque)
13671385
return;

lib/IRGen/IRGenModule.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,15 @@ class IRGenerator {
244244
/// queued up.
245245
llvm::SmallPtrSet<NominalTypeDecl *, 4> LazilyEmittedFieldMetadata;
246246

247+
/// Maps every generic type that is specialized within the module to its
248+
/// specializations.
249+
llvm::DenseMap<NominalTypeDecl *, llvm::SmallVector<CanType, 4>>
250+
SpecializationsForGenericTypes;
251+
252+
/// The queue of specialized generic types whose prespecialized metadata to
253+
/// emit.
254+
llvm::SmallVector<CanType, 4> LazySpecializedTypeMetadataRecords;
255+
247256
struct LazyOpaqueInfo {
248257
bool IsDescriptorUsed = false;
249258
bool IsDescriptorEmitted = false;
@@ -375,10 +384,16 @@ class IRGenerator {
375384

376385
void ensureRelativeSymbolCollocation(SILDefaultWitnessTable &wt);
377386

387+
llvm::SmallVector<CanType, 4> specializationsForType(NominalTypeDecl *type) {
388+
return SpecializationsForGenericTypes.lookup(type);
389+
}
390+
378391
void noteUseOfTypeMetadata(NominalTypeDecl *type) {
379392
noteUseOfTypeGlobals(type, true, RequireMetadata);
380393
}
381394

395+
void noteUseOfSpecializedGenericTypeMetadata(CanType type);
396+
382397
void noteUseOfTypeMetadata(CanType type) {
383398
type.visit([&](Type t) {
384399
if (auto *nominal = t->getAnyNominal())

0 commit comments

Comments
 (0)