Skip to content

Commit 4644486

Browse files
JIT: Merge fgRemoveConditionalJump and fgOptimizeBranchToNext (#97456)
1 parent 00cc958 commit 4644486

File tree

2 files changed

+26
-128
lines changed

2 files changed

+26
-128
lines changed

src/coreclr/jit/compiler.h

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

59685968
bool fgOptimizeSwitchBranches(BasicBlock* block);
59695969

5970-
bool fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, BasicBlock* bPrev);
5971-
59725970
bool fgOptimizeSwitchJumps();
59735971
#ifdef DEBUG
59745972
void fgPrintEdgeWeights();

src/coreclr/jit/fgopt.cpp

Lines changed: 26 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,109 +1442,6 @@ void Compiler::fgUnreachableBlock(BasicBlock* block)
14421442
fgRemoveBlockAsPred(block);
14431443
}
14441444

1445-
//-------------------------------------------------------------
1446-
// fgRemoveConditionalJump: Remove or morph a jump when we jump to the same
1447-
// block when both the condition is true or false. Remove the branch condition,
1448-
// but leave any required side effects.
1449-
//
1450-
// Arguments:
1451-
// block - block with conditional branch
1452-
//
1453-
void Compiler::fgRemoveConditionalJump(BasicBlock* block)
1454-
{
1455-
noway_assert(block->KindIs(BBJ_COND) && block->TrueTargetIs(block->GetFalseTarget()));
1456-
assert(compRationalIRForm == block->IsLIR());
1457-
1458-
FlowEdge* flow = fgGetPredForBlock(block->GetFalseTarget(), block);
1459-
noway_assert(flow->getDupCount() == 2);
1460-
1461-
// Change the BBJ_COND to BBJ_ALWAYS, and adjust the refCount and dupCount.
1462-
--block->GetFalseTarget()->bbRefs;
1463-
block->SetKind(BBJ_ALWAYS);
1464-
block->SetFlags(BBF_NONE_QUIRK);
1465-
flow->decrementDupCount();
1466-
1467-
#ifdef DEBUG
1468-
if (verbose)
1469-
{
1470-
printf("Block " FMT_BB " becoming a BBJ_ALWAYS to " FMT_BB " (jump target is the same whether the condition"
1471-
" is true or false)\n",
1472-
block->bbNum, block->GetTarget()->bbNum);
1473-
}
1474-
#endif
1475-
1476-
// Remove the block jump condition
1477-
1478-
if (block->IsLIR())
1479-
{
1480-
LIR::Range& blockRange = LIR::AsRange(block);
1481-
1482-
GenTree* test = blockRange.LastNode();
1483-
assert(test->OperIsConditionalJump());
1484-
1485-
bool isClosed;
1486-
unsigned sideEffects;
1487-
LIR::ReadOnlyRange testRange = blockRange.GetTreeRange(test, &isClosed, &sideEffects);
1488-
1489-
// TODO-LIR: this should really be checking GTF_ALL_EFFECT, but that produces unacceptable
1490-
// diffs compared to the existing backend.
1491-
if (isClosed && ((sideEffects & GTF_SIDE_EFFECT) == 0))
1492-
{
1493-
// If the jump and its operands form a contiguous, side-effect-free range,
1494-
// remove them.
1495-
blockRange.Delete(this, block, std::move(testRange));
1496-
}
1497-
else
1498-
{
1499-
// Otherwise, just remove the jump node itself.
1500-
blockRange.Remove(test, true);
1501-
}
1502-
}
1503-
else
1504-
{
1505-
Statement* test = block->lastStmt();
1506-
GenTree* tree = test->GetRootNode();
1507-
1508-
noway_assert(tree->gtOper == GT_JTRUE);
1509-
1510-
GenTree* sideEffList = nullptr;
1511-
1512-
if (tree->gtFlags & GTF_SIDE_EFFECT)
1513-
{
1514-
gtExtractSideEffList(tree, &sideEffList);
1515-
1516-
if (sideEffList)
1517-
{
1518-
noway_assert(sideEffList->gtFlags & GTF_SIDE_EFFECT);
1519-
#ifdef DEBUG
1520-
if (verbose)
1521-
{
1522-
printf("Extracted side effects list from condition...\n");
1523-
gtDispTree(sideEffList);
1524-
printf("\n");
1525-
}
1526-
#endif
1527-
}
1528-
}
1529-
1530-
// Delete the cond test or replace it with the side effect tree
1531-
if (sideEffList == nullptr)
1532-
{
1533-
fgRemoveStmt(block, test);
1534-
}
1535-
else
1536-
{
1537-
test->SetRootNode(sideEffList);
1538-
1539-
if (fgNodeThreading != NodeThreading::None)
1540-
{
1541-
gtSetStmtInfo(test);
1542-
fgSetStmtSeq(test);
1543-
}
1544-
}
1545-
}
1546-
}
1547-
15481445
//-------------------------------------------------------------
15491446
// fgOptimizeBranchToEmptyUnconditional:
15501447
// Optimize a jump to an empty block which ends in an unconditional branch.
@@ -2610,27 +2507,25 @@ bool Compiler::fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock*
26102507
}
26112508

