Eager specializer: Fix pre-specialization of imported code

We must no pre-specialize imported code (except if this was explicitly
called for by the importing module).

Therefore, don't pre-specialize `shared` definitions based on their
pre-specialization attributes.

Rather, only pre-specialize if the pre-specialization is called for
using a `target: "theFunctionToSpecialize"` parameter.

Run OnonePrespecializations before serialization so that module native functions
are not yet marked `shared` and can be identified as native.

rdar://92337361
This commit is contained in:
Arnold Schwaighofer
2022-05-03 09:19:03 -07:00
parent 4f8678563c
commit bcf24e4715
5 changed files with 36 additions and 8 deletions

View File

@@ -943,6 +943,11 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
// be no need to run another analysis of copies at -Onone.
P.addMandatoryARCOpts();
// Create pre-specializations.
// This needs to run pre-serialization because it needs to identify native
// inlinable functions from imported ones.
P.addOnonePrespecializations();
// First serialize the SIL if we are asked to.
P.startPipeline("Serialization");
P.addSerializeSILPass();
@@ -962,9 +967,6 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) {
P.addAssumeSingleThreaded();
}
// Create pre-specializations.
P.addOnonePrespecializations();
// Has only an effect if the -sil-based-debuginfo option is specified.
P.addSILDebugInfoGenerator();

View File

@@ -853,6 +853,14 @@ void EagerSpecializerTransform::run() {
assert(success);
}
onlyCreatePrespecializations = true;
} else if (targetFunc->getLinkage() == SILLinkage::Shared) {
// We have `shared` linkage if we deserialize a public serialized
// function.
// That means we are loading it from another module. In this case, we
// don't want to create a pre-specialization.
SpecializedFuncs.push_back(nullptr);
ReInfoVec.emplace_back(ReabstractionInfo());
continue;
}
ReInfoVec.emplace_back(FuncBuilder.getModule().getSwiftModule(),
FuncBuilder.getModule().isWholeModule(), targetFunc,

View File

@@ -848,6 +848,24 @@ bb0(%0 : $*T):
return %8 : $Builtin.Int64
}
// Don't specialize `shared` definitions they are imported from another module.
// CHECK-NOT: sil @$s24testDontSpecializeSharedSi_Ts5
sil shared [_specialize exported: true, kind: full, where T == Int] @testDontSpecializeShared : $@convention(thin) <T>(@in T) -> () {
bb(%0: $*T):
destroy_addr %0 : $*T
%t = tuple()
return %t : $()
}
// But do specialize `shared` definitions when they are target from another // function.
// CHECK: sil @$s24testDontSpecializeSharedSd_Ts5
sil shared [_specialize exported: true, kind: full, target: "testDontSpecializeShared" ,where T == Double] @butSpecializeWhenTargetIsPresent : $@convention(thin) <T>(@in T) -> () {
bb(%0: $*T):
destroy_addr %0 : $*T
%t = tuple()
return %t : $()
}
sil_vtable ClassUsingThrowingP {
#ClassUsingThrowingP.init!allocator: (ClassUsingThrowingP.Type) -> () -> ClassUsingThrowingP : @$s34eager_specialize_throwing_function19ClassUsingThrowingPCACycfC // ClassUsingThrowingP.__allocating_init()
#ClassUsingThrowingP.init!initializer: (ClassUsingThrowingP.Type) -> () -> ClassUsingThrowingP : @$s34eager_specialize_throwing_function19ClassUsingThrowingPCACycfc // ClassUsingThrowingP.init()

View File

@@ -79,6 +79,6 @@ public class CC<T : PP> {
}
}
// CHECK-DAG: sil [serialized] [_specialize exported: false, kind: full, where T == Int, U == Float] [canonical] [ossa] @$s14serialize_attr14specializeThis_1uyx_q_tr0_lF : $@convention(thin) <T, U> (@in_guaranteed T, @in_guaranteed U) -> () {
// CHECK-DAG: sil [serialized] [canonical] [ossa] @$s14serialize_attr14specializeThis_1uyx_q_tr0_lF : $@convention(thin) <T, U> (@in_guaranteed T, @in_guaranteed U) -> () {
// CHECK-DAG: sil [serialized] [noinline] [_specialize exported: false, kind: full, where T == RR, U == SS] [canonical] [ossa] @$s14serialize_attr2CCC3foo_1gqd___AA2GGVyxGtqd___AHtAA2QQRd__lF : $@convention(method) <T where T : PP><U where U : QQ> (@in_guaranteed U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
// CHECK-DAG: sil [serialized] [noinline] [canonical] [ossa] @$s14serialize_attr2CCC3foo_1gqd___AA2GGVyxGtqd___AHtAA2QQRd__lF : $@convention(method) <T where T : PP><U where U : QQ> (@in_guaranteed U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {

View File

@@ -2,13 +2,13 @@
// CHECK: ---
// CHECK: name: Non-Diagnostic Mandatory Optimizations
// CHECK: passes: [ "for-each-loop-unroll", "mandatory-combine",
// CHECK: "mandatory-arc-opts" ]
// CHECK: passes: [ "for-each-loop-unroll", "mandatory-combine", "mandatory-arc-opts",
// CHECK: "onone-prespecializer" ]
// CHECK: ---
// CHECK: name: Serialization
// CHECK: passes: [ "serialize-sil", "sil-onone-debuginfo-canonicalizer",
// CHECK-NEXT: "ownership-model-eliminator" ]
// CHECK: ---
// CHECK: name: Rest of Onone
// CHECK: passes: [ "use-prespecialized", "onone-prespecializer", "sil-debuginfo-gen" ]
// CHECK: passes: [ "use-prespecialized", "sil-debuginfo-gen" ]
// CHECK: ...