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

JIT: Have physical promotion insert read backs before possible implicit control flow #86706

Merged
merged 3 commits into from
May 26, 2023

Conversation

jakobbotsch
Copy link
Member

Physical promotion relies on being able to read back any promoted field that is fresher in its struct local before control flows to any successor block. This was failing to take implicit control flow into account.

Fix #86498

Physical promotion relies on being able to read back any promoted field
that is fresher in its struct local before control flows to any
successor block. This was failing to take implicit control flow into
account.

Fix dotnet#86498
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 24, 2023
@ghost ghost assigned jakobbotsch May 24, 2023
@jakobbotsch jakobbotsch changed the title JIT: Insert read backs before possible implicit control flow JIT: Have physical promotion insert read backs before possible implicit control flow May 24, 2023
@ghost
Copy link

ghost commented May 24, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Physical promotion relies on being able to read back any promoted field that is fresher in its struct local before control flows to any successor block. This was failing to take implicit control flow into account.

Fix #86498

Author: jakobbotsch
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @AndyAyersMS

Small diffs. With physical promotion, without old promotion.

@@ -1449,11 +1583,11 @@ void ReplaceVisitor::WriteBackBefore(GenTree** use, unsigned lcl, unsigned offs,
// offs - The starting offset of the range in the struct local that needs to be read back from.
// size - The size of the range
//
void ReplaceVisitor::MarkForReadBack(unsigned lcl, unsigned offs, unsigned size)
bool ReplaceVisitor::MarkForReadBack(unsigned lcl, unsigned offs, unsigned size)
Copy link
Member

Choose a reason for hiding this comment

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

Document the return value?

Copy link
Member Author

Choose a reason for hiding this comment

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

In my next change I remove this return value in favor of moving the logging into this function, so will address this with that PR.

assert(!rep.NeedsReadBack || !rep.NeedsWriteBack);
if (rep.NeedsReadBack)
{
if (m_liveness->IsReplacementLiveOut(m_currentBlock, agg->LclNum, (unsigned)i))
Copy link
Member

Choose a reason for hiding this comment

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

I suppose this is where you get into the resolution strategies... if the field is partially dead (only live in some successors) you might be tempted to defer the read back until the start of the live successors (if join free, or if all other preds of those successors will do read backs too).

We might be able to get at some of this already via tail merging.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I think there's a few opportunities like that around. I liked your idea of focusing on a linear trace when making these decisions.

Compiler::fgWalkResult ReplaceVisitor::PostOrderVisit(GenTree** use, GenTree* user)
{
GenTree* tree = *use;

use = InsertMidTreeReadBacksIfNecessary(use);
Copy link
Member

Choose a reason for hiding this comment

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

Add a header comment for PostOrderVisit.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will add it as part of my follow-up.

@jakobbotsch jakobbotsch merged commit 0ad8b50 into dotnet:main May 26, 2023
@jakobbotsch jakobbotsch deleted the fix-86498 branch May 26, 2023 19:15
jakobbotsch added a commit to jakobbotsch/runtime that referenced this pull request Jun 6, 2023
…tion

Handle readbacks for parameters/OSR-locals like any other readback is
handled. Previously they were handled by creating the scratch BB and
then inserting IR after the main replacement had already been done; now,
we instead create the scratch BB eagerly and mark these as requiring a
read back at the beginning of the scratch BB, and leave normal
replacement logic up to handle it.

The main benefit is that this unification makes it easier to ensure that
future smarter handling of readbacks/writebacks (e.g. "resolution")
automatically kicks in for the common case of parameters.

Introduce another invariant, which is that we only ever mark a field as
requiring readback if it is live. Previously we would always mark them
as requiring read backs, but would then check liveness before inserting
the actual IR to do the read back. But we don't always have the liveness
information at the point where we insert IR for readbacks after dotnet#86706.

Also expand some debug logging, and address some feedback from dotnet#86706.
jakobbotsch added a commit that referenced this pull request Jun 17, 2023
…tion (#87165)

Handle readbacks for parameters/OSR-locals like any other readback is
handled. Previously they were handled by creating the scratch BB and
then inserting IR after the main replacement had already been done; now,
we instead create the scratch BB eagerly and mark these as requiring a
read back at the beginning of the scratch BB, and leave normal
replacement logic up to handle it.

The main benefit is that this unification makes it easier to ensure that
future smarter handling of readbacks/writebacks (e.g. "resolution")
automatically kicks in for the common case of parameters.

Introduce another invariant, which is that we only ever mark a field as
requiring readback if it is live. Previously we would always mark them
as requiring read backs, but would then check liveness before inserting
the actual IR to do the read back. But we don't always have the liveness
information at the point where we insert IR for readbacks after #86706.

Also expand some debug logging, and address some feedback from #86706.
@ghost ghost locked as resolved and limited conversation to collaborators Jun 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JIT: Physical promotion readback mechanism does not take implicit control flow into account
2 participants