// getBBWeight -- get the normalized weight of this block
unsigned getBBWeight(Compiler* comp);
- // setBBWeight -- if the block weight is not derived from a profile, then set the weight to the input
- // weight, but make sure to not overflow BB_MAX_WEIGHT
+ // hasProfileWeight -- Returns true if this block's weight came from profile data
+ bool hasProfileWeight() const
+ {
+ return ((this->bbFlags & BBF_PROF_WEIGHT) != 0);
+ }
+
+ // setBBWeight -- if the block weight is not derived from a profile,
+ // then set the weight to the input weight, making sure to not overflow BB_MAX_WEIGHT
+ // Note to set the weight from profile data, instead use setBBProfileWeight
void setBBWeight(unsigned weight)
{
- if (!(this->bbFlags & BBF_PROF_WEIGHT))
+ if (!hasProfileWeight())
{
this->bbWeight = min(weight, BB_MAX_WEIGHT);
}
}
+ // setBBProfileWeight -- Set the profile-derived weight for a basic block
+ void setBBProfileWeight(unsigned weight)
+ {
+ this->bbFlags |= BBF_PROF_WEIGHT;
+ // Check if the multiplication by BB_UNITY_WEIGHT will overflow.
+ this->bbWeight = (weight <= BB_MAX_WEIGHT / BB_UNITY_WEIGHT) ? weight * BB_UNITY_WEIGHT : BB_MAX_WEIGHT;
+ }
+
// modifyBBWeight -- same as setBBWeight, but also make sure that if the block is rarely run, it stays that
// way, and if it's not rarely run then its weight never drops below 1.
void modifyBBWeight(unsigned weight)
}
}
- // setBBProfileWeight -- Set the profile-derived weight for a basic block
- void setBBProfileWeight(unsigned weight)
- {
- this->bbFlags |= BBF_PROF_WEIGHT;
- // Check if the multiplication by BB_UNITY_WEIGHT will overflow.
- this->bbWeight = (weight <= BB_MAX_WEIGHT / BB_UNITY_WEIGHT) ? weight * BB_UNITY_WEIGHT : BB_MAX_WEIGHT;
- }
-
// this block will inherit the same weight and relevant bbFlags as bSrc
void inheritWeight(BasicBlock* bSrc)
{
this->bbWeight = bSrc->bbWeight;
- if (bSrc->bbFlags & BBF_PROF_WEIGHT)
+ if (bSrc->hasProfileWeight())
{
this->bbFlags |= BBF_PROF_WEIGHT;
}
if (fgFirstBB != nullptr)
{
// If we have profile data the new block will inherit fgFirstBlock's weight
- if (fgFirstBB->bbFlags & BBF_PROF_WEIGHT)
+ if (fgFirstBB->hasProfileWeight())
{
block->inheritWeight(fgFirstBB);
}
// If all BBJ_RETURN blocks have a valid profiled weights
// then allProfWeight will be true, else it is false
//
- if ((block->bbFlags & BBF_PROF_WEIGHT) == 0)
+ if (!block->hasProfileWeight())
{
allProfWeight = false;
}
// or if both block and bNext have non-zero weights
// then we select the highest weight block.
- if ((block->bbFlags & BBF_PROF_WEIGHT) || (bNext->bbFlags & BBF_PROF_WEIGHT) ||
- (block->bbWeight && bNext->bbWeight))
+ if (block->hasProfileWeight() || bNext->hasProfileWeight() || (block->bbWeight && bNext->bbWeight))
{
// We are keeping block so update its fields
// when bNext has a greater weight
NEW_RARELY_RUN:
/* If the weight of the block was obtained from a profile run,
than it's more accurate than our static analysis */
- if (bPrev->bbFlags & BBF_PROF_WEIGHT)
+ if (bPrev->hasProfileWeight())
{
continue;
}
// if bPrev->bbWeight is not based upon profile data we can adjust
// the weights of bPrev and block
//
- else if (bPrev->isBBCallAlwaysPair() && // we must have a BBJ_CALLFINALLY and BBK_ALWAYS pair
- (bPrev->bbWeight != block->bbWeight) && // the weights are currently different
- ((bPrev->bbFlags & BBF_PROF_WEIGHT) == 0)) // and the BBJ_CALLFINALLY block is not using profiled
- // weights
+ else if (bPrev->isBBCallAlwaysPair() && // we must have a BBJ_CALLFINALLY and BBK_ALWAYS pair
+ (bPrev->bbWeight != block->bbWeight) && // the weights are currently different
+ !bPrev->hasProfileWeight()) // and the BBJ_CALLFINALLY block is not using profiled
+ // weights
{
if (block->isRunRarely())
{
for (bDst = fgFirstBB; bDst != nullptr; bDst = bDst->bbNext)
{
- if (((bDst->bbFlags & BBF_PROF_WEIGHT) == 0) && (bDst->bbPreds != nullptr))
+ if (!bDst->hasProfileWeight() && (bDst->bbPreds != nullptr))
{
BasicBlock* bOnlyNext;
bOnlyNext = nullptr;
}
- if ((bOnlyNext == bDst) && ((bSrc->bbFlags & BBF_PROF_WEIGHT) != 0))
+ if ((bOnlyNext == bDst) && bSrc->hasProfileWeight())
{
// We know the exact weight of bDst
newWeight = bSrc->bbWeight;
// Sum up the weights of all of the return blocks and throw blocks
// This is used when we have a back-edge into block 1
//
- if (((bDst->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((bDst->bbJumpKind == BBJ_RETURN) || (bDst->bbJumpKind == BBJ_THROW)))
+ if (bDst->hasProfileWeight() && ((bDst->bbJumpKind == BBJ_RETURN) || (bDst->bbJumpKind == BBJ_THROW)))
{
returnWeight += bDst->bbWeight;
}
// then we must reset any values that they currently have
//
- if (((bSrc->bbFlags & BBF_PROF_WEIGHT) == 0) || ((bDst->bbFlags & BBF_PROF_WEIGHT) == 0))
+ if (!bSrc->hasProfileWeight() || !bDst->hasProfileWeight())
{
edge->flEdgeWeightMin = BB_ZERO_WEIGHT;
edge->flEdgeWeightMax = BB_MAX_WEIGHT;
// When we optimize a branch to branch we need to update the profile weight
// of bDest by subtracting out the block/edge weight of the path that is being optimized.
//
- if (fgHaveValidEdgeWeights && ((bDest->bbFlags & BBF_PROF_WEIGHT) != 0))
+ if (fgHaveValidEdgeWeights && bDest->hasProfileWeight())
{
flowList* edge1 = fgGetPredForBlock(bDest, block);
noway_assert(edge1 != nullptr);
// When we optimize a branch to branch we need to update the profile weight
// of bDest by subtracting out the block/edge weight of the path that is being optimized.
//
- if (fgIsUsingProfileWeights() && ((bDest->bbFlags & BBF_PROF_WEIGHT) != 0))
+ if (fgIsUsingProfileWeights() && bDest->hasProfileWeight())
{
if (fgHaveValidEdgeWeights)
{
BasicBlock::weight_t profHotWeight = -1;
- if ((bPrev->bbFlags & BBF_PROF_WEIGHT) && (block->bbFlags & BBF_PROF_WEIGHT) &&
- ((bDest == nullptr) || (bDest->bbFlags & BBF_PROF_WEIGHT)))
+ if (bPrev->hasProfileWeight() && block->hasProfileWeight() && ((bDest == nullptr) || bDest->hasProfileWeight()))
{
//
// All blocks have profile information
if (wcscmp(filename, W("profiled")) == 0)
{
- if ((fgFirstBB->bbFlags & BBF_PROF_WEIGHT) != 0)
+ if (fgFirstBB->hasProfileWeight())
{
createDuplicateFgxFiles = true;
goto ONE_FILE_PER_METHOD;
{
fprintf(fgxFile, "\n inHandler=\"%s\"", "true");
}
- if (((fgFirstBB->bbFlags & BBF_PROF_WEIGHT) != 0) && ((block->bbFlags & BBF_COLD) == 0))
+ if ((fgFirstBB->hasProfileWeight()) && ((block->bbFlags & BBF_COLD) == 0))
{
fprintf(fgxFile, "\n hot=\"true\"");
}
if (ibcColWidth > 0)
{
- if (block->bbFlags & BBF_PROF_WEIGHT)
+ if (block->hasProfileWeight())
{
printf("%*u", ibcColWidth, block->bbWeight);
}
int ibcColWidth = 0;
for (block = firstBlock; block != nullptr; block = block->bbNext)
{
- if (block->bbFlags & BBF_PROF_WEIGHT)
+ if (block->hasProfileWeight())
{
int thisIbcWidth = CountDigits(block->bbWeight);
ibcColWidth = max(ibcColWidth, thisIbcWidth);
unsigned weight;
- if ((curBlk->bbFlags & BBF_PROF_WEIGHT) != 0)
+ if (curBlk->hasProfileWeight())
{
// We have real profile weights, so we aren't going to change this blocks weight
weight = curBlk->bbWeight;
// Don't unmark blocks that are set to BB_MAX_WEIGHT
// Don't unmark blocks when we are using profile weights
//
- if (!curBlk->isMaxBBWeight() && ((curBlk->bbFlags & BBF_PROF_WEIGHT) == 0))
+ if (!curBlk->isMaxBBWeight() && !curBlk->hasProfileWeight())
{
if (!fgDominate(curBlk, endBlk))
{
{
// Only rely upon the profile weight when all three of these blocks
// have good profile weights
- if ((block->bbFlags & BBF_PROF_WEIGHT) && (bTest->bbFlags & BBF_PROF_WEIGHT) &&
- (block->bbNext->bbFlags & BBF_PROF_WEIGHT))
+ if (block->hasProfileWeight() && bTest->hasProfileWeight() && block->bbNext->hasProfileWeight())
{
allProfileWeightsAreValid = true;
}
else
{
- bool allValidProfileWeights = ((head->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((head->bbJumpDest->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((head->bbNext->bbFlags & BBF_PROF_WEIGHT) != 0);
+ bool allValidProfileWeights =
+ (head->hasProfileWeight() && head->bbJumpDest->hasProfileWeight() && head->bbNext->hasProfileWeight());
if (allValidProfileWeights)
{