It's nice to be able to index with a scope-id,
but coherence rules prevent us from implementing
`Index<ScopeId>` for `Vec<ScopeAuxiliary>`, and I'd
prefer that `ScopeAuxiliary` remain in librustc_mir,
just for compilation time reasons.
Add Pass manager for MIR
A new PR, since rebasing the original one (https://github.com/rust-lang/rust/pull/31448) properly was a pain. Since then there has been several changes most notable of which:
1. Removed the pretty-printing with `#[rustc_mir(graphviz/pretty)]`, mostly because we now have `--unpretty=mir`, IMHO that’s the direction we should expand this functionality into;
2. Reverted the infercx change done for typeck, because typeck can make an infercx for itself by being a `MirMapPass`
r? @nikomatsakis
The pass removes the unwind branch of each terminator, thus moving the responsibility of handling
the -Z no-landing-pads flag to a small self-contained pass… instead of polluting the translator.
This is roughly the same as my previous PR that created a dependency graph, but that:
1. The dependency graph is only optionally constructed, though this doesn't seem to make much of a difference in terms of overhead (see measurements below).
2. The dependency graph is simpler (I combined a lot of nodes).
3. The dependency graph debugging facilities are much better: you can now use `RUST_DEP_GRAPH_FILTER` to filter the dep graph to just the nodes you are interested in, which is super help.
4. The tests are somewhat more elaborate, including a few known bugs I need to fix in a second pass.
This is potentially a `[breaking-change]` for plugin authors. If you are poking about in tcx state or something like that, you probably want to add `let _ignore = tcx.dep_graph.in_ignore();`, which will cause your reads/writes to be ignored and not affect the dep-graph.
After this, or perhaps as an add-on to this PR in some cases, what I would like to do is the following:
- [x] Write-up a little guide to how to use this system, the debugging options available, and what the possible failure modes are.
- [ ] Introduce read-only and perhaps the `Meta` node
- [x] Replace "memoization tasks" with node from the map itself
- [ ] Fix the shortcomings, obviously! Notably, the HIR map needs to register reads, and there is some state that is not yet tracked. (Maybe as a separate PR.)
- [x] Refactor the dep-graph code so that the actual maintenance of the dep-graph occurs in a parallel thread, and the main thread simply throws things into a shared channel (probably a fixed-size channel). There is no reason for dep-graph construction to be on the main thread. (Maybe as a separate PR.)
Regarding performance: adding this tracking does add some overhead, approximately 2% in my measurements (I was comparing the build times for rustdoc). Interestingly, enabling or disabling tracking doesn't seem to do very much. I want to poke at this some more and gather a bit more data -- in some tests I've seen that 2% go away, but on others it comes back. It's not entirely clear to me if that 2% is truly due to constructing the dep-graph at all.
The next big step after this is write some code to dump the dep-graph to disk and reload it.
r? @michaelwoerister
For now, this pass does some easy transformations, like eliminating
empty blocks that just jump to another block, some trivial
conversion of If terminators into Gotos and removal of dead blocks.
r? @nikomatsakis
For now, this pass does some easy transformations, like eliminating
empty blocks that just jump to another block, some trivial
conversion of If terminators into Gotos and removal of dead blocks.