-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Reimplement ConstProp using DataflowConstProp #110719
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
4837cfb
to
79c1168
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
79c1168
to
39b5ce5
Compare
c58cc1e
to
f960de6
Compare
☔ The latest upstream changes (presumably #113758) made this pull request unmergeable. Please resolve the merge conflicts. |
f960de6
to
542052d
Compare
☔ The latest upstream changes (presumably #114483) made this pull request unmergeable. Please resolve the merge conflicts. |
Improvements to dataflow const-prop Partially cherry-picked from rust-lang#110719 r? `@oli-obk` cc `@jachris`
Improvements to dataflow const-prop Partially cherry-picked from rust-lang#110719 r? `@oli-obk` cc `@jachris`
542052d
to
b1c7b7d
Compare
This comment has been minimized.
This comment has been minimized.
@@ -1,11 +1,10 @@ | |||
Function name: <issue_84561::Foo as core::cmp::PartialEq>::eq | |||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 0a, 00, 13, 00, 00, 0a, 00, 13] | |||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 0a, 00, 13] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Zalathar This commit blesses the coverage map. However, I have no idea how to check that it is still correct. What do you recommend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a rule of thumb, any PR that doesn't touch coverage-specific code should feel free to just re-bless these.
(They're unfortunately quite sensitive to changes in MIR lowering/optimization, in a way that tends to result in different but equivalent mappings.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In particular, as long as the run-coverage
tests still pass, then any changes to the mappings are probably just noise.
(Those tests only run if the profiler runtime is enabled in config.toml
, so they don't run by default in dev builds or on PRs, but they do run in the full CI before merging.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the actual diff, it seems like some MIR statements that were previously being optimized out are no longer being optimized out. Nothing to worry about from a coverage perspective.
Improvements to dataflow const-prop Partially cherry-picked from rust-lang/rust#110719 r? `@oli-obk` cc `@jachris`
☔ The latest upstream changes (presumably #115705) made this pull request unmergeable. Please resolve the merge conflicts. |
I'd like to close this PR and pursue another direction for #109597 creates a general framework for value analyses. I believe that implementing constant-folding in this pass can achieve the same level as what this PR proposes, while being more flexible:
|
That makes sense |
const-prop can simplify some things here, right, like x*0 -> 0 or x+0 -> x? |
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang#110719 (comment) Based on rust-lang#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in rust-lang#109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang@2767c49)" r? `@oli-obk`
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang#110719 (comment) Based on rust-lang#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in rust-lang#109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang@2767c49)" r? `@oli-obk`
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang#110719 (comment) Based on rust-lang#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in rust-lang#109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang@2767c49)" r? `@oli-obk`
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang#110719 (comment) Based on rust-lang#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in rust-lang#109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang@2767c49)" r? `@oli-obk`
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang#110719 (comment) Based on rust-lang#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in rust-lang#109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang@2767c49)" r? `@oli-obk`
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang#110719 (comment) Based on rust-lang#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in rust-lang#109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang@2767c49)" r? `@oli-obk`
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in rust-lang/rust#110719 (comment) Based on rust-lang/rust#109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in #109597. From this abstract representation, we can perform more involved simplifications, for example in rust-lang/rust#111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](rust-lang/rust@2767c49)" r? `@oli-obk`
This PR attempts to remove the current ConstProp optimization, and replace it by an implementation based on DataflowConstProp.
The current ConstProp twists the MIR interpreter to do things it is not designed to do, including manipulating generic types. Meanwhile, @jachris has implemented a new DataflowConstProp pass that only uses a few chosen methods for arithmetic.
The main change concerns how propagatable places and operations are tracked. In the current ConstProp, all places are tracked and all operations executed, and we removed wrong or non-propagatable results. This new implementation does the opposite : place tracking is opt-in, and we only propagate supported operations. I believe this approach to be less risky from a soundness point of view.
As a consequence, this new implementation is more restricted. The main limitation is that we stop propagating inside a basic block, and only propagate SSA locals. This makes the implementation simpler, and is more consistent with this "opt-in" logic.
Some operations are added inside this PR (transmutes, algebraic simplifications,
Len
operations). The handling of statics and non-scalar consts are left to a follow-up PR.This PR does not remove the const-prop lints (arithmetic overflow and unconditional panic), as I need to design a way to pass more span information around.
There has been quite a few perf runs below. Marking as ready for review, since I removed the massive regressions on diesel/keccak/serde. Kept as waiting-on-author until I bless CI.
Regressed optimizations:
Based on #110728, #110732, #110820