Skip to content

Commit a7b0249

Browse files
authored
JIT: make global morph its own phase (#94185)
Contributes to #93246.
1 parent 18cb172 commit a7b0249

File tree

4 files changed

+82
-87
lines changed

4 files changed

+82
-87
lines changed

src/coreclr/jit/compiler.cpp

+12-10
Original file line numberDiff line numberDiff line change
@@ -4747,9 +4747,10 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
47474747

47484748
// Morph the trees in all the blocks of the method
47494749
//
4750-
auto morphGlobalPhase = [this]() {
4751-
unsigned prevBBCount = fgBBcount;
4752-
fgMorphBlocks();
4750+
unsigned const preMorphBBCount = fgBBcount;
4751+
DoPhase(this, PHASE_MORPH_GLOBAL, &Compiler::fgMorphBlocks);
4752+
4753+
auto postMorphPhase = [this]() {
47534754

47544755
// Fix any LclVar annotations on discarded struct promotion temps for implicit by-ref args
47554756
fgMarkDemotedImplicitByRefArgs();
@@ -4765,16 +4766,17 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
47654766
compCurBB = nullptr;
47664767
#endif // DEBUG
47674768

4768-
// If we needed to create any new BasicBlocks then renumber the blocks
4769-
if (fgBBcount > prevBBCount)
4770-
{
4771-
fgRenumberBlocks();
4772-
}
4773-
47744769
// Enable IR checks
47754770
activePhaseChecks |= PhaseChecks::CHECK_IR;
47764771
};
4777-
DoPhase(this, PHASE_MORPH_GLOBAL, morphGlobalPhase);
4772+
DoPhase(this, PHASE_POST_MORPH, postMorphPhase);
4773+
4774+
// If we needed to create any new BasicBlocks then renumber the blocks
4775+
//
4776+
if (fgBBcount > preMorphBBCount)
4777+
{
4778+
fgRenumberBlocks();
4779+
}
47784780

47794781
// GS security checks for unsafe buffers
47804782
//

src/coreclr/jit/compiler.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -4797,8 +4797,9 @@ class Compiler
47974797

47984798
FoldResult fgFoldConditional(BasicBlock* block);
47994799

4800+
PhaseStatus fgMorphBlocks();
4801+
void fgMorphBlock(BasicBlock* block);
48004802
void fgMorphStmts(BasicBlock* block);
4801-
void fgMorphBlocks();
48024803

48034804
void fgMergeBlockReturn(BasicBlock* block);
48044805

src/coreclr/jit/compphases.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ CompPhaseNameMacro(PHASE_IMPBYREF_COPY_OMISSION, "Identify candidates for im
4949
CompPhaseNameMacro(PHASE_MORPH_IMPBYREF, "Morph - ByRefs", false, -1, false)
5050
CompPhaseNameMacro(PHASE_PROMOTE_STRUCTS, "Morph - Promote Structs", false, -1, false)
5151
CompPhaseNameMacro(PHASE_MORPH_GLOBAL, "Morph - Global", false, -1, false)
52+
CompPhaseNameMacro(PHASE_POST_MORPH, "Post-Morph", false, -1, false)
5253
CompPhaseNameMacro(PHASE_MORPH_END, "Morph - Finish", false, -1, true)
5354
CompPhaseNameMacro(PHASE_GS_COOKIE, "GS Cookie", false, -1, false)
5455
CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1, false)",false, -1, false)

src/coreclr/jit/morph.cpp

+67-76
Original file line numberDiff line numberDiff line change
@@ -13619,13 +13619,12 @@ void Compiler::fgMorphStmtBlockOps(BasicBlock* block, Statement* stmt)
1361913619
}
1362013620
}
1362113621

13622-
/*****************************************************************************
13623-
*
13624-
* Morph the statements of the given block.
13625-
* This function should be called just once for a block. Use fgMorphBlockStmt()
13626-
* for reentrant calls.
13627-
*/
13628-
13622+
//------------------------------------------------------------------------
13623+
// fgMorphStmts: Morph all statements in a block
13624+
//
13625+
// Arguments:
13626+
// block - block in question
13627+
//
1362913628
void Compiler::fgMorphStmts(BasicBlock* block)
1363013629
{
1363113630
fgRemoveRestOfBlock = false;
@@ -13809,36 +13808,65 @@ void Compiler::fgMorphStmts(BasicBlock* block)
1380913808
fgRemoveRestOfBlock = false;
1381013809
}
1381113810

