Skip to content

Commit bf3e425

Browse files
committed
[Mem2Reg] Omit lexical moves for lexical values.
When promoting an `alloc_stack [lexical]` that is "owned" (i.e. not a store_borrow location), omit lexical lifetimes (represented with `move_value [lexical]` instructions) if the value being stored is already lexical. Such moves are redundant. rdar://99160718
1 parent 3da0e6a commit bf3e425

File tree

4 files changed

+365
-235
lines changed

4 files changed

+365
-235
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

+19-4
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 {
@@ -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+
525533
static 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

Comments
 (0)