Skip to content

Commit d93e65d

Browse files
authored
[SILOpt] Apply _Class pre-specializations to wrapped single references (#70170)
* [SILOpt] Apply _Class pre-specializations to wrapped single references rdar://119047505 A struct wrapping a single reference has an identical layout to the reference itself, so we can apply the same pre-specializations. * Add test case for overaligned struct
1 parent 86d9e2c commit d93e65d

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,9 +2988,17 @@ bool usePrespecialized(
29882988

29892989
if (!erased || !layout || !layout->isClass()) {
29902990
newSubs.push_back(entry.value());
2991-
} else if (!entry.value()->isAnyClassReferenceType() ||
2992-
entry.value()->isAnyExistentialType()) {
2993-
// non-reference or existential type can't be applied
2991+
continue;
2992+
}
2993+
2994+
auto lowered = refF->getLoweredType(entry.value());
2995+
while (auto singleton = lowered.getSingletonAggregateFieldType(
2996+
refF->getModule(), refF->getResilienceExpansion())) {
2997+
lowered = singleton;
2998+
}
2999+
3000+
if (!lowered.hasRetainablePointerRepresentation()) {
3001+
// non-reference type can't be applied
29943002
break;
29953003
} else if (!specializedSig->getRequiredProtocols(genericParam)
29963004
.empty()) {

test/SILOptimizer/pre_specialize_layouts.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ import pre_specialized_module_layouts
2222
@inline(never)
2323
public func consume<T>(_ x: T) {}
2424

25+
public struct ReferenceWrapperStruct {
26+
let x: AnyObject
27+
}
28+
29+
@_alignment(16)
30+
public struct OveralignedReferenceWrapperStruct {
31+
let x: AnyObject
32+
}
33+
2534
// Make sure we generate the public pre-specialized entry points.
2635

2736
// OPT-DAG: sil @$s22pre_specialize_layouts10testPublic1tyx_tlFSf_Ts5 : $@convention(thin) (Float) -> () {
@@ -63,7 +72,8 @@ internal func testEmitIntoClient<T>(t: T) {
6372
print(t)
6473
}
6574

66-
// OPT: sil @$s22pre_specialize_layouts28usePrespecializedEntryPointsyyF : $@convention(thin) () -> () {
75+
// OPT: sil @$s22pre_specialize_layouts28usePrespecializedEntryPoints13wrapperStruct11overalignedyAA016ReferenceWrapperI0V_AA011OveralignedklI0VtF : $@convention(thin) (@guaranteed ReferenceWrapperStruct, @guaranteed OveralignedReferenceWrapperStruct) -> () {
76+
// OPT: bb0([[P1:%.*]] : $ReferenceWrapperStruct, [[P2:%.*]] : $OveralignedReferenceWrapperStruct):
6777
// OPT: [[F1:%.*]] = function_ref @$s30pre_specialized_module_layouts20publicPrespecializedyyxlFSi_Ts5 : $@convention(thin) (Int) -> ()
6878
// OPT: apply [[F1]]
6979
// OPT: [[F2:%.*]] = function_ref @$s30pre_specialized_module_layouts20publicPrespecializedyyxlFSd_Ts5 : $@convention(thin) (Double) -> ()
@@ -73,13 +83,17 @@ internal func testEmitIntoClient<T>(t: T) {
7383
// OPT: [[F7:%.*]] = function_ref @$s30pre_specialized_module_layouts20publicPrespecializedyyxlFyXl_Ts5 : $@convention(thin) (@guaranteed AnyObject) -> ()
7484
// OPT: [[A1:%.*]] = unchecked_ref_cast {{%.*}} : $SomeClass to $AnyObject
7585
// OPT: apply [[F7]]([[A1]]) : $@convention(thin) (@guaranteed AnyObject) -> ()
86+
// OPT: [[A2:%.*]] = unchecked_bitwise_cast [[P1]] : $ReferenceWrapperStruct to $AnyObject
87+
// OPT: apply [[F7]]([[A2]]) : $@convention(thin) (@guaranteed AnyObject) -> ()
88+
// OPT: [[A3:%.*]] = alloc_stack $OveralignedReferenceWrapperStruct
89+
// OPT: apply {{%.*}}<OveralignedReferenceWrapperStruct>([[A3]])
7690
// OPT: [[F3:%.*]] = function_ref @$s30pre_specialized_module_layouts36internalEmitIntoClientPrespecializedyyxlFSi_Ts5 : $@convention(thin) (Int) -> ()
7791
// OPT: apply [[F3]]
7892
// OPT: [[F4:%.*]] = function_ref @$s30pre_specialized_module_layouts36internalEmitIntoClientPrespecializedyyxlFSd_Ts5 : $@convention(thin) (Double) -> ()
7993
// OPT: apply [[F4]]
8094
// OPT: [[F5:%.*]] = function_ref @$s30pre_specialized_module_layouts16useInternalThingyyxlFSi_Tg5
8195
// OPT: apply [[F5]]({{.*}}) : $@convention(thin) (Int) -> ()
82-
// OPT: } // end sil function '$s22pre_specialize_layouts28usePrespecializedEntryPointsyyF'
96+
// OPT: } // end sil function '$s22pre_specialize_layouts28usePrespecializedEntryPoints13wrapperStruct11overalignedyAA016ReferenceWrapperI0V_AA011OveralignedklI0VtF'
8397

8498
// OPT: sil {{.*}} @$s30pre_specialized_module_layouts16useInternalThingyyxlFSi_Tg5 : $@convention(thin) (Int) -> () {
8599
// OPT: [[F1:%.*]] = function_ref @$s30pre_specialized_module_layouts14InternalThing2V7computexyFSi_Ts5 : $@convention(method) (InternalThing2<Int>) -> Int
@@ -124,11 +138,14 @@ internal func testEmitIntoClient<T>(t: T) {
124138
// OPT: [[R10:%.*]] = unchecked_addr_cast [[R9]] : $*AnyObject to $*SomeClass
125139
// OPT: } // end sil function '$s30pre_specialized_module_layouts16useInternalThingyyxlFAA9SomeClassC_Tg5'
126140

127-
public func usePrespecializedEntryPoints() {
141+
public func usePrespecializedEntryPoints(wrapperStruct: ReferenceWrapperStruct, overaligned: OveralignedReferenceWrapperStruct) {
128142
publicPrespecialized(1)
129143
publicPrespecialized(1.0)
130144
publicPrespecialized(SomeData())
131145
publicPrespecialized(SomeClass())
146+
publicPrespecialized(wrapperStruct)
147+
// should not apply _Class specialization for overaligned struct
148+
publicPrespecialized(overaligned)
132149
useInternalEmitIntoClientPrespecialized(2)
133150
useInternalEmitIntoClientPrespecialized(2.0)
134151
useInternalThing(2)

0 commit comments

Comments
 (0)