@@ -193,36 +193,47 @@ class VisitUnreachableLifetimeEnds {
193
193
194
194
void VisitUnreachableLifetimeEnds::computeRegion (
195
195
const SSAPrunedLiveness &liveness) {
196
- // Find the non-lifetime-ending boundary of `value` .
196
+ // (1) Compute the complete liveness boundary .
197
197
PrunedLivenessBoundary boundary;
198
198
liveness.computeBoundary (boundary);
199
199
200
+ // Used in the forward walk below (3).
201
+ BasicBlockWorklist regionWorklist (value->getFunction ());
202
+
203
+ // (2) Collect the non-lifetime-ending liveness boundary. This is the
204
+ // portion of `boundary` consisting of:
205
+ // - non-lifetime-ending instructions (their parent blocks)
206
+ // - boundary edges
207
+ // - dead defs (their parent blocks)
208
+ auto collect = [&](SILBasicBlock *block) {
209
+ // `region` consists of the non-lifetime-ending boundary and all its
210
+ // iterative successors.
211
+ region.insert (block);
212
+ // `starts` just consists of the blocks in the non-lifetime-ending
213
+ // boundary.
214
+ starts.insert (block);
215
+ // The forward walk begins from the non-lifetime-ending boundary.
216
+ regionWorklist.push (block);
217
+ };
218
+
200
219
for (SILInstruction *lastUser : boundary.lastUsers ) {
201
220
if (liveness.isInterestingUser (lastUser)
202
221
!= PrunedLiveness::LifetimeEndingUse) {
203
- region.insert (lastUser->getParent ());
204
- starts.insert (lastUser->getParent ());
222
+ collect (lastUser->getParent ());
205
223
}
206
224
}
207
225
for (SILBasicBlock *edge : boundary.boundaryEdges ) {
208
- region.insert (edge);
209
- starts.insert (edge);
226
+ collect (edge);
210
227
}
211
228
for (SILNode *deadDef : boundary.deadDefs ) {
212
- region.insert (deadDef->getParentBlock ());
213
- starts.insert (deadDef->getParentBlock ());
229
+ collect (deadDef->getParentBlock ());
214
230
}
215
231
216
- // Forward walk to find the region in which `value` might be available.
217
- BasicBlockWorklist regionWorklist (value->getFunction ());
218
- // Start the forward walk from the non-lifetime-ending boundary.
219
- for (auto *start : region) {
220
- regionWorklist.push (start);
221
- }
232
+ // (3) Forward walk to find the region in which `value` might be available.
222
233
while (auto *block = regionWorklist.pop ()) {
223
234
if (block->succ_empty ()) {
224
- // This assert will fail unless there are already lifetime-ending
225
- // instruction on all paths to normal function exits.
235
+ // This assert will fail unless there is already a lifetime-ending
236
+ // instruction on each path to normal function exits.
226
237
assert (isa<UnreachableInst>(block->getTerminator ()));
227
238
}
228
239
for (auto *successor : block->getSuccessorBlocks ()) {
0 commit comments