@@ -57,6 +57,7 @@ STATISTIC(NumInstRemoved, "Number of Instructions removed");
57
57
58
58
static bool lexicalLifetimeEnsured (AllocStackInst *asi);
59
59
static bool isGuaranteedLexicalValue (SILValue src);
60
+ static bool isOwnedLexicalValue (SILValue src);
60
61
61
62
namespace {
62
63
@@ -96,9 +97,11 @@ class LiveValues {
96
97
if (!lexicalLifetimeEnsured (asi)) {
97
98
return stored;
98
99
}
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;
102
105
}
103
106
104
107
bool canEndLexicalLifetime () {
@@ -107,7 +110,8 @@ class LiveValues {
107
110
// to end a lexical lifetime. In that case, the lifetime end will be
108
111
// added later, when we have enough information, namely the live in
109
112
// values, to end it.
110
- return move;
113
+ auto storedIsLexical = stored && isOwnedLexicalValue (stored);
114
+ return storedIsLexical ? stored : move;
111
115
}
112
116
};
113
117
struct Guaranteed {
@@ -221,6 +225,7 @@ class LiveValues {
221
225
return guaranteed.stored ;
222
226
}
223
227
228
+ // / Whether it's possible and appropriate to end the lifetime.
224
229
bool canEndLexicalLifetime () {
225
230
if (auto *owned = storage.dyn_cast <Owned>()) {
226
231
return owned->canEndLexicalLifetime ();
@@ -521,16 +526,15 @@ static bool lexicalLifetimeEnsured(AllocStackInst *asi) {
521
526
!asi->getElementType ().isTrivial (*asi->getFunction ());
522
527
}
523
528
529
+ static bool isOwnedLexicalValue (SILValue src) {
530
+ return src->getOwnershipKind () == OwnershipKind::Owned && src->isLexical ();
531
+ }
532
+
524
533
static bool isGuaranteedLexicalValue (SILValue src) {
525
534
return src->getOwnershipKind () == OwnershipKind::Guaranteed &&
526
535
src->isLexical ();
527
536
}
528
537
529
- // / Returns true if we have enough information to end the lifetime.
530
- static bool canEndLexicalLifetime (LiveValues values) {
531
- return values.canEndLexicalLifetime ();
532
- }
533
-
534
538
// / Begin a lexical borrow scope for the value stored into the provided
535
539
// / StoreInst after that instruction.
536
540
// /
@@ -546,6 +550,9 @@ beginOwnedLexicalLifetimeAfterStore(AllocStackInst *asi, StoreInst *inst) {
546
550
SILValue stored = inst->getOperand (CopyLikeInstruction::Src);
547
551
SILLocation loc = RegularLocation::getAutoGeneratedLocation (inst->getLoc ());
548
552
553
+ if (isOwnedLexicalValue (stored)) {
554
+ return {LiveValues::forOwned (stored, {}), /* isStorageValid*/ true };
555
+ }
549
556
MoveValueInst *mvi = nullptr ;
550
557
SILBuilderWithScope::insertAfter (inst, [&](SILBuilder &builder) {
551
558
mvi = builder.createMoveValue (loc, stored, /* isLexical*/ true );
@@ -825,7 +832,7 @@ SILInstruction *StackAllocationPromoter::promoteAllocationInBlock(
825
832
if (lexicalLifetimeEnsured (asi)) {
826
833
// End the lexical lifetime at a load [take]. The storage is no
827
834
// longer keeping the value alive.
828
- if (runningVals && canEndLexicalLifetime ( runningVals->value )) {
835
+ if (runningVals && runningVals->value . canEndLexicalLifetime ( )) {
829
836
// End it right now if we have enough information.
830
837
endOwnedLexicalLifetimeBeforeInst (asi, /* beforeInstruction=*/ li,
831
838
ctx,
@@ -908,7 +915,7 @@ SILInstruction *StackAllocationPromoter::promoteAllocationInBlock(
908
915
lastStoreInst = si;
909
916
if (lexicalLifetimeEnsured (asi)) {
910
917
if (oldRunningVals && oldRunningVals->isStorageValid &&
911
- canEndLexicalLifetime ( oldRunningVals->value )) {
918
+ oldRunningVals->value . canEndLexicalLifetime ( )) {
912
919
endOwnedLexicalLifetimeBeforeInst (asi, /* beforeInstruction=*/ si, ctx,
913
920
oldRunningVals->value .getOwned ());
914
921
}
@@ -965,7 +972,7 @@ SILInstruction *StackAllocationPromoter::promoteAllocationInBlock(
965
972
}
966
973
// Mark storage as invalid and mark end_borrow as a deinit point.
967
974
runningVals->isStorageValid = false ;
968
- if (!canEndLexicalLifetime ( runningVals->value )) {
975
+ if (!runningVals->value . canEndLexicalLifetime ( )) {
969
976
continue ;
970
977
}
971
978
endGuaranteedLexicalLifetimeBeforeInst (
@@ -1067,6 +1074,10 @@ StackAllocationPromoter::getLiveOutValues(BlockSetVector &phiBlocks,
1067
1074
auto values = LiveValues::forGuaranteed (stored, borrow);
1068
1075
return values;
1069
1076
}
1077
+ if (isOwnedLexicalValue (stored)) {
1078
+ auto values = LiveValues::forOwned (stored, {});
1079
+ return values;
1080
+ }
1070
1081
auto move = cast<MoveValueInst>(inst->getNextInstruction ());
1071
1082
auto values = LiveValues::forOwned (stored, move);
1072
1083
return values;
@@ -1422,7 +1433,7 @@ void StackAllocationPromoter::endLexicalLifetime(BlockSetVector &phiBlocks) {
1422
1433
if (isa<EndBorrowInst>(inst)) {
1423
1434
// Not all store_borrows will have a begin_borrow [lexical] that needs
1424
1435
// to be ended. If the source is already lexical, we don't create it.
1425
- if (!canEndLexicalLifetime (*values )) {
1436
+ if (!values-> canEndLexicalLifetime ()) {
1426
1437
continue ;
1427
1438
}
1428
1439
endGuaranteedLexicalLifetimeBeforeInst (
@@ -1445,7 +1456,7 @@ void StackAllocationPromoter::endLexicalLifetime(BlockSetVector &phiBlocks) {
1445
1456
if (terminatesInUnreachable || uniqueSuccessorLacksLiveInValues ()) {
1446
1457
auto values = getLiveOutValues (phiBlocks, bb);
1447
1458
if (values->isGuaranteed ()) {
1448
- if (!canEndLexicalLifetime (*values )) {
1459
+ if (!values-> canEndLexicalLifetime ()) {
1449
1460
continue ;
1450
1461
}
1451
1462
endGuaranteedLexicalLifetimeBeforeInst (
@@ -1971,7 +1982,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
1971
1982
continue ;
1972
1983
}
1973
1984
runningVals->isStorageValid = false ;
1974
- if (!canEndLexicalLifetime ( runningVals->value )) {
1985
+ if (!runningVals->value . canEndLexicalLifetime ( )) {
1975
1986
continue ;
1976
1987
}
1977
1988
endGuaranteedLexicalLifetimeBeforeInst (
0 commit comments