Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Check all preds for each top
Browse files Browse the repository at this point in the history
Since we may treat multiple back-edges to the same successor as nested
loops, we need to continue iterating a `top` block's predecessors even
after finding a back-edge targeting it.
  • Loading branch information
JosephTremoulet committed Aug 17, 2017
1 parent 1091e89 commit a9c20d2
Showing 1 changed file with 44 additions and 59 deletions.
103 changes: 44 additions & 59 deletions src/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1570,43 +1570,6 @@ class LoopSearch
assert(comp->fgBBNumMax <= comp->fgCurBBEpochSize);
}

//------------------------------------------------------------------------
// findLoop: Search for a loop with the given HEAD block.
//
// Arguments:
// head - Block to be the HEAD of any loop identified
//
// Return Value:
// true - Found a valid loop.
// false - Did not find a valid loop.
//
// Notes:
// May modify flow graph go make loop compact before returning.
// Will set instance fields to track loop's extent and exits.
//
bool findLoop(BasicBlock* head)
{
BasicBlock* top = head->bbNext;

// Blocks that are rarely run have a zero bbWeight and should
// never be optimized here

if (top->bbWeight == BB_ZERO_WEIGHT)
{
return false;
}

for (flowList* pred = top->bbPreds; pred; pred = pred->flNext)
{
if (findLoop(head, top, pred->flBlock))
{
return true;
}
}

return false;
}

//------------------------------------------------------------------------
// recordLoop: Notify the Compiler that a loop has been found.
//
Expand All @@ -1633,7 +1596,6 @@ class LoopSearch
return false;
}

private:
//------------------------------------------------------------------------
// findLoop: Search for a loop with the given HEAD block and back-edge.
//
Expand Down Expand Up @@ -1778,6 +1740,7 @@ class LoopSearch
return true;
}

private:
//------------------------------------------------------------------------
// findEntry: See if given HEAD flows to valid ENTRY between given TOP and BOTTOM
//
Expand Down Expand Up @@ -2420,37 +2383,59 @@ void Compiler::optFindNaturalLoops()

for (BasicBlock* head = fgFirstBB; head->bbNext; head = head->bbNext)
{
if (search.findLoop(head))
BasicBlock* top = head->bbNext;

// Blocks that are rarely run have a zero bbWeight and should
// never be optimized here

if (top->bbWeight == BB_ZERO_WEIGHT)
{
// Found a loop; record it and see if we've hit the limit.
bool recordedLoop = search.recordLoop();
continue;
}

(recordedLoop); // avoid unusued variable warnings in COUNT_LOOPS and !DEBUG
for (flowList* pred = top->bbPreds; pred; pred = pred->flNext)
{
if (search.findLoop(head, top, pred->flBlock))
{
// Found a loop; record it and see if we've hit the limit.
bool recordedLoop = search.recordLoop();

(recordedLoop); // avoid unusued variable warnings in COUNT_LOOPS and !DEBUG

#if COUNT_LOOPS
if (!hasMethodLoops)
{
/* mark the method as containing natural loops */
totalLoopMethods++;
hasMethodLoops = true;
}
if (!hasMethodLoops)
{
/* mark the method as containing natural loops */
totalLoopMethods++;
hasMethodLoops = true;
}

/* increment total number of loops found */
totalLoopCount++;
loopsThisMethod++;
/* increment total number of loops found */
totalLoopCount++;
loopsThisMethod++;

/* keep track of the number of exits */
loopExitCountTable.record(static_cast<unsigned>(exitCount));
/* keep track of the number of exits */
loopExitCountTable.record(static_cast<unsigned>(exitCount));
#else // COUNT_LOOPS
assert(recordedLoop);
if (optLoopCount == MAX_LOOP_NUM)
{
// We won't be able to record any more loops, so stop looking.
break;
}
assert(recordedLoop);
if (optLoopCount == MAX_LOOP_NUM)
{
// We won't be able to record any more loops, so stop looking.
goto NO_MORE_LOOPS;
}
#endif // COUNT_LOOPS

// Continue searching preds of `top` to see if any other are
// back-edges (this can happen for nested loops). The iteration
// is safe because the compaction we do only modifies predecessor
// lists of blocks that gain or lose fall-through from their
// `bbPrev`, but since the motion is from within the loop to below
// it, we know we're not altering the relationship between `top`
// and its `bbPrev`.
}
}
}
NO_MORE_LOOPS:

#if COUNT_LOOPS
loopCountTable.record(loopsThisMethod);
Expand Down

0 comments on commit a9c20d2

Please sign in to comment.