Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: change loop inversion edge weight updates and add phase #48364

Merged
merged 7 commits into from
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4838,19 +4838,23 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags

if (opts.OptimizationEnabled())
{
// Invert loops
//
DoPhase(this, PHASE_INVERT_LOOPS, &Compiler::optInvertLoops);

// Optimize block order
//
DoPhase(this, PHASE_OPTIMIZE_LAYOUT, &Compiler::optOptimizeLayout);

// Compute reachability sets and dominators.
//
DoPhase(this, PHASE_COMPUTE_REACHABILITY, &Compiler::fgComputeReachability);

// Perform loop inversion (i.e. transform "while" loops into
// "repeat" loops) and discover and classify natural loops
// Discover and classify natural loops
// (e.g. mark iterative loops as such). Also marks loop blocks
// and sets bbWeight to the loop nesting levels
//
DoPhase(this, PHASE_OPTIMIZE_LOOPS, &Compiler::optOptimizeLoops);
DoPhase(this, PHASE_FIND_LOOPS, &Compiler::optFindLoops);

// Clone loops with optimization opportunities, and
// choose the one based on dynamic condition evaluation.
Expand Down Expand Up @@ -5299,10 +5303,8 @@ void Compiler::RecomputeLoopInfo()
block->bbFlags &= ~BBF_LOOP_FLAGS;
}
fgComputeReachability();
// Rebuild the loop tree annotations themselves. Since this is performed as
// part of 'optOptimizeLoops', this will also re-perform loop rotation, but
// not other optimizations, as the others are not part of 'optOptimizeLoops'.
optOptimizeLoops();
// Rebuild the loop tree annotations themselves
optFindLoops();
}

/*****************************************************************************/
Expand Down
17 changes: 10 additions & 7 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5383,7 +5383,7 @@ class Compiler
void fgComputeCalledCount(BasicBlock::weight_t returnWeight);
void fgComputeEdgeWeights();

void fgReorderBlocks();
bool fgReorderBlocks();

void fgDetermineFirstColdBlock();

Expand Down Expand Up @@ -5451,8 +5451,13 @@ class Compiler
void fgDebugCheckFlagsHelper(GenTree* tree, unsigned treeFlags, unsigned chkFlags);
void fgDebugCheckTryFinallyExits();
void fgDebugCheckProfileData();
bool fgDebugCheckIncomingProfileData(BasicBlock* block);
bool fgDebugCheckOutgoingProfileData(BasicBlock* block);
#endif

bool fgProfileWeightsEqual(BasicBlock::weight_t weight1, BasicBlock::weight_t weight2);
bool fgProfileWeightsConsistent(BasicBlock::weight_t weight1, BasicBlock::weight_t weight2);

static GenTree* fgGetFirstNode(GenTree* tree);

//--------------------- Walking the trees in the IR -----------------------
Expand Down Expand Up @@ -6119,11 +6124,9 @@ class Compiler
void optOptimizeBoolsGcStress(BasicBlock* condBlock);
#endif
public:
void optOptimizeLayout(); // Optimize the BasicBlock layout of the method

void optOptimizeLoops(); // for "while-do" loops duplicates simple loop conditions and transforms
// the loop into a "do-while" loop
// Also finds all natural loops and records them in the loop table
PhaseStatus optInvertLoops(); // Invert loops so they're entered at top and tested at bottom.
PhaseStatus optOptimizeLayout(); // Optimize the BasicBlock layout of the method
PhaseStatus optFindLoops(); // Finds loops and records them in the loop table

// Optionally clone loops in the loop table.
void optCloneLoops();
Expand Down Expand Up @@ -6449,7 +6452,7 @@ class Compiler
}
}

void fgOptWhileLoop(BasicBlock* block);
void optInvertWhileLoop(BasicBlock* block);

bool optComputeLoopRep(int constInit,
int constLimit,
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1, false
CompPhaseNameMacro(PHASE_CREATE_FUNCLETS, "Create EH funclets", "EH-FUNC", false, -1, false)
#endif // FEATURE_EH_FUNCLETS
CompPhaseNameMacro(PHASE_MERGE_THROWS, "Merge throw blocks", "MRGTHROW", false, -1, false)
CompPhaseNameMacro(PHASE_INVERT_LOOPS, "Invert loops", "LOOP-INV", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_LAYOUT, "Optimize layout", "LAYOUT", false, -1, false)
CompPhaseNameMacro(PHASE_COMPUTE_REACHABILITY, "Compute blocks reachability", "BL_REACH", false, -1, false)
CompPhaseNameMacro(PHASE_ZERO_INITS, "Redundant zero Inits", "ZERO-INIT", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_LOOPS, "Optimize loops", "LOOP-OPT", false, -1, false)
CompPhaseNameMacro(PHASE_FIND_LOOPS, "Find loops", "LOOP-FND", false, -1, false)
CompPhaseNameMacro(PHASE_CLONE_LOOPS, "Clone loops", "LP-CLONE", false, -1, false)
CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops", "UNROLL", false, -1, false)
CompPhaseNameMacro(PHASE_HOIST_LOOP_CODE, "Hoist loop code", "LP-HOIST", false, -1, false)
Expand Down
29 changes: 18 additions & 11 deletions src/coreclr/jit/fgopt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3661,15 +3661,17 @@ bool Compiler::fgOptimizeSwitchJumps()
#pragma warning(push)
#pragma warning(disable : 21000) // Suppress PREFast warning about overly large function
#endif
/*****************************************************************************
*
* Function called to reorder the flowgraph of BasicBlocks such that any
* rarely run blocks are placed at the end of the block list.
* If we have profile information we also use that information to reverse
* all conditional jumps that would benefit.
*/

void Compiler::fgReorderBlocks()
//-----------------------------------------------------------------------------
// fgReorderBlocks: reorder blocks to favor frequent fall through paths,
// move rare blocks to the end of the method/eh region, and move
// funclets to the ends of methods.
//
// Returns:
// True if anything got reordered. Reordering blocks may require changing
// IR to reverse branch conditions.
//
bool Compiler::fgReorderBlocks()
{
noway_assert(opts.compDbgCode == false);

Expand All @@ -3680,12 +3682,13 @@ void Compiler::fgReorderBlocks()
// We can't relocate anything if we only have one block
if (fgFirstBB->bbNext == nullptr)
{
return;
return false;
}

bool newRarelyRun = false;
bool movedBlocks = false;
bool optimizedSwitches = false;
bool optimizedBranches = false;

// First let us expand the set of run rarely blocks
newRarelyRun |= fgExpandRarelyRunBlocks();
Expand Down Expand Up @@ -4094,9 +4097,11 @@ void Compiler::fgReorderBlocks()
// Check for an unconditional branch to a conditional branch
// which also branches back to our next block
//
if (fgOptimizeBranch(bPrev))
const bool optimizedBranch = fgOptimizeBranch(bPrev);
if (optimizedBranch)
{
noway_assert(bPrev->bbJumpKind == BBJ_COND);
optimizedBranches = true;
}
continue;
}
Expand Down Expand Up @@ -4816,7 +4821,7 @@ void Compiler::fgReorderBlocks()

} // end of for loop(bPrev,block)

bool changed = movedBlocks || newRarelyRun || optimizedSwitches;
const bool changed = movedBlocks || newRarelyRun || optimizedSwitches || optimizedBranches;

if (changed)
{
Expand All @@ -4829,6 +4834,8 @@ void Compiler::fgReorderBlocks()
}
#endif // DEBUG
}

return changed;
}
#ifdef _PREFAST_
#pragma warning(pop)
Expand Down
Loading