diff options
author | SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> | 2021-02-18 05:45:35 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-18 05:45:35 +0300 |
commit | aa138f7cb11502043a12668f48a6bc122be27485 (patch) | |
tree | d9e9b07e85733523bef52eb1ec3c3234fdf46b1e /src/coreclr/jit/fgdiagnostic.cpp | |
parent | 0c5dbbbbdf0d336c7190144981f00ace9a30dc3b (diff) |
Add debug checking of the loop table (#48060)
* Add fgDebugCheckLoopTable()
* Minify some logging
* Add checking of the loop table to some phases
* Ignore removed loops in fgDebugCheckLoopTable
Diffstat (limited to 'src/coreclr/jit/fgdiagnostic.cpp')
-rw-r--r-- | src/coreclr/jit/fgdiagnostic.cpp | 80 |
1 files changed, 66 insertions, 14 deletions
diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 67083e50d6d..07720a8b187 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -1617,13 +1617,8 @@ Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTree** pTree, fgWalkData return WALK_CONTINUE; } -#ifdef DEBUG - if (pComp->verbose) - { - printf("STRESS_64RSLT_MUL before:\n"); - pComp->gtDispTree(tree); - } -#endif // DEBUG + JITDUMP("STRESS_64RSLT_MUL before:\n"); + DISPTREE(tree); // To ensure optNarrowTree() doesn't fold back to the original tree. tree->AsOp()->gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->AsOp()->gtOp1, false, TYP_LONG); @@ -1633,13 +1628,8 @@ Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTree** pTree, fgWalkData tree->gtType = TYP_LONG; *pTree = pComp->gtNewCastNode(TYP_INT, tree, false, TYP_INT); -#ifdef DEBUG - if (pComp->verbose) - { - printf("STRESS_64RSLT_MUL after:\n"); - pComp->gtDispTree(*pTree); - } -#endif // DEBUG + JITDUMP("STRESS_64RSLT_MUL after:\n"); + DISPTREE(*pTree); return WALK_SKIP_SUBTREES; } @@ -3031,5 +3021,67 @@ void Compiler::fgDebugCheckNodesUniqueness() } } +//------------------------------------------------------------------------------ +// fgDebugCheckLoopTable: checks that the loop table is valid. +// - If the method has natural loops, the loop table is not null +// - All basic blocks with loop numbers set have a corresponding loop in the table +// - All basic blocks without a loop number are not in a loop +// - All parents of the loop with the block contain that block +// +void Compiler::fgDebugCheckLoopTable() +{ + if (optLoopCount > 0) + { + assert(optLoopTable != nullptr); + } + + for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext) + { + if (optLoopCount == 0) + { + assert(block->bbNatLoopNum == BasicBlock::NOT_IN_LOOP); + continue; + } + + // Walk the loop table and find the first loop that contains our block. + // It should be the innermost one. + int loopNum = BasicBlock::NOT_IN_LOOP; + for (int i = optLoopCount - 1; i >= 0; i--) + { + // Ignore removed loops + if (optLoopTable[i].lpFlags & LPFLG_REMOVED) + { + continue; + } + // Does this loop contain our block? + if (optLoopTable[i].lpContains(block)) + { + loopNum = i; + break; + } + } + + // If there is at least one loop that contains this block... + if (loopNum != BasicBlock::NOT_IN_LOOP) + { + // ...it must be the one pointed to by bbNatLoopNum. + assert(block->bbNatLoopNum == loopNum); + } + else + { + // Otherwise, this block should not point to a loop. + assert(block->bbNatLoopNum == BasicBlock::NOT_IN_LOOP); + } + + // All loops that contain the innermost loop with this block must also contain this block. + while (loopNum != BasicBlock::NOT_IN_LOOP) + { + assert(optLoopTable[loopNum].lpContains(block)); + + loopNum = optLoopTable[loopNum].lpParent; + } + } +} + /*****************************************************************************/ #endif // DEBUG |