about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
AgeCommit message (Collapse)AuthorLines
2025-09-09Auto merge of #145717 - BoxyUwU:erase_regions_rename, r=lcnrbors-3/+4
rename erase_regions to erase_and_anonymize_regions I find it consistently confusing that `erase_regions` does more than replacing regions with `'erased`. it also makes some code look real goofy to be writing manual folders to erase regions with a comment saying "we cant use erase regions" :> or code that re-calls erase_regions on types with regions already erased just to anonymize all the bound regions. r? lcnr idk how i feel about the name being almost twice as long now
2025-09-09erase_regions to erase_and_anonymize_regionsBoxy-3/+4
2025-09-08fixup limit handling codeJana Dönszelmann-1/+1
2025-09-08Rollup merge of #146298 - cjgillot:gvn-derefer, r=nnethercoteMatthias Krüger-0/+5
GVN: Ensure indirect is first projection in try_as_place. I haven't found any report for this bug on existing code, but managed to trigger it with rust-lang/rust#143333
2025-09-08Auto merge of #145910 - saethlin:ignore-intrinsic-calls, r=cjgillotbors-1/+10
Ignore intrinsic calls in cross-crate-inlining cost model I noticed in a side project that a function which just compares to `[u64; 2]` for equality is not cross-crate-inlinable. That was surprising to me because I didn't think that code contained a function call, but of course our array comparisons are lowered to an intrinsic. Intrinsic calls don't make a function no longer a leaf, so it makes sense to add this as an exception to the "only leaves" cross-crate-inline heuristic. This is the useful compare link: https://perf.rust-lang.org/compare.html?start=7cb1a81145a739c4fd858abe3c624ce8e6e5f9cd&end=c3f0a64dbf9fba4722dacf8e39d2fe00069c995e&stat=instructions%3Au because it disables CGU merging in both commits, so effects that cause changes in the sysroot to perturb partitioning downstream are excluded. Perturbations to what is and isn't cross-crate-inlinable in the sysroot has chaotic effects on what items are in which CGUs after merging. It looks like before this PR by sheer luck some of the CGUs dirtied by the patch in eza incr-unchanged happened to be merged together, and with this PR they are not. The perf runs on this PR point to a nice runtime performance improvement.
2025-09-07Auto merge of #145541 - cjgillot:dest-prop-live-range, r=Amanieubors-502/+292
Reimplement DestinationPropagation according to live ranges. This PR reimplements DestinationPropagation as a problem of merging live-ranges of locals. We merge locals that have disjoint live-ranges. This allows merging several locals in the same round by updating live range information. Live ranges are mainly computed using the `MaybeLiveLocals` analysis. The subtlety is that we split each statement and terminator in 2 positions. The first position is the regular statement. The second position is a shadow, which is always more live. It encodes partial writes and dead writes as a local being live for half a statement. This half statement ensures that writes conflict with another local's writes and regular liveness. r? `@Amanieu`
2025-09-07Rollup merge of #146297 - cjgillot:may-observe-address, r=saethlinMatthias Krüger-1/+3
Introduce PlaceContext::may_observe_address. A small utility method to avoid open-coding the logic in several MIR opts.
2025-09-07Use rustc_data_structures::union_find.Camille Gillot-28/+14
2025-09-07Simplify candidate collection.Camille Gillot-55/+43
2025-09-07Unify a source with all possible destinations.Camille Gillot-59/+39
2025-09-07Do not use prepend to avoid quadratic behaviour.Camille Gillot-23/+28
2025-09-07Simplify VisitPlacesWith.Camille Gillot-18/+7
2025-09-07Use regular MaybeLiveLocals.Camille Gillot-133/+48
2025-09-07Reimplement DestinationPropagation according to live ranges.Camille GILLOT-458/+385
2025-09-07Auto merge of #146289 - cjgillot:gvn-aggregate, r=dianqkbors-28/+17
GVN: Allow reusing aggregates if LHS is not a simple local. This resolves a FIXME in the code. I don't see a reason not to allow this.
2025-09-07Ensure indirect is first projection in try_as_place.Camille GILLOT-0/+5
2025-09-07Introduce PlaceContext::may_observe_address.Camille GILLOT-1/+3
2025-09-07Rollup merge of #146254 - yotamofek:pr/itertools-all-equal-value, r=cjgillotMatthias Krüger-22/+18
Use `Itertools::all_equal_value()` where applicable Just a small cleanup. We already have `itertools` as a dep in these crates, so might as well use another of its features. Makes the code simpler IMHO :)
2025-09-07Allow simplifying aggregates if LHS is not a simple local.Camille GILLOT-28/+17
2025-09-05Ignore intrinsic calls in cross-crate-inlining cost modelBen Kimock-1/+10
2025-09-05Use `Itertools::all_equal_value()` where applicableYotam Ofek-22/+18
2025-09-05remove couple of clonesMatthias Krüger-1/+1
2025-09-04Rollup merge of #145932 - JamieCunliffe:target-feature-inlining, r=jackh726Stuart Cook-0/+133
Allow `inline(always)` with a target feature behind a unstable feature `target_feature_inline_always`. Rather than adding the inline always attribute to the function definition, we add it to the callsite. We can then check that the target features match and that the call would be safe to inline. If the function isn't inlined due to a mismatch, we emit a warning informing the user that the function can't be inlined due to the target feature mismatch. See tracking issue rust-lang/rust#145574
2025-09-01Auto merge of #146077 - Zalathar:rollup-l7ip5yi, r=Zalatharbors-141/+212
Rollup of 5 pull requests Successful merges: - rust-lang/rust#145468 (dedup recip, powi, to_degrees, and to_radians float tests) - rust-lang/rust#145643 (coverage: Build an "expansion tree" and use it to unexpand raw spans) - rust-lang/rust#145754 (fix(lexer): Don't require frontmatters to be escaped with indented fences) - rust-lang/rust#146060 (fixup nix dev shell again) - rust-lang/rust#146068 (compiletest: Capture panic messages via a custom panic hook) r? `@ghost` `@rustbot` modify labels: rollup
2025-09-01Rollup merge of #145643 - Zalathar:tree, r=SparrowLiiStuart Cook-141/+212
coverage: Build an "expansion tree" and use it to unexpand raw spans Historically and currently, coverage instrumentation assumes that all of a function's spans are in the same file and have the same syntax context. The spans extracted directly from MIR don't satisfy that assumption, so there is an “unexpansion” step that walks up each span's expansion-call-site tree to find a suitable span in the same context as the function's body span. (That unexpansion step is what allows us to have somewhat reasonable coverage instrumentation for macros like `println!`, and for syntax like `for` and `?` that undergo desugaring expansion.) The current unexpansion code mostly works fine in that “flat” single-file single-context world. But it's not suitable for incremental work towards proper expansion-aware coverage instrumentation, which would allow a function's coverage spans to encompass multiple expansion contexts and multiple files. This PR therefore replaces the current unexpansion code with a more sophisticated system that uses the raw MIR spans to reconstruct an “expansion tree”, and then uses that tree to help perform most of the unexpansion work. Building the tree is “overkill” for current unexpansion needs (though it does give some minor edge-case improvements), but my hope is that having the explicit tree available will be a big help when taking the next steps towards proper expansion-region support.
2025-09-01Introduce `MirDumper` and `MirWriter`.Nicholas Nethercote-37/+70
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-09-01Use trait object references for closures.Nicholas Nethercote-15/+15
The dynamic dispatch cost doesn't matter for MIR dumping, which is perf-insensitive. And it's necessary for the next commit, which will store some `extra_data` closures in a struct.
2025-09-01Inline and remove `dump_mir_for_pass`.Nicholas Nethercote-16/+6
The code is more readable without it.
2025-08-27inline at the callsite & warn when target features mismatchJames Barford-Evans-0/+133
Co-authored-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
2025-08-26add a flag to codegen fn attrs for foreign itemsJana Dönszelmann-1/+1
2025-08-24coverage: Build an "expansion tree" and use it to unexpand raw spansZalathar-141/+212
2025-08-23Fix ICE when validating transmuting ZST to inhabited enumSamuel Tardieu-0/+15
MIR validation attempts to determine the number of bytes needed to represent the size of the source type to compute the discriminant for the inhabited target enum. For a ZST source, there is no source data to use as a discriminant so no proper runtime check can be generated. Since that should never be possible, insert a delayed bug to ensure the problem has been properly reported to the user by the type checker.
2025-08-22Rollup merge of #145738 - cjgillot:union-find-uplift, r=ZalatharJacob Pratt-131/+1
Uplift rustc_mir_transform::coverage::counters::union_find to rustc_data_structures. I was wondering if we had some union-find implementation in the compiler. We do. So put it where we can find it.
2025-08-22Rollup merge of #145695 - cjgillot:place-elem-map, r=oli-obk,lcnrJacob Pratt-47/+15
Introduce ProjectionElem::try_map. Small utility function useful to manipulate MIR place projections.
2025-08-22Rollup merge of #142185 - saethlin:refprop-moves, r=cjgillotJacob Pratt-3/+36
Convert moves of references to copies in ReferencePropagation This is a fix for https://github.com/rust-lang/rust/issues/141101. The root cause of this miscompile is that the SsaLocals analysis that MIR transforms use is supposed to detect locals that are only written to once, in their single assignment. But that analysis is subtly wrong; it does not consider `Operand::Move` to be a write even though the meaning ascribed to `Operand::Move` (at least as a function parameter) by Miri is that the callee may have done arbitrary writes to the caller's Local that the Operand wraps (because `Move` is pass-by-pointer). So Miri conwiders `Operand::Move` to be a write but both the MIR visitor system considers it a read, and so does SsaLocals. I have tried fixing this by changing the `PlaceContext` that is ascribed to an `Operand::Move` to a `MutatingUseContext` but that seems to have borrow checker implications, and changing SsaLocals seems to have wide-ranging regressions in MIR optimizations. So instead of doing those, this PR adds a new kludge to ReferencePropagation, which follows the same line of thinking as the kludge in CopyProp that solves this same problem inside that pass: https://github.com/rust-lang/rust/blob/a5584a8fe16037dc01782064fa41424a6dbe9987/compiler/rustc_mir_transform/src/copy_prop.rs#L65-L98
2025-08-22Uplift rustc_mir_transform::coverage::counters::union_find to ↵Camille Gillot-131/+1
rustc_data_structures.
2025-08-21Correct comments.Camille Gillot-2/+2
2025-08-21Introduce ProjectionElem::try_map.Camille GILLOT-47/+15
2025-08-17Auto merge of #145284 - nnethercote:type_name-print-regions, r=lcnrbors-17/+28
Print regions in `type_name`. Currently they are skipped, which is a bit weird, and it sometimes causes malformed output like `Foo<>` and `dyn Bar<, A = u32>`. Most regions are erased by the time `type_name` does its work. So all regions are now printed as `'_` in non-optional places. Not perfect, but better than the status quo. `c_name` is updated to trim lifetimes from MIR pass names, so that the `PASS_NAMES` sanity check still works. It is also renamed as `simplify_pass_type_name` and made non-const, because it doesn't need to be const and the non-const implementation is much shorter. The commit also renames `should_print_region` as `should_print_optional_region`, which makes it clearer that it only applies to some regions. Fixes rust-lang/rust#145168. r? `@lcnr`
2025-08-15Rollup merge of #145392 - Zalathar:create-mappings, r=petrochenkovStuart Cook-77/+31
coverage: Remove intermediate data structures from mapping creation The data structures in `coverage::mappings` were historically very useful for isolating the details of mapping-extraction from the details of how coverage mappings are stored in MIR. But because of various changes that have taken place over time, they now provide little value, and cause difficulty for the coordinated changes that will be needed for introducing expansion mapping support. In the future, the pendulum might eventually swing back towards these being useful again, but we can always reintroduce suitable intermediate data structures if and when that happens. For now, the simplicity of not having this intermediate layer is a higher priority. There should be no changes to compiler output.
2025-08-14coverage: Remove intermediate data structures from mapping creationZalathar-77/+31
2025-08-14Print regions in `type_name`.Nicholas Nethercote-17/+28
Currently they are skipped, which is a bit weird, and it sometimes causes malformed output like `Foo<>` and `dyn Bar<, A = u32>`. Most regions are erased by the time `type_name` does its work. So all regions are now printed as `'_` in non-optional places. Not perfect, but better than the status quo. `c_name` is updated to trim lifetimes from MIR pass names, so that the `PASS_NAMES` sanity check still works. It is also renamed as `simplify_pass_type_name` and made non-const, because it doesn't need to be const and the non-const implementation is much shorter. The commit also renames `should_print_region` as `should_print_optional_region`, which makes it clearer that it only applies to some regions. Fixes #145168.
2025-08-13Cleanup assoc parent utilsCameron Steffen-4/+4
2025-08-12make no_mangle explicit on foreign itemsJana Dönszelmann-1/+1
2025-08-11Convert moves of references to copies in RefPropBen Kimock-3/+36
2025-08-09Rollup merge of #144883 - scottmcm:remove-unneeded-drop_in_place, r=nnethercoteStuart Cook-7/+24
Remove unneeded `drop_in_place` calls Might as well pull this out from rust-lang/rust#144561 because this is still used in things like `Vec::truncate` where it'd be nice to allow it be removed if inlined enough to see that the type is `Copy`. So long as perf says it's ok, at least 🤞
2025-08-08coverage: Remove obsolete comment about hashing HIRZalathar-2/+5
This code does not hash HIR manually (and has not done so for some time); it merely obtains a hash returned as part of `hir_owner_nodes`.
2025-08-08coverage: Extract HIR-related helper code out of the main moduleZalathar-136/+139
2025-08-08Rollup merge of #145030 - cjgillot:gvn-no-flatten-index, r=saethlinStuart Cook-2/+13
GVN: Do not flatten derefs with ProjectionElem::Index. r? `@saethlin` This should fix the bug you found with https://github.com/rust-lang/rust/pull/131650
2025-08-08Rollup merge of #144999 - Zalathar:remove-mcdc, r=oli-obkStuart Cook-379/+5
coverage: Remove all unstable support for MC/DC instrumentation Preliminary support for a partial implementation of “Modified Condition/Decision Coverage” instrumentation was added behind the unstable flag `-Zcoverage-options=mcdc` in 2024. These are the most substantial PRs involved: - rust-lang/rust#123409 - rust-lang/rust#126733 At the time, I accepted these PRs with relatively modest scrutiny, because I did not want to stand in the way of independent work on MC/DC instrumentation. My hope was that ongoing work by interested contributors would lead to the code becoming clearer and more maintainable over time. --- However, that MC/DC code has proven itself to be a major burden on overall maintenance of coverage instrumentation, and a major obstacle to other planned improvements, such as internal changes needed for proper support of macro expansion regions. I have also become reluctant to accept any further MC/DC-related changes that would increase this burden. That tension has resulted in an unhappy impasse. On one hand, the present MC/DC implementation is not yet complete, and shows little sign of being complete at an acceptable level of code quality in the foreseeable future. On the other hand, the continued existence of this partial MC/DC implementation is imposing serious maintenance burdens on every other aspect of coverage instrumentation, and is preventing some of the very improvements that would make it easier to accept expanded MC/DC support in the future. While I know this will be disappointing to some, I think the healthy way forward is accept that I made the wrong call in accepting the current implementation, and to remove it entirely from the compiler.