Skip to content
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

[MIR-OPT]: Optimization that turns Eq-Not pair into Ne #77031

Closed
wants to merge 5 commits into from

Conversation

simonvandel
Copy link
Contributor

No description provided.

@rust-highfive
Copy link
Collaborator

r? @matthewjasper

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 21, 2020
StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
switchInt(_15) -> [false: bb4, otherwise: bb5]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
switchInt(move _17) -> [1_i32: bb4, otherwise: bb5]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is a pretty cool interaction between SimplifyComparisonIntegral and this optimization that makes it possible to eliminate the Ne entirely, since we can just switch on _17 directly.

if *l == place {
match r {
Rvalue::BinaryOp(BinOp::Eq, op1, op2) => {
// We need to make sure that the StorageDeads we saw are for
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why this is important. I'd rather think that the StorageDead for l is important, otherwise we should not remove the Neg, but instead also copy the result of the Ne operation to l.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you expand on your statement? I don't understand your point about not removing Neq (you mean Not? or Ne?).

Now that I think about it, yeah, it is perhaps unneccessary to require that the StorageDeads are for the Eq operands. Hmm do we even need to do anything special about potential StorageDeads between Eq and Not? I think not, besides doing the swap, which I think we can just do unconditionally for simplicity. We already assert that only StorageDead statements can appear between Eq and Not, and I think simply swapping a StorageDead for a complete unrelated local with Ne should not matter.

Copy link
Contributor

Choose a reason for hiding this comment

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

What I'm wondering is whether it is generally simpler to replace

                                    // _4 = Eq(move _5, move _6);
                                    // StorageDead(_5);
                                    // StorageDead(_6);
                                    // _3 = Not(move _4);

with

                                    // _4 = Ne(move _5, move _6);
                                    // StorageDead(_5);
                                    // StorageDead(_6);
                                    // _3 = move _4;

since then you don't have to care about any liveness or similar and leave further changes to other optimizations.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you want to get rid of the additional _3 = move 4;, maybe another peephole optimization may be better? One that just checks for _x = foo; /*arbitrary statements not touching _x or _y*/ _y = _x; and changes it to _y = foo; /*arbitrary statements not touching _x or _y*/ nop;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that might be simpler to do. For simplicity I'll let other passes optimize the move

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it may be beneficial to keep the current version. With your proposal, the interaction in #77031 (comment) would break. This is only one case, yeah, but it still seems worth to keep that.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I personally would prefer to break that interaction and fix it in a separate PR. Otherwise we need to implement both the simpler version of this PR together with the peephole opt for trivial copy propagation.

}

// We need to make sure that the Ne we are going to insert comes before the
// StorageDeads so we want to swap the StorageDead closest to Eq with Ne.
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought we are replacing the comparison, not the StorageDead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the confusion comes from the use of "insert"? We are replacing the Not with a Ne. And since we are going to use the operands from Eq in Ne, we need to make sure that we do not mark these operands as dead before they are used. I'll push up a new commit where I try to explain this better.

@bors
Copy link
Contributor

bors commented Sep 22, 2020

☔ The latest upstream changes (presumably #76683) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

Comment on lines 274 to 403
op1: Operand<'tcx>,
op2: Operand<'tcx>,
Copy link
Member

Choose a reason for hiding this comment

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

I think it would good to add some doc comments explaining what these fields are for. These two in particular are fairly opaque names but it would be good to have comments for the other fields too.

@simonvandel
Copy link
Contributor Author

Hi @oli-obk and @wesleywiser
I have added a set of commits on top of the original 2, which should resolve your comments.
@oli-obk I still need to understand your one comment.

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@bors
Copy link
Contributor

bors commented Sep 25, 2020

☔ The latest upstream changes (presumably #77198) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@camelid camelid added A-mir-opt Area: MIR optimizations S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 16, 2020
@Dylan-DPC-zz
Copy link

@simonvandel if you can merge the conflicts we can get this reviewed

@crlf0710
Copy link
Member

crlf0710 commented Nov 6, 2020

@simonvandel Ping from triage, could you resolve the merge conflicts? Also the CI is still red.

@crlf0710 crlf0710 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 6, 2020
@JohnCSimon JohnCSimon added the S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. label Nov 24, 2020
@JohnCSimon
Copy link
Member

@simonvandel
Thanks for your contribution, but unfortunately I'll have to close this due to being inactive for two months, please feel free to reopen when you ready to proceed.

@JohnCSimon JohnCSimon closed this Nov 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-mir-opt Area: MIR optimizations S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants