Skip to content

Commit 81312cd

Browse files
authored
JIT: finish converting all phases to use common post phase dumps and checks (#74308)
* Rework fgComputeReachability * Rework optSetBlockWeights * Rework optVnCopyProp * Rework things for optRedundantBranches This has a few small diffs, as I had to disable jump threading in one case and generalize how morph updates the loop table. * Rework optOptimizeValnumCSEs * Rework assertion prop * Rework range prop * Rework second flow opt and edge weight phases * Rework fgDetermineFirstColdBlock * Rework fgSimpleLowering * Rework linear scan * Rework placeLoopAlignInstructions * Enable checks after fgMorphArrayOps * Enable remaining phases. * only dump starting messages under verbose
1 parent ee4ce42 commit 81312cd

File tree

15 files changed

+361
-401
lines changed

15 files changed

+361
-401
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6058,29 +6058,26 @@ Statement* Compiler::optVNAssertionPropCurStmt(BasicBlock* block, Statement* stm
60586058
return nextStmt;
60596059
}
60606060

6061-
/*****************************************************************************
6062-
*
6063-
* The entry point for assertion propagation
6064-
*/
6065-
6066-
void Compiler::optAssertionPropMain()
6061+
//------------------------------------------------------------------------------
6062+
// optAssertionPropMain: assertion propagation phase
6063+
//
6064+
// Returns:
6065+
// Suitable phase status.
6066+
//
6067+
PhaseStatus Compiler::optAssertionPropMain()
60676068
{
60686069
if (fgSsaPassesCompleted == 0)
60696070
{
6070-
return;
6071-
}
6072-
#ifdef DEBUG
6073-
if (verbose)
6074-
{
6075-
printf("*************** In optAssertionPropMain()\n");
6076-
printf("Blocks/Trees at start of phase\n");
6077-
fgDispBasicBlocks(true);
6071+
return PhaseStatus::MODIFIED_NOTHING;
60786072
}
6079-
#endif
60806073

60816074
optAssertionInit(false);
60826075

60836076
noway_assert(optAssertionCount == 0);
6077+
bool madeChanges = false;
6078+
6079+
// Assertion prop can speculatively create trees.
6080+
INDEBUG(const unsigned baseTreeID = compGenTreeID);
60846081

60856082
// First discover all value assignments and record them in the table.
60866083
for (BasicBlock* const block : Blocks())
@@ -6096,13 +6093,16 @@ void Compiler::optAssertionPropMain()
60966093
if (fgRemoveRestOfBlock)
60976094
{
60986095
fgRemoveStmt(block, stmt);
6099-
stmt = stmt->GetNextStmt();
6096+
stmt = stmt->GetNextStmt();
6097+
madeChanges = true;
61006098
continue;
61016099
}
61026100
else
61036101
{
61046102
// Perform VN based assertion prop before assertion gen.
61056103
Statement* nextStmt = optVNAssertionPropCurStmt(block, stmt);
6104+
madeChanges |= optAssertionPropagatedCurrentStmt;
6105+
INDEBUG(madeChanges |= (baseTreeID != compGenTreeID));
61066106

61076107
// Propagation resulted in removal of the remaining stmts, perform it.
61086108
if (fgRemoveRestOfBlock)
@@ -6139,7 +6139,7 @@ void Compiler::optAssertionPropMain()
61396139
{
61406140
block->bbAssertionIn = BitVecOps::MakeEmpty(apTraits);
61416141
}
6142-
return;
6142+
return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
61436143
}
61446144

61456145
#ifdef DEBUG
@@ -6209,7 +6209,8 @@ void Compiler::optAssertionPropMain()
62096209
if (fgRemoveRestOfBlock)
62106210
{
62116211
fgRemoveStmt(block, stmt);
6212-
stmt = stmt->GetNextStmt();
6212+
stmt = stmt->GetNextStmt();
6213+
madeChanges = true;
62136214
continue;
62146215
}
62156216

@@ -6255,6 +6256,7 @@ void Compiler::optAssertionPropMain()
62556256
#endif
62566257
// Re-morph the statement.
62576258
fgMorphBlockStmt(block, stmt DEBUGARG("optAssertionPropMain"));
6259+
madeChanges = true;
62586260
}
62596261

62606262
// Check if propagation removed statements starting from current stmt.
@@ -6265,8 +6267,5 @@ void Compiler::optAssertionPropMain()
62656267
optAssertionPropagatedCurrentStmt = false; // clear it back as we are done with stmts.
62666268
}
62676269

