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

rBreak Critical Edges and other MIR work #32210

Merged
merged 7 commits into from
Apr 3, 2016
Merged

Conversation

Aatch
Copy link
Contributor

@Aatch Aatch commented Mar 12, 2016

This PR is built on top of #32080.

This adds the basic depth-first traversals for MIR, preorder, postorder and reverse postorder. The MIR blocks are now translated using reverse postorder. There is also a transform for breaking critical edges, which includes the edges from invoked calls (Drop and Call), to account for the fact that we can't add code after an invoke. It also stops generating the intermediate block (since the transform essentially does it if necessary already).

The kinds of cases this deals with are difficult to produce, so the test is the one I managed to get. However, it seems to bootstrap with -Z orbit, which it didn't before my changes.

@Aatch
Copy link
Contributor Author

Aatch commented Mar 12, 2016

/cc #32105

@arielb1
Copy link
Contributor

arielb1 commented Mar 12, 2016

I would do the transform in the MIR pipeline, rather than in a separate pass.

@Aatch
Copy link
Contributor Author

Aatch commented Mar 12, 2016

@arielb1 I was considering this: #32105 (comment). Given that it's more of a "utility" pass, I'm not sure it really makes sense to have it in the main set of passes anyway, at least until we have a proper MIR pass that needs it.

@arielb1
Copy link
Contributor

arielb1 commented Mar 13, 2016

@Aatch

I would either run the pass in the mir_map pipeline or in a newly-created trans pipeline. I don't think that inserting spread-around MIR passes in the driver is a good idea - you would have to make sure that no pass interferes with the dependencies of another.

@bors
Copy link
Contributor

bors commented Mar 13, 2016

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

@Aatch
Copy link
Contributor Author

Aatch commented Mar 14, 2016

@arielb1 I was considering a general "trans preparation" phase, similar to LLVM's CodegenPrepare, so that sounds good. It should probably include the erase regions pass too.

@alexcrichton
Copy link
Member

r? @nikomatsakis

@eddyb
Copy link
Member

eddyb commented Mar 15, 2016

cc me (I wish PR mentions did this automatically)

@nikomatsakis
Copy link
Contributor

Well spotted. IMO we should just remove the special-casing for the return BB and let the block removal pass remove it once initial MIR build is complete. I think any reasons for the end-block existence requirement are legacy by now.

The reason I added the end-block in the first place is that it's often convenient when doing analysis to have an easy reference point to walk backwards from. But we can always patch this up later I imagine, if it makes sense.

@nikomatsakis
Copy link
Contributor

I was considering a general "trans preparation" phase, similar to LLVM's CodegenPrepare, so that sounds good. It should probably include the erase regions pass too.

👍

///
/// A preorder traversal of this graph is either `A B D C` or `A C D B`
#[derive(Clone)]
pub struct Preorder<'a, 'tcx: 'a> {
Copy link
Contributor

Choose a reason for hiding this comment

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

This kind of code is crying out for unit tests, but I'm not sure what'd be the easiest way to add them. The only thing I can think of is trying to make the core logic generic, which is probably more trouble than its worth -- though I've thought about making some kind of graph trait that MIR (as well as librustc_data_structures::graph::Graph) could implement, precisely so that we could write (and test) these sorts of algorithms generically.

@nikomatsakis
Copy link
Contributor

r=me

@dotdash dotdash changed the title Break Critical Edges and other MIR work rBreak Critical Edges and other MIR work Mar 18, 2016
@Aatch
Copy link
Contributor Author

Aatch commented Mar 26, 2016

Apologies for the delay here. My laptop needed repair the day #32080 landed... I'll rebase and update soon.

Adds Preorder, Postorder and Reverse Postorder traversal iterators.

Also makes trans/mir use Reverse Postorder traversal for blocks.
This is a fairly standard transform that inserts blocks along critical
edges so code can be inserted along the edge without it affecting other
edges. The main difference is that it considers a Drop or Call
terminator that would require an `invoke` instruction in LLVM a critical
edge. This is because we can't actually insert code after an invoke, so
it ends up looking similar to a critical edge anyway.

The transform is run just before translation right now.
Some blocks won't be translated at all because they aren't reachable at
the LLVM level, these need to be dealt with because they lack a
terminator and therefore trigger an LLVM assertion.

Other blocks aren't reachable because of codegen-time optimistions, for
example not dropping types that don't need it, often resulting in blocks
with no predecessors. We'll clean those up as well.
@Aatch Aatch force-pushed the mir-traversal branch 2 times, most recently from 71c948a to 42c856a Compare March 30, 2016 01:55
@Aatch
Copy link
Contributor Author

Aatch commented Mar 30, 2016

Rebased and updated. I added a pipeline for running MIR passes that prepare the MIR for translation.

Also adds a new set of passes to run just before translation that
"prepare" the MIR for codegen. Removal of landing pads, region erasure
and break critical edges are run in this pass.

Also fixes some merge/rebase errors.
@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Apr 2, 2016

📌 Commit 63321ca has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Apr 2, 2016

⌛ Testing commit 63321ca with merge dfd4040...

@bors
Copy link
Contributor

bors commented Apr 2, 2016

💔 Test failed - auto-win-msvc-64-opt-mir

@Aatch
Copy link
Contributor Author

Aatch commented Apr 3, 2016

Figured out what failure was. I wasn't making the inserted blocks inherit the is_cleanup flag from the original target which screwed up the cleanupret codegen on MSVC. Just testing a fix now.

Also adds a FromIterator impl for BitVector to allow construction of a
BitVector from an iterator yeilding bools.
@Aatch
Copy link
Contributor Author

Aatch commented Apr 3, 2016

@bors r=nikomatsakis 605bc04

@bors
Copy link
Contributor

bors commented Apr 3, 2016

⌛ Testing commit 605bc04 with merge 251fd8b...

@bors
Copy link
Contributor

bors commented Apr 3, 2016

💔 Test failed - auto-win-msvc-64-opt-rustbuild

@dotdash
Copy link
Contributor

dotdash commented Apr 3, 2016

@bors retry

@bors
Copy link
Contributor

bors commented Apr 3, 2016

⌛ Testing commit 605bc04 with merge c0b8c43...

bors added a commit that referenced this pull request Apr 3, 2016
rBreak Critical Edges and other MIR work

This PR is built on top of #32080.

This adds the basic depth-first traversals for MIR, preorder, postorder and reverse postorder. The MIR blocks are now translated using reverse postorder. There is also a transform for breaking critical edges, which includes the edges from `invoke`d calls (`Drop` and `Call`), to account for the fact that we can't add code after an `invoke`. It also stops generating the intermediate block (since the transform essentially does it if necessary already).

The kinds of cases this deals with are difficult to produce, so the test is the one I managed to get. However, it seems to bootstrap with `-Z orbit`, which it didn't before my changes.
@bors bors merged commit 605bc04 into rust-lang:master Apr 3, 2016
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.

7 participants