@@ -278,14 +278,29 @@ void CanonicalizeOSSALifetime::extendLivenessToDeinitBarriers() {
278
278
});
279
279
});
280
280
281
+ ArrayRef<SILInstruction *> ends = {};
282
+ SmallVector<SILInstruction *, 8 > lexicalEnds;
283
+ if (currentLexicalLifetimeEnds.size () > 0 ) {
284
+ visitExtendedUnconsumedBoundary (
285
+ currentLexicalLifetimeEnds,
286
+ [&lexicalEnds](auto *instruction, auto lifetimeEnding) {
287
+ instruction->visitSubsequentInstructions ([&](auto *next) {
288
+ lexicalEnds.push_back (next);
289
+ return true ;
290
+ });
291
+ });
292
+ ends = lexicalEnds;
293
+ } else {
294
+ ends = outsideDestroys;
295
+ }
296
+
281
297
auto *def = getCurrentDef ()->getDefiningInstruction ();
282
298
using InitialBlocks = ArrayRef<SILBasicBlock *>;
283
299
auto *defBlock = getCurrentDef ()->getParentBlock ();
284
300
auto initialBlocks = defBlock ? InitialBlocks (defBlock) : InitialBlocks ();
285
301
ReachableBarriers barriers;
286
- findBarriersBackward (outsideDestroys, initialBlocks,
287
- *getCurrentDef ()->getFunction (), barriers,
288
- [&](auto *inst) {
302
+ findBarriersBackward (ends, initialBlocks, *getCurrentDef ()->getFunction (),
303
+ barriers, [&](auto *inst) {
289
304
if (inst == def)
290
305
return true ;
291
306
if (!isDeinitBarrier (inst, calleeAnalysis))
@@ -569,11 +584,17 @@ void CanonicalizeOSSALifetime::findOriginalBoundary(
569
584
// / extent.
570
585
// / [Extend liveness down to the boundary between green blocks and uncolored.]
571
586
void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary (
572
- ArrayRef<SILInstruction *> ends ,
587
+ ArrayRef<SILInstruction *> consumes ,
573
588
llvm::function_ref<void (SILInstruction *, PrunedLiveness::LifetimeEnding)>
574
589
visitor) {
575
590
auto currentDef = getCurrentDef ();
576
591
592
+ #ifndef NDEBUG
593
+ for (auto *consume : consumes) {
594
+ assert (!liveness->isWithinBoundary (consume));
595
+ }
596
+ #endif
597
+
577
598
// First, collect the blocks that were _originally_ live. We can't use
578
599
// liveness here because it doesn't include blocks that occur before a
579
600
// destroy_value.
@@ -619,7 +640,7 @@ void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary(
619
640
// consumes. These are just the instructions on the boundary which aren't
620
641
// destroys.
621
642
BasicBlockWorklist worklist (currentDef->getFunction ());
622
- for (auto *instruction : ends ) {
643
+ for (auto *instruction : consumes ) {
623
644
if (destroys.contains (instruction))
624
645
continue ;
625
646
if (liveness->isInterestingUser (instruction)
@@ -1223,8 +1244,9 @@ void CanonicalizeOSSALifetime::rewriteLifetimes() {
1223
1244
}
1224
1245
1225
1246
// / Canonicalize a single extended owned lifetime.
1226
- bool CanonicalizeOSSALifetime::canonicalizeValueLifetime (SILValue def) {
1227
- LivenessState livenessState (*this , def);
1247
+ bool CanonicalizeOSSALifetime::canonicalizeValueLifetime (
1248
+ SILValue def, ArrayRef<SILInstruction *> lexicalLifetimeEnds) {
1249
+ LivenessState livenessState (*this , def, lexicalLifetimeEnds);
1228
1250
1229
1251
// Don't canonicalize the lifetimes of values of move-only type. According to
1230
1252
// language rules, they are fixed.
@@ -1252,6 +1274,7 @@ namespace swift::test {
1252
1274
// access scopes which they previously enclosed but can't be hoisted
1253
1275
// before
1254
1276
// - SILValue: value to canonicalize
1277
+ // - [SILInstruction]: the lexicalLifetimeEnds to recognize
1255
1278
// Dumps:
1256
1279
// - function after value canonicalization
1257
1280
static FunctionTest CanonicalizeOSSALifetimeTest (
@@ -1271,7 +1294,11 @@ static FunctionTest CanonicalizeOSSALifetimeTest(
1271
1294
respectAccessScopes ? accessBlockAnalysis : nullptr , domTree,
1272
1295
calleeAnalysis, deleter);
1273
1296
auto value = arguments.takeValue ();
1274
- canonicalizer.canonicalizeValueLifetime (value);
1297
+ SmallVector<SILInstruction *, 4 > lexicalLifetimeEnds;
1298
+ while (arguments.hasUntaken ()) {
1299
+ lexicalLifetimeEnds.push_back (arguments.takeInstruction ());
1300
+ }
1301
+ canonicalizer.canonicalizeValueLifetime (value, lexicalLifetimeEnds);
1275
1302
function.print (llvm::outs ());
1276
1303
});
1277
1304
} // end namespace swift::test
0 commit comments