summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Rozenfeld <erozen@microsoft.com>2018-02-06 11:19:32 -0800
committerGitHub <noreply@github.com>2018-02-06 11:19:32 -0800
commit72b955cc23125c0bf63e6623ecc8496114ed186c (patch)
tree4e180eebf5286be013e65062e31b923621e6ed8c /src
parenta3632298282f1c6a85c02b80d921075ee1af0d1e (diff)
downloadcoreclr-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.cpp25
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);