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: Add explicit successor for BBJ_COND false branch #95773

Merged
merged 34 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7075361
Introduce bbNormalJumpDest
amanasifkhalid Dec 7, 2023
edcd975
Replace Next() with GetNormalJumpDest()
amanasifkhalid Dec 7, 2023
bdc886d
Replace NextIs() with HasNormalJumpTo()
amanasifkhalid Dec 7, 2023
4c71330
Style
amanasifkhalid Dec 7, 2023
bdcf9ea
Update TODO comments
amanasifkhalid Dec 8, 2023
4e94533
Style
amanasifkhalid Dec 8, 2023
3855094
Add comment explaining assert
amanasifkhalid Dec 8, 2023
f630b5d
Rename bbNormalJumpDest to bbFalseTarget
amanasifkhalid Dec 8, 2023
5be6ed2
Rename bbJumpDest to bbTarget
amanasifkhalid Dec 8, 2023
a286d86
Rename SetJumpKindAndTarget variants
amanasifkhalid Dec 8, 2023
9ff966b
Rename bbJumpKind
amanasifkhalid Dec 8, 2023
e632217
Rename bbJumpOffs
amanasifkhalid Dec 8, 2023
dcf7ce9
Rename bbJumpSwt
amanasifkhalid Dec 8, 2023
07ff2dd
Rename bbJumpEhf
amanasifkhalid Dec 8, 2023
e2ab378
Rename HasJumpTo
amanasifkhalid Dec 8, 2023
92139e3
Rename method args, dspJumpKind
amanasifkhalid Dec 8, 2023
6802c17
Introduce getters/setters/checkers for bbTrueTarget
amanasifkhalid Dec 8, 2023
2bddac2
Replace GetTarget with GetTrueTarget for BBJ_COND
amanasifkhalid Dec 8, 2023
32174ab
Replace SetTarget with SetTrueTarget for BBJ_COND
amanasifkhalid Dec 8, 2023
5cbd2c4
Replace TargetIs with TrueTargetIs for BBJ_COND
amanasifkhalid Dec 8, 2023
69cbbc7
Style
amanasifkhalid Dec 8, 2023
a35bd40
Fix comment
amanasifkhalid Dec 8, 2023
f45a824
Fix bbNext/bbTarget access for BBJ_COND in BBSuccList
amanasifkhalid Dec 8, 2023
2e5fc28
Split out SetSwtKindAndTarget and SetEhfKindAndTarget
amanasifkhalid Dec 9, 2023
a8f3ffd
Add SetCondKindAndTarget
amanasifkhalid Dec 9, 2023
b1de3c6
Rename to SetCond
amanasifkhalid Dec 9, 2023
a038073
Rename to SetSwitch
amanasifkhalid Dec 9, 2023
3625c39
Rename to SetEhf
amanasifkhalid Dec 9, 2023
fbd3943
Rename to GetSwitchTarget (for consistency)
amanasifkhalid Dec 9, 2023
ed0b149
Rename GetSwitchTarget > GetSwitchTargets
amanasifkhalid Dec 11, 2023
7f1fbb7
Rename GetEhfTarget > GetEhfTargets
amanasifkhalid Dec 11, 2023
e453580
Rename bbSwtTarget > bbSwtTargets
amanasifkhalid Dec 11, 2023
c78e766
Rename bbEhfTarget/SetEhfTarget
amanasifkhalid Dec 11, 2023
f445e29
Add asserts
amanasifkhalid Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5558,7 +5558,7 @@ class AssertionPropFlowCallback
{
// Scenario where next block and conditional block, both point to the same block.
// In such case, intersect the assertions present on both the out edges of predBlock.
assert(predBlock->NextIs(block));
assert(predBlock->HasNormalJumpTo(block));
BitVecOps::IntersectionD(apTraits, pAssertionOut, predBlock->bbAssertionOut);

if (VerboseDataflow())
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1112,7 +1112,7 @@ bool BasicBlock::bbFallsThrough() const
return false;

case BBJ_COND:
return true;
return NextIs(GetNormalJumpDest());

case BBJ_CALLFINALLY:
return !HasFlag(BBF_RETLESS_CALL);
Expand Down
38 changes: 38 additions & 0 deletions src/coreclr/jit/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ struct BasicBlock : private LIR::Range
BBehfDesc* bbJumpEhf; // BBJ_EHFINALLYRET descriptor
};

// Points to the successor of a BBJ_COND block if bbJumpDest is not taken
BasicBlock* bbNormalJumpDest;