6268-
#ifdef DEBUG
6269-
fgDebugCheckBBlist();
6270-
fgDebugCheckLinks();
6271-
#endif
6270+
return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
62726271
}

src/coreclr/jit/compiler.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,8 +1836,9 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
18361836
// Initialize this to the first phase to run.
18371837
mostRecentlyActivePhase = PHASE_PRE_IMPORT;
18381838

1839-
// Initially, no phase checks are active.
1839+
// Initially, no phase checks are active, and all dumps are enabled.
18401840
activePhaseChecks = PhaseChecks::CHECK_NONE;
1841+
activePhaseDumps = PhaseDumps::DUMP_ALL;
18411842

18421843
#ifdef FEATURE_TRACELOGGING
18431844
// Make sure JIT telemetry is initialized as soon as allocations can be made
@@ -4810,20 +4811,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
48104811

48114812
if (doRangeAnalysis)
48124813
{
4813-
auto rangePhase = [this]() {
4814-
RangeCheck rc(this);
4815-
rc.OptimizeRangeChecks();
4816-
};
4817-
48184814
// Bounds check elimination via range analysis
48194815
//
4820-
DoPhase(this, PHASE_OPTIMIZE_INDEX_CHECKS, rangePhase);
4816+
DoPhase(this, PHASE_OPTIMIZE_INDEX_CHECKS, &Compiler::rangeCheckPhase);
48214817
}
48224818

48234819
if (fgModified)
48244820
{
48254821
// update the flowgraph if we modified it during the optimization phase
48264822
//
4823+
// Note: this invalidates loops, dominators and reachability
4824+
//
48274825
DoPhase(this, PHASE_OPT_UPDATE_FLOW_GRAPH, &Compiler::fgUpdateFlowGraphPhase);
48284826

48294827
// Recompute the edge weight if we have modified the flow graph
@@ -4841,11 +4839,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
48414839
}
48424840
}
48434841

4844-
#ifdef DEBUG
4845-
// Run this before we potentially tear down dominators.
4846-
fgDebugCheckLinks(compStressCompile(STRESS_REMORPH_TREES, 50));
4847-
#endif
4848-
48494842
// Dominator and reachability sets are no longer valid.
48504843
// The loop table is no longer valid.
48514844
fgDomsComputed = false;
@@ -4942,6 +4935,11 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
49424935
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
49434936
#endif
49444937

4938+
// The common phase checks and dumps are no longer relevant past this point.
4939+
//
4940+
activePhaseChecks = PhaseChecks::CHECK_NONE;
4941+
activePhaseDumps = PhaseDumps::DUMP_NONE;
4942+
49454943
// Generate code
49464944
codeGen->genGenerateCode(methodCodePtr, methodCodeSize);
49474945

@@ -5023,25 +5021,32 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
50235021
#if FEATURE_LOOP_ALIGN
50245022

50255023
//------------------------------------------------------------------------
5026-
// placeLoopAlignInstructions: Iterate over all the blocks and determine
5027-
// the best position to place the 'align' instruction. Inserting 'align'
5028-
// instructions after an unconditional branch is preferred over inserting
5029-
// in the block before the loop. In case there are multiple blocks
5030-
// having 'jmp', the one that has lower weight is preferred.
5031-
// If the block having 'jmp' is hotter than the block before the loop,
5032-
// the align will still be placed after 'jmp' because the processor should
5033-
// be smart enough to not fetch extra instruction beyond jmp.
5024+
// placeLoopAlignInstructions: determine where to place alignment padding
5025+
//
5026+
// Returns:
5027+
// Suitable phase status
50345028
//
5035-
void Compiler::placeLoopAlignInstructions()
5029+
// Notes:
5030+
// Iterate over all the blocks and determine
5031+
// the best position to place the 'align' instruction. Inserting 'align'
5032+
// instructions after an unconditional branch is preferred over inserting
5033+
// in the block before the loop. In case there are multiple blocks
5034+
// having 'jmp', the one that has lower weight is preferred.
5035+
// If the block having 'jmp' is hotter than the block before the loop,
5036+
// the align will still be placed after 'jmp' because the processor should
5037+
// be smart enough to not fetch extra instruction beyond jmp.
5038+
//
5039+
PhaseStatus Compiler::placeLoopAlignInstructions()
50365040
{
50375041
if (loopAlignCandidates == 0)
50385042
{
5039-
return;
5043+
return PhaseStatus::MODIFIED_NOTHING;
50405044
}
50415045

50425046
JITDUMP("Inside placeLoopAlignInstructions for %d loops.\n", loopAlignCandidates);
50435047

50445048
// Add align only if there were any loops that needed alignment
5049+
bool madeChanges = false;
50455050
weight_t minBlockSoFar = BB_MAX_WEIGHT;
50465051
BasicBlock* bbHavingAlign = nullptr;
50475052
BasicBlock::loopNumber currentAlignedLoopNum = BasicBlock::NOT_IN_LOOP;
@@ -5051,6 +5056,7 @@ void Compiler::placeLoopAlignInstructions()
50515056
// Adding align instruction in prolog is not supported
50525057
// hence just remove that loop from our list.
50535058
fgFirstBB->unmarkLoopAlign(this DEBUG_ARG("prolog block"));
5059+
madeChanges = true;
50545060
}
50555061

