@@ -1119,10 +1119,11 @@ bool Compiler::optExtractInitTestIncr(
11191119
11201120/* ****************************************************************************
11211121 *
1122- * Record the loop in the loop table.
1122+ * Record the loop in the loop table. Return true if successful, false if
1123+ * out of entries in loop table.
11231124 */
11241125
1125- void Compiler::optRecordLoop (BasicBlock* head,
1126+ bool Compiler::optRecordLoop (BasicBlock* head,
11261127 BasicBlock* first,
11271128 BasicBlock* top,
11281129 BasicBlock* entry,
@@ -1138,7 +1139,7 @@ void Compiler::optRecordLoop(BasicBlock* head,
11381139#if COUNT_LOOPS
11391140 loopOverflowThisMethod = true ;
11401141#endif
1141- return ;
1142+ return false ;
11421143 }
11431144
11441145 // Assumed preconditions on the loop we're adding.
@@ -1318,6 +1319,7 @@ void Compiler::optRecordLoop(BasicBlock* head,
13181319DONE_LOOP:
13191320 DBEXEC (verbose, optPrintLoopRecording (loopInd));
13201321 optLoopCount++;
1322+ return true ;
13211323}
13221324
13231325#ifdef DEBUG
@@ -1725,7 +1727,7 @@ void Compiler::optFindNaturalLoops()
17251727 goto NO_LOOP;
17261728 }
17271729
1728- if (!loopBlocks.isMember (bottom ->bbNum ))
1730+ if (!loopBlocks.isMember (top ->bbNum ))
17291731 {
17301732 // The "back-edge" we identified isn't actually part of the flow cycle containing ENTRY
17311733 goto NO_LOOP;
@@ -1786,12 +1788,12 @@ void Compiler::optFindNaturalLoops()
17861788 // This code is lexically between TOP and BOTTOM, but it does not
17871789 // participate in the flow cycle. Check for a run of consecutive
17881790 // such blocks.
1789- BasicBlock* lastExitBlock = block;
1790- BasicBlock* nextLoopBlock = block->bbNext ;
1791+ BasicBlock* lastNonLoopBlock = block;
1792+ BasicBlock* nextLoopBlock = block->bbNext ;
17911793 while (!loopBlocks.isMember (nextLoopBlock->bbNum ))
17921794 {
1793- lastExitBlock = nextLoopBlock;
1794- nextLoopBlock = nextLoopBlock->bbNext ;
1795+ lastNonLoopBlock = nextLoopBlock;
1796+ nextLoopBlock = nextLoopBlock->bbNext ;
17951797 // This loop must terminate because we know BOTTOM is in loopBlocks.
17961798 }
17971799
@@ -1802,7 +1804,8 @@ void Compiler::optFindNaturalLoops()
18021804 moveAfter = bottom;
18031805 while (moveAfter->bbFallsThrough ())
18041806 {
1805- // Avoid splitting up this fall-through if we can.
1807+ // Avoid splitting up this fall-through if we can; see if we can legally
1808+ // change `moveAfter` to the next block after it.
18061809 BasicBlock* next = moveAfter->bbNext ;
18071810
18081811 if (!BasicBlock::sameEHRegion (moveAfter, next))
@@ -1863,13 +1866,13 @@ void Compiler::optFindNaturalLoops()
18631866 for (flowList* predIter = testBlock->bbPreds ; predIter != nullptr ;
18641867 predIter = predIter->flNext )
18651868 {
1866- BasicBlock* testPred = predIter->flBlock ;
1867- unsigned int predPosNum = positionNum (testPred);
1868- unsigned int blockPosNum = positionNum (block);
1869- unsigned int lastExitPosNum = positionNum (lastExitBlock );
1869+ BasicBlock* testPred = predIter->flBlock ;
1870+ unsigned int predPosNum = positionNum (testPred);
1871+ unsigned int blockPosNum = positionNum (block);
1872+ unsigned int lastNonLoopPosNum = positionNum (lastNonLoopBlock );
18701873
18711874 if (loopBlocks.isMember (predPosNum) ||
1872- ((predPosNum >= blockPosNum) && (predPosNum <= lastExitPosNum )))
1875+ ((predPosNum >= blockPosNum) && (predPosNum <= lastNonLoopPosNum )))
18731876 {
18741877 // This pred is in the loop (or what will be the loop if we determine this
18751878 // run of exit blocks doesn't include a side-entry).
@@ -1900,19 +1903,21 @@ void Compiler::optFindNaturalLoops()
19001903 continue ;
19011904 }
19021905
1903- fgUnlinkRange (block, lastExitBlock);
1904- fgMoveBlocksAfter (block, lastExitBlock, moveAfter);
1905- ehUpdateLastBlocks (moveAfter, lastExitBlock);
1906+ BasicBlock* moveBefore = moveAfter->bbNext ;
1907+
1908+ fgUnlinkRange (block, lastNonLoopBlock);
1909+ fgMoveBlocksAfter (block, lastNonLoopBlock, moveAfter);
1910+ ehUpdateLastBlocks (moveAfter, lastNonLoopBlock);
19061911
1907- // If lastExitBlock fell through to nextLoopBlock, then it also would have been in the loop.
1908- assert (!lastExitBlock ->bbFallsThrough ());
1912+ // If lastNonLoopBlock fell through to nextLoopBlock, then it also would have been in the loop.
1913+ assert (!lastNonLoopBlock ->bbFallsThrough ());
19091914
19101915 if (moveAfter->bbFallsThrough ())
19111916 {
19121917 // We've just inserted blocks between moveAfter and moveBefore which it was supposed
19131918 // to fall through to, so insert a jump to reconnect it to moveBefore.
19141919 assert (moveAfter->bbNum >= bottom->bbNum ); // Blocks we moved out didn't have fallthrough.
1915- fgConnectFallThrough (moveAfter, lastExitBlock-> bbNext );
1920+ fgConnectFallThrough (moveAfter, moveBefore );
19161921 }
19171922
19181923 if (previous->bbFallsThrough ())
@@ -1952,8 +1957,8 @@ void Compiler::optFindNaturalLoops()
19521957 }
19531958 }
19541959
1955- // Update moveAfter for the next insertion
1956- moveAfter = lastExitBlock ;
1960+ // Update moveAfter for the next insertion.
1961+ moveAfter = lastNonLoopBlock ;
19571962
19581963 // Note that we've changed the flow graph, and continue without updating
19591964 // `previous` so that we'll process nextLoopBlock.
@@ -2044,7 +2049,11 @@ void Compiler::optFindNaturalLoops()
20442049 {
20452050 exit = nullptr ;
20462051 }
2047- optRecordLoop (head, first, top, entry, bottom, exit, exitCount);
2052+ if (!optRecordLoop (head, first, top, entry, bottom, exit, exitCount))
2053+ {
2054+ // We can't record any more loops (ran into MAX_LOOP_NUM), so stop looking.
2055+ break ;
2056+ }
20482057
20492058#if COUNT_LOOPS
20502059 if (!hasMethodLoops)
0 commit comments