Skip to content

Commit 874360e

Browse files
committed
GenericCloner: make sure that we can always specialize in mandatory mode
This may involve changing the linkage of the specialized function. If called from a serialized function we cannot make the specialized function shared and non-serialized. The only other option is to keep the original function's linkage. rdar://121675461
1 parent 7fb4fc0 commit 874360e

File tree

4 files changed

+40
-9
lines changed

4 files changed

+40
-9
lines changed

lib/SILOptimizer/Utils/GenericCloner.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ using namespace swift;
3232
SILFunction *GenericCloner::createDeclaration(
3333
SILOptFunctionBuilder &FunctionBuilder, SILFunction *Orig,
3434
const ReabstractionInfo &ReInfo, StringRef NewName) {
35-
assert((!ReInfo.isSerialized() || Orig->isSerialized())
36-
&& "Specialization cannot make body more resilient");
3735
assert((Orig->isTransparent() || Orig->isBare() || Orig->getLocation())
3836
&& "SILFunction missing location");
3937
assert((Orig->isTransparent() || Orig->isBare() || Orig->getDebugScope())

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,11 +3210,17 @@ void swift::trySpecializeApplyOfGeneric(
32103210
// not have an external entry point, Since the callee is not
32113211
// fragile we cannot serialize the body of the specialized
32123212
// callee either.
3213-
if (F->isSerialized() && !RefF->hasValidLinkageForFragileInline())
3214-
return;
3213+
bool needSetLinkage = false;
3214+
if (isMandatory) {
3215+
if (F->isSerialized() && !RefF->hasValidLinkageForFragileInline())
3216+
needSetLinkage = true;
3217+
} else {
3218+
if (F->isSerialized() && !RefF->hasValidLinkageForFragileInline())
3219+
return;
32153220

3216-
if (shouldNotSpecialize(RefF, F))
3217-
return;
3221+
if (shouldNotSpecialize(RefF, F))
3222+
return;
3223+
}
32183224

32193225
// If the caller and callee are both fragile, preserve the fragility when
32203226
// cloning the callee. Otherwise, strip it off so that we can optimize
@@ -3331,7 +3337,15 @@ void swift::trySpecializeApplyOfGeneric(
33313337
return;
33323338
}
33333339

3334-
if (F->isSerialized() && !SpecializedF->hasValidLinkageForFragileInline()) {
3340+
if (needSetLinkage) {
3341+
assert(F->isSerialized() && !RefF->hasValidLinkageForFragileInline());
3342+
// If called from a serialized function we cannot make the specialized function
3343+
// shared and non-serialized. The only other option is to keep the original
3344+
// function's linkage. It's not great, because it can prevent dead code
3345+
// elimination - usually the original function is a public function.
3346+
SpecializedF->setLinkage(RefF->getLinkage());
3347+
SpecializedF->setSerialized(IsNotSerialized);
3348+
} else if (F->isSerialized() && !SpecializedF->hasValidLinkageForFragileInline()) {
33353349
// If the specialized function already exists as a "IsNotSerialized" function,
33363350
// but now it's called from a "IsSerialized" function, we need to mark it as
33373351
// IsSerialized.

test/SILOptimizer/mandatory_performance_optimizations.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,14 @@ bb0(%0 : $Int, %1 : $@thick Int.Type, %2 : @owned $Builtin.NativeObject):
256256
return %2 : $Builtin.NativeObject
257257
}
258258

259-
// CHECK-LABEL: sil shared [ossa] @$s12metatype_argTf4dnn_n : $@convention(thin) (Int, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
259+
// CHECK-LABEL: sil [ossa] @$s12metatype_argTf4dnn_n : $@convention(thin) (Int, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
260260
// CHECK: bb0(%0 : $Int, %1 : @owned $Builtin.NativeObject):
261261
// CHECK: %2 = metatype $@thick Int.Type
262262
// CHECK: fix_lifetime %2 : $@thick Int.Type
263263
// CHECK: return %1 : $Builtin.NativeObject
264264
// CHECK: } // end sil function '$s12metatype_argTf4dnn_n'
265265

266-
// CHECK-LABEL: sil shared [ossa] @$s19metatype_arg_throwsTf4dnn_n : $@convention(thin) (Int, @owned Builtin.NativeObject) -> (@owned Builtin.NativeObject, @error any Error) {
266+
// CHECK-LABEL: sil [ossa] @$s19metatype_arg_throwsTf4dnn_n : $@convention(thin) (Int, @owned Builtin.NativeObject) -> (@owned Builtin.NativeObject, @error any Error) {
267267
// CHECK: bb0(%0 : $Int, %1 : @owned $Builtin.NativeObject):
268268
// CHECK: %2 = metatype $@thick Int.Type
269269
// CHECK: fix_lifetime %2 : $@thick Int.Type

test/embedded/default-arguments.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -emit-ir %s -enable-experimental-feature Embedded -o /dev/null
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: VENDOR=apple
5+
// REQUIRES: OS=macosx
6+
7+
// Check that this doesn't crash the compiler in embedded mode.
8+
9+
public func foo<T>(_ t: T) -> T {
10+
t
11+
}
12+
13+
public func testit(_ x: Int = foo(27)) -> Int {
14+
x
15+
}
16+
17+
public func callit() -> Int {
18+
testit()
19+
}

0 commit comments

Comments
 (0)