Skip to content

Commit 1248faa

Browse files
authored
Merge pull request #11901 from gottesmm/pr-6b12d7d6cffff0304c0d0d41d31df5b499d54f3f
[mandatory-inline] Move fixupReferenceCounts to /before/ inlining.
2 parents 2afb3c8 + 6b12d7d commit 1248faa

File tree

5 files changed

+96
-42
lines changed

5 files changed

+96
-42
lines changed

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -479,24 +479,8 @@ runOnFunctionRecursively(SILFunction *F, FullApplySite AI,
479479

480480
// If we intend to inline a thick function, then we need to balance the
481481
// reference counts for correctness.
482-
if (IsThick && II != ApplyBlock->begin()) {
483-
// We need to find an appropriate location for our fix up code
484-
// We used to do this after inlining Without any modifications
485-
// This caused us to add a release in a wrong place:
486-
// It would release a value *before* retaining it!
487-
// It is really problematic to do this after inlining -
488-
// Finding a valid insertion point is tricky:
489-
// Inlining might add new basic blocks and/or remove the apply
490-
// We want to add the fix up *just before* where the current apply is!
491-
// Unfortunately, we *can't* add the fix up code here:
492-
// Inlining might fail for any reason -
493-
// If that occurred we'd need to undo our fix up code.
494-
// Instead, we split the current basic block -
495-
// Making sure we have a basic block that starts with our apply.
496-
SILBuilderWithScope B(II);
497-
ApplyBlock = splitBasicBlockAndBranch(B, &*II, nullptr, nullptr);
498-
II = ApplyBlock->begin();
499-
}
482+
if (IsThick)
483+
fixupReferenceCounts(II, CalleeValue, CaptureArgs);
500484

501485
// Decrement our iterator (carefully, to avoid going off the front) so it
502486
// is valid after inlining is done. Inlining deletes the apply, and can
@@ -515,11 +499,6 @@ runOnFunctionRecursively(SILFunction *F, FullApplySite AI,
515499
// Update the iterator when instructions are removed.
516500
DeleteInstructionsHandler DeletionHandler(II);
517501

518-
// If the inlined apply was a thick function, then we need to balance the
519-
// reference counts for correctness.
520-
if (IsThick)
521-
fixupReferenceCounts(II, CalleeValue, CaptureArgs);
522-
523502
// Now that the IR is correct, see if we can remove dead callee
524503
// computations (e.g. dead partial_apply closures).
525504
cleanupCalleeValue(CalleeValue, CaptureArgs, FullArgs);

test/IRGen/big_types_corner_cases.sil

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,77 @@ bb0:
138138
sil private @part_apply_callee : $@convention(thin) (@owned Builtin.Int64, () -> @owned BigStruct) -> @owned BigStruct {
139139
bb0(%0 : $Builtin.Int64, %1 : $() -> @owned BigStruct):
140140
return undef : $BigStruct
141-
}
141+
}
142+
143+
//////////////////////
144+
// Autoclosure Test //
145+
//////////////////////
146+
147+
class SuperBase {
148+
}
149+
150+
class SuperSub : SuperBase {
151+
}
152+
153+
sil @boom : $@convention(thin) (@guaranteed SuperBase) -> BigStruct
154+
155+
sil [transparent] @autoclosure_rhs : $@convention(thin) (@owned SuperSub) -> (BigStruct, @error Error) {
156+
bb0(%0 : $SuperSub):
157+
strong_retain %0 : $SuperSub
158+
%5 = upcast %0 : $SuperSub to $SuperBase
159+
%6 = function_ref @boom : $@convention(thin) (@guaranteed SuperBase) -> BigStruct
160+
%7 = apply %6(%5) : $@convention(thin) (@guaranteed SuperBase) -> BigStruct
161+
strong_release %5 : $SuperBase
162+
strong_release %0 : $SuperSub
163+
return %7 : $BigStruct
164+
}
165+
166+
sil @get_optional_none : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
167+
sil @short_circuit_operation : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, @owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error)
168+
sil @autoclosure_partialapply : $@convention(thin) (@owned @callee_owned () -> (BigStruct, @error Error)) -> (@out BigStruct, @error Error)
169+
170+
// CHECK-LABEL: define{{( protected)?}} swiftcc void @closure(%T22big_types_corner_cases9BigStructV* noalias nocapture sret, %T22big_types_corner_cases8SuperSubC*) #0 {
171+
// CHECK-64: [[ALLOC1:%.*]] = alloca %T22big_types_corner_cases9BigStructV
172+
// CHECK-64: [[ALLOC2:%.*]] = alloca %T22big_types_corner_cases9BigStructV
173+
// CHECK-64: [[ALLOC3:%.*]] = alloca %T22big_types_corner_cases9BigStructVSg
174+
// CHECK-64: [[ALLOC4:%.*]] = alloca %T22big_types_corner_cases9BigStructVSg
175+
// CHECK-64: call swiftcc void @_T022big_types_corner_cases8SuperSubC1fyyFAA9BigStructVycfU_AFyKXKfu_TA(%T22big_types_corner_cases9BigStructV* noalias nocapture sret [[ALLOC1]], %swift.refcounted* swiftself {{.*}}, %swift.error** nocapture swifterror %swifterror)
176+
// CHECK: ret void
177+
sil @closure : $@convention(thin) (@owned SuperSub) -> BigStruct {
178+
bb0(%0 : $SuperSub):
179+
%2 = function_ref @short_circuit_operation : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, @owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error)
180+
%3 = alloc_stack $BigStruct
181+
%4 = function_ref @get_optional_none : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
182+
%5 = alloc_stack $Optional<BigStruct>
183+
%6 = metatype $@thin Optional<BigStruct>.Type
184+
%7 = apply %4<BigStruct>(%5, %6) : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
185+
%8 = load %5 : $*Optional<BigStruct>
186+
%9 = alloc_stack $Optional<BigStruct>
187+
store %8 to %9 : $*Optional<BigStruct>
188+
189+
%11 = function_ref @autoclosure_rhs : $@convention(thin) (@owned SuperSub) -> (BigStruct, @error Error)
190+
strong_retain %0 : $SuperSub
191+
%13 = partial_apply %11(%0) : $@convention(thin) (@owned SuperSub) -> (BigStruct, @error Error)
192+
193+
%14 = function_ref @autoclosure_partialapply : $@convention(thin) (@owned @callee_owned () -> (BigStruct, @error Error)) -> (@out BigStruct, @error Error)
194+
%15 = partial_apply %14(%13) : $@convention(thin) (@owned @callee_owned () -> (BigStruct, @error Error)) -> (@out BigStruct, @error Error)
195+
try_apply %2<BigStruct>(%3, %9, %15) : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, @owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error), normal bb1, error bb2
196+
197+
bb1(%17 : $()):
198+
dealloc_stack %9 : $*Optional<BigStruct>
199+
dealloc_stack %5 : $*Optional<BigStruct>
200+
%20 = load %3 : $*BigStruct
201+
dealloc_stack %3 : $*BigStruct
202+
strong_release %0 : $SuperSub
203+
return %20 : $BigStruct
204+
205+
bb2(%24 : $Error):
206+
unreachable
207+
}
208+
209+
sil_vtable SuperBase {
210+
}
211+
212+
sil_vtable SuperSub {
213+
}
214+

