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

Commit 00ea5af

Browse files
Apply review feedback
- Rename lastExitBlock -> lastNonLoopBlock - Bail out of loop search when MAX_LOOP_NUM hit - Define `moveBefore` and clarify comments around `moveAfter` and `next` - Check to see if the back-edge is in the loop by testing against top, rather than bottom, since the loop discovery walks to preds.
1 parent 2c598e5 commit 00ea5af

File tree

2 files changed

+33
-24
lines changed

2 files changed

+33
-24
lines changed

src/jit/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5357,7 +5357,7 @@ class Compiler
53575357
GenTreePtr* ppTest,
53585358
GenTreePtr* ppIncr);
53595359

5360-
void optRecordLoop(BasicBlock* head,
5360+
bool optRecordLoop(BasicBlock* head,
53615361
BasicBlock* first,
53625362
BasicBlock* top,
53635363
BasicBlock* entry,

src/jit/optimizer.cpp

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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,
13181319
DONE_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

Comments
 (0)