Skip to content

Commit 1d47d3c

Browse files
committed
[OME] Erase dead_end lifetime ends.
Such instructions are inserted to ensure complete OSSA lifetimes and should be removed when lowering out of OSSA.
1 parent dd730b8 commit 1d47d3c

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

lib/SIL/Utils/OSSALifetimeCompletion.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static SILInstruction *endOSSALifetime(SILValue value,
7676
}
7777
return builder.createDestroyValue(loc, value, DontPoisonRefs, isDeadEnd);
7878
}
79-
return builder.createEndBorrow(loc, value, isDeadEnd);
79+
return builder.createEndBorrow(loc, value);
8080
}
8181

8282
static bool endLifetimeAtLivenessBoundary(SILValue value,

lib/SILOptimizer/Mandatory/OwnershipModelEliminator.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ struct OwnershipModelEliminatorVisitor
141141

142142
void splitDestroy(DestroyValueInst *destroy);
143143
bool visitDestroyValueInst(DestroyValueInst *dvi);
144+
bool visitDeallocBoxInst(DeallocBoxInst *dbi) {
145+
if (!dbi->isDeadEnd())
146+
return false;
147+
148+
// dead_end instructions are required for complete OSSA lifetimes but should
149+
// not exist post-OSSA.
150+
eraseInstruction(dbi);
151+
return true;
152+
}
144153
bool visitLoadBorrowInst(LoadBorrowInst *lbi);
145154
bool visitMoveValueInst(MoveValueInst *mvi) {
146155
eraseInstructionAndRAUW(mvi, mvi->getOperand());
@@ -571,6 +580,13 @@ void OwnershipModelEliminatorVisitor::splitDestroy(DestroyValueInst *destroy) {
571580

572581
bool OwnershipModelEliminatorVisitor::visitDestroyValueInst(
573582
DestroyValueInst *dvi) {
583+
if (dvi->isDeadEnd()) {
584+
// dead_end instructions are required for complete OSSA lifetimes but should
585+
// not exist post-OSSA.
586+
eraseInstruction(dvi);
587+
return true;
588+
}
589+
574590
// Nonescaping closures are represented ultimately as trivial pointers to
575591
// their context, but we use ownership to do borrow checking of their captures
576592
// in OSSA. Now that we're eliminating ownership, fold away destroys.

test/SILOptimizer/ownership_model_eliminator.sil

+45
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,48 @@ bb0(%0 : @guaranteed $C, %1 : $*C):
411411
return %t : $()
412412
}
413413

414+
// CHECK-LABEL: sil @test_dead_end_destroy_value : {{.*}} {
415+
// CHECK: bb0([[C:%[^,]+]] :
416+
// CHECK: cond_br undef, [[DIE:bb[0-9]+]], [[EXIT:bb[0-9]+]]
417+
// CHECK: [[DIE]]:
418+
// Verify that there's no release_value before this trap.
419+
// CHECK-NEXT: unreachable
420+
// CHECK: [[EXIT]]:
421+
// CHECK: strong_release [[C]]
422+
// CHECK-LABEL: } // end sil function 'test_dead_end_destroy_value'
423+
sil [ossa] @test_dead_end_destroy_value : $@convention(thin) (@owned C) -> () {
424+
entry(%c : @owned $C):
425+
cond_br undef, die, exit
426+
427+
die:
428+
destroy_value [dead_end] %c : $C
429+
unreachable
430+
431+
exit:
432+
destroy_value %c : $C
433+
%retval = tuple ()
434+
return %retval : $()
435+
}
436+
437+
// CHECK-LABEL: sil @test_dead_end_dealloc_box : {{.*}} {
438+
// CHECK: [[B:%[^,]+]] = alloc_box
439+
// CHECK: cond_br undef, [[DIE:bb[0-9]+]], [[EXIT:bb[0-9]+]]
440+
// CHECK: [[DIE]]:
441+
// CHECK-NEXT: unreachable
442+
// CHECK: [[EXIT]]:
443+
// CHECK: dealloc_box [[B]]
444+
// CHECK-LABEL: } // end sil function 'test_dead_end_dealloc_box'
445+
sil [ossa] @test_dead_end_dealloc_box : $@convention(thin) () -> () {
446+
entry:
447+
%b = alloc_box ${ var C }
448+
cond_br undef, die, exit
449+
450+
die:
451+
dealloc_box [dead_end] %b : ${ var C }
452+
unreachable
453+
454+
exit:
455+
dealloc_box %b : ${ var C }
456+
%retval = tuple ()
457+
return %retval : $()
458+
}

0 commit comments

Comments
 (0)