public:
static BasicBlock* New(Compiler* compiler);
static BasicBlock* New(Compiler* compiler, BBjumpKinds jumpKind, BasicBlock* jumpDest = nullptr);
Expand Down Expand Up @@ -573,11 +576,18 @@ struct BasicBlock : private LIR::Range

void SetNext(BasicBlock* next)
{
// TODO: remove
Copy link
Member Author

Choose a reason for hiding this comment

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

I meant to delete this; will get rid of it in the next revision.

bbNext = next;
if (next)
{
next->bbPrev = this;
}

// BBJ_COND convenience: This ensures bbNormalJumpDest is always consistent with bbNext.
// For now, if a BBJ_COND's bbJumpDest is not taken, we expect to fall through,
// so bbNormalJumpDest must be the next block.
// TODO: Remove this once we allow bbNormalJumpDest to diverge from bbNext
bbNormalJumpDest = next;
}

bool IsFirst() const
Expand Down Expand Up @@ -639,11 +649,39 @@ struct BasicBlock : private LIR::Range
assert(!HasJumpDest() || HasInitializedJumpDest());
}

BasicBlock* GetNormalJumpDest() const
{
assert(KindIs(BBJ_COND));
assert((bbNormalJumpDest != nullptr) || IsLast());
return bbNormalJumpDest;
}

void SetNormalJumpDest(BasicBlock* jumpDest)
{
assert(KindIs(BBJ_COND));
assert(jumpDest != nullptr);
bbNormalJumpDest = jumpDest;
}

bool HasNormalJumpTo(BasicBlock* jumpDest) const
{
assert(KindIs(BBJ_COND));
assert(jumpDest != nullptr);
assert(bbNormalJumpDest != nullptr);
return (bbNormalJumpDest == jumpDest);
}

void SetJumpKindAndTarget(BBjumpKinds jumpKind, BasicBlock* jumpDest = nullptr)
{
bbJumpKind = jumpKind;
bbJumpDest = jumpDest;

// BBJ_COND convenience: We might be setting this block's jump kind to BBJ_COND.
// In that case, set bbNormalJumpDest to bbNext to ensure they are consistent after setting the jump kind.
// TODO: Allow bbNormalJumpDest to diverge from bbNext
// assert(!IsLast());
// bbNormalJumpDest = bbNext;

// If bbJumpKind indicates this block has a jump, bbJumpDest cannot be null
assert(!HasJumpDest() || HasInitializedJumpDest());
}
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,9 +628,9 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func)
return BasicBlockVisit::Continue;

case BBJ_COND:
RETURN_ON_ABORT(func(bbNext));
RETURN_ON_ABORT(func(bbNormalJumpDest));

if (bbJumpDest != bbNext)
if (bbJumpDest != bbNormalJumpDest)
{
RETURN_ON_ABORT(func(bbJumpDest));
}
Expand Down Expand Up @@ -694,9 +694,9 @@ BasicBlockVisit BasicBlock::VisitRegularSuccs(Compiler* comp, TFunc func)
return func(bbJumpDest);

case BBJ_COND:
RETURN_ON_ABORT(func(bbNext));
RETURN_ON_ABORT(func(bbNormalJumpDest));

if (bbJumpDest != bbNext)
if (bbJumpDest != bbNormalJumpDest)
{
RETURN_ON_ABORT(func(bbJumpDest));
}
Expand Down
16 changes: 10 additions & 6 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2962,7 +2962,8 @@ void Compiler::fgLinkBasicBlocks()

// The fall-through block is also reachable
assert(curBBdesc->KindIs(BBJ_COND));
fgAddRefPred<initializingPreds>(curBBdesc->Next(), curBBdesc, oldEdge);
curBBdesc->SetNormalJumpDest(curBBdesc->Next());
fgAddRefPred<initializingPreds>(curBBdesc->GetNormalJumpDest(), curBBdesc, oldEdge);
break;
}

Expand Down Expand Up @@ -4242,7 +4243,7 @@ void Compiler::fgCheckBasicBlockControlFlow()

case BBJ_COND: // block conditionally jumps to the target

fgControlFlowPermitted(blk, blk->Next());
fgControlFlowPermitted(blk, blk->GetNormalJumpDest());

fgControlFlowPermitted(blk, blk->GetJumpDest());

