Skip to content

Commit 71772d1

Browse files
JIT: Consolidate layout passes into one phase (#112004)
Part of #107749. This replaces our RPO layout and cold code motion phases with a single loop-aware RPO computation (with cold blocks ignored) that we feed into 3-opt as its initial layout. This has the nice property of needing to reorder the block list only once, and never leaving it in a temporarily invalid state (i.e. with EH regions broken up). My initial plan was for this PR to be zero-diff since I split out all the invariant changes (like not reordering cold/handler blocks at all) into separate PRs, but I found it necessary to implement moving try regions around to avoid regressing layout quality. Suppose we have some initial layout that looks like this: [BB01 (hot)] [BB02 (cold)] [BB03 (hot, try entry)] [BB04 (hot, try exit)] [BB05 (hot)] When reordering the block list, we want to only reorder within try regions to avoid breaking their contiguity. Suppose 3-opt wants the block list to look like BB01 -> BB03 -> BB04 -> BB05 -> BB02. If we only reorder within regions, we cannot place BB03 after BB01, so the layout remains as-is, with the cold block inline. And if BB05 were somewhere else in the initial layout, we wouldn't be able to move it after BB04 because they're in different regions. We can be a bit clever and remember the last hot block in each region, so that EH region boundaries don't trip us up. However, this only enables better movement within regions, and nested regions end up sinking down the method. We end up with the following layout: [BB01 (hot)] [BB05 (hot)] [BB02 (cold)] [BB03 (hot, try entry)] [BB04 (hot, try exit)] The hot part of the main method body is compact, but the try region is interleaved with cold code. After adding support for try region movement, we can now move try regions up to their ideal successors, when doing so doesn't break EH nesting invariants: [BB01 (hot)] [BB03 (hot, try entry)] [BB04 (hot, try exit)] [BB05 (hot)] [BB02 (cold)] Thus, this change has some churn, but it looks mostly like a PerfScore win.
1 parent c40c261 commit 71772d1

File tree

4 files changed

+279
-427
lines changed

4 files changed

+279
-427
lines changed

src/coreclr/jit/compiler.cpp

+1-24
Original file line numberDiff line numberDiff line change
@@ -5023,30 +5023,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
50235023
//
50245024
if (JitConfig.JitDoReversePostOrderLayout())
50255025
{
5026-
auto lateLayoutPhase = [this] {
5027-
// Skip preliminary reordering passes to create more work for 3-opt layout
5028-
if (compStressCompile(STRESS_THREE_OPT_LAYOUT, 10))
5029-
{
5030-
m_dfsTree = fgComputeDfs</* useProfile */ true>();
5031-
}
5032-
else
5033-
{
5034-
fgDoReversePostOrderLayout();
5035-
fgMoveColdBlocks();
5036-
}
5037-
5038-
fgSearchImprovedLayout();
5039-
fgInvalidateDfsTree();
5040-
5041-
if (compHndBBtabCount != 0)
5042-
{
5043-
fgRebuildEHRegions();
5044-
}
5045-
5046-
return PhaseStatus::MODIFIED_EVERYTHING;
5047-
};
5048-
5049-
DoPhase(this, PHASE_OPTIMIZE_LAYOUT, lateLayoutPhase);
5026+
DoPhase(this, PHASE_OPTIMIZE_LAYOUT, &Compiler::fgSearchImprovedLayout);
50505027
}
50515028
else
50525029
{

src/coreclr/jit/compiler.h

+7-8
Original file line numberDiff line numberDiff line change
@@ -2904,7 +2904,7 @@ class Compiler
29042904

29052905
void fgSetHndEnd(EHblkDsc* handlerTab, BasicBlock* newHndLast);
29062906

2907-
void fgRebuildEHRegions();
2907+
void fgFindTryRegionEnds();
29082908

29092909
void fgSkipRmvdBlocks(EHblkDsc* handlerTab);
29102910

@@ -6179,9 +6179,7 @@ class Compiler
61796179
bool fgComputeMissingBlockWeights();
61806180

61816181
bool fgReorderBlocks(bool useProfile);
6182-
void fgDoReversePostOrderLayout();
6183-
void fgMoveColdBlocks();
6184-
void fgSearchImprovedLayout();
6182+
PhaseStatus fgSearchImprovedLayout();
61856183

61866184
class ThreeOptLayout
61876185
{
@@ -6208,12 +6206,13 @@ class Compiler
62086206
void AddNonFallthroughPreds(unsigned blockPos);
62096207
bool RunGreedyThreeOptPass(unsigned startPos, unsigned endPos);
62106208

6211-
bool CompactHotJumps();
6212-
bool RunThreeOpt();
6209+
void RunThreeOpt();
6210+
void CompactHotJumps();
6211+
bool ReorderBlockList();
62136212

62146213
public:
6215-
ThreeOptLayout(Compiler* comp);
6216-
void Run();
6214+
ThreeOptLayout(Compiler* comp, BasicBlock** initialLayout, unsigned numHotBlocks);
6215+
bool Run();
62176216
};
62186217

62196218
bool fgFuncletsAreCold();

0 commit comments

Comments
 (0)