mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[embedded] avoid metadata accessors, fix vtable map, add a diagnostic on non-final generic functions
This commit is contained in:
@@ -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", ())
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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});
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
6
test/embedded/classes-non-final-method-no-stdlib.swift
Normal file
6
test/embedded/classes-non-final-method-no-stdlib.swift
Normal 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() { }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user