@@ -278,14 +278,29 @@ void CanonicalizeOSSALifetime::extendLivenessToDeinitBarriers() {
278278 });
279279 });
280280
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+
281297 auto *def = getCurrentDef ()->getDefiningInstruction ();
282298 using InitialBlocks = ArrayRef<SILBasicBlock *>;
283299 auto *defBlock = getCurrentDef ()->getParentBlock ();
284300 auto initialBlocks = defBlock ? InitialBlocks (defBlock) : InitialBlocks ();
285301 ReachableBarriers barriers;
286- findBarriersBackward (outsideDestroys, initialBlocks,
287- *getCurrentDef ()->getFunction (), barriers,
288- [&](auto *inst) {
302+ findBarriersBackward (ends, initialBlocks, *getCurrentDef ()->getFunction (),
303+ barriers, [&](auto *inst) {
289304 if (inst == def)
290305 return true ;
291306 if (!isDeinitBarrier (inst, calleeAnalysis))
@@ -569,11 +584,17 @@ void CanonicalizeOSSALifetime::findOriginalBoundary(
569584// / extent.
570585// / [Extend liveness down to the boundary between green blocks and uncolored.]
571586void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary (
572- ArrayRef<SILInstruction *> ends ,
587+ ArrayRef<SILInstruction *> consumes ,
573588 llvm::function_ref<void (SILInstruction *, PrunedLiveness::LifetimeEnding)>
574589 visitor) {
575590 auto currentDef = getCurrentDef ();
576591
592+ #ifndef NDEBUG
593+ for (auto *consume : consumes) {
594+ assert (!liveness->isWithinBoundary (consume));
595+ }
596+ #endif
597+
577598 // First, collect the blocks that were _originally_ live. We can't use
578599 // liveness here because it doesn't include blocks that occur before a
579600 // destroy_value.
@@ -619,7 +640,7 @@ void CanonicalizeOSSALifetime::visitExtendedUnconsumedBoundary(
619640 // consumes. These are just the instructions on the boundary which aren't
620641 // destroys.
621642 BasicBlockWorklist worklist (currentDef->getFunction ());
622- for (auto *instruction : ends ) {
643+ for (auto *instruction : consumes ) {
623644 if (destroys.contains (instruction))
624645 continue ;
625646 if (liveness->isInterestingUser (instruction)
@@ -1223,8 +1244,9 @@ void CanonicalizeOSSALifetime::rewriteLifetimes() {
12231244}
12241245
12251246// / 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);
12281250
12291251 // Don't canonicalize the lifetimes of values of move-only type. According to
12301252 // language rules, they are fixed.
@@ -1252,6 +1274,7 @@ namespace swift::test {
12521274// access scopes which they previously enclosed but can't be hoisted
12531275// before
12541276// - SILValue: value to canonicalize
1277+ // - [SILInstruction]: the lexicalLifetimeEnds to recognize
12551278// Dumps:
12561279// - function after value canonicalization
12571280static FunctionTest CanonicalizeOSSALifetimeTest (
@@ -1271,7 +1294,11 @@ static FunctionTest CanonicalizeOSSALifetimeTest(
12711294 respectAccessScopes ? accessBlockAnalysis : nullptr , domTree,
12721295 calleeAnalysis, deleter);
12731296 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);
12751302 function.print (llvm::outs ());
12761303 });
12771304} // end namespace swift::test
0 commit comments