Skip to content

Commit 4fc6287

Browse files
authored
Hoist the invariants out of multi-level nested loops (#68061)
* first working version * Skip check of VN hoisting * Account for duplicate blocks * clean up * wip * isCommaTree && hasExcep * revert lsra changes * Update hoisting condition - Only update if node to be hoisted has side-effects and the sibling that is before that throws exception * Change to BasicBlockList * organize preheaders * update hoistedInCurLoop and hoistedInSiblingLoop * Reverse the loop order * cleanup and jit-format * Revert "Minor fix to display IG01 weight correctly" This reverts commit 757120e863b2da188db2593da1b7142fd1ecf191. * simplify code * Remove m_hoistedVNInSiblingLoop * Add back ResetHoistedInCurLoop Fix igWeight * Remove reversal of loop processing order * jit format * Experimental: Also generate PerfScore: * review feedback * fix the superpmi script * Revert superpmi asmdiffs change * Rename method * Add a comment
1 parent a361f7f commit 4fc6287

File tree

2 files changed

+183
-63
lines changed

2 files changed

+183
-63
lines changed

src/coreclr/jit/compiler.h

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5931,13 +5931,11 @@ class Compiler
59315931
VNSet* m_pHoistedInCurLoop;
59325932

59335933
public:
5934-
// Value numbers of expressions that have been hoisted in parent loops in the loop nest.
5935-
VNSet m_hoistedInParentLoops;
5936-
59375934
// Value numbers of expressions that have been hoisted in the current (or most recent) loop in the nest.
59385935
// Previous decisions on loop-invariance of value numbers in the current loop.
59395936
VNSet m_curLoopVnInvariantCache;
59405937

5938+
// Get the VN cache for current loop
59415939
VNSet* GetHoistedInCurLoop(Compiler* comp)
59425940
{
59435941
if (m_pHoistedInCurLoop == nullptr)
@@ -5947,35 +5945,35 @@ class Compiler
59475945
return m_pHoistedInCurLoop;
59485946
}
59495947

5950-
VNSet* ExtractHoistedInCurLoop()
5948+
// Return the so far collected VNs in cache for current loop and reset it.
5949+
void ResetHoistedInCurLoop()
59515950
{
5952-
VNSet* res = m_pHoistedInCurLoop;
59535951
m_pHoistedInCurLoop = nullptr;
5954-
return res;
5952+
JITDUMP("Resetting m_pHoistedInCurLoop\n");
59555953
}
59565954

59575955
LoopHoistContext(Compiler* comp)
5958-
: m_pHoistedInCurLoop(nullptr)
5959-
, m_hoistedInParentLoops(comp->getAllocatorLoopHoist())
5960-
, m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist())
5956+
: m_pHoistedInCurLoop(nullptr), m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist())
59615957
{
59625958
}
59635959
};
59645960

5965-
// Do hoisting for loop "lnum" (an index into the optLoopTable), and all loops nested within it.
5966-
// Tracks the expressions that have been hoisted by containing loops by temporarily recording their
5967-
// value numbers in "m_hoistedInParentLoops". This set is not modified by the call.
5961+
// Do hoisting of all loops nested within loop "lnum" (an index into the optLoopTable), followed
5962+
// by the loop "lnum" itself.
5963+
//
5964+
// "m_pHoistedInCurLoop" helps a lot in eliminating duplicate expressions getting hoisted
5965+
// and reducing the count of total expressions hoisted out of loop. When calculating the
5966+
// profitability, we compare this with number of registers and hence, lower the number of expressions
5967+
// getting hoisted, better chances that they will get enregistered and CSE considering them.
5968+
//
59685969
void optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt);
59695970

59705971
// Do hoisting for a particular loop ("lnum" is an index into the optLoopTable.)
5971-
// Assumes that expressions have been hoisted in containing loops if their value numbers are in
5972-
// "m_hoistedInParentLoops".
5973-
//
5974-
void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt);
5972+
// Returns the new preheaders created.
5973+
void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt, BasicBlockList* existingPreHeaders);
59755974

59765975
// Hoist all expressions in "blocks" that are invariant in loop "loopNum" (an index into the optLoopTable)
5977-
// outside of that loop. Exempt expressions whose value number is in "m_hoistedInParentLoops"; add VN's of hoisted
5978-
// expressions to "hoistInLoop".
5976+
// outside of that loop.
59795977
void optHoistLoopBlocks(unsigned loopNum, ArrayStack<BasicBlock*>* blocks, LoopHoistContext* hoistContext);
59805978

59815979
// Return true if the tree looks profitable to hoist out of loop 'lnum'.
@@ -6358,6 +6356,9 @@ class Compiler
63586356
// A loop contains itself.
63596357
bool optLoopContains(unsigned l1, unsigned l2) const;
63606358

6359+
// Returns the lpEntry for given preheader block of a loop
6360+
BasicBlock* optLoopEntry(BasicBlock* preHeader);
6361+
63616362
// Updates the loop table by changing loop "loopInd", whose head is required
63626363
// to be "from", to be "to". Also performs this transformation for any
63636364
// loop nested in "loopInd" that shares the same head as "loopInd".

0 commit comments

Comments
 (0)