diff options
author | Eugene Rozenfeld <erozen@microsoft.com> | 2018-02-06 11:19:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-06 11:19:32 -0800 |
commit | 72b955cc23125c0bf63e6623ecc8496114ed186c (patch) | |
tree | 4e180eebf5286be013e65062e31b923621e6ed8c /src | |
parent | a3632298282f1c6a85c02b80d921075ee1af0d1e (diff) | |
download | coreclr-72b955cc23125c0bf63e6623ecc8496114ed186c.tar.gz coreclr-72b955cc23125c0bf63e6623ecc8496114ed186c.tar.bz2 coreclr-72b955cc23125c0bf63e6623ecc8496114ed186c.zip |
Don't remove the first non-internal block that has profile weight. (#16227)
When using profile weights, fgComputeEdgeWeights expects the first non-internal block to have profile weight.
Make sure we don't break that invariant when removing an empty block.
This fixes VSO 546031.
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/flowgraph.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index 1b588e6821..45e1ce4b48 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -13936,6 +13936,31 @@ bool Compiler::fgOptimizeEmptyBlock(BasicBlock* block) fgLastBB = bPrev; } + // When using profile weights, fgComputeEdgeWeights expects the first non-internal block to have profile + // weight. + // Make sure we don't break that invariant. + if (fgIsUsingProfileWeights() && block->hasProfileWeight() && (block->bbFlags & BBF_INTERNAL) == 0) + { + BasicBlock* bNext = block->bbNext; + + // Check if the next block can't maintain the invariant. + if ((bNext == nullptr) || ((bNext->bbFlags & BBF_INTERNAL) != 0) || !bNext->hasProfileWeight()) + { + // Check if the current block is the first non-internal block. + BasicBlock* curBB = bPrev; + while ((curBB != nullptr) && (curBB->bbFlags & BBF_INTERNAL) != 0) + { + curBB = curBB->bbPrev; + } + if (curBB == nullptr) + { + // This block is the first non-internal block and it has profile weight. + // Don't delete it. + break; + } + } + } + /* Remove the block */ compCurBB = block; fgRemoveBlock(block, false); |