Skip to content

Commit ebb6a4b

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

File tree

1 file changed

+38
-28
lines changed

1 file changed

+38
-28
lines changed

lib/SIL/Utils/OwnershipUtils.cpp

+38-28
Original file line numberDiff line numberDiff line change
@@ -2405,42 +2405,52 @@ bool swift::isRedundantMoveValue(MoveValueInst *mvi) {
24052405

24062406
// The move doesn't alter constraints: ownership and lexicality match.
24072407

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

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

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

0 commit comments

Comments
 (0)