50565062
int loopsToProcess = loopAlignCandidates;
@@ -5099,6 +5105,7 @@ void Compiler::placeLoopAlignInstructions()
50995105
if ((block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) && (block->bbNatLoopNum == loopTop->bbNatLoopNum))
51005106
{
51015107
loopTop->unmarkLoopAlign(this DEBUG_ARG("loop block appears before top of loop"));
5108+
madeChanges = true;
51025109
}
51035110
else
51045111
{
@@ -5116,6 +5123,7 @@ void Compiler::placeLoopAlignInstructions()
51165123

51175124
if (bbHavingAlign != nullptr)
51185125
{
5126+
madeChanges = true;
51195127
bbHavingAlign->bbFlags |= BBF_HAS_ALIGN;
51205128
}
51215129

@@ -5131,6 +5139,8 @@ void Compiler::placeLoopAlignInstructions()
51315139
}
51325140

51335141
assert(loopsToProcess == 0);
5142+
5143+
return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
51345144
}
51355145
#endif
51365146

src/coreclr/jit/compiler.h

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,11 +1377,20 @@ class TempDsc
13771377
}
13781378
};
13791379

1380+
// Specify compiler data that a phase might modify
1381+
enum class PhaseStatus : unsigned
1382+
{
1383+
MODIFIED_NOTHING, // Phase did not make any changes that warrant running post-phase checks or dumping
1384+
// the main jit data strutures.
1385+
MODIFIED_EVERYTHING, // Phase made changes that warrant running post-phase checks or dumping
1386+
// the main jit data strutures.
1387+
};
1388+
13801389
// interface to hide linearscan implementation from rest of compiler
13811390
class LinearScanInterface
13821391
{
13831392
public:
1384-
virtual void doLinearScan() = 0;
1393+
virtual PhaseStatus doLinearScan() = 0;
13851394
virtual void recordVarLocationsAtStartOfBB(BasicBlock* bb) = 0;
13861395
virtual bool willEnregisterLocalVars() const = 0;
13871396
#if TRACK_LSRA_STATS
@@ -1413,13 +1422,12 @@ enum class PhaseChecks
14131422
CHECK_ALL
14141423
};
14151424

1416-
// Specify compiler data that a phase might modify
1417-
enum class PhaseStatus : unsigned
1425+
// Specify which dumps should be run after each phase
1426+
//
1427+
enum class PhaseDumps
14181428
{
1419-
MODIFIED_NOTHING, // Phase did not make any changes that warrant running post-phase checks or dumping
1420-
// the main jit data strutures.
1421-
MODIFIED_EVERYTHING, // Phase made changes that warrant running post-phase checks or dumping
1422-
// the main jit data strutures.
1429+
DUMP_NONE,
1430+
DUMP_ALL
14231431
};
14241432

14251433
// The following enum provides a simple 1:1 mapping to CLR API's
@@ -2927,7 +2935,6 @@ class Compiler
29272935
#endif
29282936

29292937
BasicBlock* bbNewBasicBlock(BBjumpKinds jumpKind);
2930-
void placeLoopAlignInstructions();
29312938

