Skip to content

Commit eda0080

Browse files
authored
Merge pull request #40020 from nate-chandler/mem2reg/leverage-lack-of-critical-edges
2 parents e4bbb46 + ee9d309 commit eda0080

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,11 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
666666
runningVals = beginLexicalLifetimeAfterStore(asi, si);
667667
// Create a use of the newly created copy in order to keep phi pruning
668668
// from deleting our lifetime beginning instructions.
669+
//
670+
// TODO: Remove this hack, it is only necessary because erasePhiArgument
671+
// calls deleteEdgeValue which calls
672+
// deleteTriviallyDeadOperandsOfDeadArgument and deletes the copy
673+
// and borrow that we added and want not to have deleted.
669674
SILBuilderWithScope::insertAfter(
670675
runningVals->value.copy->getDefiningInstruction(),
671676
[&](auto builder) {
@@ -1665,22 +1670,30 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
16651670
GraphNodeWorklist<SILBasicBlock *, 2> worklist;
16661671
worklist.initialize(parentBlock);
16671672
while (auto *block = worklist.pop()) {
1673+
assert(domInfo->dominates(parentBlock, block));
16681674
auto *terminator = block->getTerminator();
16691675
if (isa<UnreachableInst>(terminator)) {
16701676
endLexicalLifetimeBeforeInst(asi, /*beforeInstruction=*/terminator, ctx,
16711677
runningVals->value);
16721678
continue;
16731679
}
1674-
bool endedLifetime = false;
1675-
for (auto *successor : block->getSuccessorBlocks()) {
1676-
if (!domInfo->dominates(parentBlock, successor)) {
1677-
endLexicalLifetimeBeforeInst(asi, /*beforeInstruction=*/terminator,
1678-
ctx, runningVals->value);
1679-
endedLifetime = true;
1680-
break;
1681-
}
1682-
}
1683-
if (endedLifetime) {
1680+
SILBasicBlock *successor = nullptr;
1681+
// If any successor is not dominated by the parentBlock, then we must end
1682+
// the lifetime before that successor.
1683+
//
1684+
// Suppose that a successor is not dominated by parentBlock. Recall that
1685+
// block _is_ dominated by parentBlock. Thus that successor must have
1686+
// more than one predecessor: block, and at least one other. (Otherwise
1687+
// it would be dominated by parentBlock contrary to our assumption.)
1688+
// Recall that SIL does not allow critical edges. Therefore block has
1689+
// only a single successor.
1690+
//
1691+
// Use the above fact to only look for lack of domination of a successor
1692+
// if that successor is the single successor of block.
1693+
if ((successor = block->getSingleSuccessorBlock()) &&
1694+
(!domInfo->dominates(parentBlock, successor))) {
1695+
endLexicalLifetimeBeforeInst(asi, /*beforeInstruction=*/terminator, ctx,
1696+
runningVals->value);
16841697
continue;
16851698
}
16861699
for (auto *successor : block->getSuccessorBlocks()) {

test/SILOptimizer/mem2reg_lifetime.sil

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,7 @@ entry(%instance : @owned $C):
15481548
}
15491549

15501550

1551+
// End lifetime before unreachable inst.
15511552
// CHECK-LABEL: sil [ossa] @unreachable_5 : $@convention(thin) (@owned C) -> () {
15521553
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
15531554
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
@@ -1567,6 +1568,7 @@ exit:
15671568
unreachable
15681569
}
15691570

1571+
// Bail out if alloc_stack is in unreachable block.
15701572
// CHECK-LABEL: sil [ossa] @unreachable_6 : $@convention(thin) (@owned C) -> () {
15711573
// CHECK: alloc_stack [lexical]
15721574
// CHECK-LABEL: } // end sil function 'unreachable_6'
@@ -1585,6 +1587,7 @@ exit:
15851587
}
15861588

15871589

1590+
// Bail out if alloc_stack is in unreachable block.
15881591
// CHECK-LABEL: sil [ossa] @unreachable_7 : $@convention(thin) (@owned C) -> () {
15891592
// CHECK: alloc_stack [lexical]
15901593
// CHECK-LABEL: } // end sil function 'unreachable_7'
@@ -1606,7 +1609,7 @@ exit:
16061609
return %res : $()
16071610
}
16081611

1609-
1612+
// Bail out if alloc_stack is in unreachable block.
16101613
// CHECK-LABEL: sil [ossa] @unreachable_8 : $@convention(thin) (@owned C) -> () {
16111614
// CHECK: alloc_stack [lexical]
16121615
// CHECK-LABEL: } // end sil function 'unreachable_8'
@@ -1632,7 +1635,7 @@ exit:
16321635
return %res : $()
16331636
}
16341637

1635-
1638+
// End lifetime after loop which is followed by unreachable.
16361639
// CHECK-LABEL: sil [ossa] @unreachable_loop_1 : $@convention(thin) () -> () {
16371640
// CHECK: {{bb[0-9]+}}:
16381641
// CHECK: [[GET_C:%[^,]+]] = function_ref @getC : $@convention(thin) () -> @owned C
@@ -1672,7 +1675,7 @@ die:
16721675
unreachable
16731676
}
16741677

1675-
1678+
// Bail out if alloc_stack is in unreachable block.
16761679
// CHECK-LABEL: sil [ossa] @unreachable_loop_2 : $@convention(thin) () -> () {
16771680
// CHECK: alloc_stack [lexical]
16781681
// CHECK-LABEL: } // end sil function 'unreachable_loop_2'
@@ -1697,7 +1700,7 @@ die:
16971700
unreachable
16981701
}
16991702

1700-
1703+
// Bail out if alloc_stack is in unreachable block.
17011704
// CHECK-LABEL: sil [ossa] @unreachable_loop_3 : $@convention(thin) () -> () {
17021705
// CHECK: alloc_stack [lexical]
17031706
// CHECK-LABEL: } // end sil function 'unreachable_loop_3'

0 commit comments

Comments
 (0)