mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix MultiDefPrunedLiveness; add boundaries for dead end blocks.
Make sure liveness reports a complete boundary even for OSSA lifetimes that are incomplete. Definition blocks can be on the liveness boundary in this case.
This commit is contained in:
@@ -578,6 +578,11 @@ void MultiDefPrunedLiveness::findBoundariesInBlock(
|
||||
boundary.deadDefs.push_back(deadArg);
|
||||
}
|
||||
}
|
||||
if (auto *predBB = block->getSinglePredecessorBlock()) {
|
||||
if (getBlockLiveness(predBB) == PrunedLiveBlocks::LiveOut) {
|
||||
boundary.boundaryEdges.push_back(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
// All live-within blocks must contain a boundary.
|
||||
assert(isLiveOut
|
||||
|
||||
@@ -176,7 +176,9 @@ bb0(%0 : @guaranteed $D):
|
||||
return %99 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @testMultiDef
|
||||
// A LiveOut block with a non-SSA def, bb0, has no liveness boundary.
|
||||
//
|
||||
// CHECK-LABEL: @testMultiDefLiveOutNoBoundary
|
||||
// CHECK: MultiDef lifetime analysis:
|
||||
// CHECK: def: [[CP0:%.*]] = copy_value %0 : $C
|
||||
// CHECK: def: %{{.*}} = copy_value %0 : $C
|
||||
@@ -187,12 +189,12 @@ bb0(%0 : @guaranteed $D):
|
||||
// CHECK: bb3: LiveWithin,
|
||||
// CHECK: bb4: LiveWithin,
|
||||
// CHECK: bb1: LiveWithin,
|
||||
// CHECK: lifetime-ending user: %{{.*}} = move_value [[CP0]] : $C
|
||||
// CHECK: lifetime-ending user: destroy_value [[CP0]] : $C
|
||||
// CHECK: lifetime-ending user: br bb4(%5 : $C)
|
||||
// CHECK: lifetime-ending user: br bb4(%7 : $C)
|
||||
// CHECK: lifetime-ending user: destroy_value %9 : $C
|
||||
sil [ossa] @testMultiDef : $@convention(thin) (@guaranteed C) -> () {
|
||||
// CHECK: last user: br bb4
|
||||
// CHECK-NEXT: last user: br bb4
|
||||
// CHECK-NEXT: last user: %{{.*}} = move_value [[CP0]] : $C
|
||||
// CHECK-NEXT: last user: destroy_value %{{.*}} : $C
|
||||
// CHECK-NEXT: last user: destroy_value [[CP0]] : $C
|
||||
sil [ossa] @testMultiDefLiveOutNoBoundary : $@convention(thin) (@guaranteed C) -> () {
|
||||
bb0(%0 : @guaranteed $C):
|
||||
%copy0 = copy_value %0 : $C
|
||||
debug_value [trace] %copy0 : $C
|
||||
@@ -218,3 +220,33 @@ bb4(%phi : @owned $C):
|
||||
%99 = tuple()
|
||||
return %99 : $()
|
||||
}
|
||||
|
||||
// A dead-end block with a def can still be a boundary edge. This can
|
||||
// only happen in OSSA with incomplete lifetimes.
|
||||
//
|
||||
// CHECK-LABEL: @testMultiDefDeadDefBoundaryEdge
|
||||
// CHECK: MultiDef lifetime analysis:
|
||||
// CHECK: def: [[CP0:%.*]] = copy_value %0 : $C
|
||||
// CHECK: def: [[CP3:%.*]] = copy_value %0 : $C
|
||||
// CHECK: bb0: LiveOut,
|
||||
// CHECK: bb1: LiveWithin,
|
||||
// CHECK: bb2: LiveWithin,
|
||||
// CHECK: last user: destroy_value [[CP0]] : $C
|
||||
// CHECK-NEXT: boundary edge: bb1
|
||||
// CHECK-NEXT: dead def: [[CP3]] = copy_value %0 : $C
|
||||
sil [ossa] @testMultiDefDeadDefBoundaryEdge : $@convention(thin) (@guaranteed C) -> () {
|
||||
bb0(%0 : @guaranteed $C):
|
||||
%copy0 = copy_value %0 : $C
|
||||
debug_value [trace] %copy0 : $C
|
||||
cond_br undef, bb1, bb3
|
||||
|
||||
bb1:
|
||||
%dead = copy_value %0 : $C
|
||||
debug_value [trace] %dead : $C
|
||||
unreachable
|
||||
|
||||
bb3:
|
||||
destroy_value %copy0 : $C
|
||||
%99 = tuple()
|
||||
return %99 : $()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user