[embedded] avoid metadata accessors, fix vtable map, add a diagnostic on non-final generic functions

This commit is contained in:
Kuba Mracek
2023-09-12 16:57:09 -07:00
parent d2bb064548
commit e2de477609
7 changed files with 59 additions and 41 deletions

View File

@@ -358,6 +358,8 @@ ERROR(bad_attr_on_non_const_global,none,
"global variable must be a compile-time constant to use %0 attribute", (StringRef)) "global variable must be a compile-time constant to use %0 attribute", (StringRef))
ERROR(global_must_be_compile_time_const,none, ERROR(global_must_be_compile_time_const,none,
"global variable must be a compile-time constant", ()) "global variable must be a compile-time constant", ())
ERROR(non_final_generic_class_function,none,
"classes cannot have non-final generic fuctions in embedded Swift", ())
NOTE(performance_called_from,none, NOTE(performance_called_from,none,
"called from here", ()) "called from here", ())

View File

@@ -5006,7 +5006,6 @@ void irgen::emitEmbeddedClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
fragileLayout); fragileLayout);
metadataBuilder.layout(); metadataBuilder.layout();
bool canBeConstant = metadataBuilder.canBeConstant(); bool canBeConstant = metadataBuilder.canBeConstant();
metadataBuilder.createMetadataAccessFunction();
CanType declaredType = classDecl->getDeclaredType()->getCanonicalType(); CanType declaredType = classDecl->getDeclaredType()->getCanonicalType();

View File

