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

Change and extend the reverse analyser #1531

Merged
merged 9 commits into from
Dec 30, 2024
Merged

Conversation

ltratt
Copy link
Contributor

@ltratt ltratt commented Dec 28, 2024

This PR gradually gets the reverse analyser in better shape, ultimately speeding big_loop up by another 5%. There are really 3 things going on here:

  1. We're only ever propagating register hints, not (the more general) VarLocations (277a52b and c3680da).
  2. Previously we forced the trace header and body to have the same hints, but this misses an opportunity: the header can leave additional things in registers for the body. This requires a number of refactorings, as we now have to run reverse analysis in two phases: once for the header, then we run the code generator, then we reverse analyse the body (8f3aab7 and 4a9454b).
  3. We were generating inappropriate hints for OutputCanBeSameAsInput instructions (6ceac88).

[FWIW, I experimented with a couple of designs for (2), but came to the conclusion that there's not much point in wholesale change here. It might be marginally better to treat header and body as separate Modules which we jmp between (I think that would be closer in spirit to RPython), but we are now fairly well set-up to deal with the two combined. I don't think changing now would gain us much, and it would cause a lot of churn.]

@@ -262,24 +256,36 @@ impl<'a> LSRegAlloc<'a> {
self.stack.size()
}

/// Is the instruction at [iidx] dead?
pub(crate) fn is_inst_dead(&self, iidx: InstIdx) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does "dead" mean "was alive and now is not", or could it also mean "has not been live yet, but will be"?

I think the former, since iirc this replaces something with a name like "is_still_alive_after()"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question. It means "has DCE identified it as equivalent to a tombstone?" "Dead" was my quick attempt to capture that, but I can see that it might not be entirely clear. I'm open to suggestions!

Copy link
Contributor

Choose a reason for hiding this comment

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

Does has_inst_died() capture it perhaps? The past tense is an attempt to anchor the event in time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not exactly time based: it really means "has DCE identified this as dead". That could even happen conceptually during trace creation. So "is" is probably right. I think "died" might be the contentious bit: it could be that we should call is is_inst_tombstone or similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to is_inst_tombstone in the fixup! commits below. [Note: I accidentally pushed another change which I didn't intend, so force pushed that away.]

@ltratt ltratt force-pushed the rev_analyse_change branch from b7c6f9c to f592b47 Compare December 29, 2024 09:16
@vext01
Copy link
Contributor

vext01 commented Dec 29, 2024

please squash.

We will need to propagate spill hints with another mechanism, so
renaming this to be more specific is a start. There is no functional
change with this commit.
This is a stepping stone towards a different representation.
Soon we will want to do something a bit more fiddly than just assigning
to a vector, so duplicating ever more code in many places will become
intolerable.
In an ideal world, we'd probably share `RevAnalyse` amongst the code
generator and register allocator. That isn't quite doable yet.
Other code generators will also need to do the same. However, we do want
to run DCE before showing the user jit-post-opt output, so we still run
DCE in that situation.
This is the precursor to us passing register information to the body
phase: there is no meaningful functional change here.
This allows it to add register hints to the body that reflect the state
of the allocator at the *end* of the header rather than, as before, the
*beginning*. In many cases, these two sets are the same, but this allows
the header to pass additional things in registers to the body.
The challenge here for the reverse analyser is that some instructions --
currently `PtrAdd`s and `Load`s -- can keep a variable alive without
having the register allocator explicitly move it. Fortunately the logic
for this is relatively simple.
@ltratt ltratt force-pushed the rev_analyse_change branch from f592b47 to af3277b Compare December 29, 2024 20:33
@ltratt
Copy link
Contributor Author

ltratt commented Dec 29, 2024

Squashed.

@vext01 vext01 added this pull request to the merge queue Dec 30, 2024
Merged via the queue into ykjit:master with commit a898029 Dec 30, 2024
2 checks passed
@ltratt ltratt deleted the rev_analyse_change branch December 31, 2024 08:46
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.

3 participants