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 |
|
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 comment has been minimized.
This comment has been minimized.
| /// 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.
There was a problem hiding this comment.
Pushed an approach which records the source for the body-opt-level to at least retain the behaviour; this is kind of overkill (we could just have a local_override: bool flag or something on PassCtx), but having this information around might be useful.
There was a problem hiding this comment.
Urgh :/
I'd rather "free up" mir-opt-level 3 so that we can map -Copt-level=1 to a different mir-opt-level. Or decide that the inliner doesn't need to be that special. The -Copt-levels other than 0 and 3 are not widely used anyway I assume...
76a3d9e to
efdd293
Compare
|
While we figure out the semantics, just going to try a perf run of mapping @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
efdd293 to
fcdb1a5
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. |
View all comments
cc @RalfJung