Skip to content

Commit 51a116d

Browse files
Don't recompute preds lists during loop cloning (#51757)
Instead, add and modify the appropriate preds when the mechanical cloning is performed. This will preserve existing profile data on the edges. Contributes to #49030 No x86/x64 SPMI asm diffs.
1 parent 86c1132 commit 51a116d

File tree

7 files changed

+208
-70
lines changed

7 files changed

+208
-70
lines changed

src/coreclr/jit/compiler.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5268,7 +5268,7 @@ class Compiler
52685268

52695269
// When the flow graph changes, we need to update the block numbers, predecessor lists, reachability sets, and
52705270
// dominators.
5271-
void fgUpdateChangedFlowGraph(bool computeDoms = true);
5271+
void fgUpdateChangedFlowGraph(const bool computePreds = true, const bool computeDoms = true);
52725272

52735273
public:
52745274
// Compute the predecessors of the blocks in the control flow graph.
@@ -6534,8 +6534,9 @@ class Compiler
65346534
void optUpdateLoopHead(unsigned loopInd, BasicBlock* from, BasicBlock* to);
65356535

65366536
// Updates the successors of "blk": if "blk2" is a successor of "blk", and there is a mapping for "blk2->blk3" in
6537-
// "redirectMap", change "blk" so that "blk3" is this successor. Note that the predecessor lists are not updated.
6538-
void optRedirectBlock(BasicBlock* blk, BlockToBlockMap* redirectMap);
6537+
// "redirectMap", change "blk" so that "blk3" is this successor. If `addPreds` is true, add predecessor edges
6538+
// for the block based on its new target, whether redirected or not.
6539+
void optRedirectBlock(BasicBlock* blk, BlockToBlockMap* redirectMap, const bool addPreds = false);
65396540

65406541
// Marks the containsCall information to "lnum" and any parent loops.
65416542
void AddContainsCallAllContainingLoops(unsigned lnum);

src/coreclr/jit/fgdiagnostic.cpp

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -707,11 +707,24 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
707707
fprintf(fgxFile, ">");
708708
}
709709

710+
// In some cases, we want to change the display based on whether an edge is lexically backwards, forwards,
711+
// or lexical successor. Also, for the region tree, using the lexical order is useful for determining where
712+
// to insert in the tree, to determine nesting. We'd like to use the bbNum to do this. However, we don't
713+
// want to renumber the blocks. So, create a mapping of bbNum to ordinal, and compare block order by
714+
// comparing the mapped ordinals instead.
715+
716+
unsigned blockOrdinal = 0;
717+
unsigned* blkMap = new (this, CMK_DebugOnly) unsigned[fgBBNumMax + 1];
718+
memset(blkMap, 0, sizeof(unsigned) * (fgBBNumMax + 1));
719+
for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
720+
{
721+
blkMap[block->bbNum] = blockOrdinal++;
722+
}
723+
710724
static const char* kindImage[] = {"EHFINALLYRET", "EHFILTERRET", "EHCATCHRET", "THROW", "RETURN", "NONE",
711725
"ALWAYS", "LEAVE", "CALLFINALLY", "COND", "SWITCH"};
712726

