-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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: Make BasicBlock::bbPrev and bbNext private #93032
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
No asm diffs but some TP diffs (maybe because SetBBPrev() does more than what it replaces?) |
Seems like we should work to avoid too many E.g., instead of
This might be more controversial, but Given the above, should we name Looks like there are a few more places that can use the block iterators instead of manual |
src/coreclr/jit/block.h
Outdated
} | ||
} | ||
|
||
BasicBlock* GetBBNext() const |
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.
While we're renaming things, we could give these more "obvious" names, e. g. GetNextBlock
.
We previously had BasicBlock::setNext() that updated bbNext, and also null-checked the new next block to see if it could update its bbPrev; most of the time, we'd just directly update bbNext, and would sparingly call setNext() if we also intended to update the next block's bbPrev. Would it make sense to not have SetBBNext() do this additional work, and keep setNext() around to do it? I think this would reduce/eliminate the TP diffs, but we'd lose the guarantee that bbNext and bbNext->bbPrev are consistent within SetBBNext().
I'm happy to add helper methods for checking bbNext/bbPrev. This is for readability, since GetBBNext() should be getting inlined, right? |
Would it be preferable to check against fgFirstBB and fgLastBB instead of adding new methods? Ditto checking if block == fgFirstColdBlock instead of a new method (though for checking if a block is the last hot block, I agree we'd need a new method to avoid calling GetBBNext()). |
No, it's probably best to leave it as you have it now.
Yes.
We don't always have a For |
I suspect over time we're going to see more and more cases where BB operations are contextual and need access to the compiler instance. At various times I've wondered if blocks should just point back to some parent object (either the compiler or some sort of "flow graph" object, but that seems wasteful. Given that blocks are all the same size we could perhaps play tricks to factor out common fields, if we say allocated them contiguously. For now, I think providing the context when needed via args is ok. One issue with either a context arg or a parent object is that when we inline we do some funny things as there are two compiler objects around, and so it's possible to consult the wrong one.... |
@BruceForstall @AndyAyersMS PTAL. CI is clean, but small TP diffs. I'm planning on making the jump target members private next; if we can assert the jump kind is valid every time we try to read the jump destination, then maybe we can remove code that sets the jump destination to null when changing the jump kind. This might make up for the TP regression in Release builds. |
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.
This LGTM. Thanks!
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.
Found a few nits that could be updated. Can't say I looked at every case.
@@ -186,6 +186,21 @@ FlowEdge* Compiler::BlockPredsWithEH(BasicBlock* blk) | |||
return res; | |||
} | |||
|
|||
//------------------------------------------------------------------------ | |||
// IsLastHotBlock: see if this is the last block before the cold section |
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.
Should we have a corresponding IsFirstColdBlock(Compiler*)
?
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 can add that in for consistency.
src/coreclr/jit/block.h
Outdated
assert((m_block->IsLast()) || m_block->Next()->PrevIs(m_block)); | ||
assert((m_block->IsFirst()) || m_block->Prev()->NextIs(m_block)); |
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.
With the function, we can remove an unnecessary set of parens
assert((m_block->IsLast()) || m_block->Next()->PrevIs(m_block)); | |
assert((m_block->IsFirst()) || m_block->Prev()->NextIs(m_block)); | |
assert(m_block->IsLast() || m_block->Next()->PrevIs(m_block)); | |
assert(m_block->IsFirst() || m_block->Prev()->NextIs(m_block)); |
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.
Thanks for catching all these nits (sorry, these kinds of PRs seem especially tedious to review).
src/coreclr/jit/codegencommon.cpp
Outdated
@@ -5210,7 +5210,7 @@ void CodeGen::genReserveEpilog(BasicBlock* block) | |||
|
|||
assert(block != nullptr); | |||
const VARSET_TP& gcrefVarsArg(GetEmitter()->emitThisGCrefVars); | |||
bool last = (block->bbNext == nullptr); | |||
bool last = (block->IsLast()); |
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.
bool last = (block->IsLast()); | |
bool last = block->IsLast(); |
or just substitute it in the call below and eliminate the last
var
src/coreclr/jit/codegencommon.cpp
Outdated
@@ -5257,7 +5257,7 @@ void CodeGen::genReserveFuncletEpilog(BasicBlock* block) | |||
|
|||
JITDUMP("Reserving funclet epilog IG for block " FMT_BB "\n", block->bbNum); | |||
|
|||
bool last = (block->bbNext == nullptr); | |||
bool last = (block->IsLast()); |
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.
ditto
src/coreclr/jit/codegenlinear.cpp
Outdated
@@ -547,10 +546,10 @@ void CodeGen::genCodeForBBlist() | |||
|
|||
/* Is this the last block, and are there any open scopes left ? */ | |||
|
|||
bool isLastBlockProcessed = (block->bbNext == nullptr); | |||
bool isLastBlockProcessed = (block->IsLast()); |
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.
bool isLastBlockProcessed = (block->IsLast()); | |
bool isLastBlockProcessed = block->IsLast(); |
src/coreclr/jit/codegenlinear.cpp
Outdated
if (block->isBBCallAlwaysPair()) | ||
{ | ||
isLastBlockProcessed = (block->bbNext->bbNext == nullptr); | ||
isLastBlockProcessed = (block->Next()->IsLast()); |
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.
isLastBlockProcessed = (block->Next()->IsLast()); | |
isLastBlockProcessed = block->Next()->IsLast(); |
src/coreclr/jit/codegenlinear.cpp
Outdated
@@ -615,7 +614,7 @@ void CodeGen::genCodeForBBlist() | |||
// Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically, | |||
// if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions | |||
// generated before the OS epilog starts, such as a GS cookie check. | |||
if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext)) | |||
if ((block->IsLast()) || !BasicBlock::sameEHRegion(block, block->Next())) |
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->IsLast()) || !BasicBlock::sameEHRegion(block, block->Next())) | |
if (block->IsLast() || !BasicBlock::sameEHRegion(block, block->Next())) |
src/coreclr/jit/codegenlinear.cpp
Outdated
@@ -818,7 +817,7 @@ void CodeGen::genCodeForBBlist() | |||
GetEmitter()->emitLoopAlignment(DEBUG_ARG1(block->KindIs(BBJ_ALWAYS))); | |||
} | |||
|
|||
if ((block->bbNext != nullptr) && (block->bbNext->isLoopAlign())) | |||
if (!block->IsLast() && (block->Next()->isLoopAlign())) |
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->IsLast() && (block->Next()->isLoopAlign())) | |
if (!block->IsLast() && block->Next()->isLoopAlign()) |
src/coreclr/jit/compiler.cpp
Outdated
@@ -5291,11 +5291,11 @@ PhaseStatus Compiler::placeLoopAlignInstructions() | |||
} | |||
} | |||
|
|||
if ((block->bbNext != nullptr) && (block->bbNext->isLoopAlign())) | |||
if (!block->IsLast() && (block->Next()->isLoopAlign())) |
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->IsLast() && (block->Next()->isLoopAlign())) | |
if (!block->IsLast() && block->Next()->isLoopAlign()) |
src/coreclr/jit/fgbasic.cpp
Outdated
@@ -5641,24 +5635,20 @@ void Compiler::fgMoveBlocksAfter(BasicBlock* bStart, BasicBlock* bEnd, BasicBloc | |||
{ | |||
printf("Relocated block%s [" FMT_BB ".." FMT_BB "] inserted after " FMT_BB "%s\n", (bStart == bEnd) ? "" : "s", | |||
bStart->bbNum, bEnd->bbNum, insertAfterBlk->bbNum, | |||
(insertAfterBlk->bbNext == nullptr) ? " at the end of method" : ""); | |||
(insertAfterBlk->IsLast()) ? " at the end of method" : ""); |
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.
(insertAfterBlk->IsLast()) ? " at the end of method" : ""); | |
insertAfterBlk->IsLast() ? " at the end of method" : ""); |
@BruceForstall I think I fixed all the style issues introduced (plus a couple extra I found along the way). |
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. Thanks!
Followup to #92908, and next step for #93020. CC @dotnet/jit-contrib.