-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
rustc_mir: Hide initial block state when defining transfer functions #61787
rustc_mir: Hide initial block state when defining transfer functions #61787
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
dbc8b07
to
0d29e43
Compare
☔ The latest upstream changes (presumably #61817) made this pull request unmergeable. Please resolve the merge conflicts. |
0d29e43
to
c61b4c9
Compare
I also don't know what to call things but "const-correctness" does seem confusing from a C/C++ POV if it isn't that? |
To be clear: I don't think we should be using "const-correctness" to talk about mutability in Rust code. |
"refactor for more precise mutability information"? |
Yes, I meant "const-correctness" in the C++ sense. "Ensure |
I changed the title and made the names of the fields of |
☔ The latest upstream changes (presumably #61891) made this pull request unmergeable. Please resolve the merge conflicts. |
@ecstatic-morse : Lets rebase this on top of PR ##62010 and then revise it to change the dataflow API to not pass entry-set at all. Does that sound okay to you? |
83dd5c9
to
f9a6037
Compare
@pnkfelix. This PR now removes See the summary at the top for a full description. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
f9a6037
to
39faf52
Compare
This commit makes `sets.on_entry` inaccessible in `{before_,}{statement,terminator}_effect`. This field was meant to allow implementors of `BitDenotation` to access the initial state for each block (optionally with the effect of all previous statements applied via `accumulates_intrablock_state`) while defining transfer functions. However, the ability to set the initial value for the entry set of each basic block (except for START_BLOCK) no longer exists. As a result, this functionality is mostly useless, and when it *was* used it was used erroneously (see rust-lang#62007). Since `on_entry` is now useless, we can also remove `BlockSets`, which held the `gen`, `kill`, and `on_entry` bitvectors and replace it with a `GenKill` struct. Variables of this type are called `trans` since they represent a transfer function. `GenKill`s are stored contiguously in `AllSets`, which reduces the number of bounds checks and may improve cache performance: one is almost never accessed without the other. Replacing `BlockSets` with `GenKill` allows us to define some new helper functions which streamline dataflow iteration and the dataflow-at-location APIs. Notably, `state_for_location` used a subtle side-effect of the `kill`/`kill_all` setters to apply the transfer function, and could be incorrect if a transfer function depended on effects of previous statements in the block on `gen_set`.
Since the value of `InitialFlow` defines the semantics of the `join` operation, there's no reason to have seperate traits for each. We can add a default impl of `join` which branches based on `BOTTOM_VALUE`. This should get optimized away.
39faf52
to
c8cbd4f
Compare
@pnkfelix This is now rebased and ready for another round of review. |
fn bottom_value() -> bool; | ||
/// | ||
/// `BottomValue` determines whether the initial entry set for each basic block is empty or full. | ||
/// This also determines the semantics of the lattice `join` operator used to merge dataflow |
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.
hmm, clever
@bors r+ |
📌 Commit c8cbd4f has been approved by |
⌛ Testing commit c8cbd4f with merge c873491e73405ff647abd78f06db6e699bafcdb0... |
💔 Test failed - checks-travis |
Your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Spurious failure. |
@bors retry spurious network |
…kfelix rustc_mir: Hide initial block state when defining transfer functions This PR addresses [this FIXME](https://github.com/rust-lang/rust/blob/2887008e0ce0824be4e0e9562c22ea397b165c97/src/librustc_mir/dataflow/mod.rs#L594-L596). This makes `sets.on_entry` inaccessible in `{before_,}{statement,terminator}_effect`. This field was meant to allow implementors of `BitDenotation` to access the initial state for each block (optionally with the effect of all previous statements applied via `accumulates_intrablock_state`) while defining transfer functions. However, the ability to set the initial value for the entry set of each basic block (except for START_BLOCK) no longer exists. As a result, this functionality is mostly useless, and when it *was* used it was used erroneously (see #62007). Since `on_entry` is now useless, we can also remove `BlockSets`, which held the `gen`, `kill`, and `on_entry` bitvectors and replace it with a `GenKill` struct. Variables of this type are called `trans` since they represent a transfer function. `GenKill`s are stored contiguously in `AllSets`, which reduces the number of bounds checks and may improve cache performance: one is almost never accessed without the other. Replacing `BlockSets` with `GenKill` allows us to define some new helper functions which streamline dataflow iteration and the dataflow-at-location APIs. Notably, `state_for_location` used a subtle side-effect of the `kill`/`kill_all` setters to apply the transfer function, and could be incorrect if a transfer function depended on effects of previous statements in the block on `gen_set`. Additionally, this PR merges `BitSetOperator` and `InitialFlow` into one trait. Since the value of `InitialFlow` defines the semantics of the `join` operation, there's no reason to have seperate traits for each. We can add a default impl of `join` which branches based on `BOTTOM_VALUE`. This should get optimized away.
☀️ Test successful - checks-travis, status-appveyor |
This PR addresses this FIXME.
This makes
sets.on_entry
inaccessible in{before_,}{statement,terminator}_effect
. This field was meant to allow implementors ofBitDenotation
to access the initial state for each block (optionally with the effect of all previous statements applied viaaccumulates_intrablock_state
) while defining transfer functions. However, the ability to set the initial value for the entry set of each basic block (except for START_BLOCK) no longer exists. As a result, this functionality is mostly useless, and when it was used it was used erroneously (see #62007).Since
on_entry
is now useless, we can also removeBlockSets
, which held thegen
,kill
, andon_entry
bitvectors and replace it with aGenKill
struct. Variables of this type are calledtrans
since they represent a transfer function.GenKill
s are stored contiguously inAllSets
, which reduces the number of bounds checks and may improve cache performance: one is almost never accessed without the other.Replacing
BlockSets
withGenKill
allows us to define some new helper functions which streamline dataflow iteration and the dataflow-at-location APIs. Notably,state_for_location
used a subtle side-effect of thekill
/kill_all
setters to apply the transfer function, and could be incorrect if a transfer function depended on effects of previous statements in the block ongen_set
.Additionally, this PR merges
BitSetOperator
andInitialFlow
into one trait. Since the value ofInitialFlow
defines the semantics of thejoin
operation, there's no reason to have seperate traits for each. We can add a default impl ofjoin
which branches based onBOTTOM_VALUE
. This should get optimized away.