Skip to content

Commit

Permalink
JIT: Add a head merging transformation alongside the tail merging tra…
Browse files Browse the repository at this point in the history
…nsformation (#90468)

Add a pass that does head merging to compliment the existing tail
merging pass. Unlike tail merging this requires reordering the first
statement with the terminator node of the predecessor, which requires
some interference checking.

The head merging is enabled only for BBJ_COND since the CQ benefit
for enabling it more generally does not seem to pay off. Additionally
we mainly try to target the IR produced by the importer due to spill
cliques, which usually happen with the IL that results from using
ternaries.

Fix #90017
  • Loading branch information
jakobbotsch authored Aug 18, 2023
1 parent 64243bb commit e9ce3aa
Show file tree
Hide file tree
Showing 11 changed files with 415 additions and 34 deletions.
5 changes: 5 additions & 0 deletions src/coreclr/jit/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ struct BasicBlock : private LIR::Range
return KindIs(kind) || KindIs(rest...);
}

bool HasTerminator()
{
return KindIs(BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHFILTERRET, BBJ_COND, BBJ_SWITCH, BBJ_RETURN);
}

// NumSucc() gives the number of successors, and GetSucc() returns a given numbered successor.
//
// There are two versions of these functions: ones that take a Compiler* and ones that don't. You must
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4718,7 +4718,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
{
// Tail merge
//
DoPhase(this, PHASE_TAIL_MERGE, &Compiler::fgTailMerge);
DoPhase(this, PHASE_HEAD_TAIL_MERGE, [this]() { return fgHeadTailMerge(true); });

// Merge common throw blocks
//
Expand Down Expand Up @@ -4835,7 +4835,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

// Second pass of tail merge
//
DoPhase(this, PHASE_TAIL_MERGE2, &Compiler::fgTailMerge);
DoPhase(this, PHASE_HEAD_TAIL_MERGE2, [this]() { return fgHeadTailMerge(false); });

// Compute reachability sets and dominators.
//
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5519,7 +5519,11 @@ class Compiler

void fgMoveBlocksAfter(BasicBlock* bStart, BasicBlock* bEnd, BasicBlock* insertAfterBlk);

PhaseStatus fgTailMerge();
PhaseStatus fgHeadTailMerge(bool early);
bool fgHeadMerge(BasicBlock* block, bool early);
bool fgTryOneHeadMerge(BasicBlock* block, bool early);
bool gtTreeContainsTailCall(GenTree* tree);
bool fgCanMoveFirstStatementIntoPred(bool early, Statement* firstStmt, BasicBlock* pred);

enum FG_RELOCATE_TYPE
{
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,8 @@ inline bool BasicBlock::HasPotentialEHSuccs(Compiler* comp)
return false;
}

// Throwing in a filter is the same as returning "continue search", which
// causes enclosed finally/fault handlers to be executed.
return hndDesc->InFilterRegionBBRange(this);
}

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1, f
#if defined(FEATURE_EH_FUNCLETS)
CompPhaseNameMacro(PHASE_CREATE_FUNCLETS, "Create EH funclets", false, -1, false)
#endif // FEATURE_EH_FUNCLETS
CompPhaseNameMacro(PHASE_TAIL_MERGE, "Tail merge", false, -1, false)
CompPhaseNameMacro(PHASE_HEAD_TAIL_MERGE, "Head and tail merge", false, -1, false)
CompPhaseNameMacro(PHASE_MERGE_THROWS, "Merge throw blocks", false, -1, false)
CompPhaseNameMacro(PHASE_INVERT_LOOPS, "Invert loops", false, -1, false)
CompPhaseNameMacro(PHASE_TAIL_MERGE2, "Post-morph tail merge", false, -1, false)
CompPhaseNameMacro(PHASE_HEAD_TAIL_MERGE2, "Post-morph head and tail merge", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_FLOW, "Optimize control flow", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_LAYOUT, "Optimize layout", false, -1, false)
CompPhaseNameMacro(PHASE_COMPUTE_REACHABILITY, "Compute blocks reachability", false, -1, false)
Expand Down
Loading

0 comments on commit e9ce3aa

Please sign in to comment.