Skip to content

Commit 6b8d056

Browse files
EgorBoAndyAyersMS
andauthored
JIT: Run optRedundantBranches twice and try to compute more accurate doms (#70907)
Co-authored-by: Andy Ayers <[email protected]>
1 parent 5391db5 commit 6b8d056

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

src/coreclr/jit/compiler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5178,6 +5178,8 @@ class Compiler
51785178

51795179
BasicBlock* fgEndBBAfterMainFunction();
51805180

5181+
BasicBlock* fgGetDomSpeculatively(const BasicBlock* block);
5182+
51815183
void fgUnlinkRange(BasicBlock* bBeg, BasicBlock* bEnd);
51825184

51835185
void fgRemoveBlock(BasicBlock* block, bool unreachable);

src/coreclr/jit/flowgraph.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,6 +3116,45 @@ BasicBlock* Compiler::fgLastBBInMainFunction()
31163116
return fgLastBB;
31173117
}
31183118

3119+
//------------------------------------------------------------------------------
3120+
// fgGetDomSpeculatively: Try determine a more accurate dominator than cached bbIDom
3121+
//
3122+
// Arguments:
3123+
// block - Basic block to get a dominator for
3124+
//
3125+
// Return Value:
3126+
// Basic block that dominates this block
3127+
//
3128+
BasicBlock* Compiler::fgGetDomSpeculatively(const BasicBlock* block)
3129+
{
3130+
assert(fgDomsComputed);
3131+
BasicBlock* lastReachablePred = nullptr;
3132+
3133+
// Check if we have unreachable preds
3134+
for (const flowList* predEdge : block->PredEdges())
3135+
{
3136+
BasicBlock* predBlock = predEdge->getBlock();
3137+
if (predBlock == block)
3138+
{
3139+
continue;
3140+
}
3141+
3142+
// We check pred's count of InEdges - it's quite conservative.
3143+
// We, probably, could use fgReachable(fgFirstBb, pred) here to detect unreachable preds
3144+
if (predBlock->countOfInEdges() > 0)
3145+
{
3146+
if (lastReachablePred != nullptr)
3147+
{
3148+
// More than one of "reachable" preds - return cached result
3149+
return block->bbIDom;
3150+
}
3151+
lastReachablePred = predBlock;
3152+
}
3153+
}
3154+
3155+
return lastReachablePred == nullptr ? block->bbIDom : lastReachablePred;
3156+
}
3157+
31193158
/*****************************************************************************************************
31203159
*
31213160
* Function to return the first basic block after the main part of the function. With funclets, it is

src/coreclr/jit/redundantbranchopts.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,29 @@ PhaseStatus Compiler::optRedundantBranches()
4747
if (block->bbJumpKind == BBJ_COND)
4848
{
4949
madeChanges |= m_compiler->optRedundantRelop(block);
50+
51+
BasicBlock* bbNext = block->bbNext;
52+
BasicBlock* bbJump = block->bbJumpDest;
53+
5054
madeChanges |= m_compiler->optRedundantBranch(block);
55+
56+
// It's possible that either bbNext or bbJump were unlinked and it's proven
57+
// to be profitable to pay special attention to their successors.
58+
if (madeChanges && (bbNext->countOfInEdges() == 0))
59+
{
60+
for (BasicBlock* succ : bbNext->Succs())
61+
{
62+
m_compiler->optRedundantBranch(succ);
63+
}
64+
}
65+
66+
if (madeChanges && (bbJump->countOfInEdges() == 0))
67+
{
68+
for (BasicBlock* succ : bbJump->Succs())
69+
{
70+
m_compiler->optRedundantBranch(succ);
71+
}
72+
}
5173
}
5274
}
5375
};
@@ -293,8 +315,27 @@ bool Compiler::optRedundantBranch(BasicBlock* const block)
293315
relopValue == 0 ? "false" : "true");
294316
}
295317

296-
while ((relopValue == -1) && (domBlock != nullptr))
318+
bool trySpeculativeDom = false;
319+
while ((relopValue == -1) && !trySpeculativeDom)
297320
{
321+
if (domBlock == nullptr)
322+
{
323+
// It's possible that bbIDom is not up to date at this point due to recent BB modifications
324+
// so let's try to quickly calculate new one
325+
domBlock = fgGetDomSpeculatively(block);
326+
if (domBlock == block->bbIDom)
327+
{
328+
// We already checked this one
329+
break;
330+
}
331+
trySpeculativeDom = true;
332+
}
333+
334+
if (domBlock == nullptr)
335+
{
336+
break;
337+
}
338+
298339
// Check the current dominator
299340
//
300341
if (domBlock->bbJumpKind == BBJ_COND)
@@ -351,6 +392,12 @@ bool Compiler::optRedundantBranch(BasicBlock* const block)
351392

352393
if (trueReaches && falseReaches && rii.canInferFromTrue && rii.canInferFromFalse)
353394
{
395+
// JIT-TP: it didn't produce diffs so let's skip it
396+
if (trySpeculativeDom)
397+
{
398+
break;
399+
}
400+
354401
// Both dominating compare outcomes reach the current block so we can't infer the
355402
// value of the relop.
356403
//

0 commit comments

Comments
 (0)