Skip to content

Commit f06244f

Browse files
committed
[region-isolation] Take into account that Swift's RPO order doesn't include blocks that are dead.
When we run RegionAnalysis, since it uses RPO order, we do not visit dead blocks. This can create a problem when we emit diagnostics since we may merge in a value into the region that was never actually defined. In this patch, if we actually visit the block while performing dataflow, I mark a bit in its state saying that it was live. Then when we emit diagnostics, I do not visit blocks that were not marked live. rdar://124042351
1 parent b65e926 commit f06244f

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

include/swift/SILOptimizer/Analysis/RegionAnalysis.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ class BlockPartitionState {
6161
/// Set if this block in the next iteration needs to be visited.
6262
bool needsUpdate = false;
6363

64+
/// Set if this block is live.
65+
///
66+
/// If the block is not live, then we shouldnt try to emit diagnostics for it
67+
/// since we will not have performed dataflow upon it.
68+
bool isLive = false;
69+
6470
/// The partition of elements into regions at the top of the block.
6571
Partition entryPartition;
6672

@@ -81,6 +87,8 @@ class BlockPartitionState {
8187
TransferringOperandSetFactory &ptrSetFactory);
8288

8389
public:
90+
bool getLiveness() const { return isLive; }
91+
8492
ArrayRef<PartitionOp> getPartitionOps() const { return blockPartitionOps; }
8593

8694
const Partition &getEntryPartition() const { return entryPartition; }

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3057,6 +3057,7 @@ void RegionAnalysisFunctionInfo::runDataflow() {
30573057

30583058
for (auto *block : pofi->getReversePostOrder()) {
30593059
auto &blockState = (*blockStates)[block];
3060+
blockState.isLive = true;
30603061

30613062
LLVM_DEBUG(llvm::dbgs() << "Block: bb" << block->getDebugID() << "\n");
30623063
if (!blockState.needsUpdate) {

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,12 @@ void TransferNonSendableImpl::runDiagnosticEvaluator() {
13241324
LLVM_DEBUG(llvm::dbgs() << "Walking blocks for diagnostics.\n");
13251325
for (auto [block, blockState] : regionInfo->getRange()) {
13261326
LLVM_DEBUG(llvm::dbgs() << "|--> Block bb" << block.getDebugID() << "\n");
1327+
1328+
if (!blockState.getLiveness()) {
1329+
LLVM_DEBUG(llvm::dbgs() << "Dead block... skipping!\n");
1330+
continue;
1331+
}
1332+
13271333
LLVM_DEBUG(llvm::dbgs() << "Entry Partition: ";
13281334
blockState.getEntryPartition().print(llvm::dbgs()));
13291335

test/Concurrency/transfernonsendable.sil

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,28 @@ bb0:
174174
dealloc_stack %2 : $*NonSendableKlass
175175
%19 = tuple ()
176176
return %19 : $()
177-
}
177+
}
178+
179+
// Dead block crasher
180+
//
181+
// We used to crash here since we attempted to process /all/ blocks for
182+
// diagnostic even for non-dead blocks. This is a problem since the dataflow
183+
// uses a reverse post order traversal to get quick convergence and that skips
184+
// dead blocks.
185+
sil [ossa] @dead_block_crasher : $@convention(thin) @async () -> () {
186+
bb0:
187+
%0 = function_ref @constructNonSendableKlass : $@convention(thin) () -> @owned NonSendableKlass
188+
%1 = apply %0() : $@convention(thin) () -> @owned NonSendableKlass
189+
br bb1
190+
191+
bbDeadBlock:
192+
%transfer = function_ref @transferNonSendableKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
193+
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %transfer(%1) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
194+
br bb1
195+
196+
bb1:
197+
destroy_value %1 : $NonSendableKlass
198+
%9999 = tuple ()
199+
return %9999 : $()
200+
}
201+

0 commit comments

Comments
 (0)