Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 5 additions & 53 deletions src/coreclr/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,7 @@ class MergedReturns
// cases, `fgReturnCount` and the merged return block's profile information
// will be updated to reflect or anticipate the rewrite of `returnBlock`.
//
void Record(BasicBlock* returnBlock)
bool Record(BasicBlock* returnBlock)
{
// Add this return to our tally
unsigned oldReturnCount = comp->fgReturnCount++;
Expand All @@ -1917,7 +1917,7 @@ class MergedReturns
{
// No need to merge just yet; simply record this return.
returnBlocks[oldReturnCount] = returnBlock;
return;
return false;
}

// We've reached our threshold
Expand All @@ -1939,6 +1939,7 @@ class MergedReturns
// Search limit is new return count minus one (to exclude this block).
unsigned searchLimit = comp->fgReturnCount - 1;
Merge(returnBlock, searchLimit);
return true;
}

//------------------------------------------------------------------------
Expand All @@ -1953,54 +1954,6 @@ class MergedReturns
return Merge(nullptr, 0);
}

//------------------------------------------------------------------------
// PlaceReturns: Move any generated const return blocks to an appropriate
// spot in the lexical block list.
//
// Returns:
// True if any returns were impacted.
//
// Notes:
// The goal is to set things up favorably for a reasonable layout without
// putting too much burden on fgReorderBlocks; in particular, since that
// method doesn't (currently) shuffle non-profile, non-rare code to create
// fall-through and reduce gotos, this method places each const return
// block immediately after its last predecessor, so that the flow from
// there to it can become fallthrough without requiring any motion to be
// performed by fgReorderBlocks.
//
bool PlaceReturns()
{
if (!mergingReturns)
{
// No returns generated => no returns to place.
return false;
}

for (unsigned index = 0; index < comp->fgReturnCount; ++index)
{
BasicBlock* returnBlock = returnBlocks[index];
BasicBlock* genReturnBlock = comp->genReturnBB;
if (returnBlock == genReturnBlock)
{
continue;
}

BasicBlock* insertionPoint = insertionPoints[index];
assert(insertionPoint != nullptr);

comp->fgUnlinkBlock(returnBlock);
comp->fgMoveBlocksAfter(returnBlock, returnBlock, insertionPoint);
// Treat the merged return block as belonging to the same EH region
// as the insertion point block, to make sure we don't break up
// EH regions; since returning a constant won't throw, this won't
// affect program behavior.
comp->fgExtendEHRegionAfter(insertionPoint);
}

return true;
}

private:
//------------------------------------------------------------------------
// CreateReturnBB: Create a basic block to serve as a merged return point, stored to
Expand Down Expand Up @@ -2425,6 +2378,7 @@ PhaseStatus Compiler::fgAddInternal()
// will expect to find it.
BasicBlock* mergedReturn = merger.EagerCreate();
assert(mergedReturn == genReturnBB);
madeChanges = true;
}
else
{
Expand Down Expand Up @@ -2454,12 +2408,10 @@ PhaseStatus Compiler::fgAddInternal()
{
if (block->KindIs(BBJ_RETURN) && !block->HasFlag(BBF_HAS_JMP))
{
merger.Record(block);
madeChanges |= merger.Record(block);
}
}

madeChanges |= merger.PlaceReturns();

if (compMethodRequiresPInvokeFrame())
{
// The P/Invoke helpers only require a frame variable, so only allocate the
Expand Down
Loading