26122509
//-------------------------------------------------------------
2613-
// fgOptimizeBranchToNext:
2614-
// Optimize a block which has a branch to the following block
2510+
// fgRemoveConditionalJump:
2511+
// Optimize a BBJ_COND block that unconditionally jumps to the same target
26152512
//
26162513
// Arguments:
2617-
// block - block with a BBJ_COND jump kind
2618-
// bNext - target that block jumps to regardless of its condition
2619-
// bPrev - block which is prior to the first block
2514+
// block - BBJ_COND block with identical true/false targets
26202515
//
2621-
// Returns: true if changes were made
2622-
//
2623-
bool Compiler::fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, BasicBlock* bPrev)
2516+
void Compiler::fgRemoveConditionalJump(BasicBlock* block)
26242517
{
26252518
assert(block->KindIs(BBJ_COND));
2626-
assert(block->TrueTargetIs(bNext));
2627-
assert(block->FalseTargetIs(bNext));
2628-
assert(block->PrevIs(bPrev));
2519+
assert(block->TrueTargetIs(block->GetFalseTarget()));
2520+
2521+
BasicBlock* target = block->GetTrueTarget();
26292522

26302523
#ifdef DEBUG
26312524
if (verbose)
26322525
{
2633-
printf("\nRemoving conditional jump to next block (" FMT_BB " -> " FMT_BB ")\n", block->bbNum, bNext->bbNum);
2526+
printf("Block " FMT_BB " becoming a BBJ_ALWAYS to " FMT_BB " (jump target is the same whether the condition"
2527+
" is true or false)\n",
2528+
block->bbNum, target->bbNum);
26342529
}
26352530
#endif // DEBUG
26362531

@@ -2729,17 +2624,19 @@ bool Compiler::fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, Basi
27292624
}
27302625
}
27312626

2732-
/* Conditional is gone - always jump to the next block */
2627+
/* Conditional is gone - always jump to target */
27332628

27342629
block->SetKind(BBJ_ALWAYS);
2630+
assert(block->TargetIs(target));
2631+
2632+
// TODO-NoFallThrough: Set BBF_NONE_QUIRK only when false target is the next block
2633+
block->SetFlags(BBF_NONE_QUIRK);
27352634

27362635
/* Update bbRefs and bbNum - Conditional predecessors to the same
27372636
* block are counted twice so we have to remove one of them */
27382637

2739-
noway_assert(bNext->countOfInEdges() > 1);
2740-
fgRemoveRefPred(bNext, block);
2741-
2742-
return true;
2638+
noway_assert(target->countOfInEdges() > 1);
2639+
fgRemoveRefPred(target, block);
27432640
}
27442641

27452642
//-------------------------------------------------------------
@@ -4928,12 +4825,15 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication, bool isPhase)
49284825
{
49294826
// TODO-NoFallThrough: Fix above condition once bbFalseTarget can diverge from bbNext
49304827
assert(block->FalseTargetIs(bNext));
4931-
if (fgOptimizeBranchToNext(block, bNext, bPrev))
4932-
{
4933-
change = true;
4934-
modified = true;
4935-
bDest = nullptr;
4936-
}
4828+
fgRemoveConditionalJump(block);
4829+
4830+
assert(block->KindIs(BBJ_ALWAYS));
4831+
assert(block->TargetIs(bNext));
4832+
change = true;
4833+
modified = true;
4834+
4835+
// Skip jump optimizations, and try to compact block and bNext later
4836+
bDest = nullptr;
49374837
}
49384838
}
49394839

0 commit comments

Comments
 (0)