test/IRGen/big_types_corner_cases.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public func enumCallee(_ x: LargeEnum) {
152152
// CHECK-64: [[ALLOC2:%.*]] = alloca %T22big_types_corner_cases9BigStructV
153153
// CHECK-64: [[ALLOC3:%.*]] = alloca %T22big_types_corner_cases9BigStructVSg
154154
// CHECK-64: [[ALLOC4:%.*]] = alloca %T22big_types_corner_cases9BigStructVSg
155-
// CHECK-64: call swiftcc void @_T022big_types_corner_cases8SuperSubC1fyyFAA9BigStructVycfU_AFyKXKfu_TA(%T22big_types_corner_cases9BigStructV* noalias nocapture sret [[ALLOC1]], %swift.refcounted* swiftself {{.*}}, %swift.error** nocapture swifterror %swifterror)
155+
// CHECK-64: call swiftcc void @_T022big_types_corner_cases9SuperBaseC4boomAA9BigStructVyF(%T22big_types_corner_cases9BigStructV* noalias nocapture sret [[ALLOC1]], %T22big_types_corner_cases9SuperBaseC* swiftself {{.*}})
156156
// CHECK: ret void
157157
class SuperBase {
158158
func boom() -> BigStruct {

test/SILOptimizer/mandatory_inlining.sil

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -522,15 +522,12 @@ bb0(%0 : $@callee_owned (@owned Builtin.NativeObject) -> @owned Builtin.NativeOb
522522
// CHECK: bb2:
523523
// CHECK: strong_retain [[ARG]]
524524
// CHECK: strong_retain [[PAI]]
525-
// CHECK: br bb3
526-
//
527-
// CHECK: bb3:
528525
// CHECK: strong_retain [[ARG]]
529526
// CHECK: strong_release [[PAI]]
530527
// CHECK: [[FN2:%.*]] = function_ref @nativeobject_plus :
531528
// CHECK: [[RESULT:%.*]] = apply [[FN2]]([[ARG]], [[ARG]])
532529
//
533-
// CHECK: bb4:
530+
// CHECK: bb3:
534531
// CHECK: strong_retain [[PAI]]
535532
// CHECK: [[OPAQUE_FN:%.*]] = function_ref @partial_apply_user
536533
// CHECK: apply [[OPAQUE_FN]]([[PAI]])
@@ -589,8 +586,10 @@ bb1:
589586
br bb3(%10 : $Bool)
590587

591588
bb2:
589+
%m2 = integer_literal $Builtin.Int32, 2 // Marker
592590
%12 = load %3a : $*@callee_owned () -> Bool
593591
strong_retain %12 : $@callee_owned () -> Bool
592+
%m3 = integer_literal $Builtin.Int32, 3 // Marker
594593
%14 = apply %12() : $@callee_owned () -> Bool
595594
br bb3(%14 : $Bool)
596595

@@ -619,20 +618,22 @@ sil @test_short_circuit : $@convention(thin) (Bool, Bool) -> Bool {
619618
// CHECK: br [[BB2:.*]](
620619

621620
// CHECK: [[BB2]](
622-
// CHECK: br [[BB5:.*]](
621+
// CHECK: br [[BB4:.*]](
623622

624623
// CHECK: bb3:
625-
// CHECK: br bb4
626-
627-
// CHECK: [[BB4]]:
624+
// CHECK: [[OLD_CALLEE:%.*]] = load {{%[0-9]+}} :
625+
// CHECK: strong_retain [[OLD_CALLEE]]
626+
// Separation marker
627+
// CHECK: integer_literal $Builtin.Int32, 3
628628
// CHECK: strong_retain [[VAL4:%[0-9]*]]
629+
// CHECK: strong_release [[OLD_CALLEE]]
629630
// CHECK: [[ADDR4:%.*]] = project_box [[VAL4]]
630631
// CHECK: {{%.*}} = tuple ()
631632
// CHECK: {{%.*}} = load [[ADDR4]]
632633
// CHECK: strong_release [[VAL4]]
633634
// CHECK: br [[BB2]](
634635

635-
// CHECK: [[BB5]](
636+
// CHECK: [[BB4]](
636637
// CHECK: strong_release [[VAL4]]
637638
// CHECK: return {{.*}}
638639

@@ -648,6 +649,7 @@ bb0(%0 : $Bool, %1 : $Bool):
648649
%8 = function_ref @closure0 : $@convention(thin) (@owned { var Bool }) -> Bool
649650
strong_retain %3 : ${ var Bool }
650651
%10 = partial_apply %8(%3) : $@convention(thin) (@owned { var Bool }) -> Bool
652+
%12 = integer_literal $Builtin.Int32, 1 // Marker
651653
%11 = apply %6(%7, %10) : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool
652654
strong_release %3 : ${ var Bool }
653655
strong_release %2 : ${ var Bool }
@@ -666,11 +668,15 @@ sil @test_short_circuit2 : $@convention(thin) (Bool, Bool) -> Bool {
666668
// CHECK: [[BB2]](
667669
// CHECK: br [[BB5:.*]](
668670

669-
// CHECK: bb3:
670-
// CHECK: br bb4
671-
672-
// CHECK: [[BB4]]:
671+
// CHECK: [[BB3]]:
672+
// Marker -
673+
// CHECK: integer_literal $Builtin.Int32, 2
674+
// CHECK: [[OLD_CALLEE:%.*]] = load {{%.*}}
675+
// CHECK: strong_retain [[OLD_CALLEE]]
676+
// Marker -
677+
// CHECK: integer_literal $Builtin.Int32, 3
673678
// CHECK: strong_retain [[VAL4:%[0-9]*]]
679+
// CHECK: strong_release [[OLD_CALLEE]]
674680
// CHECK: [[ADDR4:%.*]] = project_box [[VAL4]]
675681
// CHECK: {{%.*}} = tuple ()
676682
// CHECK: {{%.*}} = load [[ADDR4]]
@@ -968,8 +974,6 @@ bb0(%0 : $@callee_owned () -> Builtin.Int8):
968974
// CHECK-LABEL: sil @testouter_transparent
969975
sil @testouter_transparent : $@convention(thin) (Builtin.Int8) -> Builtin.Int8 {
970976
// CHECK: bb0
971-
// CHECK-NEXT: br bb1
972-
// CHECK: bb1
973977
// CHECK-NEXT: return
974978
bb0(%0 : $Builtin.Int8):
975979
%2 = function_ref @outer_transparent : $@convention(thin) (@owned @callee_owned () -> Builtin.Int8) -> Builtin.Int8

test/SILOptimizer/mandatory_inlining.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ func call_let_auto_closure(_ x: @autoclosure () -> Bool) -> Bool {
136136
// CHECK: sil hidden @{{.*}}test_let_auto_closure_with_value_capture
137137
// CHECK: bb0(%0 : $Bool):
138138
// CHECK-NEXT: debug_value %0 : $Bool
139-
// CHECK-NEXT: br bb1
140-
// CHECK: bb1:
141139
// CHECK-NEXT: return %0 : $Bool
142140

143141
func test_let_auto_closure_with_value_capture(_ x: Bool) -> Bool {

0 commit comments

Comments
 (0)