未验证 提交 2e930e5a 编写于 作者: B Bruce Forstall 提交者: GitHub

Clean up some flow graph functions (#51645)

Convert a lot of function header comments to the current standard.
Write more documentation for many functions.
Remove a couple unused functions.
上级 89709410
......@@ -4700,7 +4700,9 @@ public:
void fgInsertBBafter(BasicBlock* insertAfterBlk, BasicBlock* newBlk);
void fgUnlinkBlock(BasicBlock* block);
#ifdef FEATURE_JIT_METHOD_PERF
unsigned fgMeasureIR();
#endif // FEATURE_JIT_METHOD_PERF
bool fgModified; // True if the flow graph has been modified recently
bool fgComputePredsDone; // Have we computed the bbPreds list
......@@ -5376,14 +5378,10 @@ public:
flowList* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred, flowList*** ptrToPred);
flowList* fgSpliceOutPred(BasicBlock* block, BasicBlock* blockPred);
flowList* fgRemoveRefPred(BasicBlock* block, BasicBlock* blockPred);
flowList* fgRemoveAllRefPreds(BasicBlock* block, BasicBlock* blockPred);
flowList* fgRemoveAllRefPreds(BasicBlock* block, flowList** ptrToPred);
void fgRemoveBlockAsPred(BasicBlock* block);
void fgChangeSwitchBlock(BasicBlock* oldSwitchBlock, BasicBlock* newSwitchBlock);
......
......@@ -22,7 +22,7 @@
//
// Assumptions:
// -- This only works on the full predecessor lists, not the cheap preds lists.
//
flowList* Compiler::fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred)
{
assert(block);
......@@ -58,7 +58,7 @@ flowList* Compiler::fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred)
//
// Assumptions:
// -- This only works on the full predecessor lists, not the cheap preds lists.
//
flowList* Compiler::fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred, flowList*** ptrToPred)
{
assert(block);
......@@ -83,73 +83,16 @@ flowList* Compiler::fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred,
return nullptr;
}
//------------------------------------------------------------------------
// fgSpliceOutPred: Removes a predecessor edge for a block from the predecessor list.
//
// Arguments:
// block -- The block with the predecessor list to operate on.
// blockPred -- The predecessor block to remove from the predecessor list. It must be a predecessor of "block".
//
// Return Value:
// The flowList edge that was removed.
//
// Assumptions:
// -- "blockPred" must be a predecessor block of "block".
// -- This simply splices out the flowList object. It doesn't update block ref counts, handle duplicate counts, etc.
// For that, use fgRemoveRefPred() or fgRemoveAllRefPred().
// -- This only works on the full predecessor lists, not the cheap preds lists.
//
// Notes:
// -- This must walk the predecessor list to find the block in question. If the predecessor edge
// is found using fgGetPredForBlock(), consider using the version that hands back the predecessor pointer
// address instead, to avoid this search.
// -- Marks fgModified = true, since the flow graph has changed.
flowList* Compiler::fgSpliceOutPred(BasicBlock* block, BasicBlock* blockPred)
{
assert(!fgCheapPredsValid);
noway_assert(block->bbPreds);
flowList* oldEdge = nullptr;
// Is this the first block in the pred list?
if (blockPred == block->bbPreds->getBlock())
{
oldEdge = block->bbPreds;
block->bbPreds = block->bbPreds->flNext;
}
else
{
flowList* pred;
for (pred = block->bbPreds; (pred->flNext != nullptr) && (blockPred != pred->flNext->getBlock());
pred = pred->flNext)
{
// empty
}
oldEdge = pred->flNext;
if (oldEdge == nullptr)
{
noway_assert(!"Should always find the blockPred");
}
pred->flNext = pred->flNext->flNext;
}
// Any changes to the flow graph invalidate the dominator sets.
fgModified = true;
return oldEdge;
}
//------------------------------------------------------------------------
// fgAddRefPred: Increment block->bbRefs by one and add "blockPred" to the predecessor list of "block".
//
// Arguments:
// block -- A block to operate on.
// block -- A block to operate on.
// blockPred -- The predecessor block to add to the predecessor list.
// oldEdge -- Optional (default: nullptr). If non-nullptr, and a new edge is created (and the dup count
// of an existing edge is not just incremented), the edge weights are copied from this edge.
// oldEdge -- Optional (default: nullptr). If non-nullptr, and a new edge is created (and the dup count
// of an existing edge is not just incremented), the edge weights are copied from this edge.
// initializingPreds -- Optional (default: false). Only set to "true" when the initial preds computation is
// happening.
// happening.
//
// Return Value:
// The flow edge representing the predecessor.
......@@ -158,12 +101,12 @@ flowList* Compiler::fgSpliceOutPred(BasicBlock* block, BasicBlock* blockPred)
// -- This only works on the full predecessor lists, not the cheap preds lists.
//
// Notes:
// -- block->bbRefs is incremented by one to account for the reduction in incoming edges.
// -- block->bbRefs is incremented by one to account for the increase in incoming edges.
// -- block->bbRefs is adjusted even if preds haven't been computed. If preds haven't been computed,
// the preds themselves aren't touched.
// -- fgModified is set if a new flow edge is created (but not if an existing flow edge dup count is incremented),
// indicating that the flow graph shape has changed.
//
flowList* Compiler::fgAddRefPred(BasicBlock* block,
BasicBlock* blockPred,
flowList* oldEdge /* = nullptr */,
......@@ -330,7 +273,7 @@ flowList* Compiler::fgAddRefPred(BasicBlock* block,
// the preds themselves aren't touched.
// -- fgModified is set if a flow edge is removed (but not if an existing flow edge dup count is decremented),
// indicating that the flow graph shape has changed.
//
flowList* Compiler::fgRemoveRefPred(BasicBlock* block, BasicBlock* blockPred)
{
noway_assert(block != nullptr);
......@@ -352,7 +295,7 @@ flowList* Compiler::fgRemoveRefPred(BasicBlock* block, BasicBlock* blockPred)
flowList** ptrToPred;
flowList* pred = fgGetPredForBlock(block, blockPred, &ptrToPred);
noway_assert(pred);
noway_assert(pred != nullptr);
noway_assert(pred->flDupCount > 0);
pred->flDupCount--;
......@@ -389,7 +332,7 @@ flowList* Compiler::fgRemoveRefPred(BasicBlock* block, BasicBlock* blockPred)
//
// Notes:
// block->bbRefs is decremented to account for the reduction in incoming edges.
//
flowList* Compiler::fgRemoveAllRefPreds(BasicBlock* block, BasicBlock* blockPred)
{
assert(block != nullptr);
......@@ -416,52 +359,15 @@ flowList* Compiler::fgRemoveAllRefPreds(BasicBlock* block, BasicBlock* blockPred
}
//------------------------------------------------------------------------
// fgRemoveAllRefPreds: Remove a predecessor edge, given the address of a pointer to it in the
// predecessor list, no matter what the "dup count" is.
// fgRemoveBlockAsPred: Removes all the appearances of block as a predecessor of other blocks
// (namely, as a member of the predecessor lists of this block's successors).
//
// Arguments:
// block -- A block with the predecessor list to operate on.
// ptrToPred -- The address of a pointer to the predecessor to remove.
//
// Return Value:
// The removed predecessor edge. The dup count on the edge is no longer valid.
// block -- A block to operate on.
//
// Assumptions:
// -- The predecessor edge must be in the predecessor list for "block".
// -- This only works on the full predecessor lists, not the cheap preds lists.
//
// Notes:
// block->bbRefs is decremented by the dup count of the predecessor edge, to account for the reduction in incoming
// edges.
flowList* Compiler::fgRemoveAllRefPreds(BasicBlock* block, flowList** ptrToPred)
{
assert(block != nullptr);
assert(ptrToPred != nullptr);
assert(fgComputePredsDone);
assert(!fgCheapPredsValid);
assert(block->countOfInEdges() > 0);
flowList* pred = *ptrToPred;
assert(pred != nullptr);
assert(pred->flDupCount > 0);
assert(block->bbRefs >= pred->flDupCount);
block->bbRefs -= pred->flDupCount;
// Now splice out the predecessor edge.
*ptrToPred = pred->flNext;
// Any changes to the flow graph invalidate the dominator sets.
fgModified = true;
return pred;
}
/*
Removes all the appearances of block as predecessor of others
*/
void Compiler::fgRemoveBlockAsPred(BasicBlock* block)
{
assert(!fgCheapPredsValid);
......@@ -573,22 +479,21 @@ void Compiler::fgRemoveBlockAsPred(BasicBlock* block)
}
}
/*****************************************************************************
*
* fgComputeCheapPreds: Function called to compute the BasicBlock::bbCheapPreds lists.
*
* No other block data is changed (e.g., bbRefs, bbFlags).
*
* The cheap preds lists are similar to the normal (bbPreds) predecessor lists, but are cheaper to
* compute and store, as follows:
* 1. A flow edge is typed BasicBlockList, which only has a block pointer and 'next' pointer. It doesn't
* have weights or a dup count.
* 2. The preds list for a block is not sorted by block number.
* 3. The predecessors of the block following a BBJ_CALLFINALLY (the corresponding BBJ_ALWAYS,
* for normal, non-retless calls to the finally) are not computed.
* 4. The cheap preds lists will contain duplicates if a single switch table has multiple branches
* to the same block. Thus, we don't spend the time looking for duplicates for every edge we insert.
*/
//------------------------------------------------------------------------
// fgComputeCheapPreds: Compute the BasicBlock::bbCheapPreds lists.
//
// No other block data is changed (e.g., bbRefs, bbFlags).
//
// The cheap preds lists are similar to the normal (bbPreds) predecessor lists, but are cheaper to
// compute and store, as follows:
// 1. A flow edge is typed BasicBlockList, which only has a block pointer and 'next' pointer. It doesn't
// have weights or a dup count.
// 2. The preds list for a block is not sorted by block number.
// 3. The predecessors of the block following a BBJ_CALLFINALLY (the corresponding BBJ_ALWAYS,
// for normal, non-retless calls to the finally) are not computed.
// 4. The cheap preds lists will contain duplicates if a single switch table has multiple branches
// to the same block. Thus, we don't spend the time looking for duplicates for every edge we insert.
//
void Compiler::fgComputeCheapPreds()
{
noway_assert(!fgComputePredsDone); // We can't do this if we've got the full preds.
......@@ -677,10 +582,17 @@ void Compiler::fgComputeCheapPreds()
#endif
}
/*****************************************************************************
* Add 'blockPred' to the cheap predecessor list of 'block'.
*/
//------------------------------------------------------------------------
// fgAddCheapPred: Add 'blockPred' to the cheap predecessor list of 'block'.
//
// Arguments:
// block -- A block to operate on.
// blockPred -- The predecessor block to add to the cheap predecessors list. It must be a predecessor of "block".
//
// Assumptions:
// -- "blockPred" must be a predecessor block of "block".
// -- This only works on the cheap predecessor lists.
//
void Compiler::fgAddCheapPred(BasicBlock* block, BasicBlock* blockPred)
{
assert(!fgComputePredsDone);
......@@ -695,10 +607,19 @@ void Compiler::fgAddCheapPred(BasicBlock* block, BasicBlock* blockPred)
#endif // MEASURE_BLOCK_SIZE
}
/*****************************************************************************
* Remove 'blockPred' from the cheap predecessor list of 'block'.
* If there are duplicate edges, only remove one of them.
*/
//------------------------------------------------------------------------
// fgRemoveCheapPred: Remove 'blockPred' from the cheap predecessor list of 'block'.
// If there are duplicate edges, only remove one of them.
//
// Arguments:
// block -- A block to operate on.
// blockPred -- The predecessor block to remove from the cheap predecessors list. It must be a
// predecessor of "block".
//
// Assumptions:
// -- "blockPred" must be a predecessor block of "block".
// -- This only works on the cheap predecessor lists.
//
void Compiler::fgRemoveCheapPred(BasicBlock* block, BasicBlock* blockPred)
{
assert(!fgComputePredsDone);
......@@ -729,14 +650,14 @@ void Compiler::fgRemoveCheapPred(BasicBlock* block, BasicBlock* blockPred)
}
//------------------------------------------------------------------------
// fgRemovePreds - remove all pred information from blocks
// fgRemovePreds: Remove all pred information from blocks
//
void Compiler::fgRemovePreds()
{
C_ASSERT(offsetof(BasicBlock, bbPreds) ==
offsetof(BasicBlock, bbCheapPreds)); // bbPreds and bbCheapPreds are at the same place in a union,
C_ASSERT(sizeof(((BasicBlock*)nullptr)->bbPreds) ==
sizeof(((BasicBlock*)nullptr)->bbCheapPreds)); // and are the same size. So, this function removes both.
// bbPreds and bbCheapPreds are at the same place in a union
static_assert_no_msg(offsetof(BasicBlock, bbPreds) == offsetof(BasicBlock, bbCheapPreds));
// and are the same size. So, this function removes both.
static_assert_no_msg(sizeof(((BasicBlock*)nullptr)->bbPreds) == sizeof(((BasicBlock*)nullptr)->bbCheapPreds));
for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
......@@ -747,11 +668,21 @@ void Compiler::fgRemovePreds()
}
//------------------------------------------------------------------------
// fgComputePreds - compute the bbPreds lists
// fgComputePreds: Compute the predecessor lists for each block.
//
// Notes:
// Resets and then fills in the list of predecessors for each basic
// block. Assumes blocks (via bbNext) are in increasing bbNum order.
// -- Resets and then fills in the list of `bbPreds` predecessor lists for each basic block.
// -- Sets the `bbRefs` reference count for each block.
// -- Uses `bbLastPred` to optimize inserting predecessors in increasing block number order.
// -- The first block of the function gets a `bbRefs` count of at least one because it is always
// reachable via the prolog.
// -- The first block of each EH handler and EH filter gets an artificial addition ref count to ensure they are
// considered reachable.
// -- `fgModified` is reset to `false` to indicate the flow graph is in an unmodified state.
// -- `fgComputePredsDone` is set to `true`.
//
// Assumptions:
// Assumes blocks (via bbNext) are in increasing bbNum order.
//
void Compiler::fgComputePreds()
{
......@@ -1096,18 +1027,14 @@ void Compiler::SwitchUniqueSuccSet::UpdateTarget(CompAllocator alloc,
}
else if (!fromStillPresent && !toAlreadyPresent)
{
#ifdef DEBUG
// write "to" where "from" was
bool foundFrom = false;
#endif // DEBUG
INDEBUG(bool foundFrom = false);
for (unsigned i = 0; i < numDistinctSuccs; i++)
{
if (nonDuplicates[i] == from)
{
nonDuplicates[i] = to;
#ifdef DEBUG
foundFrom = true;
#endif // DEBUG
INDEBUG(foundFrom = true);
break;
}
}
......@@ -1116,19 +1043,15 @@ void Compiler::SwitchUniqueSuccSet::UpdateTarget(CompAllocator alloc,
else
{
assert(!fromStillPresent && toAlreadyPresent);
#ifdef DEBUG
// remove "from".
bool foundFrom = false;
#endif // DEBUG
INDEBUG(bool foundFrom = false);
for (unsigned i = 0; i < numDistinctSuccs; i++)
{
if (nonDuplicates[i] == from)
{
nonDuplicates[i] = nonDuplicates[numDistinctSuccs - 1];
numDistinctSuccs--;
#ifdef DEBUG
foundFrom = true;
#endif // DEBUG
INDEBUG(foundFrom = true);
break;
}
}
......
此差异已折叠。
......@@ -2931,21 +2931,18 @@ void Compiler::fgComputeCalledCount(BasicBlock::weight_t returnWeight)
BasicBlock* firstILBlock = fgFirstBB; // The first block for IL code (i.e. for the IL code at offset 0)
// Do we have an internal block as our first Block?
if (firstILBlock->bbFlags & BBF_INTERNAL)
// Skip past any/all BBF_INTERNAL blocks that may have been added before the first real IL block.
//
while (firstILBlock->bbFlags & BBF_INTERNAL)
{
// Skip past any/all BBF_INTERNAL blocks that may have been added before the first real IL block.
//
while (firstILBlock->bbFlags & BBF_INTERNAL)
{
firstILBlock = firstILBlock->bbNext;
}
// The 'firstILBlock' is now expected to have a profile-derived weight
assert(firstILBlock->hasProfileWeight());
firstILBlock = firstILBlock->bbNext;
}
// If the first block only has one ref then we use it's weight for fgCalledCount.
// Otherwise we have backedge's into the first block, so instead we use the sum
// The 'firstILBlock' is now expected to have a profile-derived weight
assert(firstILBlock->hasProfileWeight());
// If the first block only has one ref then we use its weight for fgCalledCount.
// Otherwise we have backedges into the first block, so instead we use the sum
// of the return block weights for fgCalledCount.
//
// If the profile data has a 0 for the returnWeight
......@@ -2954,7 +2951,6 @@ void Compiler::fgComputeCalledCount(BasicBlock::weight_t returnWeight)
//
if ((firstILBlock->countOfInEdges() == 1) || (returnWeight == BB_ZERO_WEIGHT))
{
assert(firstILBlock->hasProfileWeight()); // This should always be a profile-derived weight
fgCalledCount = firstILBlock->bbWeight;
}
else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册