@@ -1442,109 +1442,6 @@ void Compiler::fgUnreachableBlock(BasicBlock* block)
1442
1442
fgRemoveBlockAsPred (block);
1443
1443
}
1444
1444
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
-
1548
1445
// -------------------------------------------------------------
1549
1446
// fgOptimizeBranchToEmptyUnconditional:
1550
1447
// Optimize a jump to an empty block which ends in an unconditional branch.
@@ -2610,27 +2507,25 @@ bool Compiler::fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock*
2610
2507
}
2611
2508
2612
2509
// -------------------------------------------------------------
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
2615
2512
//
2616
2513
// 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
2620
2515
//
2621
- // Returns: true if changes were made
2622
- //
2623
- bool Compiler::fgOptimizeBranchToNext (BasicBlock* block, BasicBlock* bNext, BasicBlock* bPrev)
2516
+ void Compiler::fgRemoveConditionalJump (BasicBlock* block)
2624
2517
{
2625
2518
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 ( );
2629
2522
2630
2523
#ifdef DEBUG
2631
2524
if (verbose)
2632
2525
{
2633
- printf (" \n Removing 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 );
2634
2529
}
2635
2530
#endif // DEBUG
2636
2531
@@ -2729,17 +2624,19 @@ bool Compiler::fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, Basi
2729
2624
}
2730
2625
}
2731
2626
2732
- /* Conditional is gone - always jump to the next block */
2627
+ /* Conditional is gone - always jump to target */
2733
2628
2734
2629
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);
2735
2634
2736
2635
/* Update bbRefs and bbNum - Conditional predecessors to the same
2737
2636
* block are counted twice so we have to remove one of them */
2738
2637
2739
- noway_assert (bNext->countOfInEdges () > 1 );
2740
- fgRemoveRefPred (bNext, block);
2741
-
2742
- return true ;
2638
+ noway_assert (target->countOfInEdges () > 1 );
2639
+ fgRemoveRefPred (target, block);
2743
2640
}
2744
2641
2745
2642
// -------------------------------------------------------------
@@ -4928,12 +4825,15 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication, bool isPhase)
4928
4825
{
4929
4826
// TODO-NoFallThrough: Fix above condition once bbFalseTarget can diverge from bbNext
4930
4827
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 ;
4937
4837
}
4938
4838
}
4939
4839
0 commit comments