Skip to content

[SILOptimizer] Add RedundantMoveValueElimination. #64190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2023

Conversation

nate-chandler
Copy link
Contributor

Adds to SemanticARCOpts a new step of removing move_value instructions if they are redundant. A move_value is redundant if it adds no new information or optimization opportunities.

An example of adding information: a lifetime becoming lexical. The new lifetime's destroys cannot be hoisted over deinit barriers.

An example of adding an optimization opportunity: the original value escapes but the value produced by the move_value does not escape. So destroys of the new value can be hoisted more aggressively.

@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler
Copy link
Contributor Author

@swift-ci please benchmark

Copy link
Contributor

@atrick atrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice. But the hasPointerEscape preconditions need to be defined on the API and enforced.

if (auto borrowedValue = BorrowedValue(value)) {
return hasPointerEscape(borrowedValue);
}
for (auto use : value->getUses()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking immediate uses only makes sense for an owned value. Do you want an assert here and document that \p value must introduce an OSSA lifetime (either BorrowedValue or owned value)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. And added a check in RedundantMoveValueElimination that the original value is owned.

@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler
Copy link
Contributor Author

@swift-ci please test macOS platform

return hasPointerEscape(borrowedValue);
}
assert(value->getOwnershipKind() == OwnershipKind::Owned);
for (auto use : value->getUses()) {
Copy link
Contributor

@meg-gupta meg-gupta Mar 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if there's an escape in the "extended" lifetime ? i.e a phi values escapes

Copy link
Contributor Author

@nate-chandler nate-chandler Mar 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, great point. From recent discussion with @atrick, my understanding was that a ForwardingConsumes shouldn't be considered part of the same lifetime for the purposes of pointer escapes. If that applies even to branches, since a br(%owned) is a forwarding consume of %owned, it wouldn't be included. On the other hand, excluding phi-extended lifetime is inconsistent with the intuition that "things should be the same" whether (1) there's a merge and a phi or (2) the function body portion is cloned for each incoming value. So it's seeming to me like we do need to look through phis like you say.

If we need to look through phis, phis also probably need to be rejected as inputs to this function like they are rejected by hasPointerEscape(BorrowedValue). It seems we also might not want to count them as "owned value introducers" (or allow them to be used in @atrick's forthcoming OwnedValue abstraction). If we need to look through phis, this function need to either reject them (like hasPointerEscape(BorrowedValue)) or visit the transitive incoming values, which hasPointerEscape(BorrowedValue) could be doing as well.

I updated the patch to look through phis and ban them as input and accept them as input by adding transitive incoming values to the worklist.

@nate-chandler nate-chandler force-pushed the redundant-move-elim branch 5 times, most recently from e6604bd to 62546a7 Compare March 10, 2023 17:10
There is a preexisting function with this name that takes a
BorrowedValue.  The new function calls that preexisting function if a
BorrowedValue can be constructed from the SILValue.  Otherwise, it looks
for direct uses of the value which qualify as "pointer escapes".
Adds to SemanticARCOpts a new step of removing move_value instructions
if they are redundant.  A move_value is redundant if it adds no new
information or optimization opportunities.

An example of adding information: a lifetime becoming lexical.  The new
lifetime's destroys cannot be hoisted over deinit barriers.

An example of adding an optimization opportunity: the original value
escapes but the value produced by the move_value does not escape.  So
destroys of the new value can be hoisted more aggressively.
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

Copy link
Contributor

@meg-gupta meg-gupta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you

@nate-chandler
Copy link
Contributor Author

@swift-ci please clean test linux platform

1 similar comment
@nate-chandler
Copy link
Contributor Author

@swift-ci please clean test linux platform

@nate-chandler
Copy link
Contributor Author

@swift-ci please smoke test linux platform

@nate-chandler
Copy link
Contributor Author

@swift-ci please test linux platform

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants