Skip to content

Commit 252cc1e

Browse files
Merge pull request swiftlang#65022 from nate-chandler/rdar99160718
[Mem2Reg] Omit lexical moves for lexical values.
2 parents fb7275b + bf3e425 commit 252cc1e

File tree

4 files changed

+372
-246
lines changed

4 files changed

+372
-246
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

+26-15
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ STATISTIC(NumInstRemoved, "Number of Instructions removed");
5757

5858
static bool lexicalLifetimeEnsured(AllocStackInst *asi);
5959
static bool isGuaranteedLexicalValue(SILValue src);
60+
static bool isOwnedLexicalValue(SILValue src);
6061

6162
namespace {
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 {
@@ -221,6 +225,7 @@ class LiveValues {
221225
return guaranteed.stored;
222226
}
223227

228+
/// Whether it's possible and appropriate to end the lifetime.
224229
bool canEndLexicalLifetime() {
225230
if (auto *owned = storage.dyn_cast<Owned>()) {
226231
return owned->canEndLexicalLifetime();
@@ -521,16 +526,15 @@ static bool lexicalLifetimeEnsured(AllocStackInst *asi) {
521526
!asi->getElementType().isTrivial(*asi->getFunction());
522527
}
523528

529+
static bool isOwnedLexicalValue(SILValue src) {
530+
return src->getOwnershipKind() == OwnershipKind::Owned && src->isLexical();
531+
}
532+
524533
static bool isGuaranteedLexicalValue(SILValue src) {
525534
return src->getOwnershipKind() == OwnershipKind::Guaranteed &&
526535
src->isLexical();
527536
}
528537

529-
/// Returns true if we have enough information to end the lifetime.
530-
static bool canEndLexicalLifetime(LiveValues values) {
531-
return values.canEndLexicalLifetime();
532-
}
533-
534538
/// Begin a lexical borrow scope for the value stored into the provided
535539
/// StoreInst after that instruction.
536540
///
@@ -546,6 +550,9 @@ beginOwnedLexicalLifetimeAfterStore(AllocStackInst *asi, StoreInst *inst) {
546550
SILValue stored = inst->getOperand(CopyLikeInstruction::Src);
547551
SILLocation loc = RegularLocation::getAutoGeneratedLocation(inst->getLoc());
548552

553+
if (isOwnedLexicalValue(stored)) {
554+
return {LiveValues::forOwned(stored, {}), /*isStorageValid*/ true};
555+
}
549556
MoveValueInst *mvi = nullptr;
550557
SILBuilderWithScope::insertAfter(inst, [&](SILBuilder &builder) {
551558
mvi = builder.createMoveValue(loc, stored, /*isLexical*/ true);
@@ -825,7 +832,7 @@ SILInstruction *StackAllocationPromoter::promoteAllocationInBlock(
825832
if (lexicalLifetimeEnsured(asi)) {
826833
// End the lexical lifetime at a load [take]. The storage is no
827834
// longer keeping the value alive.
828-
if (runningVals && canEndLexicalLifetime(runningVals->value)) {
835+
if (runningVals && runningVals->value.canEndLexicalLifetime()) {
829836
// End it right now if we have enough information.
830837
endOwnedLexicalLifetimeBeforeInst(asi, /*beforeInstruction=*/li,
831838
ctx,
@@ -908,7 +915,7 @@ SILInstruction *StackAllocationPromoter::promoteAllocationInBlock(
908915
lastStoreInst = si;
909916
if (lexicalLifetimeEnsured(asi)) {
910917
if (oldRunningVals && oldRunningVals->isStorageValid &&
911-
canEndLexicalLifetime(oldRunningVals->value)) {
918+
oldRunningVals->value.canEndLexicalLifetime()) {
912919
endOwnedLexicalLifetimeBeforeInst(asi, /*beforeInstruction=*/si, ctx,
913920
oldRunningVals->value.getOwned());
914921
}
@@ -965,7 +972,7 @@ SILInstruction *StackAllocationPromoter::promoteAllocationInBlock(
965972
}
966973
// Mark storage as invalid and mark end_borrow as a deinit point.
967974
runningVals->isStorageValid = false;
968-
if (!canEndLexicalLifetime(runningVals->value)) {
975+
if (!runningVals->value.canEndLexicalLifetime()) {
969976
continue;
970977
}
971978
endGuaranteedLexicalLifetimeBeforeInst(
@@ -1067,6 +1074,10 @@ StackAllocationPromoter::getLiveOutValues(BlockSetVector &phiBlocks,
10671074
auto values = LiveValues::forGuaranteed(stored, borrow);
10681075
return values;
10691076
}
1077+
if (isOwnedLexicalValue(stored)) {
1078+
auto values = LiveValues::forOwned(stored, {});
1079+
return values;
1080+
}
10701081
auto move = cast<MoveValueInst>(inst->getNextInstruction());
10711082
auto values = LiveValues::forOwned(stored, move);
10721083
return values;
@@ -1422,7 +1433,7 @@ void StackAllocationPromoter::endLexicalLifetime(BlockSetVector &phiBlocks) {
14221433
if (isa<EndBorrowInst>(inst)) {
14231434
// Not all store_borrows will have a begin_borrow [lexical] that needs
14241435
// to be ended. If the source is already lexical, we don't create it.
1425-
if (!canEndLexicalLifetime(*values)) {
1436+
if (!values->canEndLexicalLifetime()) {
14261437
continue;
14271438
}
14281439
endGuaranteedLexicalLifetimeBeforeInst(
@@ -1445,7 +1456,7 @@ void StackAllocationPromoter::endLexicalLifetime(BlockSetVector &phiBlocks) {
14451456
if (terminatesInUnreachable || uniqueSuccessorLacksLiveInValues()) {
14461457
auto values = getLiveOutValues(phiBlocks, bb);
14471458
if (values->isGuaranteed()) {
1448-
if (!canEndLexicalLifetime(*values)) {
1459+
if (!values->canEndLexicalLifetime()) {
14491460
continue;
14501461
}
14511462
endGuaranteedLexicalLifetimeBeforeInst(
@@ -1971,7 +1982,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
19711982
continue;
19721983
}
19731984
runningVals->isStorageValid = false;
1974-
if (!canEndLexicalLifetime(runningVals->value)) {
1985+
if (!runningVals->value.canEndLexicalLifetime()) {
19751986
continue;
19761987
}
19771988
endGuaranteedLexicalLifetimeBeforeInst(

0 commit comments

Comments
 (0)