Skip to content

Add #[optimize(none)] - #128657

Merged
bors merged 3 commits into
rust-lang:masterfrom
clubby789:optimize-none
Jan 25, 2025
Merged

bors merged 3 commits into
rust-lang:masterfrom
clubby789:optimize-none

Conversation

@clubby789

Copy link
Copy Markdown
Contributor

cc #54882

This extends the optimize attribute to add none, which corresponds to the LLVM OptimizeNone attribute.

Not sure if an MCP is required for this, happy to file one if so.

@rustbot

rustbot commented Aug 4, 2024

Copy link
Copy Markdown
Collaborator

r? @fee1-dead

rustbot has assigned @fee1-dead.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 4, 2024
@clubby789

clubby789 commented Aug 4, 2024 •

Copy link
Copy Markdown
Contributor Author

While writing a codegen test, looks like there's some extra work to do -

pub fn none() -> i32 {
    2 + 2
}

emits overflow checks in opt-level=0 but not =1. It looks like with overflow checks disabled this is constant folded to 4, even in opt-level=0

@cjgillot

cjgillot commented Aug 4, 2024

Copy link
Copy Markdown
Contributor

You may need to skip mir opts too.

@clubby789

clubby789 commented Aug 4, 2024 •

Copy link
Copy Markdown
Contributor Author

I've turned off MIR opts in the tests for now, but I think ideally we'd want to skip running them for #[optimize(none)] functions - will look into that
While we could enable overflow checks (to match opt-level=0), I feel like if the main goal of opt-none is to make debugging easier then leaving them off is probably best.

@rust-log-analyzer

This comment has been minimized.

@clubby789

clubby789 commented Aug 4, 2024 •

Copy link
Copy Markdown
Contributor Author

Unhelpfully, LLVM doesn't seem to fully account for optnone: https://godbolt.org/z/8hs17bc44 - the constant is propogated from the inner function despite optnone: https://groups.google.com/g/llvm-dev/c/lqgPRW_akSU

@rustbot

rustbot commented Aug 4, 2024

Copy link
Copy Markdown
Collaborator

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Comment thread compiler/rustc_mir_transform/src/lib.rs Outdated
}

fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if body.optimization_disabled {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is actually correct - some of these should run in debug mode. Not sure how best to decide which passes should be omitted

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed incorrect. There are required passes that must be run on every MIR for soundness IIRC.

@rust-lang/wg-mir-opt: Anyone willing to provide assistance to how to disable MIR optimizations while only keeping the required passes?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe check it against the opt level of the pass. If it runs on opt level 0, then don't disable it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a brief look, there are 3 or 4 passes that need keeping, including marking the mir phase.
The easiest way would be to compute the list of passes based on the opt level, or tweak the pass manager to compare default opt level with this flag.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Comment thread compiler/rustc_attr/src/builtin.rs Outdated
Comment thread compiler/rustc_mir_build/src/build/mod.rs Outdated
Comment thread compiler/rustc_mir_transform/src/lib.rs Outdated
}

fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if body.optimization_disabled {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed incorrect. There are required passes that must be run on every MIR for soundness IIRC.

@rust-lang/wg-mir-opt: Anyone willing to provide assistance to how to disable MIR optimizations while only keeping the required passes?

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 6, 2024
Comment thread compiler/rustc_middle/src/mir/mod.rs Outdated
Comment thread compiler/rustc_mir_transform/src/lib.rs Outdated
}

fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if body.optimization_disabled {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a brief look, there are 3 or 4 passes that need keeping, including marking the mir phase.
The easiest way would be to compute the list of passes based on the opt level, or tweak the pass manager to compare default opt level with this flag.

@clubby789

Copy link
Copy Markdown
Contributor Author

Pushed an approach which adds a min_mir_opt_level to the pass trait, then removes any which are > 1 before running opts - this does seem a bit invasive

@cjgillot

Copy link
Copy Markdown
Contributor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 10, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 10, 2024
Add `#[optimize(none)]`

cc rust-lang#54882

This extends the `optimize` attribute to add `none`, which corresponds to the LLVM `OptimizeNone` attribute.

Not sure if an MCP is required for this, happy to file one if so.
@bors

bors commented Aug 10, 2024

Copy link
Copy Markdown
Collaborator

⌛ Trying commit 4408092 with merge 334c324...

@bors

bors commented Aug 10, 2024

Copy link
Copy Markdown
Collaborator

☀️ Try build successful - checks-actions
Build commit: 334c324 (334c3248c902c016532b42926eaa3defca560875)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (334c324): comparison URL.

Overall result: no relevant changes - no action needed

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results (primary -0.4%, secondary 3.6%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.6% [3.6%, 3.6%] 1
Improvements ✅
(primary)
-0.4% [-0.4%, -0.4%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.4% [-0.4%, -0.4%] 1

Cycles

Results (secondary 2.0%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.0% [2.0%, 2.0%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 762.637s -> 762.18s (-0.06%)
Artifact size: 339.23 MiB -> 339.29 MiB (0.02%)

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jan 25, 2025
@bors
bors merged commit 6365178 into rust-lang:master Jan 25, 2025
@rustbot rustbot added this to the 1.86.0 milestone Jan 25, 2025
@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (6365178): comparison URL.

Overall result: ❌ regressions - no action needed

@rustbot label: -perf-regression

Instruction count

This is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.3% [0.3%, 0.3%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results (primary -2.2%, secondary -5.2%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.2% [-2.2%, -2.2%] 1
Improvements ✅
(secondary)
-5.2% [-5.2%, -5.2%] 1
All ❌✅ (primary) -2.2% [-2.2%, -2.2%] 1

Cycles

Results (primary 1.2%, secondary 1.7%)

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
1.2% [1.0%, 1.4%] 2
Regressions ❌
(secondary)
1.7% [1.7%, 1.7%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.2% [1.0%, 1.4%] 2

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 772.322s -> 771.261s (-0.14%)
Artifact size: 325.82 MiB -> 325.82 MiB (-0.00%)

@scottmcm

scottmcm commented Feb 3, 2025

Copy link
Copy Markdown
Member

It looks like with overflow checks disabled this is constant folded to 4, even in opt-level=0

Based on what I found in #135760 (comment), it looks like the LLVM APIs won't emit add i32 2, 2, and will always just fold that.

So it's expected that even with optimize(none) that the IR won't have that addition.

jhpratt added a commit to jhpratt/rust that referenced this pull request Feb 18, 2026
…ired, r=cjgillot

compiler: Don't mark `SingleUseConsts` MIR pass as "required for soundness"

I don't think this MIR pass is required for soundness. The reasons are:
* Something like it was not enabled by default before PR rust-lang#107404 which was the precursor to `SingleUseConsts` (see rust-lang#125910 for the switch).
* By following the advice from rust-lang#128657 (comment) we can conclude it is not required for soundness since it has only ever run on MIR opt level > 0.
* Its [`MirPass::can_be_overridden()`](https://github.com/rust-lang/rust/blob/0ee7d96253f92b15115c94a530db8b79cb341b15/compiler/rustc_mir_transform/src/pass_manager.rs#L98-L102) is unchanged and thus returns `true`, indicating that it is not a required MIR pass.
* PR CI pass in rust-lang#151426 which stops enabling it by default in non-optimized builds.

As shown in the updated test `tests/mir-opt/optimize_none.rs`, `#[optimize(none)]` functions become even less optimized, as expected and desired.

Unblocks rust-lang#151426.
jhpratt added a commit to jhpratt/rust that referenced this pull request Feb 18, 2026
…ired, r=cjgillot

compiler: Don't mark `SingleUseConsts` MIR pass as "required for soundness"

I don't think this MIR pass is required for soundness. The reasons are:
* Something like it was not enabled by default before PR rust-lang#107404 which was the precursor to `SingleUseConsts` (see rust-lang#125910 for the switch).
* By following the advice from rust-lang#128657 (comment) we can conclude it is not required for soundness since it has only ever run on MIR opt level > 0.
* Its [`MirPass::can_be_overridden()`](https://github.com/rust-lang/rust/blob/0ee7d96253f92b15115c94a530db8b79cb341b15/compiler/rustc_mir_transform/src/pass_manager.rs#L98-L102) is unchanged and thus returns `true`, indicating that it is not a required MIR pass.
* PR CI pass in rust-lang#151426 which stops enabling it by default in non-optimized builds.

As shown in the updated test `tests/mir-opt/optimize_none.rs`, `#[optimize(none)]` functions become even less optimized, as expected and desired.

Unblocks rust-lang#151426.
jhpratt added a commit to jhpratt/rust that referenced this pull request Feb 18, 2026
…ired, r=cjgillot

compiler: Don't mark `SingleUseConsts` MIR pass as "required for soundness"

I don't think this MIR pass is required for soundness. The reasons are:
* Something like it was not enabled by default before PR rust-lang#107404 which was the precursor to `SingleUseConsts` (see rust-lang#125910 for the switch).
* By following the advice from rust-lang#128657 (comment) we can conclude it is not required for soundness since it has only ever run on MIR opt level > 0.
* Its [`MirPass::can_be_overridden()`](https://github.com/rust-lang/rust/blob/0ee7d96253f92b15115c94a530db8b79cb341b15/compiler/rustc_mir_transform/src/pass_manager.rs#L98-L102) is unchanged and thus returns `true`, indicating that it is not a required MIR pass.
* PR CI pass in rust-lang#151426 which stops enabling it by default in non-optimized builds.

As shown in the updated test `tests/mir-opt/optimize_none.rs`, `#[optimize(none)]` functions become even less optimized, as expected and desired.

Unblocks rust-lang#151426.
Zalathar added a commit to Zalathar/rust that referenced this pull request Feb 18, 2026
…ired, r=cjgillot

compiler: Don't mark `SingleUseConsts` MIR pass as "required for soundness"

I don't think this MIR pass is required for soundness. The reasons are:
* Something like it was not enabled by default before PR rust-lang#107404 which was the precursor to `SingleUseConsts` (see rust-lang#125910 for the switch).
* By following the advice from rust-lang#128657 (comment) we can conclude it is not required for soundness since it has only ever run on MIR opt level > 0.
* Its [`MirPass::can_be_overridden()`](https://github.com/rust-lang/rust/blob/0ee7d96253f92b15115c94a530db8b79cb341b15/compiler/rustc_mir_transform/src/pass_manager.rs#L98-L102) is unchanged and thus returns `true`, indicating that it is not a required MIR pass.
* PR CI pass in rust-lang#151426 which stops enabling it by default in non-optimized builds.

As shown in the updated test `tests/mir-opt/optimize_none.rs`, `#[optimize(none)]` functions become even less optimized, as expected and desired.

Unblocks rust-lang#151426.
rust-timer added a commit that referenced this pull request Feb 18, 2026
Rollup merge of #152729 - Enselic:single_use_consts-not-required, r=cjgillot

compiler: Don't mark `SingleUseConsts` MIR pass as "required for soundness"

I don't think this MIR pass is required for soundness. The reasons are:
* Something like it was not enabled by default before PR #107404 which was the precursor to `SingleUseConsts` (see #125910 for the switch).
* By following the advice from #128657 (comment) we can conclude it is not required for soundness since it has only ever run on MIR opt level > 0.
* Its [`MirPass::can_be_overridden()`](https://github.com/rust-lang/rust/blob/0ee7d96253f92b15115c94a530db8b79cb341b15/compiler/rustc_mir_transform/src/pass_manager.rs#L98-L102) is unchanged and thus returns `true`, indicating that it is not a required MIR pass.
* PR CI pass in #151426 which stops enabling it by default in non-optimized builds.

As shown in the updated test `tests/mir-opt/optimize_none.rs`, `#[optimize(none)]` functions become even less optimized, as expected and desired.

Unblocks #151426.
github-actions Bot pushed a commit to rust-lang/miri that referenced this pull request Feb 19, 2026
…jgillot

compiler: Don't mark `SingleUseConsts` MIR pass as "required for soundness"

I don't think this MIR pass is required for soundness. The reasons are:
* Something like it was not enabled by default before PR rust-lang/rust#107404 which was the precursor to `SingleUseConsts` (see rust-lang/rust#125910 for the switch).
* By following the advice from rust-lang/rust#128657 (comment) we can conclude it is not required for soundness since it has only ever run on MIR opt level > 0.
* Its [`MirPass::can_be_overridden()`](https://github.com/rust-lang/rust/blob/0ee7d96253f92b15115c94a530db8b79cb341b15/compiler/rustc_mir_transform/src/pass_manager.rs#L98-L102) is unchanged and thus returns `true`, indicating that it is not a required MIR pass.
* PR CI pass in rust-lang/rust#151426 which stops enabling it by default in non-optimized builds.

As shown in the updated test `tests/mir-opt/optimize_none.rs`, `#[optimize(none)]` functions become even less optimized, as expected and desired.

Unblocks rust-lang/rust#151426.

fn is_required(&self) -> bool {
true
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pass removes UB. Such a pass must NOT be marked as "required" as otherwise Miri will miss UB. See rust-lang/miri#5226.

For every one of the is_required that are made to return true in this PR, how carefully did you check that they can never remove UB?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From reading the new context in the other linked issue, it seems like is_required is not related to the UB issue, is that correct? I think it still makes sense to clean up and clarify this part of the pass manager though

@RalfJung RalfJung Jul 27, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's not related after all.

But it's definitely misnamed: we have passes that are not required (they are even turned off by mir-opt-level=0), but whose is_required returns true.

/// Returns `true` if this pass must be run (i.e. it is required for soundness).
/// For passes which are strictly optimizations, this should return `false`.
/// If this is `false`, `#[optimize(none)]` will disable the pass.
fn is_required(&self) -> bool;

@RalfJung RalfJung Jul 26, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does is_required relate to the already existing can_be_overridden and why are they separate?

How can it make sense to have passes that are "required" but also only enabled for opt-level > 0? Clearly they aren't required if they aren't always enabled.

I'm afraid is_required made our MIR pass manager a lot more messy and it is not documented very well. I'd appreciate some help cleaning that up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can_be_overridden was added after I pushed the is_required approach, which I raised in #128657 (comment). It makes sense to merge them, unless there's a case where -Zmir-enable-passes should be able to disable a pass and #[optimize(none)] shouldn't (or vice versa).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I got the order wrong then, sorry for that.

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 30, 2026
…d, r=RalfJung

refactor(mir-transform): Merge `can_be_overridden`, `is_required` and `is_enabled` into one

rust-lang#128657 and rust-lang#134082 both merged at similar times, and added two similar flags to the `MirPass` trait
- `can_be_overridden`: Controls if `-Zmir-enable-passes` can enable/disable a pass; only set to `false` for `ForceInline`
- `is_required`: Controls if `#[optimize(none)]` should suppress a pass; set to explicitly `true`/`false` across all passes based on which appeared to be unconditionally enabled at the time

<del>
This adds some redundancy, so this PR merges both into `can_be_overridden`:
- removes cases of `is_required(&self) -> bool { true }`
- replaces `is_required(&self) -> bool { false }` with `can_be_overridden(&self) -> bool { true }`

Also, previously, `-Zmir-enable-passes` took precedence, but now `#[optimize(none)]` does, as the latter is more local.
</del>

This merges both functions as well as `is_enabled` into a single `PassPolicy` enum

r? @RalfJung
rust-timer added a commit that referenced this pull request Jul 31, 2026
Rollup merge of #160015 - clubby789:merge-required-suppressed, r=RalfJung

refactor(mir-transform): Merge `can_be_overridden`, `is_required` and `is_enabled` into one

#128657 and #134082 both merged at similar times, and added two similar flags to the `MirPass` trait
- `can_be_overridden`: Controls if `-Zmir-enable-passes` can enable/disable a pass; only set to `false` for `ForceInline`
- `is_required`: Controls if `#[optimize(none)]` should suppress a pass; set to explicitly `true`/`false` across all passes based on which appeared to be unconditionally enabled at the time

<del>
This adds some redundancy, so this PR merges both into `can_be_overridden`:
- removes cases of `is_required(&self) -> bool { true }`
- replaces `is_required(&self) -> bool { false }` with `can_be_overridden(&self) -> bool { true }`

Also, previously, `-Zmir-enable-passes` took precedence, but now `#[optimize(none)]` does, as the latter is more local.
</del>

This merges both functions as well as `is_enabled` into a single `PassPolicy` enum

r? @RalfJung
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 7, 2026
…eywiser

Stabilize `optimize` attribute

This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control of optimization levels.

# Stabilization report

## Summary

Tracking issue: rust-lang#54882
Reference PRs: rust-lang/reference#2278

cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/t-compiler

### What is stabilized

```rust
// Instructs the optimization pipeline to prioritize smaller code size over speed.
#[optimize(size)]
pub fn binary_size_sensitive() {
    // ...
}

// Instructs the optimization pipeline to prioritize execution speed over code size.
#[optimize(speed)]
pub fn performance_critical() {
    // ...
}

// Disables optimizations entirely for this item.
#[optimize(none)]
pub fn debug_only() {
    // ...
}
```

### What isn't stabilized

We might want to allow specifying a per-function optimization level (i.e. `#[optimize(level = 3)]`). To my understanding, backend support for this is not quite there yet (and this - or other - extensions have consequently not been implemented yet).

Applying the attribute on a module level is also not implemented yet.

## Design

### Reference

- Description of the new attribute: rust-lang/reference#2278

### RFC history

- https://rust-lang.github.io/rfcs/2412-optimize-attr.html

### Answers to unresolved question

- Should we also implement optimize(always)? optimize(level=x)?

Not yet.

- Should there be any way to specify what global optimization for speed level is used in conjunction with the optimization for speed option (e.g. -Copt-level=s3 could be equivalent to -Copt-level=3 and #[optimize(size)] on the crate item).

Not yet.

### Post-RFC changes

The `optimize(none)` variant was added. The variants above were discussed here: rust-lang#54882 (comment)

### Key points

- `#[optimize(none)]` implies `#[inline(never)]` to be effective (rust-lang#136329)
- As with all optimization-controlling flags, the effects on speed and binary size can be hard to predict: rust-lang#54882 (comment)
- Applying the attribute to incompatible items emits an error: rust-lang#128458

### Nightly uses

The standard library itself uses this attribute in a few places

## Implementation
### Major part

- Wiring it up to the llvm codegen backend: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/compiler/rustc_codegen_llvm/src/attributes.rs#L416
- Catching usage on incompatible items: rust-lang#128458
- Implementing `optimize(none)`: rust-lang#128657 rust-lang#136358 (includes disabling MIR opts)

### Coverage

- Basic tests: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/ui/attributes/optimize.rs
- Testing the effect on compilation: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/codegen-llvm/optimize-attr-1.rs

### Tool changes
Trivial changes to rust-analyzer to support the new attribute as an inert attribute: rust-lang/rust-analyzer#22511

## Type system, opsem
### Breaks the AM?
As far as the AM is concerned, this attribute doesn't exist.

## Acknowledgments
Most of the work was not done by me, I'm just writing the stabilization report :-)

@nagisa did the initial implementation, @clubby789 implemented optimize(none) and fixed the attribute being allowed in too many places.

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_CONCERN-ISSUE_START -->

> [!NOTE]
> # Concerns (0 active)
>
> - ~~[are-we-happy-wiht-capability-and-scope-of-this-attribute](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
> - ~~[meaning-of-optimize-size](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
> - ~~[explicitly-decide-on-effect-on-nested-functions](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
>
> *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.*

<!-- TRIAGEBOT_CONCERN-ISSUE_END -->
<!-- TRIAGEBOT_END -->
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 7, 2026
…eywiser

Stabilize `optimize` attribute

This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control of optimization levels.

# Stabilization report

## Summary

Tracking issue: rust-lang#54882
Reference PRs: rust-lang/reference#2278

cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/t-compiler

### What is stabilized

```rust
// Instructs the optimization pipeline to prioritize smaller code size over speed.
#[optimize(size)]
pub fn binary_size_sensitive() {
    // ...
}

// Instructs the optimization pipeline to prioritize execution speed over code size.
#[optimize(speed)]
pub fn performance_critical() {
    // ...
}

// Disables optimizations entirely for this item.
#[optimize(none)]
pub fn debug_only() {
    // ...
}
```

### What isn't stabilized

We might want to allow specifying a per-function optimization level (i.e. `#[optimize(level = 3)]`). To my understanding, backend support for this is not quite there yet (and this - or other - extensions have consequently not been implemented yet).

Applying the attribute on a module level is also not implemented yet.

## Design

### Reference

- Description of the new attribute: rust-lang/reference#2278

### RFC history

- https://rust-lang.github.io/rfcs/2412-optimize-attr.html

### Answers to unresolved question

- Should we also implement optimize(always)? optimize(level=x)?

Not yet.

- Should there be any way to specify what global optimization for speed level is used in conjunction with the optimization for speed option (e.g. -Copt-level=s3 could be equivalent to -Copt-level=3 and #[optimize(size)] on the crate item).

Not yet.

### Post-RFC changes

The `optimize(none)` variant was added. The variants above were discussed here: rust-lang#54882 (comment)

### Key points

- `#[optimize(none)]` implies `#[inline(never)]` to be effective (rust-lang#136329)
- As with all optimization-controlling flags, the effects on speed and binary size can be hard to predict: rust-lang#54882 (comment)
- Applying the attribute to incompatible items emits an error: rust-lang#128458

### Nightly uses

The standard library itself uses this attribute in a few places

## Implementation
### Major part

- Wiring it up to the llvm codegen backend: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/compiler/rustc_codegen_llvm/src/attributes.rs#L416
- Catching usage on incompatible items: rust-lang#128458
- Implementing `optimize(none)`: rust-lang#128657 rust-lang#136358 (includes disabling MIR opts)

### Coverage

- Basic tests: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/ui/attributes/optimize.rs
- Testing the effect on compilation: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/codegen-llvm/optimize-attr-1.rs

### Tool changes
Trivial changes to rust-analyzer to support the new attribute as an inert attribute: rust-lang/rust-analyzer#22511

## Type system, opsem
### Breaks the AM?
As far as the AM is concerned, this attribute doesn't exist.

## Acknowledgments
Most of the work was not done by me, I'm just writing the stabilization report :-)

@nagisa did the initial implementation, @clubby789 implemented optimize(none) and fixed the attribute being allowed in too many places.

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_CONCERN-ISSUE_START -->

> [!NOTE]
> # Concerns (0 active)
>
> - ~~[are-we-happy-wiht-capability-and-scope-of-this-attribute](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
> - ~~[meaning-of-optimize-size](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
> - ~~[explicitly-decide-on-effect-on-nested-functions](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
>
> *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.*

<!-- TRIAGEBOT_CONCERN-ISSUE_END -->
<!-- TRIAGEBOT_END -->
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 7, 2026
…eywiser

Stabilize `optimize` attribute

This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control of optimization levels.

# Stabilization report

## Summary

Tracking issue: rust-lang#54882
Reference PRs: rust-lang/reference#2278

cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/t-compiler

### What is stabilized

```rust
// Instructs the optimization pipeline to prioritize smaller code size over speed.
#[optimize(size)]
pub fn binary_size_sensitive() {
    // ...
}

// Instructs the optimization pipeline to prioritize execution speed over code size.
#[optimize(speed)]
pub fn performance_critical() {
    // ...
}

// Disables optimizations entirely for this item.
#[optimize(none)]
pub fn debug_only() {
    // ...
}
```

### What isn't stabilized

We might want to allow specifying a per-function optimization level (i.e. `#[optimize(level = 3)]`). To my understanding, backend support for this is not quite there yet (and this - or other - extensions have consequently not been implemented yet).

Applying the attribute on a module level is also not implemented yet.

## Design

### Reference

- Description of the new attribute: rust-lang/reference#2278

### RFC history

- https://rust-lang.github.io/rfcs/2412-optimize-attr.html

### Answers to unresolved question

- Should we also implement optimize(always)? optimize(level=x)?

Not yet.

- Should there be any way to specify what global optimization for speed level is used in conjunction with the optimization for speed option (e.g. -Copt-level=s3 could be equivalent to -Copt-level=3 and #[optimize(size)] on the crate item).

Not yet.

### Post-RFC changes

The `optimize(none)` variant was added. The variants above were discussed here: rust-lang#54882 (comment)

### Key points

- `#[optimize(none)]` implies `#[inline(never)]` to be effective (rust-lang#136329)
- As with all optimization-controlling flags, the effects on speed and binary size can be hard to predict: rust-lang#54882 (comment)
- Applying the attribute to incompatible items emits an error: rust-lang#128458

### Nightly uses

The standard library itself uses this attribute in a few places

## Implementation
### Major part

- Wiring it up to the llvm codegen backend: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/compiler/rustc_codegen_llvm/src/attributes.rs#L416
- Catching usage on incompatible items: rust-lang#128458
- Implementing `optimize(none)`: rust-lang#128657 rust-lang#136358 (includes disabling MIR opts)

### Coverage

- Basic tests: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/ui/attributes/optimize.rs
- Testing the effect on compilation: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/codegen-llvm/optimize-attr-1.rs

### Tool changes
Trivial changes to rust-analyzer to support the new attribute as an inert attribute: rust-lang/rust-analyzer#22511

## Type system, opsem
### Breaks the AM?
As far as the AM is concerned, this attribute doesn't exist.

## Acknowledgments
Most of the work was not done by me, I'm just writing the stabilization report :-)

@nagisa did the initial implementation, @clubby789 implemented optimize(none) and fixed the attribute being allowed in too many places.

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_CONCERN-ISSUE_START -->

> [!NOTE]
> # Concerns (0 active)
>
> - ~~[are-we-happy-wiht-capability-and-scope-of-this-attribute](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
> - ~~[meaning-of-optimize-size](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
> - ~~[explicitly-decide-on-effect-on-nested-functions](rust-lang#157273 (comment) resolved in [this comment](rust-lang#157273 (comment))
>
> *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.*

<!-- TRIAGEBOT_CONCERN-ISSUE_END -->
<!-- TRIAGEBOT_END -->
rust-bors Bot pushed a commit that referenced this pull request Oct 8, 2026
Rollup merge of #157273 - veluca93:optimize-attribte, r=wesleywiser

Stabilize `optimize` attribute

This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control of optimization levels.

# Stabilization report

## Summary

Tracking issue: #54882
Reference PRs: rust-lang/reference#2278

cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/t-compiler

### What is stabilized

```rust
// Instructs the optimization pipeline to prioritize smaller code size over speed.
#[optimize(size)]
pub fn binary_size_sensitive() {
    // ...
}

// Instructs the optimization pipeline to prioritize execution speed over code size.
#[optimize(speed)]
pub fn performance_critical() {
    // ...
}

// Disables optimizations entirely for this item.
#[optimize(none)]
pub fn debug_only() {
    // ...
}
```

### What isn't stabilized

We might want to allow specifying a per-function optimization level (i.e. `#[optimize(level = 3)]`). To my understanding, backend support for this is not quite there yet (and this - or other - extensions have consequently not been implemented yet).

Applying the attribute on a module level is also not implemented yet.

## Design

### Reference

- Description of the new attribute: rust-lang/reference#2278

### RFC history

- https://rust-lang.github.io/rfcs/2412-optimize-attr.html

### Answers to unresolved question

- Should we also implement optimize(always)? optimize(level=x)?

Not yet.

- Should there be any way to specify what global optimization for speed level is used in conjunction with the optimization for speed option (e.g. -Copt-level=s3 could be equivalent to -Copt-level=3 and #[optimize(size)] on the crate item).

Not yet.

### Post-RFC changes

The `optimize(none)` variant was added. The variants above were discussed here: #54882 (comment)

### Key points

- `#[optimize(none)]` implies `#[inline(never)]` to be effective (#136329)
- As with all optimization-controlling flags, the effects on speed and binary size can be hard to predict: #54882 (comment)
- Applying the attribute to incompatible items emits an error: #128458

### Nightly uses

The standard library itself uses this attribute in a few places

## Implementation
### Major part

- Wiring it up to the llvm codegen backend: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/compiler/rustc_codegen_llvm/src/attributes.rs#L416
- Catching usage on incompatible items: #128458
- Implementing `optimize(none)`: #128657 #136358 (includes disabling MIR opts)

### Coverage

- Basic tests: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/ui/attributes/optimize.rs
- Testing the effect on compilation: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/codegen-llvm/optimize-attr-1.rs

### Tool changes
Trivial changes to rust-analyzer to support the new attribute as an inert attribute: rust-lang/rust-analyzer#22511

## Type system, opsem
### Breaks the AM?
As far as the AM is concerned, this attribute doesn't exist.

## Acknowledgments
Most of the work was not done by me, I'm just writing the stabilization report :-)

@nagisa did the initial implementation, @clubby789 implemented optimize(none) and fixed the attribute being allowed in too many places.

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_CONCERN-ISSUE_START -->

> [!NOTE]
> # Concerns (0 active)
>
> - ~~[are-we-happy-wiht-capability-and-scope-of-this-attribute](#157273 (comment) resolved in [this comment](#157273 (comment))
> - ~~[meaning-of-optimize-size](#157273 (comment) resolved in [this comment](#157273 (comment))
> - ~~[explicitly-decide-on-effect-on-nested-functions](#157273 (comment) resolved in [this comment](#157273 (comment))
>
> *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.*

<!-- TRIAGEBOT_CONCERN-ISSUE_END -->
<!-- TRIAGEBOT_END -->
github-actions Bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Oct 10, 2026
Stabilize `optimize` attribute

This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control of optimization levels.

# Stabilization report

## Summary

Tracking issue: rust-lang/rust#54882
Reference PRs: rust-lang/reference#2278

cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/t-compiler

### What is stabilized

```rust
// Instructs the optimization pipeline to prioritize smaller code size over speed.
#[optimize(size)]
pub fn binary_size_sensitive() {
    // ...
}

// Instructs the optimization pipeline to prioritize execution speed over code size.
#[optimize(speed)]
pub fn performance_critical() {
    // ...
}

// Disables optimizations entirely for this item.
#[optimize(none)]
pub fn debug_only() {
    // ...
}
```

### What isn't stabilized

We might want to allow specifying a per-function optimization level (i.e. `#[optimize(level = 3)]`). To my understanding, backend support for this is not quite there yet (and this - or other - extensions have consequently not been implemented yet).

Applying the attribute on a module level is also not implemented yet.

## Design

### Reference

- Description of the new attribute: rust-lang/reference#2278

### RFC history

- https://rust-lang.github.io/rfcs/2412-optimize-attr.html

### Answers to unresolved question

- Should we also implement optimize(always)? optimize(level=x)?

Not yet.

- Should there be any way to specify what global optimization for speed level is used in conjunction with the optimization for speed option (e.g. -Copt-level=s3 could be equivalent to -Copt-level=3 and #[optimize(size)] on the crate item).

Not yet.

### Post-RFC changes

The `optimize(none)` variant was added. The variants above were discussed here: rust-lang/rust#54882 (comment)

### Key points

- `#[optimize(none)]` implies `#[inline(never)]` to be effective (rust-lang/rust#136329)
- As with all optimization-controlling flags, the effects on speed and binary size can be hard to predict: rust-lang/rust#54882 (comment)
- Applying the attribute to incompatible items emits an error: rust-lang/rust#128458

### Nightly uses

The standard library itself uses this attribute in a few places

## Implementation
### Major part

- Wiring it up to the llvm codegen backend: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/compiler/rustc_codegen_llvm/src/attributes.rs#L416
- Catching usage on incompatible items: rust-lang/rust#128458
- Implementing `optimize(none)`: rust-lang/rust#128657 rust-lang/rust#136358 (includes disabling MIR opts)

### Coverage

- Basic tests: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/ui/attributes/optimize.rs
- Testing the effect on compilation: https://github.com/rust-lang/rust/blob/c0bb140a37c81cf59a0b40c21c9413059644e294/tests/codegen-llvm/optimize-attr-1.rs

### Tool changes
Trivial changes to rust-analyzer to support the new attribute as an inert attribute: rust-lang/rust-analyzer#22511

## Type system, opsem
### Breaks the AM?
As far as the AM is concerned, this attribute doesn't exist.

## Acknowledgments
Most of the work was not done by me, I'm just writing the stabilization report :-)

@nagisa did the initial implementation, @clubby789 implemented optimize(none) and fixed the attribute being allowed in too many places.

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_CONCERN-ISSUE_START -->

> [!NOTE]
> # Concerns (0 active)
>
> - ~~[are-we-happy-wiht-capability-and-scope-of-this-attribute](rust-lang/rust#157273 (comment) resolved in [this comment](rust-lang/rust#157273 (comment))
> - ~~[meaning-of-optimize-size](rust-lang/rust#157273 (comment) resolved in [this comment](rust-lang/rust#157273 (comment))
> - ~~[explicitly-decide-on-effect-on-nested-functions](rust-lang/rust#157273 (comment) resolved in [this comment](rust-lang/rust#157273 (comment))
>
> *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.*

<!-- TRIAGEBOT_CONCERN-ISSUE_END -->
<!-- TRIAGEBOT_END -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.