Skip to content

Commit eb8d9f4

Browse files
authored
Merge pull request #77575 from atrick/preserve_extend_lifetime
Preserve extend_lifetime during dead instruction code elimination.
2 parents 452ae3b + b30fd77 commit eb8d9f4

File tree

4 files changed

+66
-13
lines changed

4 files changed

+66
-13
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ extension Instruction {
308308
// Don't remove UncheckedEnumDataInst in OSSA in case it is responsible
309309
// for consuming an enum value.
310310
return !parentFunction.hasOwnership
311+
case is ExtendLifetimeInst:
312+
// An extend_lifetime can only be removed if the operand is also removed.
313+
// If its operand is trivial, it will be removed by MandatorySimplification.
314+
return false
311315
default:
312316
break
313317
}

lib/SILOptimizer/Mandatory/MoveOnlyWrappedTypeEliminator.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -311,19 +311,6 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
311311
// - record its users for later visitation
312312
auto visitValue = [&touchedInsts, fn = fn,
313313
trivialOnly = trivialOnly](SILValue value) -> bool {
314-
// Trivial move_value instructions are relevant. After they are stripped,
315-
// any extend_lifetime uses are also stripped.
316-
if (isa<MoveValueInst>(value)
317-
&& value->getOwnershipKind() == OwnershipKind::None) {
318-
for (auto *use : value->getNonTypeDependentUses()) {
319-
auto *user = use->getUser();
320-
if (isa<ExtendLifetimeInst>(user)) {
321-
touchedInsts.insert(user);
322-
}
323-
}
324-
return true;
325-
}
326-
327314
if (!value->getType().hasAnyMoveOnlyWrapping(fn))
328315
return false;
329316

@@ -366,6 +353,10 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
366353

367354
touched = true;
368355
}
356+
// delete trivial move_value and extend_lifetime instructions.
357+
if (isa<MoveValueInst>(ii) || isa<ExtendLifetimeInst>(ii)) {
358+
touched = true;
359+
}
369360
if (!touched)
370361
continue;
371362
touchedInsts.insert(&ii);

test/SILOptimizer/moveonly_type_eliminator.sil

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,40 @@ bb0:
637637
%13 = tuple ()
638638
return %13 : $()
639639
}
640+
641+
// Remove trivial move_value + extend_lifetime
642+
//
643+
// CHECK-LABEL: sil [ossa] @move_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
644+
// CHECK: bb0(%0 : $@thin Trivial.Type):
645+
// CHECK-NOT: move_value
646+
// CHECK-NOT: extend_lifetime
647+
// CHECK-LABEL: } // end sil function 'move_extend_lifetime'
648+
sil [ossa] @move_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
649+
bb0(%0 : $@thin Trivial.Type):
650+
%mv = move_value [var_decl] %0 : $@thin Trivial.Type
651+
extend_lifetime %mv : $@thin Trivial.Type
652+
%13 = tuple ()
653+
return %13 : $()
654+
}
655+
656+
sil @captureType : $@convention(thin) (@thin Trivial.Type) -> ()
657+
sil @takeClosure : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
658+
659+
// SILGen pattern binding can (incorrectly) create a local variable to hold the value a function argument. This results
660+
// in an extend_lifetime that directly uses the argument value. Ensure that MoveOnlyTypeEliminator erases the
661+
// extend_lifetime.
662+
//
663+
// CHECK-LABEL: sil [ossa] @arg_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
664+
// CHECK-NOT: extend_lifetime
665+
// CHECK-LABEL: } // end sil function 'arg_extend_lifetime'
666+
sil [ossa] @arg_extend_lifetime : $@convention(thin) (@thin Trivial.Type) -> () {
667+
bb0(%0 : $@thin Trivial.Type):
668+
%cf = function_ref @captureType : $@convention(thin) (@thin Trivial.Type) -> ()
669+
%closure = partial_apply [callee_guaranteed] [on_stack] %cf(%0) : $@convention(thin) (@thin Trivial.Type) -> ()
670+
%f = function_ref @takeClosure : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
671+
%6 = apply %f(%closure) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
672+
destroy_value %closure : $@noescape @callee_guaranteed () -> ()
673+
extend_lifetime %0 : $@thin Trivial.Type
674+
%13 = tuple ()
675+
return %13 : $()
676+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
5+
sil_stage raw
6+
7+
import Builtin
8+
import Swift
9+
import SwiftShims
10+
11+
// extend_lifetime should not be eliminated as dead code.
12+
//
13+
// CHECK-LABEL: sil [ossa] @do_not_remove_extend : $@convention(thin) (Int) -> () {
14+
// CHECK: extend_lifetime %0 : $Int
15+
// CHECK-LABEL: } // end sil function 'do_not_remove_extend'
16+
sil [ossa] @do_not_remove_extend : $@convention(thin) (Int) -> () {
17+
bb0(%0 : $Int):
18+
extend_lifetime %0 : $Int
19+
%4 = tuple ()
20+
return %4 : $()
21+
}

0 commit comments

Comments
 (0)