-
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
[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks #30238
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nrc (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Thanks for picking that up! I didn't have the time to take care of it yet. I'm not sure if I like the predecessor counter instead of the map though. I'm somewhat expecting people to come up with passes that will require actual predecessor lookup, and then it'd be nice if the existing code already deals with keeping the map updated. Did you address your other concern about missed optimizations? |
That makes sense - that possibility was another reason that I was uncomfortable about my second commit. However, I'd be inclined to limit things to storing counts until we actually have a pass that needs the extra complexity. My other concern about missed optimizations seemed separate from this change, so I did it in #30239 (all it took was changing |
r? @dotdash |
As the original author, I don't think I should do the review for this. r? @nikomatsakis -- you expressed some interest in reviewing my original PR. FWIW, my only concern here really is that re-introducing the actual predecessor map later might be harder. |
let mut changed = false; | ||
for bb in mir.all_basic_blocks() { | ||
let mut seen = vec![false; mir.basic_blocks.len()]; |
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.
Are the graphs large enough that a BitVector would be better for the seen map?
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.
I don't think they are large enough for it to make a big difference. However, they might be small enough that using a u64
or even a u32
with no allocation might work (with a fallback to Vec
or BitVec
).
Regardless, I think such a change should be in a separate PR.
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.
It'd be interesting to instrument the compiler and find out what's the largest number of blocks we see in building rustc
at least.
I'll take a look. For various reasons I've gotten pretty behind on reviews/e-mail/everything, but I'm working backwards from the most recent stuff. I remember that for the previous PR I was a bit unsure if this change was strictly better --- I thought there might be some cases that were optimized by the older approach that are not by the newer approach? Or do you think otherwise. |
Terminator::Goto { target } if target.index() > DIVERGE_BLOCK.index() && | ||
predecessor_map.num_predecessors(target) == 1 => { | ||
changed = true; | ||
let mut other_data = BasicBlockData { |
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.
Nit: I think this would be prettier like this
let other_data = mem::replace(mir.basic_block_data_mut(target), BasicBlockData { ... });
Not sure what I was worried about. This seems like a simple extension. I'm inclined to r+ modulo the nits above. |
@gereeter do you think you'll be able to address the nits I raised above, or are you too busy at the moment? |
@nikomatsakis Sorry for the delay - school just finished up for the semester, so I should have more time. It just occurred to me that this, as currently implemented, can devolve into O(n log n) behavior. For example, if we have
then a single pass will merge |
Okay, nits and performance issue fixed. |
…nce to improve performance.
…after the main merging loop where it can do more good immediately.
186670d
to
db8729e
Compare
So I think it's clear we need to devise some unit tests for these optimizations! I imagine a macro that lets you relatively easily write MIR code by hand and then observe the result. |
Related to the comments on #30239, it seems to me that you could just make It's also pointless to run simplify_branches();
remove_dead_blocks();
merge_consecutive_blocks();
remove_dead_blocks(); |
Hmm, at first read, what @Aatch said made sense to me. |
@Aatch That makes lots of sense. Moreover,
|
Related to #26496. |
☔ The latest upstream changes (presumably #30481) made this pull request unmergeable. Please resolve the merge conflicts. |
Closing due to inactivity, but feel free to resubmit with comments addressed! |
[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks Updated from rust-lang#30238, including the changes suggested by @Aatch.
[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks Updated from rust-lang#30238, including the changes suggested by @Aatch.
[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks Updated from rust-lang#30238, including the changes suggested by @Aatch.
[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks Updated from rust-lang#30238, including the changes suggested by @Aatch.
This is a rebase of @dotdash's #29838. I'm not sure that I like the last commit, as it seems a lot harder to tell that predecessors are tracked correctly when what predecessors are changing isn't written down.