Skip to content

Commit 5608520

Browse files
committed
[embedded] specialize generic classes based on MetatypeInst too, fix lazy emit assert
1 parent e2de477 commit 5608520

File tree

5 files changed

+51
-38
lines changed

5 files changed

+51
-38
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ void IRGenModule::emitGlobalLists() {
12391239
// Eagerly emit functions that are externally visible. Functions that are
12401240
// dynamic replacements must also be eagerly emitted.
12411241
static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
1242-
// Embedded Swift only emits specialized function, so don't emit genreic
1242+
// Embedded Swift only emits specialized function, so don't emit generic
12431243
// functions, even if they're externally visible.
12441244
if (f.getASTContext().LangOpts.hasFeature(Feature::Embedded) &&
12451245
f.getLoweredFunctionType()->getSubstGenericSignature()) {
@@ -1412,13 +1412,19 @@ deleteAndReenqueueForEmissionValuesDependentOnCanonicalPrespecializedMetadataRec
14121412
void IRGenerator::emitLazyDefinitions() {
14131413
if (SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
14141414
// In embedded Swift, the compiler cannot emit any metadata, etc.
1415-
LazyTypeMetadata.clear();
1416-
LazySpecializedTypeMetadataRecords.clear();
1417-
LazyTypeContextDescriptors.clear();
1418-
LazyOpaqueTypeDescriptors.clear();
1419-
LazyCanonicalSpecializedMetadataAccessors.clear();
1420-
LazyMetadataAccessors.clear();
1421-
LazyWitnessTables.clear();
1415+
assert(LazyTypeMetadata.empty());
1416+
assert(LazySpecializedTypeMetadataRecords.empty());
1417+
assert(LazyTypeContextDescriptors.empty());
1418+
assert(LazyOpaqueTypeDescriptors.empty());
1419+
assert(LazyFieldDescriptors.empty());
1420+
// LazyFunctionDefinitions are allowed, but they must not be generic
1421+
for (SILFunction *f : LazyFunctionDefinitions) {
1422+
assert(!f->getLoweredFunctionType()->getSubstGenericSignature());
1423+
}
1424+
assert(LazyWitnessTables.empty());
1425+
assert(LazyCanonicalSpecializedMetadataAccessors.empty());
1426+
assert(LazyMetadataAccessors.empty());
1427+
// LazySpecializedClassMetadata is allowed
14221428
}
14231429

14241430
while (!LazyTypeMetadata.empty() ||
@@ -1493,9 +1499,8 @@ void IRGenerator::emitLazyDefinitions() {
14931499
while (!LazyFunctionDefinitions.empty()) {
14941500
SILFunction *f = LazyFunctionDefinitions.pop_back_val();
14951501
CurrentIGMPtr IGM = getGenModule(f);
1496-
// XXX TODO
1497-
//assert(!f->isPossiblyUsedExternally()
1498-
// && "function with externally-visible linkage emitted lazily?");
1502+
assert(!f->isPossiblyUsedExternally()
1503+
&& "function with externally-visible linkage emitted lazily?");
14991504
IGM->emitSILFunction(f);
15001505
}
15011506

@@ -1536,6 +1541,10 @@ void IRGenerator::addLazyFunction(SILFunction *f) {
15361541
// Add it to the queue if it hasn't already been put there.
15371542
if (!LazilyEmittedFunctions.insert(f).second)
15381543
return;
1544+
1545+
if (SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1546+
assert(!f->getLoweredFunctionType()->getSubstGenericSignature());
1547+
}
15391548

15401549
assert(!FinishedEmittingLazyDefinitions);
15411550
LazyFunctionDefinitions.push_back(f);

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {
234234
// occur before IRGen.
235235
P.addMoveOnlyTypeEliminator();
236236

237+
// For embedded Swift: Specialize generic class vtables.
238+
P.addVTableSpecializer();
239+
237240
P.addMandatoryPerformanceOptimizations();
238241
P.addOnoneSimplification();
239242
P.addInitializeStaticGlobals();
@@ -1007,9 +1010,6 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
10071010
// For embedded Swift: CMO is used to serialize libraries.
10081011
P.addCrossModuleOptimization();
10091012

1010-
// For embedded Swift: Specialize generic class vtables.
1011-
P.addVTableSpecializer();
1012-
10131013
// First serialize the SIL if we are asked to.
10141014
P.startPipeline("Serialization");
10151015
P.addSerializeSILPass();

lib/SILOptimizer/Transforms/VTableSpecializer.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace {
3838

3939
class VTableSpecializer : public SILModuleTransform {
4040
bool specializeVTables(SILModule &module);
41-
bool specializeVTableFor(AllocRefInst *allocRef, SILModule &module);
41+
bool specializeVTableFor(SILType classTy, SILModule &module);
4242
SILFunction *specializeVTableMethod(SILFunction *origMethod,
4343
SubstitutionMap subs, SILModule &module);
4444
bool specializeClassMethodInst(ClassMethodInst *cm);
@@ -65,12 +65,12 @@ bool VTableSpecializer::specializeVTables(SILModule &module) {
6565
for (SILBasicBlock &block : func) {
6666
for (SILInstruction &inst : block) {
6767
if (auto *allocRef = dyn_cast<AllocRefInst>(&inst)) {
68-
changed |= specializeVTableFor(allocRef, module);
69-
continue;
70-
}
71-
if (auto *cm = dyn_cast<ClassMethodInst>(&inst)) {
68+
changed |= specializeVTableFor(allocRef->getType(), module);
69+
} else if (auto *metatype = dyn_cast<MetatypeInst>(&inst)) {
70+
changed |= specializeVTableFor(
71+
metatype->getType().getInstanceTypeOfMetatype(&func), module);
72+
} else if (auto *cm = dyn_cast<ClassMethodInst>(&inst)) {
7273
changed |= specializeClassMethodInst(cm);
73-
continue;
7474
}
7575
}
7676
}
@@ -92,17 +92,17 @@ bool VTableSpecializer::specializeVTables(SILModule &module) {
9292
return changed;
9393
}
9494

95-
bool VTableSpecializer::specializeVTableFor(AllocRefInst *allocRef,
95+
bool VTableSpecializer::specializeVTableFor(SILType classTy,
9696
SILModule &module) {
97-
SILType classTy = allocRef->getType();
9897
CanType astType = classTy.getASTType();
9998
BoundGenericClassType *genClassTy = dyn_cast<BoundGenericClassType>(astType);
10099
if (!genClassTy) return false;
101100

102101
if (module.lookUpSpecializedVTable(classTy)) return false;
103102

104-
LLVM_DEBUG(llvm::dbgs() << "specializeVTableFor "
105-
<< genClassTy->getDecl()->getName() << '\n');
103+
LLVM_DEBUG(llvm::errs() << "specializeVTableFor "
104+
<< genClassTy->getDecl()->getName() << ' '
105+
<< genClassTy->getString() << '\n');
106106

107107
ClassDecl *classDecl = genClassTy->getDecl();
108108
SILVTable *origVtable = module.lookUpVTable(classDecl);
@@ -133,7 +133,7 @@ bool VTableSpecializer::specializeVTableFor(AllocRefInst *allocRef,
133133
SILFunction *VTableSpecializer::specializeVTableMethod(SILFunction *origMethod,
134134
SubstitutionMap subs,
135135
SILModule &module) {
136-
LLVM_DEBUG(llvm::dbgs() << "specializeVTableMethod " << origMethod->getName()
136+
LLVM_DEBUG(llvm::errs() << "specializeVTableMethod " << origMethod->getName()
137137
<< '\n');
138138

139139
if (!origMethod->getLoweredFunctionType()->isPolymorphic()) return origMethod;

test/embedded/basic-modules-no-stdlib.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
// RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/MyModule.swiftmodule %t/MyModule.swift -parse-stdlib -enable-experimental-feature Embedded
55
// RUN: %target-swift-frontend -swift-version 5 -emit-ir -I %t %t/Main.swift -parse-stdlib -enable-experimental-feature Embedded | %FileCheck %s
66

7-
// TODO: investigate why windows is generating more metadata.
8-
// XFAIL: OS=windows-msvc
7+
// REQUIRES: swift_in_compiler
98

109
// BEGIN MyModule.swift
1110

test/embedded/classes-generic-no-stdlib.swift

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %target-swift-emit-sil %s -parse-stdlib -enable-experimental-feature Embedded -target arm64e-apple-none | %FileCheck %s --check-prefix CHECK-SIL
22
// RUN: %target-swift-emit-ir %s -parse-stdlib -enable-experimental-feature Embedded -target arm64e-apple-none | %FileCheck %s --check-prefix CHECK-IR
33

4+
// REQUIRES: swift_in_compiler
5+
46
precedencegroup AssignmentPrecedence { assignment: true }
57

68
public struct T1 {}
@@ -51,14 +53,17 @@ public func bar(t: T2) -> MyClass<T2> {
5153
// CHECK-IR: @"$s4main7MyClassCyAA2T2VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvgAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T2V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tg5" }>
5254
// CHECK-IR: @"$s4main7MyClassCyAA2T1VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvgAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T1V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5" }>
5355

54-
// CHECK-IR: define {{.*}}void @"$s4main7MyClassC1txvgAA2T1V_Tg5"(ptr swiftself %0)
55-
// CHECK-IR: define {{.*}}void @"$s4main7MyClassC1txvsAA2T1V_Tg5"(ptr swiftself %0)
56-
// CHECK-IR: define {{.*}}ptr @"$s4main2T1VWOd"(ptr %0, ptr %1)
57-
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tgm5"()
58-
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tgm5"(i1 %0)
59-
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5"(ptr swiftself %0)
60-
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T1V_Tg5"(ptr swiftself %0)
61-
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T2V_Tg5"(i1 %0, ptr swiftself %1)
62-
// CHECK-IR: define {{.*}}void @"$s4main7MyClassCfDAA2T1V_Tg5"(ptr swiftself %0)
63-
// CHECK-IR: define {{.*}}ptr @"$s4main3foo1tAA7MyClassCyAA2T1VGAG_tF"()
64-
// CHECK-IR: define {{.*}}ptr @"$s4main3bar1tAA7MyClassCyAA2T2VGAG_tF"(i1 %0)
56+
// CHECK-IR-DAG: define {{.*}}void @"$s4main7MyClassC1txvgAA2T1V_Tg5"(ptr swiftself %0)
57+
// CHECK-IR-DAG: define {{.*}}i1 @"$s4main7MyClassC1txvgAA2T2V_Tg5"(ptr swiftself %0)
58+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5"(ptr swiftself %0)
59+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tg5"(i1 %0, ptr swiftself %1)
60+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tgm5"()
61+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tgm5"(i1 %0)
62+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T1V_Tg5"(ptr swiftself %0)
63+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T2V_Tg5"(i1 %0, ptr swiftself %1)
64+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassCfdAA2T1V_Tg5"(ptr swiftself %0)
65+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main7MyClassCfdAA2T2V_Tg5"(ptr swiftself %0)
66+
// CHECK-IR-DAG: define {{.*}}void @"$s4main7MyClassCfDAA2T1V_Tg5"(ptr swiftself %0)
67+
// CHECK-IR-DAG: define {{.*}}void @"$s4main7MyClassCfDAA2T2V_Tg5"(ptr swiftself %0)
68+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main3foo1tAA7MyClassCyAA2T1VGAG_tF"()
69+
// CHECK-IR-DAG: define {{.*}}ptr @"$s4main3bar1tAA7MyClassCyAA2T2VGAG_tF"(i1 %0)

0 commit comments

Comments
 (0)