@@ -2674,12 +2674,7 @@ void Compiler::optFindLoops()
26742674{
26752675 m_loops = FlowGraphNaturalLoops::Find (m_dfsTree);
26762676
2677- if (optCompactLoops ())
2678- {
2679- fgInvalidateDfsTree ();
2680- m_dfsTree = fgComputeDfs ();
2681- m_loops = FlowGraphNaturalLoops::Find (m_dfsTree);
2682- }
2677+ optCompactLoops ();
26832678
26842679 if (optCanonicalizeLoops ())
26852680 {
@@ -2730,18 +2725,12 @@ bool Compiler::optCanonicalizeLoops()
27302725// -----------------------------------------------------------------------------
27312726// optCompactLoops: Compact loops to make their loop blocks lexical if possible.
27322727//
2733- // Returns:
2734- // True if the flow graph was changed.
2735- //
2736- bool Compiler::optCompactLoops ()
2728+ void Compiler::optCompactLoops ()
27372729{
2738- bool changed = false ;
27392730 for (FlowGraphNaturalLoop* loop : m_loops->InReversePostOrder ())
27402731 {
2741- changed |= optCompactLoop (loop);
2732+ optCompactLoop (loop);
27422733 }
2743-
2744- return changed;
27452734}
27462735
27472736// -----------------------------------------------------------------------------
@@ -2750,18 +2739,14 @@ bool Compiler::optCompactLoops()
27502739// Parameters:
27512740// loop - The loop
27522741//
2753- // Returns:
2754- // True if the flow graph was changed.
2755- //
2756- bool Compiler::optCompactLoop (FlowGraphNaturalLoop* loop)
2742+ void Compiler::optCompactLoop (FlowGraphNaturalLoop* loop)
27572743{
27582744 BasicBlock* insertionPoint = nullptr ;
27592745
27602746 BasicBlock* top = loop->GetLexicallyTopMostBlock ();
27612747 unsigned numLoopBlocks = loop->NumLoopBlocks ();
27622748
2763- BasicBlock* cur = top;
2764- bool changedFlowGraph = false ;
2749+ BasicBlock* cur = top;
27652750 while (numLoopBlocks > 0 )
27662751 {
27672752 if (loop->ContainsBlock (cur))
@@ -2816,19 +2801,11 @@ bool Compiler::optCompactLoop(FlowGraphNaturalLoop* loop)
28162801 fgMoveBlocksAfter (cur, lastNonLoopBlock, insertionPoint);
28172802 ehUpdateLastBlocks (insertionPoint, lastNonLoopBlock);
28182803
2819- // Apply any adjustments needed for fallthrough at the boundaries of the moved region.
2820- changedFlowGraph |= optLoopCompactionFixupFallThrough (insertionPoint, cur);
2821- changedFlowGraph |= optLoopCompactionFixupFallThrough (lastNonLoopBlock, moveBefore);
2822- // Also apply any adjustments needed where the blocks were snipped out of the loop.
2823- changedFlowGraph |= optLoopCompactionFixupFallThrough (previous, nextLoopBlock);
2824-
28252804 // Update insertionPoint for the next insertion.
28262805 insertionPoint = lastNonLoopBlock;
28272806
28282807 cur = nextLoopBlock;
28292808 }
2830-
2831- return changedFlowGraph;
28322809}
28332810
28342811// -----------------------------------------------------------------------------
@@ -2930,95 +2907,6 @@ BasicBlock* Compiler::optTryAdvanceLoopCompactionInsertionPoint(FlowGraphNatural
29302907 : newInsertionPoint;
29312908}
29322909
2933- // -----------------------------------------------------------------------------
2934- // optLoopCompactionFixupFallThrough: Fix up fallthrough introduced due to
2935- // moving a range of blocks.
2936- //
2937- // Parameters:
2938- // block - Block that may have fallthrough
2939- // newNext - The new block that was the fallthrough block
2940- //
2941- // Returns:
2942- // True if the flow graph was changed by this function.
2943- //
2944- bool Compiler::optLoopCompactionFixupFallThrough (BasicBlock* block, BasicBlock* newNext)
2945- {
2946- assert (block->NextIs (newNext));
2947- bool changed = false ;
2948-
2949- if (block->KindIs (BBJ_COND) && block->TrueTargetIs (newNext))
2950- {
2951- // Reverse the jump condition
2952- GenTree* test = block->lastNode ();
2953- noway_assert (test->OperIsConditionalJump ());
2954-
2955- if (test->OperGet () == GT_JTRUE)
2956- {
2957- GenTree* cond = gtReverseCond (test->AsOp ()->gtOp1 );
2958- assert (cond == test->AsOp ()->gtOp1 ); // Ensure `gtReverseCond` did not create a new node.
2959- test->AsOp ()->gtOp1 = cond;
2960- }
2961- else
2962- {
2963- gtReverseCond (test);
2964- }
2965-
2966- // Redirect the Conditional JUMP to go to `oldNext`
2967- block->SetTrueTarget (block->GetFalseTarget ());
2968- block->SetFalseTarget (newNext);
2969- changed = true ;
2970- }
2971- else if (block->KindIs (BBJ_ALWAYS) && block->TargetIs (newNext))
2972- {
2973- // If block is newNext's only predecessor, move the IR from block to newNext,
2974- // but keep the now-empty block around.
2975- //
2976- // We move the IR because loop recognition has a very limited search capability and
2977- // won't walk from one block's statements to another, even if the blocks form
2978- // a linear chain. So this IR move enhances counted loop recognition.
2979- //
2980- // The logic here is essentially echoing fgCompactBlocks... but we don't call
2981- // that here because we don't want to delete block and do the necessary updates
2982- // to all the other data in flight, and we'd also prefer that newNext be the
2983- // survivor, not block.
2984- //
2985- if ((newNext->bbRefs == 1 ) && fgCanCompactBlocks (block, newNext))
2986- {
2987- JITDUMP (" Moving stmts from " FMT_BB " to " FMT_BB " \n " , block->bbNum , newNext->bbNum );
2988- Statement* stmtList1 = block->firstStmt ();
2989- Statement* stmtList2 = newNext->firstStmt ();
2990-
2991- // Is there anything to move?
2992- //
2993- if (stmtList1 != nullptr )
2994- {
2995- // Append newNext stmts to block's stmts.
2996- //
2997- if (stmtList2 != nullptr )
2998- {
2999- Statement* stmtLast1 = block->lastStmt ();
3000- Statement* stmtLast2 = newNext->lastStmt ();
3001-
3002- stmtLast1->SetNextStmt (stmtList2);
3003- stmtList2->SetPrevStmt (stmtLast1);
3004- stmtList1->SetPrevStmt (stmtLast2);
3005- }
3006-
3007- // Move block's stmts to newNext
3008- //
3009- newNext->bbStmtList = stmtList1;
3010- block->bbStmtList = nullptr ;
3011-
3012- // Update newNext's block flags
3013- //
3014- newNext->CopyFlags (block, BBF_COMPACT_UPD);
3015- }
3016- }
3017- }
3018-
3019- return changed;
3020- }
3021-
30222910// -----------------------------------------------------------------------------
30232911// optCreatePreheader: Create (or find) a preheader for a natural loop.
30242912//
0 commit comments