Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4295,7 +4295,7 @@ void Compiler::fgDebugCheckSsa()
}
};

// Visit the blocks that SSA intially renamed
// Visit the blocks that SSA initially renamed
//
SsaCheckVisitor scv(this);
SsaCheckDomTreeVisitor visitor(this, scv);
Expand Down Expand Up @@ -4659,6 +4659,32 @@ void Compiler::fgDebugCheckLoopTable()
loop.VERIFY_lpIterTree();
loop.VERIFY_lpTestTree();
}

// If we have dominators, we check more things:
// 1. The pre-header dominates the entry (if pre-headers are required).
// 2. The entry dominates the exit.
// 3. The IDom tree from the exit reaches the entry.
if (fgDomsComputed)
{
if (optLoopsRequirePreHeaders)
{
assert(fgDominate(loop.lpHead, loop.lpEntry));
}

if (loop.lpExitCnt == 1)
{
assert(loop.lpExit != nullptr);
assert(fgDominate(loop.lpEntry, loop.lpExit));

BasicBlock* cur = loop.lpExit;
while ((cur != nullptr) && (cur != loop.lpEntry))
{
assert(fgDominate(cur, loop.lpExit));
cur = cur->bbIDom;
}
assert(cur == loop.lpEntry); // We must be able to reach the entry from the exit via the IDom tree.
}
}
}

// Check basic blocks for loop annotations.
Expand Down
33 changes: 19 additions & 14 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2088,7 +2088,7 @@ class LoopSearch
continue;
}

// This blocks is lexically between TOP and BOTTOM, but it does not
// This block is lexically between TOP and BOTTOM, but it does not
// participate in the flow cycle. Check for a run of consecutive
// such blocks.
//
Expand Down Expand Up @@ -2502,6 +2502,21 @@ class LoopSearch
if (!loopBlocks.IsMember(exitPoint->bbNum))
{
// Exit from a block other than BOTTOM
CLANG_FORMAT_COMMENT_ANCHOR;

#if !defined(FEATURE_EH_FUNCLETS)
// On non-funclet platforms (x86), the catch exit is a BBJ_ALWAYS, but we don't want that to
// be considered a loop exit block, as catch handlers don't have predecessor lists and don't
// show up as might be expected in the dominator tree.
if (block->bbJumpKind == BBJ_ALWAYS)
{
if (!BasicBlock::sameHndRegion(block, exitPoint))
{
break;
}
}
#endif // !defined(FEATURE_EH_FUNCLETS)

lastExit = block;
exitCount++;
}
Expand Down Expand Up @@ -6986,7 +7001,6 @@ bool Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt)
// convenient). But note that it is arbitrary because there is not guaranteed execution order amongst
// the child loops.

int childLoopPreHeaders = 0;
for (BasicBlock::loopNumber childLoop = pLoopDsc->lpChild; //
childLoop != BasicBlock::NOT_IN_LOOP; //
childLoop = optLoopTable[childLoop].lpSibling)
Expand Down Expand Up @@ -7016,7 +7030,6 @@ bool Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt)
}
JITDUMP(" -- " FMT_BB " (child loop pre-header)\n", childPreHead->bbNum);
defExec.Push(childPreHead);
++childLoopPreHeaders;
}

if (pLoopDsc->lpExitCnt == 1)
Expand All @@ -7029,22 +7042,14 @@ bool Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt)
// Push dominators, until we reach "entry" or exit the loop.

BasicBlock* cur = pLoopDsc->lpExit;
while (cur != nullptr && pLoopDsc->lpContains(cur) && cur != pLoopDsc->lpEntry)
while ((cur != nullptr) && (cur != pLoopDsc->lpEntry))
{
JITDUMP(" -- " FMT_BB " (dominate exit block)\n", cur->bbNum);
assert(pLoopDsc->lpContains(cur));
defExec.Push(cur);
cur = cur->bbIDom;
}

// If we didn't reach the entry block, give up and *just* push the entry block (and the pre-headers).
if (cur != pLoopDsc->lpEntry)
{
JITDUMP(" -- odd, we didn't reach entry from exit via dominators. Only considering hoisting in entry "
"block " FMT_BB "\n",
pLoopDsc->lpEntry->bbNum);
defExec.Pop(defExec.Height() - childLoopPreHeaders);
assert(defExec.Height() == childLoopPreHeaders);
}
noway_assert(cur == pLoopDsc->lpEntry);
}
else // More than one exit
{
Expand Down