Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better aim spills #1547

Merged
merged 9 commits into from
Jan 16, 2025
Merged

Better aim spills #1547

merged 9 commits into from
Jan 16, 2025

Conversation

ltratt
Copy link
Contributor

@ltratt ltratt commented Jan 15, 2025

This PR gradually nudges spilling to a better place: we avoid spillings unnecessarily (38419d3) and we spill things we don't need on the fast (d879093). Both of these are intended to help with medium to long traces, with the latter potentially significantly reducing pressure on the register allocator. The various other commits are various helpers/cleanups needed to make the main commits possible.

I'd completely forgotten that we use it in our (rather terrible)
heuristic for "what to spill" so introduce the (hopefully temporary)
`used_later_than` function to capture this, at which point the field can
be made private to the reverse analyser.
Previously the reverse analyser only recorded whether an instruction's
output value was used. This commit records which (later!) instructions
use an instruction's output value.

For the time being, we only use this to make a slightly better heuristic
about "what to spill". Previously we used the (fairly terrible) proxy of
"spill the value which lives the longest". Now we use the heuristic
"spill the value which is not used for the longest time". On small
examples, these two often coincide, but on bigger examples they
definitely won't.
When we've run out of registers, we have to chose a register to "spill".
This commit recognises that we often don't have to spill anything,
either because the register contains a constant or because the register
is duplicating an already-spilled value. We thus prefer not to actually
spill (i.e. store!) anything if one of those cases happens, only
spilling if we really have to.
`Param`s are not normal instructions: they're effectively declarations of
the state of the system at the point that a trace is about to start.
Previously we accidentally treated these in two different ways:

  1. In "full, normal" compilation mode, they were implicitly never
     removed because they appeared in `TraceHeaderStart` and
     `TraceBodyStart`.

  2. In tests, they could be removed if they weren't "used".

This commit makes `Param`s never removable by treating them as "internal
instructions", so tests in (2) now observe the same behaviour as (1).
This is one of those little edge cases where having "funny" instructions
causes weirdness. Previously, we said that there was a def/use edge
between a `Param` and `Trace{Header|Body}Start`. That's not really true:
`Trace{Header|Body}Start` are declarations more than uses. By
considering them to be users of `Param`s, we make some other analyses a
bit weirder. This commit thus explicitly teaches `def_use` to ignore
these instructions.
When a trace starts, we typically have lots of `Param`s that appear in
guards and `TraceHeaderEnd`/`TraceBodyEnd` but nowhere else. These
registers then gum up the register allocator, making our spill choices
poor -- even though we don't typically use them much.

There are various ways we might be able to tackle this: this commit does
the simplest thing, which is to spill such registers at the very start
of the trace.
@ptersilie ptersilie added this pull request to the merge queue Jan 15, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 15, 2025
@ltratt
Copy link
Contributor Author

ltratt commented Jan 15, 2025

This is Bounce failing so probably this just needs to be retried (unless we've actually broken Bounce for good in this PR!).

@ptersilie ptersilie added this pull request to the merge queue Jan 15, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 15, 2025
@ptersilie ptersilie added this pull request to the merge queue Jan 16, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 16, 2025
@ltratt
Copy link
Contributor Author

ltratt commented Jan 16, 2025

early_return2.c has failed but (somehow) buildbot has mangled stdout/stderr so I can't see why. The parts of the test that are output all look correct. Did it segfault or similar? Dunno. I have try_repeated this test on b16 and it passed successfully over 100 times so it might be something as simple as PT temporarily bombing out and the test not being marked as rerun-if-. Let's retry and see what happens?

@ptersilie ptersilie added this pull request to the merge queue Jan 16, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 16, 2025
@ptersilie ptersilie added this pull request to the merge queue Jan 16, 2025
Merged via the queue into ykjit:master with commit 762413f Jan 16, 2025
2 checks passed
@ltratt ltratt deleted the better_aim_spills branch January 20, 2025 11:12
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.

2 participants