Expand Down Expand Up @@ -5030,6 +5031,7 @@ BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
// an immediately following block of a BBJ_SWITCH (which has
// no fall-through path). For this case, simply insert a new
// fall-through block after 'curr'.
// TODO: Once bbNormalJumpDest can diverge from bbNext, this will be unnecessary for BBJ_COND
newBlock = fgNewBBafter(BBJ_ALWAYS, curr, true /* extendRegion */, /* jumpDest */ succ);
newBlock->SetFlags(BBF_NONE_QUIRK);
assert(newBlock->JumpsToNext());
Expand Down Expand Up @@ -5386,8 +5388,8 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
break;
}

/* Check if both side of the BBJ_COND now jump to the same block */
if (predBlock->NextIs(succBlock))
/* Check if both sides of the BBJ_COND now jump to the same block */
if (predBlock->HasNormalJumpTo(succBlock))
{
// Make sure we are replacing "block" with "succBlock" in predBlock->bbJumpDest.
noway_assert(predBlock->HasJumpTo(block));
Expand Down Expand Up @@ -5433,8 +5435,8 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
break;

case BBJ_COND:
/* Check for branch to next block */
if (bPrev->JumpsToNext())
/* Check if both sides of the BBJ_COND now jump to the same block */
if (bPrev->HasJumpTo(bPrev->GetNormalJumpDest()))
{
fgRemoveConditionalJump(bPrev);
}
Expand Down Expand Up @@ -6336,6 +6338,8 @@ bool Compiler::fgIsBetterFallThrough(BasicBlock* bCur, BasicBlock* bAlt)
}

// Currently bNext is the fall through for bCur
// TODO: Allow bbNormalJumpDest to diverge from bbNext for BBJ_COND
assert(!bCur->KindIs(BBJ_COND) || bCur->NextIs(bCur->GetNormalJumpDest()));
BasicBlock* bNext = bCur->Next();
noway_assert(bNext != nullptr);

Expand Down
9 changes: 8 additions & 1 deletion src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2751,7 +2751,7 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block)
switch (blockPred->GetJumpKind())
{
case BBJ_COND:
assert(blockPred->NextIs(block) || blockPred->HasJumpTo(block));
assert(blockPred->HasNormalJumpTo(block) || blockPred->HasJumpTo(block));
return true;

case BBJ_ALWAYS:
Expand Down Expand Up @@ -2957,6 +2957,13 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef

maxBBNum = max(maxBBNum, block->bbNum);

// BBJ_COND's normal (false) jump target is expected to be the next block
// TODO: Allow bbNormalJumpDest to diverge from bbNext
Copy link
Contributor

Choose a reason for hiding this comment

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

A little tip for writing future TODOs: in ongoing work, it is handy to add a unique postfix to a TODO, e. g. TODO-NoFallThrough, s. t. they can be text-searched for easily afterwards.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you for the tip; I realized this might be a better approach about halfway through... I'll update the TODOs I introduced to make them easier to Ctrl+F when I remove them in the next PR.

if (block->KindIs(BBJ_COND))
{
assert(block->NextIs(block->GetNormalJumpDest()));
}

// Check that all the successors have the current traversal stamp. Use the 'Compiler*' version of the
// iterator, but not for BBJ_SWITCH: we don't want to end up calling GetDescriptorForSwitch(), which will
// dynamically create the unique switch list.
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/jit/fgehopt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2058,7 +2058,7 @@ PhaseStatus Compiler::fgTailMergeThrows()
case BBJ_COND:
{
// Flow to non canonical block could be via fall through or jump or both.
if (predBlock->NextIs(nonCanonicalBlock))
if (predBlock->HasNormalJumpTo(nonCanonicalBlock))
{
fgTailMergeThrowsFallThroughHelper(predBlock, nonCanonicalBlock, canonicalBlock, predEdge);
}
Expand Down Expand Up @@ -2134,7 +2134,8 @@ void Compiler::fgTailMergeThrowsFallThroughHelper(BasicBlock* predBlock,
BasicBlock* canonicalBlock,
FlowEdge* predEdge)
{
assert(predBlock->NextIs(nonCanonicalBlock));
assert(predBlock->KindIs(BBJ_COND));
assert(predBlock->HasNormalJumpTo(nonCanonicalBlock));

BasicBlock* const newBlock = fgNewBBafter(BBJ_ALWAYS, predBlock, true, canonicalBlock);

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/fgflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ void Compiler::fgRemoveBlockAsPred(BasicBlock* block)

case BBJ_COND:
fgRemoveRefPred(block->GetJumpDest(), block);
fgRemoveRefPred(block->Next(), block);
fgRemoveRefPred(block->GetNormalJumpDest(), block);
break;

case BBJ_EHFINALLYRET:
Expand Down
Loading
Loading