13812-
/*****************************************************************************
13813-
*
13814-
* Morph the blocks of the method.
13815-
* Returns true if the basic block list is modified.
13816-
* This function should be called just once.
13817-
*/
13818-
13819-
void Compiler::fgMorphBlocks()
13811+
//------------------------------------------------------------------------
13812+
// fgMorphBlock: Morph a basic block
13813+
//
13814+
// Arguments:
13815+
// block - block in question
13816+
//
13817+
void Compiler::fgMorphBlock(BasicBlock* block)
1382013818
{
13821-
#ifdef DEBUG
13822-
if (verbose)
13819+
JITDUMP("\nMorphing " FMT_BB "\n", block->bbNum);
13820+
13821+
if (optLocalAssertionProp)
1382313822
{
13824-
printf("\n*************** In fgMorphBlocks()\n");
13823+
// Clear out any currently recorded assertion candidates
13824+
// before processing each basic block,
13825+
// also we must handle QMARK-COLON specially
13826+
//
13827+
optAssertionReset(0);
1382513828
}
13826-
#endif
1382713829

13828-
/* Since fgMorphTree can be called after various optimizations to re-arrange
13829-
* the nodes we need a global flag to signal if we are during the one-pass
13830-
* global morphing */
13830+
// Make the current basic block address available globally.
13831+
compCurBB = block;
1383113832

13832-
fgGlobalMorph = true;
13833+
// Process all statement trees in the basic block.
13834+
fgMorphStmts(block);
13835+
13836+
// Do we need to merge the result of this block into a single return block?
13837+
if (block->KindIs(BBJ_RETURN) && ((block->bbFlags & BBF_HAS_JMP) == 0))
13838+
{
13839+
if ((genReturnBB != nullptr) && (genReturnBB != block))
13840+
{
13841+
fgMergeBlockReturn(block);
13842+
}
13843+
}
1383313844

13845+
compCurBB = nullptr;
13846+
}
13847+
13848+
//------------------------------------------------------------------------
13849+
// fgMorphBlocks: Morph all blocks in the method
13850+
//
13851+
// Returns:
13852+
// Suitable phase status.
13853+
//
13854+
// Note:
13855+
// Morph almost always changes IR, so we don't actually bother to
13856+
// track if it made any changees.
13857+
//
13858+
PhaseStatus Compiler::fgMorphBlocks()
13859+
{
13860+
// This is the one and only global morph phase
1383413861
//
13862+
fgGlobalMorph = true;
13863+
1383513864
// Local assertion prop is enabled if we are optimized
1383613865
//
1383713866
optLocalAssertionProp = opts.OptimizationEnabled();
1383813867

1383913868
if (optLocalAssertionProp)
1384013869
{
13841-
//
1384213870
// Initialize for local assertion prop
1384313871
//
1384413872
optAssertionInit(true);
@@ -13862,53 +13890,16 @@ void Compiler::fgMorphBlocks()
1386213890
fgEnsureFirstBBisScratch();
1386313891
}
1386413892

13865-
/*-------------------------------------------------------------------------
13866-
* Process all basic blocks in the function
13867-
*/
13868-
13869-
BasicBlock* block = fgFirstBB;
13870-
noway_assert(block);
13871-
13872-
do
13893+
// Morph all blocks.
13894+
//
13895+
// Note morph can add blocks downstream from the current block,
13896+
// and alter (but not null out) the current block's bbNext;
13897+
// this iterator ensures they all get visited.
13898+
//
13899+
for (BasicBlock* block : Blocks())
1387313900
{
13874-
#ifdef DEBUG
13875-
if (verbose)
13876-
{
13877-
printf("\nMorphing " FMT_BB " of '%s'\n", block->bbNum, info.compFullName);
13878-
}
13879-
#endif
13880-
13881-
if (optLocalAssertionProp)
13882-
{
13883-
//
13884-
// Clear out any currently recorded assertion candidates
13885-
// before processing each basic block,
13886-
// also we must handle QMARK-COLON specially
13887-
//
13888-
optAssertionReset(0);
13889-
}
13890-
13891-
// Make the current basic block address available globally.
13892-
compCurBB = block;
13893-
13894-
// Process all statement trees in the basic block.
13895-
fgMorphStmts(block);
13896-
13897-
// Do we need to merge the result of this block into a single return block?
13898-
if (block->KindIs(BBJ_RETURN) && ((block->bbFlags & BBF_HAS_JMP) == 0))
13899-
{
13900-
if ((genReturnBB != nullptr) && (genReturnBB != block))
13901-
{
13902-
fgMergeBlockReturn(block);
13903-
}
13904-
}
13905-
13906-
block = block->Next();
13907-
} while (block != nullptr);
13908-
13909-
// We are done with the global morphing phase
13910-
fgGlobalMorph = false;
13911-
compCurBB = nullptr;
13901+
fgMorphBlock(block);
13902+
}
1391213903

1391313904
// Under OSR, we no longer need to specially protect the original method entry
1391413905
//
@@ -13924,12 +13915,12 @@ void Compiler::fgMorphBlocks()
1392413915
fgEntryBB = nullptr;
1392513916
}
1392613917

13927-
#ifdef DEBUG
13928-
if (verboseTrees)
13929-
{
13930-
fgDispBasicBlocks(true);
13931-
}
13932-
#endif
13918+
// We are done with the global morphing phase
13919+
//
13920+
fgGlobalMorph = false;
13921+
compCurBB = nullptr;
13922+
13923+
return PhaseStatus::MODIFIED_EVERYTHING;
1393313924
}
1393413925

1393513926
//------------------------------------------------------------------------

0 commit comments

Comments
 (0)