-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Filter blocks to be used for hiding alignment instruction #62262
Conversation
This reverts commit 1fc26a5.
Tagging subscribers to this area: @JulieLeeMSFT Issue Details
|
|
@dotnet/jit-contrib |
src/coreclr/jit/compiler.cpp
Outdated
bbHavingAlign = block; | ||
JITDUMP(FMT_BB ", bbWeight=" FMT_WT " ends with unconditional 'jmp' \n", block->bbNum, block->bbWeight); | ||
// Only if they are not part of the loop that will be aligned | ||
if ((block->bbNatLoopNum == BasicBlock::NOT_IN_LOOP) || (block->bbNatLoopNum != currentLoopNum)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ((block->bbNatLoopNum == BasicBlock::NOT_IN_LOOP) || (block->bbNatLoopNum != currentLoopNum)) | |
if (currentLoopNum != BasicBlock::NOT_IN_LOOP) |
We only care whether we're in an aligned loop or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming I will keep the reset of currentLoopNum = NOT_IN_LOOP
inside bbJumpDest
check (the way I have currently), this will not work. currentLoopNum
is initialized with NOT_IN_LOOP
and we will never select a block that ends with jmp
until we come across a loop that sets a valid value of currentLoopNum
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, my logic is backwards. It should be:
if (currentLoopNum == BasicBlock::NOT_IN_LOOP)
// ... ok to insert alignment insruction behind JMP
The idea being:
- If
curLoopNum == NOT_IN_LOOP
, then we aren't processing an aligned loop. In this case, we can put an align instruction behind a JMP. - If
curLoopNum != NOT_IN_LOOP
, thenblock
is within a loop that we are aligning. Don't put align after a JMP instruction; wait until we reach the end of the aligned loop (determined by comparingcurLoopNum
againstbbNatLoopNum
)
src/coreclr/jit/compiler.cpp
Outdated
|
||
if ((block->bbJumpDest != nullptr) && (block->bbJumpDest->isLoopAlign())) | ||
{ | ||
// This is the last block of current loop. Reset the latestLoopNum so we can resume | ||
// placing the align behind jmp for subsequent loops. | ||
currentLoopNum = BasicBlock::NOT_IN_LOOP; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest removing this code and adding the following at the top of the loop:
if (currentLoopNum != BasicBlock::NOT_IN_LOOP)
{
// We've been processing blocks within an aligned loop. Are we out of that loop now?
if (currentLoopNum != block->bbNatLoopNum)
{
currentLoopNum = BasicBlock::NOT_IN_LOOP;
}
}
Note that this only works because we only align innermost loops, since the bbNatLoopNum
has the innermost loop number for a block.
Then, if this block is a BBJ_ALWAYS, subsequent code will allow it to be used to add alignment. And, if the next block starts a loop, the code at the end will set up currentLoopNum
for the next iteration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation will make sure we reset the currentLoopNum
for the earliest back-edge we see. With your suggestion, if we have multiple back-edges to the loop, and in between, one of the block ended with jmp
, we won't be able to use that for hiding the alignment because the currentLoopNum
will still match the block->bbNatLoopNum
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's correct, but do you think that's a limitation? After all, if the bbNatLoopNum still matches, it's still part of the same inner loop. Is this concern because the first back-edge is considered the loop end in emitter::getLoopSize()
? I would argue that is incorrect, even if it's not an unreasonable simplification. I don't think this situation arises often anyway, as most loops have a single back edge to the top.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this concern because the first back-edge is considered the loop end in
emitter::getLoopSize()
?
Yes. My thinking behind the existing logic is that if getLoopSize()
only considers the first back-edge, then we should open the opportunity to find jmp
after that point and use them if needed instead of waiting to complete the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would argue, alternatively, that we should think of ways to fix getLoopSize()
to respect the loop package's determination about what constitutes the inner loop.
Note that, even as is, there are a few other concerns: (1) bbJumpDest is part of a union
and not valid for all jump types, (2) you don't check that the branch is to the beginning of the loop we care about; it could be a forward branch so a subsequent loop that is aligned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would argue, alternatively, that we should think of ways to fix getLoopSize() to respect the loop package's determination about what constitutes the inner loop.
I think that needs separate discussion and should be not part of this PR. The initial decision was to just check the earliest back-edge to determine the loop size. If we want something smarter, we can definitely look at the weights of other blocks (the ones that follows after the earlier back-edge) to determine if those blocks are hot enough and do we need to include them as part of our loop size. It might further complicate things and we don't even have data to check if it will give us benefit.
(1) bbJumpDest is part of a union and not valid for all jump types,
That's true. We check that in codegenlinear.cpp
and I should add similar check here as well.
(2) you don't check that the branch is to the beginning of the loop we care about; it could be a forward branch so a subsequent loop that is aligned
To make that work properly, we will need block renumbering, after which I can check it based on bbNum
if it is forward or backward, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, no need to change getLoopSize() here. I'm arguing that this code code be the "correct" general case, and getLoopSize can follow later, if necessary.
To make that work properly, we will need block renumbering, after which I can check it based on bbNum if it is forward or backward, right?
You could save away the block with the ALIGN bit and compare against that when looking for back edges.
However, I think my suggestion is simpler and doesn't require that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
/azp run runtime-coreclr jitstress |
/azp run runtime-coreclr libraries-jitstress |
Azure Pipelines successfully started running 1 pipeline(s). |
1 similar comment
Azure Pipelines successfully started running 1 pipeline(s). |
bbNaturalLoopNum
track which blocks are in a loop and do not use those blocks for hidingalign
instruction.callf/finally
pair for hidingalign
instruction.Fixes: #62238 and #61899