mir-transform: Treat optimize(none) the same as opt-level=0 - #160524
mir-transform: Treat optimize(none) the same as opt-level=0#160524clubby789 wants to merge 2 commits into
optimize(none) the same as opt-level=0#160524Conversation
354d5d9 to
e4742bc
Compare
|
Typo error caused an ICE in drop elaboration - optimizations.0 >= min_level
+ optimizations.0 < min_levelwhich seems a bit surprising EDIT: Seems like some other opts rely on |
This comment has been minimized.
This comment has been minimized.
|
Note that this now fails because #[optimize(none)]
pub fn const_branch() -> i32 {
if true { 1 } else { 0 }
}produces |
What do you mean by "rely" here and why does this become more of a problem with this PR? |
I didn't look into it deeply, but a few passes seemed to ICE if they ran with dead BBs.
It doesn't; I just made a typo during implementation which exposed this and I was unsure if that was intentional/known. |
We'd have to ask the people that wrote the passes, so it'd help if you had a concrete example and backtrace. I presume this can be reproduced with |
|
The ICE is from a debug assertion; with the typo reverted, and debug-assertions enabled, the ICE is as follows (when building std) rustc-ice-2026-08-10T06_58_41-132370.txt Minimised to a baseline rustc with debug assertions: // rustc ice.rs -Zmir-enable-passes=-SimplifyCfg-initial,-SimplifyCfg-promote-consts,-SimplifyCfg-post-analysis
fn mir_drop<T>(_place: T) {
panic!()
}
fn main() {
mir_drop(());
}Not sure if this is a problem at all in practice? If you think it is I can split out a new issue since it's not too relevant to this PR specifically |
|
Thanks! Could you file an issue? Then we can ping some folks to see what the expected contract for these passes is.
|
e4742bc to
963617f
Compare
This comment has been minimized.
This comment has been minimized.
963617f to
011d6ef
Compare
|
Refactored around this API: impl PassPolicy {
/// Create a [`PassPolicy::Optional`] that is not an optimization,
/// enabled by default under the given condition.
pub(crate) fn optional_non_optimization(enabled_by_default: bool) -> Self;
/// Create a [`PassPolicy::Optional`] optimization enabled at the given MIR optimization level.
pub(crate) fn optimization(ctx: &PassCtx<'_>, min_mir_opt_level: usize) -> Self;
/// Add another condition to an optional pass's default enablement.
pub(crate) fn and_enabled(self, enabled: bool) -> Self;
/// Add a minimum mir-opt-level to an optional pass.
/// Will panic if used on a required pass.
fn with_min_mir_opt_level(self, ctx: &PassCtx<'_>, min_mir_opt_level: usize) -> Self ; |
This comment has been minimized.
This comment has been minimized.
011d6ef to
7911d5f
Compare
This comment has been minimized.
This comment has been minimized.
|
I am not sure that |
7911d5f to
67ab36c
Compare
|
Some changes occurred in coverage instrumentation. cc @Zalathar Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
|
r? @JohnTitor rustbot has assigned @JohnTitor. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
I dropped the |
mir-transform: Treat `optimize(none)` the same as `opt-level=0` try-job: i686-msvc-1
|
💔 Test for a898f90 failed: CI. Failed job:
|
This comment has been minimized.
This comment has been minimized.
|
💔 I suspect this PR failed tests as part of a rollup After fixing the problem, consider running a try job for the failed job before re-approving. Link to failure: #161417 (comment) |
|
This pull request was unapproved. |
|
Odd, shouldn't this leave the existing pass behavior entirely unchanged (unless there's an |
|
Line 6 in 8925ea3 We dropped the -Copt-level checks in inlining; as this test runs at -Copt-level=1, inlining improves reachability checks and eliminates the branch calling d(), making it unused
- Function name: async::j::d
- Raw bytes (19): 0x[01, 01, 00, 03, 01, 40, 05, 00, 11, 01, 00, 14, 00, 15, 01, 00, 16, 00, 17]
+ Function name: async::j::d (unused)
+ Raw bytes (19): 0x[01, 01, 00, 03, 00, 40, 05, 00, 11, 00, 00, 14, 00, 15, 00, 00, 16, 00, 17] |
|
Some changes occurred in coverage tests. cc @Zalathar |
|
Would be good to know if this change (just @bors try jobs=i686-msvc-1 |
Yep, blessing is the correct fix here. (Being known-unused affects some internal details which is why it shows up in the snapshots, but it's not something the test deeply cares about.) |
I thought we droppe dthem in a way that would be equivalent... but I see now, we map So with this PR, non-incremental I guess we could just keep the original logic, just with |
8523cd1 to
b1106cc
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
| /// Prefer [`Self::mir_opt_level`] to [`Session::mir_opt_level`] to account for overrides. | ||
| session: &'sess Session, | ||
| /// The MIR optimization level for this body; may be overridden by `#[optimize]`. | ||
| body_mir_opt_level: usize, |
There was a problem hiding this comment.
Would it make sense to store an OptLevel here instead, so that the inliner can query it?
There was a problem hiding this comment.
That would mean mir_opt_level 0/3/4 wouldn't apply (if manually overridden), since OptLevel translates to only MIR opt-level 1/2
As an aside, I was wondering about introducing an MIR opt-level newtype/enum rather than passing around usize, does that make any sense to do here?
There was a problem hiding this comment.
That would mean mir_opt_level 0/3/4 wouldn't apply (if manually overridden), since OptLevel translates to only MIR opt-level 1/2
Ah, right.
As an aside, I was wondering about introducing an MIR opt-level newtype/enum rather than passing around usize, does that make any sense to do here?
Not in this PR please.
| _ => true, | ||
| }); | ||
| PassPolicy::optimization(enabled_by_default) | ||
| }), |
There was a problem hiding this comment.
With this, we won't do MIR inlining with optimize(speed) if the global opt level is 0 or 1 which seems wrong. The inliner kind of introduces a mir-opt-level 1.5 here, it's the only MIR opt that dintinguishes -Copt-level=1 from -Copt-level=2. It seems like it has done this ever since #91743. @cjgillot @wesleywiser @oli-obk what is the reason this was done and do you have ideas for how it could be handled with the per-function attribute? We use ctx to communicate the intended opt level for the function this pass runs on, but that needs to reflected -Zmir-opt-level so it is expressed as a MIR opt level and therefore can't capture the logic here that depends on both mir-opt-level and -Copt-level. The easiest fix it to stop doing this odd special case but that would mean the MIR inliner would kick in at -Copt-level=1. IMO if we don't want that we shouldn't map -Copt-level=1 and -Copt-level=2 to the same MIR opt level.
76a3d9e to
efdd293
Compare
|
While we figure out the semantics, just going to try a perf run of mapping @bors try @rust-timer queue |
|
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
|
⌛ Trying commit efdd293 with merge 9e33c30… To cancel the try build, run the command Workflow: https://github.com/rust-lang/rust/actions/runs/32484518895 |
mir-transform: Treat `optimize(none)` the same as `opt-level=0`
|
FWIW the inliner distinguishes -Copt-level=1 from 2, not 2 from 3 as your new classification. |
|
IIRC the perf suite only records numbers for -C0 and -C3, so this should be fine for the perf run. Will adjust if we do make this change (but I'm assuming it's large enough to maybe worth doing in another PR) |
|
I would assume if we do this we'd also check all the conditions for MIR opts to get a very good idea of which new opts we are enabling in |
View all comments
cc @RalfJung