@@ -57,6 +57,7 @@ STATISTIC(NumInstRemoved, "Number of Instructions removed");
5757
5858static bool lexicalLifetimeEnsured (AllocStackInst *asi);
5959static bool isGuaranteedLexicalValue (SILValue src);
60+ static bool isOwnedLexicalValue (SILValue src);
6061
6162namespace {
6263
@@ -96,9 +97,11 @@ class LiveValues {
9697 if (!lexicalLifetimeEnsured (asi)) {
9798 return stored;
9899 }
99- // We should have created a move of the @owned stored value.
100- assert (move);
101- return move;
100+ auto storedIsLexical = stored && isOwnedLexicalValue (stored);
101+ // If the value was already lexical, we use it directly. Otherwise, a new
102+ // move_value [lexical] is used.
103+ assert (storedIsLexical || move);
104+ return storedIsLexical ? stored : move;
102105 }
103106
104107 bool canEndLexicalLifetime () {
@@ -107,7 +110,8 @@ class LiveValues {
107110 // to end a lexical lifetime. In that case, the lifetime end will be
108111 // added later, when we have enough information, namely the live in
109112 // values, to end it.
110- return move;
113+ auto storedIsLexical = stored && isOwnedLexicalValue (stored);
114+ return storedIsLexical ? stored : move;
111115 }
112116 };
113117 struct Guaranteed {
@@ -522,6 +526,10 @@ static bool lexicalLifetimeEnsured(AllocStackInst *asi) {
522526 !asi->getElementType ().isTrivial (*asi->getFunction ());
523527}
524528
529+ static bool isOwnedLexicalValue (SILValue src) {
530+ return src->getOwnershipKind () == OwnershipKind::Owned && src->isLexical ();
531+ }
532+
525533static bool isGuaranteedLexicalValue (SILValue src) {
526534 return src->getOwnershipKind () == OwnershipKind::Guaranteed &&
527535 src->isLexical ();
@@ -542,6 +550,9 @@ beginOwnedLexicalLifetimeAfterStore(AllocStackInst *asi, StoreInst *inst) {
542550 SILValue stored = inst->getOperand (CopyLikeInstruction::Src);
543551 SILLocation loc = RegularLocation::getAutoGeneratedLocation (inst->getLoc ());
544552
553+ if (isOwnedLexicalValue (stored)) {
554+ return {LiveValues::forOwned (stored, {}), /* isStorageValid*/ true };
555+ }
545556 MoveValueInst *mvi = nullptr ;
546557 SILBuilderWithScope::insertAfter (inst, [&](SILBuilder &builder) {
547558 mvi = builder.createMoveValue (loc, stored, /* isLexical*/ true );
@@ -1063,6 +1074,10 @@ StackAllocationPromoter::getLiveOutValues(BlockSetVector &phiBlocks,
10631074 auto values = LiveValues::forGuaranteed (stored, borrow);
10641075 return values;
10651076 }
1077+ if (isOwnedLexicalValue (stored)) {
1078+ auto values = LiveValues::forOwned (stored, {});
1079+ return values;
1080+ }
10661081 auto move = cast<MoveValueInst>(inst->getNextInstruction ());
10671082 auto values = LiveValues::forOwned (stored, move);
10681083 return values;
0 commit comments