Repository navigation
Identify trivial consts without building MIR - #165112
nnethercote wants to merge 3 commits into
Conversation
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
|
@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.
Identify trivial consts without building MIR
|
The job Click to see the possible cause of the failure (guessed by this bot) |
This comment has been minimized.
This comment has been minimized.
|
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 @bors rollup=never rustc-perf Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
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.
CyclesResults (primary -2.2%, secondary -1.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 490.291s -> 489.459s (-0.17%) |
|
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!) |
|
I started a Zulip thread to talk about this because it seems like it warrants some wider attention. |
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 PR replaces the existing MIR-based
trivial_constcheck 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.