Skip to content

Identify trivial consts without building MIR - #165112

Draft
nnethercote wants to merge 3 commits into
rust-lang:mainfrom
nnethercote:identify-trivial-consts
Draft

nnethercote wants to merge 3 commits into
rust-lang:mainfrom
nnethercote:identify-trivial-consts

Conversation

@nnethercote

@nnethercote nnethercote commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

This PR replaces the existing MIR-based trivial_const check with a HIR-based one, to avoid constructing the MIR unnecessarily for trivial consts. (MIR-based passes such as borrow checking, unsafety checking, etc., are skipped for trivial consts.)

Perf results are good: the best case is libc-0.2.172, where we see best-case wins of -6% icounts, -7% cycles and -7% max-rss.

It is rough draft code at the moment. It would need more tests and sanity checking to get it in a mergeable state.

XXX
- I checked HIR vs MIR, very similar, except for very rare cases like `{
  let _: &'a (); 3 }`, a test idiom for mentioning a lifetime inside a
  const argument.
- tests: remove "..which requires building MIR" lines from cycle errors
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 29, 2026
@nnethercote

Copy link
Copy Markdown
Contributor Author

@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 Oct 29, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Oct 29, 2026
Identify trivial consts without building MIR
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-aarch64-gnu-llvm-22-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
failures:

---- [mir-opt] tests/mir-opt/unusual_item_types.rs stdout ----

thread '[mir-opt] tests/mir-opt/unusual_item_types.rs' panicked at src/tools/compiletest/src/runtest/mir_opt.rs:52:21:
Output file `/checkout/obj/build/aarch64-unknown-linux-gnu/test/mir-opt/unusual_item_types/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir` from test does not exist, available files are in `/checkout/obj/build/aarch64-unknown-linux-gnu/test/mir-opt/unusual_item_types`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- [mir-opt] tests/mir-opt/unusual_item_types.rs stdout end ----

failures:
    [mir-opt] tests/mir-opt/unusual_item_types.rs

@rust-bors

rust-bors Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: fc37d66 (fc37d662ac8c0998e574a244a03f0fae1441488f)
Base parent: ce37c4f (ce37c4ff837c5c5dc45cddf9e1e3704e42ca67ea)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (fc37d66): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

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

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.3% [0.0%, 0.5%] 7
Improvements ✅
(primary)
-1.3% [-6.4%, -0.1%] 82
Improvements ✅
(secondary)
-1.6% [-4.5%, -0.1%] 30
All ❌✅ (primary) -1.3% [-6.4%, -0.1%] 82

Max RSS (memory usage)

Results (primary -2.3%, secondary -2.4%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.7% [0.4%, 1.1%] 4
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.7% [-6.9%, -0.6%] 31
Improvements ✅
(secondary)
-2.4% [-4.9%, -0.5%] 5
All ❌✅ (primary) -2.3% [-6.9%, 1.1%] 35

Cycles

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

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.3% [0.6%, 2.5%] 9
Regressions ❌
(secondary)
1.6% [1.6%, 1.6%] 1
Improvements ✅
(primary)
-3.7% [-7.6%, -0.6%] 20
Improvements ✅
(secondary)
-1.6% [-3.2%, -0.4%] 5
All ❌✅ (primary) -2.2% [-7.6%, 2.5%] 29

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 490.291s -> 489.459s (-0.17%)
Artifact size: 406.63 MiB -> 406.82 MiB (0.05%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Oct 29, 2026
@panstromek

Copy link
Copy Markdown
Contributor

I wonder whether this interacts with const generics somehow, because there's #165070, which creates more MIR for type system constants.

@khyperia

Copy link
Copy Markdown
Member

I wonder whether this interacts with const generics somehow, because there's #165070, which creates more MIR for type system constants.

not really! this should all be compatible and nice. to be honest, this new trivial_const is amusingly similar to gca type system direct constants - trivial_const lowers a hir expr to a mir value, const_of_item lowers a hir expr to a ty::Const. It's probably possible to be cute here and merge handling code of something or other here, but, that's not particularly important (and this PR should probably not care about gca at all and just leave it up to const generics folks (me) to deal with any cleanup)

(also, gca type system direct constants probably ought to be considered trivial constants, but, afaik they are not right now, but whatever, doesn't matter, we're a ways away from considering perf with gca. I'll do that at some point!)

@nnethercote

nnethercote commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

I started a Zulip thread to talk about this because it seems like it warrants some wider attention.

jmikedupont2 pushed a commit to meta-introspector/ra-jit that referenced this pull request Nov 5, 2026
A const or static whose body is one scalar literal of a primitive type (or a
negated integer literal of a signed one), with no macro call, no adjustment and
a type check with no error, mismatch or diagnostic, gets its value read off the
literal in hir_ty::consteval::trivial_value: the literal's little-endian bytes at
its type's size, as lowering's lower_literal_to_operand encodes it and the
evaluator's write_allocation truncates it, with no memory map. Every other body
goes to evaluate_by_mir, the previous path, unchanged.

rustc's trivial_const, in the form of rust-lang/rust#165112 (decided before MIR
is built). The test consteval::trivial runs both paths on 21 trivial items and
asserts one interned allocation each, and checks 10 non-trivial bodies (an
operation, a path, a cast, a block, a float negation, type errors) are refused.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. 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.

6 participants