713727
BasicBlock* block;
714-
unsigned blockOrdinal;
715728
for (block = fgFirstBB, blockOrdinal = 1; block != nullptr; block = block->bbNext, blockOrdinal++)
716729
{
717730
if (createDotFile)
@@ -840,13 +853,13 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
840853

841854
const char* sep = "";
842855

843-
if (bSource->bbNum > bTarget->bbNum)
856+
if (blkMap[bSource->bbNum] > blkMap[bTarget->bbNum])
844857
{
845858
// Lexical backedge
846859
fprintf(fgxFile, " [color=green");
847860
sep = ", ";
848861
}
849-
else if ((bSource->bbNum + 1) == bTarget->bbNum)
862+
else if ((blkMap[bSource->bbNum] + 1) == blkMap[bTarget->bbNum])
850863
{
851864
// Lexical successor
852865
fprintf(fgxFile, " [color=blue, weight=20");
@@ -953,12 +966,12 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
953966
{
954967
BasicBlock* const bTarget = bSource->GetSucc(i);
955968
fprintf(fgxFile, " " FMT_BB " -> " FMT_BB, bSource->bbNum, bTarget->bbNum);
956-
if (bSource->bbNum > bTarget->bbNum)
969+
if (blkMap[bSource->bbNum] > blkMap[bTarget->bbNum])
957970
{
958971
// Lexical backedge
959972
fprintf(fgxFile, " [color=green]\n");
960973
}
961-
else if ((bSource->bbNum + 1) == bTarget->bbNum)
974+
else if ((blkMap[bSource->bbNum] + 1) == blkMap[bTarget->bbNum])
962975
{
963976
// Lexical successor
964977
fprintf(fgxFile, " [color=blue]\n");
@@ -1027,24 +1040,11 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
10271040
};
10281041

10291042
public:
1030-
RegionGraph(Compiler* comp) : m_comp(comp), m_rgnRoot(nullptr)
1043+
RegionGraph(Compiler* comp, unsigned* blkMap) : m_comp(comp), m_rgnRoot(nullptr), m_blkMap(blkMap)
10311044
{
10321045
// Create a root region that encompasses the whole function.
1033-
// We don't want to renumber the blocks, but it's useful to have a sequential number
1034-
// representing the lexical block order so we know where to insert a block range
1035-
// in the region tree. To do this, create a mapping of bbNum to ordinal, and compare
1036-
// block order by comparing the mapped ordinals.
1037-
10381046
m_rgnRoot =
10391047
new (m_comp, CMK_DebugOnly) Region(RegionType::Root, "Root", comp->fgFirstBB, comp->fgLastBB);
1040-
1041-
unsigned bbOrdinal = 0;
1042-
m_blkMap = new (m_comp, CMK_DebugOnly) unsigned[comp->fgBBNumMax + 1];
1043-
memset(m_blkMap, 0, sizeof(unsigned) * (comp->fgBBNumMax + 1));
1044-
for (BasicBlock* block = comp->fgFirstBB; block != nullptr; block = block->bbNext)
1045-
{
1046-
m_blkMap[block->bbNum] = bbOrdinal++;
1047-
}
10481048
}
10491049

10501050
//------------------------------------------------------------------------
@@ -1353,7 +1353,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
13531353

13541354
// Define the region graph object. We'll add regions to this, then output the graph.
13551355

1356-
RegionGraph rgnGraph(this);
1356+
RegionGraph rgnGraph(this, blkMap);
13571357

13581358
// Add the EH regions to the region graph. An EH region consists of a region for the
13591359
// `try`, a region for the handler, and, for filter/filter-handlers, a region for the
@@ -2071,7 +2071,7 @@ class BBPredsChecker
20712071
bool CheckEhTryDsc(BasicBlock* block, BasicBlock* blockPred, EHblkDsc* ehTryDsc);
20722072
bool CheckEhHndDsc(BasicBlock* block, BasicBlock* blockPred, EHblkDsc* ehHndlDsc);
20732073
bool CheckJump(BasicBlock* blockPred, BasicBlock* block);
2074-
bool CheckEHFinalyRet(BasicBlock* blockPred, BasicBlock* block);
2074+
bool CheckEHFinallyRet(BasicBlock* blockPred, BasicBlock* block);
20752075

20762076
private:
20772077
Compiler* comp;
@@ -2130,7 +2130,7 @@ unsigned BBPredsChecker::CheckBBPreds(BasicBlock* block, unsigned curTraversalSt
21302130
assert(CheckJump(blockPred, block));
21312131
}
21322132

2133-
// Make sure preds are in increasting BBnum order
2133+
// Make sure preds are in increasing BBnum order
21342134
//
21352135
assert(block->checkPredListOrder());
21362136

@@ -2232,7 +2232,7 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block)
22322232
return true;
22332233

22342234
case BBJ_EHFINALLYRET:
2235-
assert(CheckEHFinalyRet(blockPred, block));
2235+
assert(CheckEHFinallyRet(blockPred, block));
22362236
return true;
22372237

22382238
case BBJ_THROW:
@@ -2265,9 +2265,8 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block)
22652265
return false;
22662266
}
22672267

