Skip to content

Commit

Permalink
Hoist the invariants out of multi-level nested loops (#68061)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
kunalspathak authored Jun 14, 2022
1 parent a361f7f commit 4fc6287
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 63 deletions.
37 changes: 19 additions & 18 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5931,13 +5931,11 @@ class Compiler
VNSet* m_pHoistedInCurLoop;

public:
// Value numbers of expressions that have been hoisted in parent loops in the loop nest.
VNSet m_hoistedInParentLoops;

// Value numbers of expressions that have been hoisted in the current (or most recent) loop in the nest.
// Previous decisions on loop-invariance of value numbers in the current loop.
VNSet m_curLoopVnInvariantCache;

// Get the VN cache for current loop
VNSet* GetHoistedInCurLoop(Compiler* comp)
{
if (m_pHoistedInCurLoop == nullptr)
Expand All @@ -5947,35 +5945,35 @@ class Compiler
return m_pHoistedInCurLoop;
}

VNSet* ExtractHoistedInCurLoop()
// Return the so far collected VNs in cache for current loop and reset it.
void ResetHoistedInCurLoop()
{
VNSet* res = m_pHoistedInCurLoop;
m_pHoistedInCurLoop = nullptr;
return res;
JITDUMP("Resetting m_pHoistedInCurLoop\n");
}

LoopHoistContext(Compiler* comp)
: m_pHoistedInCurLoop(nullptr)
, m_hoistedInParentLoops(comp->getAllocatorLoopHoist())
, m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist())
: m_pHoistedInCurLoop(nullptr), m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist())
{
}
};

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

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

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

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

// Returns the lpEntry for given preheader block of a loop
BasicBlock* optLoopEntry(BasicBlock* preHeader);

// Updates the loop table by changing loop "loopInd", whose head is required
// to be "from", to be "to". Also performs this transformation for any
// loop nested in "loopInd" that shares the same head as "loopInd".
Expand Down
Loading

0 comments on commit 4fc6287

Please sign in to comment.