@@ -42,9 +42,10 @@ SILVTable *SILVTable::create(SILModule &M, ClassDecl *Class, SILType classType,
auto buf = M.allocate(size, alignof(SILVTable)); auto buf = M.allocate(size, alignof(SILVTable));
SILVTable *vt = ::new (buf) SILVTable(Class, classType, Serialized, Entries); SILVTable *vt = ::new (buf) SILVTable(Class, classType, Serialized, Entries);
M.vtables.push_back(vt); M.vtables.push_back(vt);
M.VTableMap[Class] = vt;
if (vt->isSpecialized()) if (vt->isSpecialized())
M.SpecializedVTableMap[classType] = vt; M.SpecializedVTableMap[classType] = vt;
else
M.VTableMap[Class] = vt;
// Update the Module's cache with new vtable + vtable entries: // Update the Module's cache with new vtable + vtable entries:
for (const Entry &entry : Entries) { for (const Entry &entry : Entries) {
M.VTableEntryCache.insert({{vt, entry.getMethod()}, entry}); M.VTableEntryCache.insert({{vt, entry.getMethod()}, entry});

View File

@@ -17,6 +17,7 @@
#define DEBUG_TYPE "sil-vtable-specializer" #define DEBUG_TYPE "sil-vtable-specializer"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/ProtocolConformance.h" #include "swift/AST/ProtocolConformance.h"
#include "swift/SIL/OptimizationRemark.h" #include "swift/SIL/OptimizationRemark.h"
#include "swift/SIL/SILFunction.h" #include "swift/SIL/SILFunction.h"
@@ -81,26 +82,10 @@ bool VTableSpecializer::specializeVTables(SILModule &module) {
for (SILVTableEntry &entry : vtable->getMutableEntries()) { for (SILVTableEntry &entry : vtable->getMutableEntries()) {
SILFunction *method = entry.getImplementation(); SILFunction *method = entry.getImplementation();
if (!method->getLoweredFunctionType()->isPolymorphic()) continue; if (!method->getLoweredFunctionType()->isPolymorphic()) continue;
if (entry.getKind() != SILVTableEntry::Kind::Inherited) { ValueDecl *decl = entry.getMethod().getDecl();
vtable->dump(); module.getASTContext().Diags.diagnose(
entry.getMethod().dump(); decl->getLoc(), diag::non_final_generic_class_function);
}
assert(entry.getKind() == SILVTableEntry::Kind::Inherited);
Decl *classOfMethod =
entry.getMethod().getDecl()->getDeclContext()->getAsDecl();
SILType classTy = vtable->getClassType();
while (classTy.getClassOrBoundGenericClass() != classOfMethod) {
classTy = classTy.getSuperclass();
}
auto *classDecl = cast<ClassDecl>(classOfMethod);
SubstitutionMap subs = classTy.getASTType()->getContextSubstitutionMap(
classDecl->getParentModule(), classDecl);
SILFunction *specializedMethod =
specializeVTableMethod(method, subs, module);
entry.setImplementation(specializedMethod);
vtable->updateVTableCache(entry);
} }
} }
@@ -153,9 +138,6 @@ SILFunction *VTableSpecializer::specializeVTableMethod(SILFunction *origMethod,
if (!origMethod->getLoweredFunctionType()->isPolymorphic()) return origMethod; if (!origMethod->getLoweredFunctionType()->isPolymorphic()) return origMethod;
LLVM_DEBUG(llvm::dbgs() << "specializeVTableMethod " << origMethod->getName()
<< '\n');
ReabstractionInfo ReInfo(module.getSwiftModule(), module.isWholeModule(), ReabstractionInfo ReInfo(module.getSwiftModule(), module.isWholeModule(),
ApplySite(), origMethod, subs, IsNotSerialized, ApplySite(), origMethod, subs, IsNotSerialized,
/*ConvertIndirectToDirect=*/true, /*ConvertIndirectToDirect=*/true,

View File

@@ -1,4 +1,5 @@
// RUN: %target-swift-emit-ir %s -parse-stdlib -enable-experimental-feature Embedded -target arm64e-apple-none | %FileCheck %s // RUN: %target-swift-emit-sil %s -parse-stdlib -enable-experimental-feature Embedded -target arm64e-apple-none | %FileCheck %s --check-prefix CHECK-SIL
// RUN: %target-swift-emit-ir %s -parse-stdlib -enable-experimental-feature Embedded -target arm64e-apple-none | %FileCheck %s --check-prefix CHECK-IR
precedencegroup AssignmentPrecedence { assignment: true } precedencegroup AssignmentPrecedence { assignment: true }
@@ -18,17 +19,46 @@ public func bar(t: T2) -> MyClass<T2> {
return MyClass<T2>(t: t) return MyClass<T2>(t: t)
} }
// CHECK: @"$s4main7MyClassCyAA2T2VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvgAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T1V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5" }> // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1txvgAA2T1V_Tg5 {{.*}}{
// CHECK: @"$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" }> // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1txvsAA2T1V_Tg5 {{.*}}{
// CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1txvMAA2T1V_Tg5 {{.*}}{
// CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tgm5 {{.*}}{
// CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassCfDAA2T1V_Tg5 {{.*}}{
// CHECK: define {{.*}}void @"$s4main7MyClassC1txvgAA2T1V_Tg5"(ptr swiftself %0) // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1txvgAA2T2V_Tg5 {{.*}}{
// CHECK: define {{.*}}void @"$s4main7MyClassC1txvsAA2T1V_Tg5"(ptr swiftself %0) // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1txvsAA2T2V_Tg5 {{.*}}{
// CHECK: define {{.*}}ptr @"$s4main2T1VWOd"(ptr %0, ptr %1) // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1txvMAA2T2V_Tg5 {{.*}}{
// CHECK: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tgm5"() // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tgm5 {{.*}}{
// CHECK: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tgm5"(i1 %0) // CHECK-SIL-DAG: sil {{.*}}@$s4main7MyClassCfDAA2T2V_Tg5 {{.*}}{
// CHECK: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5"(ptr swiftself %0)
// CHECK: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T1V_Tg5"(ptr swiftself %0) // CHECK-SIL: sil_vtable MyClass {
// CHECK: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T2V_Tg5"(i1 %0, ptr swiftself %1) // CHECK-SIL: #MyClass.t!getter: <T> (MyClass<T>) -> () -> T : @$s4main7MyClassC1txvgAA2T1V_Tg5 // specialized MyClass.t.getter
// CHECK: define {{.*}}void @"$s4main7MyClassCfDAA2T1V_Tg5"(ptr swiftself %0) // CHECK-SIL: #MyClass.t!setter: <T> (MyClass<T>) -> (T) -> () : @$s4main7MyClassC1txvsAA2T1V_Tg5 // specialized MyClass.t.setter
// CHECK: define {{.*}}ptr @"$s4main3foo1tAA7MyClassCyAA2T1VGAG_tF"() // CHECK-SIL: #MyClass.t!modify: <T> (MyClass<T>) -> () -> () : @$s4main7MyClassC1txvMAA2T1V_Tg5 // specialized MyClass.t.modify
// CHECK: define {{.*}}ptr @"$s4main3bar1tAA7MyClassCyAA2T2VGAG_tF"(i1 %0) // CHECK-SIL: #MyClass.init!allocator: <T> (MyClass<T>.Type) -> (T) -> MyClass<T> : @$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5 // specialized MyClass.__allocating_init(t:)
// CHECK-SIL: #MyClass.deinit!deallocator: @$s4main7MyClassCfDAA2T1V_Tg5 // specialized MyClass.__deallocating_deinit
// CHECK-SIL: }
// CHECK-SIL: sil_vtable MyClass {
// CHECK-SIL: #MyClass.t!getter: <T> (MyClass<T>) -> () -> T : @$s4main7MyClassC1txvgAA2T2V_Tg5 // specialized MyClass.t.getter
// CHECK-SIL: #MyClass.t!setter: <T> (MyClass<T>) -> (T) -> () : @$s4main7MyClassC1txvsAA2T2V_Tg5 // specialized MyClass.t.setter
// CHECK-SIL: #MyClass.t!modify: <T> (MyClass<T>) -> () -> () : @$s4main7MyClassC1txvMAA2T2V_Tg5 // specialized MyClass.t.modify
// CHECK-SIL: #MyClass.init!allocator: <T> (MyClass<T>.Type) -> (T) -> MyClass<T> : @$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tg5 // specialized MyClass.__allocating_init(t:)
// CHECK-SIL: #MyClass.deinit!deallocator: @$s4main7MyClassCfDAA2T2V_Tg5 // specialized MyClass.__deallocating_deinit
// CHECK-SIL: }
// 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" }>
// 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" }>
// CHECK-IR: define {{.*}}void @"$s4main7MyClassC1txvgAA2T1V_Tg5"(ptr swiftself %0)
// CHECK-IR: define {{.*}}void @"$s4main7MyClassC1txvsAA2T1V_Tg5"(ptr swiftself %0)
// CHECK-IR: define {{.*}}ptr @"$s4main2T1VWOd"(ptr %0, ptr %1)
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tgm5"()
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tgm5"(i1 %0)
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5"(ptr swiftself %0)
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T1V_Tg5"(ptr swiftself %0)
// CHECK-IR: define {{.*}}ptr @"$s4main7MyClassC1tACyxGx_tcfcAA2T2V_Tg5"(i1 %0, ptr swiftself %1)
// CHECK-IR: define {{.*}}void @"$s4main7MyClassCfDAA2T1V_Tg5"(ptr swiftself %0)
// CHECK-IR: define {{.*}}ptr @"$s4main3foo1tAA7MyClassCyAA2T1VGAG_tF"()
// CHECK-IR: define {{.*}}ptr @"$s4main3bar1tAA7MyClassCyAA2T2VGAG_tF"(i1 %0)

View File

@@ -7,7 +7,6 @@ public class MyClass {}
// CHECK-DAG: define {{.*}}void @"$s4main7MyClassCfD" // CHECK-DAG: define {{.*}}void @"$s4main7MyClassCfD"
// CHECK-DAG: define {{.*}}ptr @"$s4main7MyClassCACycfC" // CHECK-DAG: define {{.*}}ptr @"$s4main7MyClassCACycfC"
// CHECK-DAG: define {{.*}}ptr @"$s4main7MyClassCACycfc" // CHECK-DAG: define {{.*}}ptr @"$s4main7MyClassCACycfc"
// CHECK-DAG: define {{.*}}%swift.metadata_response @"$s4main7MyClassCMa"
public func foo() -> MyClass { public func foo() -> MyClass {
return MyClass() return MyClass()
@@ -21,7 +20,6 @@ public class MySubClass: MyClass {}
// CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCACycfc" // CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCACycfc"
// CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCfd" // CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCfd"
// CHECK-DAG: define {{.*}}void @"$s4main10MySubClassCfD" // CHECK-DAG: define {{.*}}void @"$s4main10MySubClassCfD"
// CHECK-DAG: define {{.*}}%swift.metadata_response @"$s4main10MySubClassCMa"
public func bar() -> MyClass { public func bar() -> MyClass {
return MySubClass() return MySubClass()

View File

@@ -0,0 +1,6 @@
// RUN: %target-swift-emit-ir -verify %s -parse-stdlib -enable-experimental-feature Embedded -target arm64e-apple-none
public class MyClass {
func foo<T>(t: T) { } // expected-error {{classes cannot have non-final generic fuctions in embedded Swift}}
func bar() { }
}