Skip to content

Commit 2d4c05e

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

File tree

1 file changed

+40
-29
lines changed

1 file changed

+40
-29
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

+40-29
Original file line numberDiff line numberDiff line change
@@ -2383,7 +2383,9 @@ 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
@@ -2405,42 +2407,51 @@ bool swift::isRedundantMoveValue(MoveValueInst *mvi) {
24052407

24062408
// The move doesn't alter constraints: ownership and lexicality match.
24072409

2410+
// Before checking whether escaping matches, check whether the move_value is
2411+
// redundant regardless on account of how its uses are limited.
2412+
//
2413+
// At this point, ownership and lexicality are known to match. If the
2414+
// original value doesn't escape, then merging the two lifetimes won't make
2415+
// it harder to optimize the portion of the merged lifetime corresponding to
2416+
// the moved-to value. If the original's only consuming use is the
2417+
// move_value, then the original value's lifetime couldn't be shortened
2418+
// anyway.
2419+
//
2420+
// Summary: !escaping(original)
2421+
// && singleConsumingUser(original) == move
2422+
// => redundant(mvi)
2423+
//
2424+
// Check this in two ways, one cheaper than the other.
2425+
2426+
// First, avoid calling hasPointerEscape(original).
2427+
//
2428+
// If the original value is not a phi (a phi's incoming values might have
2429+
// escaping uses) and its only user is the move, then it doesn't escape. Also
2430+
// if its only user is the move, then its only _consuming_ user is the move.
24082431
auto *singleUser =
24092432
original->getSingleUse() ? original->getSingleUse()->getUser() : nullptr;
24102433
if (mvi == singleUser && !SILArgument::asPhi(original)) {
24112434
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.
2435+
assert(original->getSingleConsumingUse()->getUser() == mvi);
2436+
// - !escaping(original)
2437+
// - singleConsumingUser(original) == move
24192438
return true;
24202439
}
24212440

2422-
auto moveHasEscape = hasPointerEscape(mvi);
2441+
// Second, call hasPointerEscape(original).
2442+
//
2443+
// Explicitly check both
2444+
// - !escaping(original)
2445+
// - singleConsumingUser(original) == move
24232446
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;
2447+
auto *singleConsumingUser = original->getSingleConsumingUse()
2448+
? original->getSingleConsumingUse()->getUser()
2449+
: nullptr;
2450+
if (mvi == singleConsumingUser && !originalHasEscape) {
2451+
return true;
24432452
}
24442453

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

0 commit comments

Comments
 (0)