2268-
bool BBPredsChecker::CheckEHFinalyRet(BasicBlock* blockPred, BasicBlock* block)
2268+
bool BBPredsChecker::CheckEHFinallyRet(BasicBlock* blockPred, BasicBlock* block)
22692269
{
2270-
22712270
// If the current block is a successor to a BBJ_EHFINALLYRET (return from finally),
22722271
// then the lexically previous block should be a call to the same finally.
22732272
// Verify all of that.

src/coreclr/jit/fgflow.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ void Compiler::fgRemovePreds()
686686
//
687687
void Compiler::fgComputePreds()
688688
{
689-
noway_assert(fgFirstBB);
689+
noway_assert(fgFirstBB != nullptr);
690690

691691
BasicBlock* block;
692692

@@ -697,6 +697,14 @@ void Compiler::fgComputePreds()
697697
fgDispBasicBlocks();
698698
printf("\n");
699699
}
700+
701+
// Check that the block numbers are increasing order.
702+
unsigned lastBBnum = fgFirstBB->bbNum;
703+
for (BasicBlock* block = fgFirstBB->bbNext; block != nullptr; block = block->bbNext)
704+
{
705+
assert(lastBBnum < block->bbNum);
706+
lastBBnum = block->bbNum;
707+
}
700708
#endif // DEBUG
701709

702710
// Reset everything pred related

src/coreclr/jit/fgopt.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,18 @@ bool Compiler::fgReachable(BasicBlock* b1, BasicBlock* b2)
174174
// Arguments:
175175
// computeDoms -- `true` if we should recompute dominators
176176
//
177-
void Compiler::fgUpdateChangedFlowGraph(bool computeDoms)
177+
void Compiler::fgUpdateChangedFlowGraph(const bool computePreds, const bool computeDoms)
178178
{
179179
// We need to clear this so we don't hit an assert calling fgRenumberBlocks().
180180
fgDomsComputed = false;
181181

182182
JITDUMP("\nRenumbering the basic blocks for fgUpdateChangeFlowGraph\n");
183183
fgRenumberBlocks();
184184

185-
fgComputePreds();
185+
if (computePreds) // This condition is only here until all phases don't require it.
186+
{
187+
fgComputePreds();
188+
}
186189
fgComputeEnterBlocksSet();
187190
fgComputeReachabilitySets();
188191
if (computeDoms)

src/coreclr/jit/flowgraph.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,9 @@ PhaseStatus Compiler::fgInsertGCPolls()
190190
{
191191
noway_assert(opts.OptimizationEnabled());
192192
fgReorderBlocks();
193-
constexpr bool computeDoms = false;
194-
fgUpdateChangedFlowGraph(computeDoms);
193+
constexpr bool computePreds = true;
194+
constexpr bool computeDoms = false;
195+
fgUpdateChangedFlowGraph(computePreds, computeDoms);
195196
}
196197
#ifdef DEBUG
197198
if (verbose)

src/coreclr/jit/jithashtable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class JitHashTable
471471

472472
public:
473473
//------------------------------------------------------------------------
474-
// CheckGrowth: Replace the bucket table with a larger one and copy all nodes
474+
// Reallocate: Replace the bucket table with a larger one and copy all nodes
475475
// from the existing bucket table.
476476
//
477477
// Notes:

0 commit comments

Comments
 (0)