Skip to content

Seed check-cfg target values from static tables instead of all targets [fixed cost; secondary -0.41%, small crates ~-4%]#32

Draft
xmakro wants to merge 1 commit into
perf/base-0703from
perf/checkcfg-static-target-values
Draft

Seed check-cfg target values from static tables instead of all targets [fixed cost; secondary -0.41%, small crates ~-4%]#32
xmakro wants to merge 1 commit into
perf/base-0703from
perf/checkcfg-static-target-values

Conversation

@xmakro

@xmakro xmakro commented Jul 4, 2026

Copy link
Copy Markdown
Owner

fill_well_known collected the well known values of the target_* cfgs by constructing every builtin target spec and reading nine fields back out of each. Building all 329 target specs costs close to two million instructions, paid once per rustc invocation whenever check-cfg is enabled, which cargo does by default. Measured with callgrind on an empty crate this was about 5% of the whole compilation.

The target spec enums already know every value the compiler accepts: the target_spec_enum macro now emits a KNOWN_DESCS table of the canonical variant strings, and target_abi, target_arch, target_endian, target_env, target_os and target_object_format are seeded from those tables. Families and vendors are free form strings, so they get explicit tables next to the target definitions, and a new rustc_target unit test keeps both tables and the pointer width list in sync with the builtin targets. The current session target is still merged in afterwards, so custom JSON targets keep extending the expected sets exactly as before.

The seeded sets are now the values known to the enums rather than the values used by some builtin target. In practice this adds two entries that no builtin target currently uses: spirv to target_arch and vec-default to target_abi. Both are real values accepted in custom target specs, so accepting them in cfg checks is if anything an improvement. The well-known-values ui test is reblessed accordingly.

Local measurement: from scratch ThinLTO stage2 with jemalloc, instructions:u, full rustc-perf suite, both sides built from scratch.

  • 121 cells improved by at least 0.25%, 4 regressed
  • secondary benchmark mean -0.41%; the cost is fixed per invocation so small crates benefit most: helloworld -4.0% check, unify-linearly -3.5%, await-call-tree -3.0%, issue-46449 -3.4%
  • broad -0.5% to -3% band across incr-unchanged cells, where the fixed setup cost is a larger share of the work

tests/ui/check-cfg passes (the well-known-values rebless is the only change), compiler/rustc_target unit tests pass including the new sync test, x check compiler is clean.

fill_well_known collected the well known values of the target_* cfgs by
constructing every builtin target spec and reading nine fields back out
of each. Building all 329 target specs costs close to two million
instructions, paid once per rustc invocation whenever check-cfg is
enabled, which cargo does by default. On small crates this was around
five percent of the entire compilation.

The target spec enums already know every value the compiler accepts:
let the target_spec_enum macro emit a KNOWN_DESCS table of the
canonical variant strings and seed target_abi, target_arch,
target_endian, target_env, target_os and target_object_format from
those. Families and vendors are free form strings, so they get explicit
tables next to the target definitions, and a new rustc_target unit test
keeps both tables and the pointer width list in sync with the builtin
targets. The current session target is still merged in afterwards, so
custom JSON targets keep extending the expected sets exactly as before.

The seeded sets are now the values known to the enums rather than the
values used by some builtin target. In practice this adds two entries
that no builtin target currently uses: spirv to target_arch and
vec-default to target_abi. Both are real values accepted in custom
target specs, so accepting them in cfg checks is if anything an
improvement. The well-known-values ui test is reblessed accordingly.
xmakro pushed a commit that referenced this pull request Jul 23, 2026
The `scoped_two_small_structs` test expects `sub sp, sp, #48` on
aarch64, which assumes the frame pointer (x29) is saved. Custom targets
that don't set `frame-pointer: non-leaf` (e.g., OpenEmbedded/Yocto's
`aarch64-poky-linux-gnu`) omit x29, producing `sub sp, sp, #32` instead.

Add `-Cforce-frame-pointers=yes` to the aarch64 revision so the test
produces consistent codegen regardless of the target's default frame
pointer policy.

Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com>
xmakro pushed a commit that referenced this pull request Jul 23, 2026
…arch64-stack-check, r=mati865

tests/assembly-llvm: pin frame pointer in issue-141649 aarch64 test

The `scoped_two_small_structs` test expects `sub sp, sp, #48` on
aarch64, which assumes the frame pointer (x29) is saved. Custom targets
that don't set `frame-pointer: non-leaf` (e.g., OpenEmbedded/Yocto's
`aarch64-poky-linux-gnu`) omit x29, producing `sub sp, sp, #32` instead.

Add `-Cforce-frame-pointers=yes` to the aarch64 revision so the test
produces consistent codegen regardless of the target's default frame
pointer policy.
@xmakro xmakro changed the title Seed check-cfg target values from static tables instead of all targets Seed check-cfg target values from static tables instead of all targets [fixed cost; secondary -0.41%, small crates ~-4%] Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant