Skip to content

Commit

Permalink
JIT: make global morph its own phase (#94185)
Browse files Browse the repository at this point in the history
Contributes to #93246.
  • Loading branch information
AndyAyersMS committed Oct 31, 2023
1 parent 18cb172 commit a7b0249
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 87 deletions.
22 changes: 12 additions & 10 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4747,9 +4747,10 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

// Morph the trees in all the blocks of the method
//
auto morphGlobalPhase = [this]() {
unsigned prevBBCount = fgBBcount;
fgMorphBlocks();
unsigned const preMorphBBCount = fgBBcount;
DoPhase(this, PHASE_MORPH_GLOBAL, &Compiler::fgMorphBlocks);

auto postMorphPhase = [this]() {

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

// If we needed to create any new BasicBlocks then renumber the blocks
if (fgBBcount > prevBBCount)
{
fgRenumberBlocks();
}

// Enable IR checks
activePhaseChecks |= PhaseChecks::CHECK_IR;
};
DoPhase(this, PHASE_MORPH_GLOBAL, morphGlobalPhase);
DoPhase(this, PHASE_POST_MORPH, postMorphPhase);

// If we needed to create any new BasicBlocks then renumber the blocks
//
if (fgBBcount > preMorphBBCount)
{
fgRenumberBlocks();
}

// GS security checks for unsafe buffers
//
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4797,8 +4797,9 @@ class Compiler

FoldResult fgFoldConditional(BasicBlock* block);

PhaseStatus fgMorphBlocks();
void fgMorphBlock(BasicBlock* block);
void fgMorphStmts(BasicBlock* block);
void fgMorphBlocks();

void fgMergeBlockReturn(BasicBlock* block);

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ CompPhaseNameMacro(PHASE_IMPBYREF_COPY_OMISSION, "Identify candidates for im
CompPhaseNameMacro(PHASE_MORPH_IMPBYREF, "Morph - ByRefs", false, -1, false)
CompPhaseNameMacro(PHASE_PROMOTE_STRUCTS, "Morph - Promote Structs", false, -1, false)
CompPhaseNameMacro(PHASE_MORPH_GLOBAL, "Morph - Global", false, -1, false)
CompPhaseNameMacro(PHASE_POST_MORPH, "Post-Morph", false, -1, false)
CompPhaseNameMacro(PHASE_MORPH_END, "Morph - Finish", false, -1, true)
CompPhaseNameMacro(PHASE_GS_COOKIE, "GS Cookie", false, -1, false)
CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1, false)",false, -1, false)
Expand Down
143 changes: 67 additions & 76 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13619,13 +13619,12 @@ void Compiler::fgMorphStmtBlockOps(BasicBlock* block, Statement* stmt)
}
}

/*****************************************************************************
*
* Morph the statements of the given block.
* This function should be called just once for a block. Use fgMorphBlockStmt()
* for reentrant calls.
*/

//------------------------------------------------------------------------
// fgMorphStmts: Morph all statements in a block
//
// Arguments:
// block - block in question
//
void Compiler::fgMorphStmts(BasicBlock* block)
{
fgRemoveRestOfBlock = false;
Expand Down Expand Up @@ -13809,36 +13808,65 @@ void Compiler::fgMorphStmts(BasicBlock* block)
fgRemoveRestOfBlock = false;
}

/*****************************************************************************
*
* Morph the blocks of the method.
* Returns true if the basic block list is modified.
* This function should be called just once.
*/

void Compiler::fgMorphBlocks()
//------------------------------------------------------------------------
// fgMorphBlock: Morph a basic block
//
// Arguments:
// block - block in question
//
void Compiler::fgMorphBlock(BasicBlock* block)
{
#ifdef DEBUG
if (verbose)
JITDUMP("\nMorphing " FMT_BB "\n", block->bbNum);

if (optLocalAssertionProp)
{
printf("\n*************** In fgMorphBlocks()\n");
// Clear out any currently recorded assertion candidates
// before processing each basic block,
// also we must handle QMARK-COLON specially
//
optAssertionReset(0);
}
#endif

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

fgGlobalMorph = true;
// Process all statement trees in the basic block.
fgMorphStmts(block);

// Do we need to merge the result of this block into a single return block?
if (block->KindIs(BBJ_RETURN) && ((block->bbFlags & BBF_HAS_JMP) == 0))
{
if ((genReturnBB != nullptr) && (genReturnBB != block))
{
fgMergeBlockReturn(block);
}
}

compCurBB = nullptr;
}

//------------------------------------------------------------------------
// fgMorphBlocks: Morph all blocks in the method
//
// Returns:
// Suitable phase status.
//
// Note:
// Morph almost always changes IR, so we don't actually bother to
// track if it made any changees.
//
PhaseStatus Compiler::fgMorphBlocks()
{
// This is the one and only global morph phase
//
fgGlobalMorph = true;

// Local assertion prop is enabled if we are optimized
//
optLocalAssertionProp = opts.OptimizationEnabled();

if (optLocalAssertionProp)
{
//
// Initialize for local assertion prop
//
optAssertionInit(true);
Expand All @@ -13862,53 +13890,16 @@ void Compiler::fgMorphBlocks()
fgEnsureFirstBBisScratch();
}

/*-------------------------------------------------------------------------
* Process all basic blocks in the function
*/

BasicBlock* block = fgFirstBB;
noway_assert(block);

do
// Morph all blocks.
//
// Note morph can add blocks downstream from the current block,
// and alter (but not null out) the current block's bbNext;
// this iterator ensures they all get visited.
//
for (BasicBlock* block : Blocks())
{
#ifdef DEBUG
if (verbose)
{
printf("\nMorphing " FMT_BB " of '%s'\n", block->bbNum, info.compFullName);
}
#endif

if (optLocalAssertionProp)
{
//
// Clear out any currently recorded assertion candidates
// before processing each basic block,
// also we must handle QMARK-COLON specially
//
optAssertionReset(0);
}

// Make the current basic block address available globally.
compCurBB = block;

// Process all statement trees in the basic block.
fgMorphStmts(block);

// Do we need to merge the result of this block into a single return block?
if (block->KindIs(BBJ_RETURN) && ((block->bbFlags & BBF_HAS_JMP) == 0))
{
if ((genReturnBB != nullptr) && (genReturnBB != block))
{
fgMergeBlockReturn(block);
}
}

block = block->Next();
} while (block != nullptr);

// We are done with the global morphing phase
fgGlobalMorph = false;
compCurBB = nullptr;
fgMorphBlock(block);
}

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

#ifdef DEBUG
if (verboseTrees)
{
fgDispBasicBlocks(true);
}
#endif
// We are done with the global morphing phase
//
fgGlobalMorph = false;
compCurBB = nullptr;

return PhaseStatus::MODIFIED_EVERYTHING;
}

//------------------------------------------------------------------------
Expand Down

0 comments on commit a7b0249

Please sign in to comment.