Skip to content

Commit b7f447d

Browse files
committed
[NFC] Readability for isRedundantMoveValue.
Improved comments and flattened conditions.
1 parent f5e8fc2 commit b7f447d

File tree

1 file changed

+42
-30
lines changed

1 file changed

+42
-30
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,12 +2383,15 @@ bool swift::isNestedLexicalBeginBorrow(BeginBorrowInst *bbi) {
23832383
}
23842384

23852385
bool swift::isRedundantMoveValue(MoveValueInst *mvi) {
2386-
// Check whether the moved-from value's lifetime and the moved-to value's
2386+
// Given: %moved_to_value = move_value %original_value
2387+
//
2388+
// Check whether the original value's lifetime and the moved-to value's
23872389
// lifetime have the same (1) ownership, (2) lexicality, and (3) escaping.
23882390
//
23892391
// Along the way, also check for cases where they have different values for
23902392
// those characteristics but it doesn't matter because of how limited the uses
2391-
// of the original value are (for now, whether the move is the only use).
2393+
// of the original value are (for now, whether the move is the only consuming
2394+
// use).
23922395

23932396
auto original = mvi->getOperand();
23942397

@@ -2405,42 +2408,51 @@ bool swift::isRedundantMoveValue(MoveValueInst *mvi) {
24052408

24062409
// The move doesn't alter constraints: ownership and lexicality match.
24072410

2411+
// Before checking whether escaping matches, check whether the move_value is
2412+
// redundant regardless on account of how its uses are limited.
2413+
//
2414+
// At this point, ownership and lexicality are known to match. If the
2415+
// original value doesn't escape, then merging the two lifetimes won't make
2416+
// it harder to optimize the portion of the merged lifetime corresponding to
2417+
// the moved-to value. If the original's only consuming use is the
2418+
// move_value, then the original value's lifetime couldn't be shortened
2419+
// anyway.
2420+
//
2421+
// Summary: !escaping(original)
2422+
// && singleConsumingUser(original) == move
2423+
// => redundant(mvi)
2424+
//
2425+
// Check this in two ways, one cheaper than the other.
2426+
2427+
// First, avoid calling hasPointerEscape(original).
2428+
//
2429+
// If the original value is not a phi (a phi's incoming values might have
2430+
// escaping uses) and its only user is the move, then it doesn't escape. Also
2431+
// if its only user is the move, then its only _consuming_ user is the move.
24082432
auto *singleUser =
24092433
original->getSingleUse() ? original->getSingleUse()->getUser() : nullptr;
24102434
if (mvi == singleUser && !SILArgument::asPhi(original)) {
24112435
assert(!hasPointerEscape(original));
2412-
// The moved-from value's only use is the move_value, and the moved-from
2413-
// value isn't a phi. So, it doesn't escape. (A phi's incoming values
2414-
// might escape.)
2415-
//
2416-
// Still, no optimization is enabled by separating the two lifetimes.
2417-
// The moved-from value's lifetime could not be shrunk regardless of whether
2418-
// the moved-to value escapes.
2436+
assert(original->getSingleConsumingUse()->getUser() == mvi);
2437+
// - !escaping(original)
2438+
// - singleConsumingUser(original) == move
24192439
return true;
24202440
}
24212441

2422-
auto moveHasEscape = hasPointerEscape(mvi);
2442+
// Second, call hasPointerEscape(original).
2443+
//
2444+
// Explicitly check both
2445+
// - !escaping(original)
2446+
// - singleConsumingUser(original) == move
24232447
auto originalHasEscape = hasPointerEscape(original);
2424-
2425-
// (3) Escaping matches? (Expensive check, saved for last.)
2426-
if (moveHasEscape != originalHasEscape) {
2427-
if (!originalHasEscape) {
2428-
auto *singleConsumingUser =
2429-
original->getSingleConsumingUse()
2430-
? original->getSingleConsumingUse()->getUser()
2431-
: nullptr;
2432-
if (mvi == singleConsumingUser) {
2433-
// The moved-from value's only consuming use is the move_value and it
2434-
// doesn't escape.
2435-
//
2436-
// Although the moved-to value escapes, no optimization is enabled by
2437-
// separating the two lifetimes. The moved-from value's lifetime
2438-
// already couldn't be shrunk.
2439-
return true;
2440-
}
2441-
}
2442-
return false;
2448+
auto *singleConsumingUser = original->getSingleConsumingUse()
2449+
? original->getSingleConsumingUse()->getUser()
2450+
: nullptr;
2451+
if (mvi == singleConsumingUser && !originalHasEscape) {
2452+
return true;
24432453
}
24442454

2445-
return true;
2455+
// (3) Escaping matches? (Expensive check, saved for last.)
2456+
auto moveHasEscape = hasPointerEscape(mvi);
2457+
return moveHasEscape == originalHasEscape;
24462458
}

0 commit comments

Comments
 (0)