about summary refs log tree commit diff
path: root/compiler/rustc_mir_dataflow/src/framework
AgeCommit message (Collapse)AuthorLines
2025-09-01Introduce `MirDumper` and `MirWriter`.Nicholas Nethercote-6/+7
MIR dumping is a mess. There are lots of functions and entry points, e.g. `dump_mir`, `dump_mir_with_options`, `dump_polonius_mir`, `dump_mir_to_writer`. Also, it's crucial that `create_dump_file` is never called without `dump_enabled` first being checked, but there is no mechanism for ensuring this and it's hard to tell if it is satisfied on all paths. (`dump_enabled` is checked twice on some paths, however!) This commit introduces `MirWriter`, which controls the MIR writing, and encapsulates the `extra_data` closure and `options`. Two existing functions are now methods of this type. It sets reasonable defaults, allowing the removal of many `|_, _| Ok(())` closures. The commit also introduces `MirDumper`, which is layered on top of `MirWriter`, and which manages the creation of the dump files, encapsulating pass names, disambiguators, etc. Four existing functions are now methods of this type. - `MirDumper::new` will only succeed if dumps are enabled, and will return `None` otherwise, which makes it impossible to dump when you shouldn't. - It also sets reasonable defaults for various things like disambiguators, which means you no longer need to specify them in many cases. When they do need to be specified, it's now done via setter methods. - It avoids some repetition. E.g. `dump_nll_mir` previously specifed the pass name `"nll"` four times and the disambiguator `&0` three times; now it specifies them just once, to put them in the `MirDumper`. - For Polonius, the `extra_data` closure can now be specified earlier, which avoids having to pass some arguments through some functions.
2025-08-20Eliminate unnecessary dependency from `rustc_mir_dataflow` to `rustc_hir`Josh Triplett-1/+1
`rustc_mir_dataflow` only uses `DefId`, which is a re-export from `rustc_span`.
2025-08-08Escape diff strings in graphvizAmogh Shivaram-0/+1
2025-07-11Remove support for SwitchInt edge effects in backward dataflow analysesTomasz Miąsko-9/+6
Those effects are untested and unused. Remove them along with the implementation of `BasicBlocks::switch_sources`.
2025-07-11Call `get_switch_int_data` on a block with SwitchInt terminatorTomasz Miąsko-1/+1
Fix a mix-up of a block with its predecessors in handling of SwitchInt edge effects for backward analysis. Note that this functionality is currently unused, so change has no practical impact.
2025-07-09Auto merge of #142707 - ashivaram23:drop_wildcard, r=dianqkbors-5/+7
Apply effects to `otherwise` edge in dataflow analysis This allows `ElaborateDrops` to remove drops when a `match` wildcard arm covers multiple no-Drop enum variants. It modifies dataflow analysis to update the `MaybeUninitializedPlaces` and `MaybeInitializedPlaces` data for a block reached through an `otherwise` edge. Fixes rust-lang/rust#142705.
2025-07-08Apply effects to otherwise edge in dataflow analysisAmogh Shivaram-5/+7
2025-06-29mir: Use the `new` method for `BasicBlockData`dianqk-5/+5
2025-06-29mir: Add a `new` method to `statement`dianqk-1/+1
Avoid introducing a large number of changes when adding optional initialization fields.
2025-04-24Separate `Analysis` and `Results`.Nicholas Nethercote-125/+119
`Results` contains and `Analysis` and an `EntryStates`. The unfortunate thing about this is that the analysis needs to be mutable everywhere (`&mut Analysis`) which forces the `Results` to be mutable everywhere, even though `EntryStates` is immutable everywhere. To fix this, this commit renames `Results` as `AnalysisAndResults`, renames `EntryStates` as `Results`, and separates the analysis and results as much as possible. (`AnalysisAndResults` doesn't get much use, it's mostly there to facilitate method chaining of `iterate_to_fixpoint`.) `Results` is immutable everywhere, which: - is a bit clearer on how the data is used, - avoids an unnecessary clone of entry states in `locals_live_across_suspend_points`, and - moves the results outside the `RefCell` in Formatter. The commit also reformulates `ResultsHandle` as the generic `CowMut`, which is simpler than `ResultsHandle` because it doesn't need the `'tcx` lifetime and the trait bounds. It also which sits nicely alongside the new use of `Cow` in `ResultsCursor`.
2025-04-24Pass `Analysis` to `visit_*` instead of `Results`.Nicholas Nethercote-28/+30
Every `Results` contains an `Analysis`, but these methods only need the `Analysis`. No point passing them more data than they need.
2025-04-22Remove unnecessary lifetime on `ResultsVisitor`.Nicholas Nethercote-12/+12
2025-04-22Remove unused `ResultsCursor` methods.Nicholas Nethercote-15/+0
2025-04-22Move `StateDiffCollector`'s use point.Nicholas Nethercote-10/+11
Currently the graphviz code does a `results.visit_with` call while also holding a `ResultsCursor` on the `results`. That is both kinds of results traversals at the same time, which is awkward. This commit moves the `results.visit_with` part earlier so the two results traversals don't overlap.
2025-04-21Store `Results` in Formatter.Nicholas Nethercote-20/+20
Instead of `ResultsCursor`. This partly undoes the second commit from #132346; possible because `Results::as_result_cursor` (which doesn't consume the `Results`) is now available. Delaying the `ResultsCursor` construction will facilitate the next couple of commits.
2025-04-17Avoid an `unwrap` in `RustcMirAttrs::set_field`.Nicholas Nethercote-22/+23
2025-04-17Replace infallible `name_or_empty` methods with fallible `name` methods.Nicholas Nethercote-2/+3
I'm removing empty identifiers everywhere, because in practice they always mean "no identifier" rather than "empty identifier". (An empty identifier is impossible.) It's better to use `Option` to mean "no identifier" because you then can't forget about the "no identifier" possibility. Some specifics: - When testing an attribute for a single name, the commit uses the `has_name` method. - When testing an attribute for multiple names, the commit uses the new `has_any_name` method. - When using `match` on an attribute, the match arms now have `Some` on them. In the tests, we now avoid printing empty identifiers by not printing the identifier in the `error:` line at all, instead letting the carets point out the problem.
2025-04-16Remove support for `#[rustc_mir(borrowck_graphviz_format="gen_kill")]`.Nicholas Nethercote-1/+1
Because it's equivalent to `#[rustc_mir(borrowck_graphviz_format)]`. It used to be distinct, but the distinction was removed in https://github.com/rust-lang/rust/pull/76044/commits/3233fb18a891363a2da36ce69ca16fbb219c96be.
2025-02-17Remove `SwitchIntTarget`.Nicholas Nethercote-13/+6
It's only passed to `Analysis::apply_switch_int_edge_effect`, and the existing impls of that method only use the `value` field. So pass that instead.
2025-02-17Add `SwitchTargetValue`.Nicholas Nethercote-5/+10
This is much clearer than `Option<u128>`.
2025-02-17Refactor `apply_effects_in_block`.Nicholas Nethercote-13/+7
Very minor changes that will make the next few commits easier to follow.
2025-02-08Rustfmtbjorn3-26/+33
2025-01-19Run `clippy --fix` for `unnecessary_map_or` lintYotam Ofek-1/+1
2025-01-11rename `BitSet` to `DenseBitSet`Rémy Rakic-19/+19
This should make it clearer that this bitset is dense, with the advantages and disadvantages that it entails.
2024-12-18Auto merge of #133328 - nnethercote:simplify-SwitchInt-handling, r=tmiaskobors-133/+59
Simplify `SwitchInt` handling Dataflow handling of `SwitchInt` is currently complicated. This PR simplifies it. r? `@cjgillot`
2024-12-18Rollup merge of #134161 - nnethercote:overhaul-token-cursors, r=spastorino许杰友 Jieyou Xu (Joe)-1/+0
Overhaul token cursors Some nice cleanups here. r? `````@davidtwco`````
2024-12-18Remove a comment that shouldn't have been committed.Nicholas Nethercote-1/+0
2024-12-18Re-export more `rustc_span::symbol` things from `rustc_span`.Nicholas Nethercote-1/+1
`rustc_span::symbol` defines some things that are re-exported from `rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some closely related things such as `Ident` and `kw`. So you can do `use rustc_span::{Symbol, sym}` but you have to do `use rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good reason. This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`, and changes many `rustc_span::symbol::` qualifiers in `compiler/` to `rustc_span::`. This is a 200+ net line of code reduction, mostly because many files with two `use rustc_span` items can be reduced to one.
2024-12-16Remove a `FIXME` comment.Nicholas Nethercote-2/+0
It is possible to avoid the clone as suggested in the comment. It would require introducing an enum with two variants `CloneBeforeModifying(&Domain)` and `Modifiable(&mut Domain)`. But it's not worth the effort, because this code path just isn't very hot. E.g. when compiling a large benchmark like `cargo-0.60.0` it's only hit a few thousand times.
2024-12-16Remove `opt_clone_from_or_clone`.Nicholas Nethercote-30/+13
Switches to the idiom used elsewhere of calling `Analysis::bottom_value` to initialize a `state` value outside a loop, and then using `clone_from` to update it within the loop. This is simpler and has no impact on performance.
2024-12-16Simplify dataflow `SwitchInt` handling.Nicholas Nethercote-112/+57
Current `SwitchInt` handling has complicated control flow. - The dataflow engine calls `Analysis::apply_switch_int_edge_effects`, passing in an "applier" that impls `SwitchIntEdgeEffects`. - `apply_switch_int_edge_effects` possibly calls `apply` on the applier, passing it a closure. - The `apply` method calls the closure on each `SwitchInt` edge. - The closure operates on the edge. I.e. control flow goes from the engine, to the analysis, to the applier (which came from the engine), to the closure (which came from the analysis). It took me a while to work this out. This commit changes to a simpler structure that maintains the important characteristics. - The dataflow engine calls `Analysis::get_switch_int_data`. - `get_switch_int_data` returns an `Option<Self::SwitchIntData>` value. - If that returned value was `Some`, the dataflow engine calls `Analysis::apply_switch_int_edge_effect` on each edge, passing the `Self::SwitchIntData` value. - `Analysis::apply_switch_int_edge_effect` operates on the edge. I.e. control flow goes from the engine, to the analysis, to the engine, to the analysis. Added: - The `Analysis::SwitchIntData` assoc type and the `Analysis::get_switch_int_data` method. Both only need to be defined by analyses that look at `SwitchInt` terminators. - The `MaybePlacesSwitchIntData` struct, which has three fields. Changes: - `Analysis::apply_switch_int_edge_effects` becomes `Analysis::apply_switch_int_edge_effect`, which is a little simpler because it's dealing with a single edge instead of all edges. Removed: - The `SwitchIntEdgeEffects` trait, and its two impls: `BackwardSwitchIntEdgeEffectsApplier` (which has six fields) and `ForwardSwitchIntEdgeEffectsApplier` structs (which has four fields). - The closure. The new structure is more concise and simpler.
2024-12-13Rollup merge of #133938 - nnethercote:rustc_mir_dataflow-renamings, r=oli-obkMatthias Krüger-194/+132
`rustc_mir_dataflow` cleanups, including some renamings Some opinionated commits in this collection, let's see how we go. r? `@cjgillot`
2024-12-10Rollup merge of #134065 - nnethercote:mv-write_graphviz_results, r=tmiaskoLeón Orell Valerian Liehr-187/+182
Move `write_graphviz_results` r? ``@tmiasko``
2024-12-10Reorder some `Analysis` methods.Nicholas Nethercote-33/+33
In most places, the `early` method is listed before the corresponding `primary` method, like you'd expect. This commit fixes two places where that isn't the case.
2024-12-10Rename some `Analysis` and `ResultsVisitor` methods.Nicholas Nethercote-97/+95
The words "before" and "after" have an obvious temporal meaning, e.g. `seek_before_primary_effect`, `visit_statement_{before,after}_primary_effect`. But "before" is also used to name the effect that occurs before the primary effect of a statement/terminator; this is `Effect::Before`. This leads to the confusing possibility of talking about things happening "before/after the before event". This commit removes this awkward overloading of "before" by renaming `Effect::Before` as `Effect::Early`. It also renames some of the `Analysis` and `ResultsVisitor` methods to be more consistent. Here are the before and after names: - `Effect::{Before,Primary}` -> `Effect::{Early,Primary}` - `apply_before_statement_effect` -> `apply_early_statement_effect` - `apply_statement_effect` -> `apply_primary_statement_effect` - `visit_statement_before_primary_effect` -> `visit_after_early_statement_effect` - `visit_statement_after_primary_effect` -> `visit_after_primary_statement_effect` (And s/statement/terminator/ for all the terminator events.)
2024-12-10Rename `EntrySets` as `EntryStates`.Nicholas Nethercote-14/+15
"Set" doesn't make much sense here, we refer to domain values as "state" everywhere else. (This name confused me for a while.)
2024-12-10Remove unused dataflow trait impls and bounds.Nicholas Nethercote-62/+1
2024-12-09Move `write_graphviz_results` from `results.rs` to `graphviz.rs`.Nicholas Nethercote-187/+182
It's more graphviz-y than it is results-y. This lets us reduce visibility of several types in `graphviz.rs`.
2024-12-09Remove `ChunkedBitSet` impls that are no longer needed.Nicholas Nethercote-24/+2
`ChunkedBitSet` is no longer used directly by dataflow analyses, with `MixedBitSet` replacing it in those contexts.
2024-12-09Use `MixedBitSet` instead of `ChunkedBitSet` in `fmt.rs`.Nicholas Nethercote-6/+6
Just minimizing uses of `ChunkedBitSet`.
2024-12-05Introduce `MixedBitSet`.Nicholas Nethercote-3/+45
It just uses `BitSet` for small/medium sizes (<= 2048 bits) and `ChunkedBitSet` for larger sizes. This is good because `ChunkedBitSet` is slow and memory-hungry at smaller sizes.
2024-12-02Simplify `ResultsHandle`.Nicholas Nethercote-17/+3
The `Borrowed` variant is no longer used. This commit removes it, along with the `as_results_cursor` method that produces it, and renames `as_results_cursor_mut` as `as_results_cursor`.
2024-12-02Fix crash with `-Zdump-mir-dataflow`Nicholas Nethercote-5/+5
As of #133155 `Formatter:new` uses `as_results_cursor` to create a non-mutable results reference, and then later that is accessed via `deref_mut` which results in a runtime abort. Changing to `as_results_cursor_mut` fixes it. Fixes #133641.
2024-11-29Stop using `HybridBitSet` in dataflow diffs.Nicholas Nethercote-7/+7
As part of the larger goal of reducing `HybridBitSet` use in general. This code is for debugging only and isn't performance sensitive, so `ChunkedBitSet` should be fine.
2024-11-29Remove unused `HybridBitSet` methods from `BitSetExt`.Nicholas Nethercote-34/+2
2024-11-26Rollup merge of #133326 - nnethercote:rm-DefinitelyInitializedPlaces, r=cjgillotMichael Goulet-129/+2
Remove the `DefinitelyInitializedPlaces` analysis. Its only use is in the `tests/ui/mir-dataflow/def_inits-1.rs` where it is tested via `rustc_peek_definite_init`. Also, it's probably buggy. It's supposed to be the inverse of `MaybeUninitializedPlaces`, and it mostly is, except that `apply_terminator_effect` is a little different, and `apply_switch_int_edge_effects` is missing. Unlike `MaybeUninitializedPlaces`, which is used extensively in borrow checking, any bugs in `DefinitelyInitializedPlaces` are easy to overlook because it is only used in one small test. This commit removes the analysis. It also removes `rustc_peek_definite_init`, `Dual` and `MeetSemiLattice`, all of which are no longer needed. r? ``@cjgillot``
2024-11-26Make it possible for `ResultsCursor` to borrow a `Results`.Nicholas Nethercote-25/+76
`ResultsCursor` currently owns its `Results`. But sometimes the `Results` is needed again afterwards. So there is `ResultsCursor::into_results` for extracting the `Results`, which leads to some awkwardness. This commit adds `ResultsHandle`, a `Cow`-like type that can either borrow or own a a `Results`. `ResultsCursor` now uses it. This is good because some `ResultsCursor`s really want to own their `Results`, while others just want to borrow it. We end with with a few more lines of code, but get some nice cleanups. - `ResultsCursor::into_results` and `Formatter::into_results` are removed. - `write_graphviz_results` now just borrows a `Results`, instead of the awkward "take ownership of a `Results` and then return it unchanged" pattern. This reinstates the cursor flexibility that was lost in #118230 -- which removed the old `ResultsRefCursor` and `ResultsCloneCursor` types -- but in a much simpler way. Hooray!
2024-11-26Add some useful comments.Nicholas Nethercote-12/+24
Describing some things that took me a long time to understand.
2024-11-26Merge `apply_effects_in_block` and `join_state_into_successors_of`.Nicholas Nethercote-162/+132
They are always called in succession, so it's simpler if they are merged into a single function.
2024-11-22Remove the `DefinitelyInitializedPlaces` analysis.Nicholas Nethercote-129/+2
Its only use is in the `tests/ui/mir-dataflow/def_inits-1.rs` where it is tested via `rustc_peek_definite_init`. Also, it's probably buggy. It's supposed to be the inverse of `MaybeUninitializedPlaces`, and it mostly is, except that `apply_terminator_effect` is a little different, and `apply_switch_int_edge_effects` is missing. Unlike `MaybeUninitializedPlaces`, which is used extensively in borrow checking, any bugs in `DefinitelyInitializedPlaces` are easy to overlook because it is only used in one small test. This commit removes the analysis. It also removes `rustc_peek_definite_init`, `Dual` and `MeetSemiLattice`, all of which are no longer needed.