@@ -283,14 +283,29 @@ void CanonicalizeOSSALifetime::extendLivenessToDeinitBarriers() {
283283 });
284284 });
285285
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+
286302 auto *def = getCurrentDef ()->getDefiningInstruction ();
287303 using InitialBlocks = ArrayRef<SILBasicBlock *>;
288304 auto *defBlock = getCurrentDef ()->getParentBlock ();
289305 auto initialBlocks = defBlock ? InitialBlocks (defBlock) : InitialBlocks ();
290306 ReachableBarriers barriers;
291- findBarriersBackward (outsideDestroys, initialBlocks,
292- *getCurrentDef ()->getFunction (), barriers,
293- [&](auto *inst) {
307+ findBarriersBackward (ends, initialBlocks, *getCurrentDef ()->getFunction (),
308+ barriers, [&](auto *inst) {
294309 if (inst == def)
295310 return true ;
296311 if (!isDeinitBarrier (inst, calleeAnalysis))
@@ -574,11 +589,17 @@ void CanonicalizeOSSALifetime::findOriginalBoundary(
574589// / extent.
575590// / [Extend liveness down to the boundary between green blocks and uncolored.]
576591void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary (
577- ArrayRef<SILInstruction *> ends ,
592+ ArrayRef<SILInstruction *> consumes ,
578593 llvm::function_ref<void (SILInstruction *, PrunedLiveness::LifetimeEnding)>
579594 visitor) {
580595 auto currentDef = getCurrentDef ();
581596
597+ #ifndef NDEBUG
598+ for (auto *consume : consumes) {
599+ assert (!liveness->isWithinBoundary (consume));
600+ }
601+ #endif
602+
582603 // First, collect the blocks that were _originally_ live. We can't use
583604 // liveness here because it doesn't include blocks that occur before a
584605 // destroy_value.
@@ -624,7 +645,7 @@ void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary(
624645 // consumes. These are just the instructions on the boundary which aren't
625646 // destroys.
626647 BasicBlockWorklist worklist (currentDef->getFunction ());
627- for (auto *instruction : ends ) {
648+ for (auto *instruction : consumes ) {
628649 if (destroys.contains (instruction))
629650 continue ;
630651 if (liveness->isInterestingUser (instruction)
@@ -1228,8 +1249,9 @@ void CanonicalizeOSSALifetime::rewriteLifetimes() {
12281249}
12291250
12301251// / 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);
12331255
12341256 // Don't canonicalize the lifetimes of values of move-only type. According to
12351257 // language rules, they are fixed.
@@ -1257,6 +1279,7 @@ namespace swift::test {
12571279// access scopes which they previously enclosed but can't be hoisted
12581280// before
12591281// - SILValue: value to canonicalize
1282+ // - [SILInstruction]: the lexicalLifetimeEnds to recognize
12601283// Dumps:
12611284// - function after value canonicalization
12621285static FunctionTest CanonicalizeOSSALifetimeTest (
@@ -1276,7 +1299,11 @@ static FunctionTest CanonicalizeOSSALifetimeTest(
12761299 respectAccessScopes ? accessBlockAnalysis : nullptr , domTree,
12771300 calleeAnalysis, deleter);
12781301 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);
12801307 function.print (llvm::outs ());
12811308 });
12821309} // end namespace swift::test
0 commit comments