29322939
/*
29332940
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -4633,7 +4640,11 @@ class Compiler
46334640

46344641
// Do "simple lowering." This functionality is (conceptually) part of "general"
46354642
// lowering that is distributed between fgMorph and the lowering phase of LSRA.
4636-
void fgSimpleLowering();
4643+
PhaseStatus fgSimpleLowering();
4644+
4645+
#if FEATURE_LOOP_ALIGN
4646+
PhaseStatus placeLoopAlignInstructions();
4647+
#endif
46374648

46384649
GenTree* fgInitThisClass();
46394650

@@ -5044,7 +5055,7 @@ class Compiler
50445055
template <typename CanRemoveBlockBody>
50455056
bool fgRemoveUnreachableBlocks(CanRemoveBlockBody canRemoveBlock);
50465057

5047-
void fgComputeReachability(); // Perform flow graph node reachability analysis.
5058+
PhaseStatus fgComputeReachability(); // Perform flow graph node reachability analysis.
50485059

50495060
bool fgRemoveDeadBlocks(); // Identify and remove dead blocks.
50505061

@@ -5958,6 +5969,7 @@ class Compiler
59585969
public:
59595970
void optInit();
59605971

5972+
PhaseStatus rangeCheckPhase();
59615973
GenTree* optRemoveRangeCheck(GenTreeBoundsChk* check, GenTree* comma, Statement* stmt);
59625974
GenTree* optRemoveStandaloneRangeCheck(GenTreeBoundsChk* check, Statement* stmt);
59635975
void optRemoveCommaBasedRangeCheck(GenTree* comma, Statement* stmt);
@@ -6693,7 +6705,7 @@ class Compiler
66936705
#define FMT_CSE "CSE #%02u"
66946706

66956707
public:
6696-
void optOptimizeValnumCSEs();
6708+
PhaseStatus optOptimizeValnumCSEs();
66976709

66986710
protected:
66996711
void optValnumCSE_Init();
@@ -6702,7 +6714,7 @@ class Compiler
67026714
void optValnumCSE_InitDataFlow();
67036715
void optValnumCSE_DataFlow();
67046716
void optValnumCSE_Availability();
6705-
void optValnumCSE_Heuristic();
6717+
bool optValnumCSE_Heuristic();
67066718

67076719
bool optDoCSE; // True when we have found a duplicate CSE tree
67086720
bool optValnumCSE_phase; // True when we are executing the optOptimizeValnumCSEs() phase
@@ -6775,16 +6787,16 @@ class Compiler
67756787
typedef JitHashTable<unsigned, JitSmallPrimitiveKeyFuncs<unsigned>, CopyPropSsaDefStack*> LclNumToLiveDefsMap;
67766788

67776789
// Copy propagation functions.
6778-
void optCopyProp(Statement* stmt, GenTreeLclVarCommon* tree, unsigned lclNum, LclNumToLiveDefsMap* curSsaName);
6790+
bool optCopyProp(Statement* stmt, GenTreeLclVarCommon* tree, unsigned lclNum, LclNumToLiveDefsMap* curSsaName);
67796791
void optBlockCopyPropPopStacks(BasicBlock* block, LclNumToLiveDefsMap* curSsaName);
6780-
void optBlockCopyProp(BasicBlock* block, LclNumToLiveDefsMap* curSsaName);
6792+
bool optBlockCopyProp(BasicBlock* block, LclNumToLiveDefsMap* curSsaName);
67816793
void optCopyPropPushDef(GenTree* defNode,
67826794
GenTreeLclVarCommon* lclNode,
67836795
unsigned lclNum,
67846796
LclNumToLiveDefsMap* curSsaName);
67856797
unsigned optIsSsaLocal(GenTreeLclVarCommon* lclNode);
67866798
int optCopyProp_LclVarScore(const LclVarDsc* lclVarDsc, const LclVarDsc* copyVarDsc, bool preferOp2);
6787-
void optVnCopyProp();
6799+
PhaseStatus optVnCopyProp();
67886800
INDEBUG(void optDumpCopyPropStack(LclNumToLiveDefsMap* curSsaName));
67896801

67906802
/**************************************************************************
@@ -7287,7 +7299,7 @@ class Compiler
72877299
void optAssertionRemove(AssertionIndex index);
72887300

72897301
// Assertion prop data flow functions.
7290-
void optAssertionPropMain();
7302+
PhaseStatus optAssertionPropMain();
72917303
Statement* optVNAssertionPropCurStmt(BasicBlock* block, Statement* stmt);
72927304
bool optIsTreeKnownIntValue(bool vnBased, GenTree* tree, ssize_t* pConstant, GenTreeFlags* pIconFlags);
72937305
ASSERT_TP* optInitAssertionDataflowFlags();
@@ -9873,6 +9885,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
98739885

98749886
Phases mostRecentlyActivePhase; // the most recently active phase
98759887
PhaseChecks activePhaseChecks; // the currently active phase checks
9888+
PhaseDumps activePhaseDumps; // the currently active phase dumps
98769889

98779890
//-------------------------------------------------------------------------
98789891
// The following keeps track of how many bytes of local frame space we've

0 commit comments

Comments
 (0)