@@ -283,14 +283,29 @@ void CanonicalizeOSSALifetime::extendLivenessToDeinitBarriers() {
283
283
});
284
284
});
285
285
286
+ ArrayRef<SILInstruction *> ends = {};
287
+ SmallVector<SILInstruction *, 8 > lexicalEnds;
288
+ if (currentLexicalLifetimeEnds.size () > 0 ) {
289
+ visitExtendedUnconsumedBoundary (
290
+ currentLexicalLifetimeEnds,
291
+ [&lexicalEnds](auto *instruction, auto lifetimeEnding) {
292
+ instruction->visitSubsequentInstructions ([&](auto *next) {
293
+ lexicalEnds.push_back (next);
294
+ return true ;
295
+ });
296
+ });
297
+ ends = lexicalEnds;
298
+ } else {
299
+ ends = outsideDestroys;
300
+ }
301
+
286
302
auto *def = getCurrentDef ()->getDefiningInstruction ();
287
303
using InitialBlocks = ArrayRef<SILBasicBlock *>;
288
304
auto *defBlock = getCurrentDef ()->getParentBlock ();
289
305
auto initialBlocks = defBlock ? InitialBlocks (defBlock) : InitialBlocks ();
290
306
ReachableBarriers barriers;
291
- findBarriersBackward (outsideDestroys, initialBlocks,
292
- *getCurrentDef ()->getFunction (), barriers,
293
- [&](auto *inst) {
307
+ findBarriersBackward (ends, initialBlocks, *getCurrentDef ()->getFunction (),
308
+ barriers, [&](auto *inst) {
294
309
if (inst == def)
295
310
return true ;
296
311
if (!isDeinitBarrier (inst, calleeAnalysis))
@@ -574,11 +589,17 @@ void CanonicalizeOSSALifetime::findOriginalBoundary(
574
589
// / extent.
575
590
// / [Extend liveness down to the boundary between green blocks and uncolored.]
576
591
void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary (
577
- ArrayRef<SILInstruction *> ends ,
592
+ ArrayRef<SILInstruction *> consumes ,
578
593
llvm::function_ref<void (SILInstruction *, PrunedLiveness::LifetimeEnding)>
579
594
visitor) {
580
595
auto currentDef = getCurrentDef ();
581
596
597
+ #ifndef NDEBUG
598
+ for (auto *consume : consumes) {
599
+ assert (!liveness->isWithinBoundary (consume));
600
+ }
601
+ #endif
602
+
582
603
// First, collect the blocks that were _originally_ live. We can't use
583
604
// liveness here because it doesn't include blocks that occur before a
584
605
// destroy_value.
@@ -624,7 +645,7 @@ void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary(
624
645
// consumes. These are just the instructions on the boundary which aren't
625
646
// destroys.
626
647
BasicBlockWorklist worklist (currentDef->getFunction ());
627
- for (auto *instruction : ends ) {
648
+ for (auto *instruction : consumes ) {
628
649
if (destroys.contains (instruction))
629
650
continue ;
630
651
if (liveness->isInterestingUser (instruction)
@@ -1228,8 +1249,9 @@ void CanonicalizeOSSALifetime::rewriteLifetimes() {
1228
1249
}
1229
1250
1230
1251
// / Canonicalize a single extended owned lifetime.
1231
- bool CanonicalizeOSSALifetime::canonicalizeValueLifetime (SILValue def) {
1232
- LivenessState livenessState (*this , def);
1252
+ bool CanonicalizeOSSALifetime::canonicalizeValueLifetime (
1253
+ SILValue def, ArrayRef<SILInstruction *> lexicalLifetimeEnds) {
1254
+ LivenessState livenessState (*this , def, lexicalLifetimeEnds);
1233
1255
1234
1256
// Don't canonicalize the lifetimes of values of move-only type. According to
1235
1257
// language rules, they are fixed.
@@ -1257,6 +1279,7 @@ namespace swift::test {
1257
1279
// access scopes which they previously enclosed but can't be hoisted
1258
1280
// before
1259
1281
// - SILValue: value to canonicalize
1282
+ // - [SILInstruction]: the lexicalLifetimeEnds to recognize
1260
1283
// Dumps:
1261
1284
// - function after value canonicalization
1262
1285
static FunctionTest CanonicalizeOSSALifetimeTest (
@@ -1276,7 +1299,11 @@ static FunctionTest CanonicalizeOSSALifetimeTest(
1276
1299
respectAccessScopes ? accessBlockAnalysis : nullptr , domTree,
1277
1300
calleeAnalysis, deleter);
1278
1301
auto value = arguments.takeValue ();
1279
- canonicalizer.canonicalizeValueLifetime (value);
1302
+ SmallVector<SILInstruction *, 4 > lexicalLifetimeEnds;
1303
+ while (arguments.hasUntaken ()) {
1304
+ lexicalLifetimeEnds.push_back (arguments.takeInstruction ());
1305
+ }
1306
+ canonicalizer.canonicalizeValueLifetime (value, lexicalLifetimeEnds);
1280
1307
function.print (llvm::outs ());
1281
1308
});
1282
1309
} // end namespace swift::test
0 commit comments