@@ -215,6 +215,11 @@ static void moveInstructionBefore(Instruction &I, BasicBlock::iterator Dest,
215215 ICFLoopSafetyInfo &SafetyInfo,
216216 MemorySSAUpdater &MSSAU, ScalarEvolution *SE);
217217
218+ static bool sinkUnusedInvariantsFromPreheaderToExit (
219+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
220+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
221+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE);
222+
218223static void foreachMemoryAccess (MemorySSA *MSSA, Loop *L,
219224 function_ref<void (Instruction *)> Fn);
220225using PointersAndHasReadsOutsideSet =
@@ -471,6 +476,12 @@ bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI,
471476 TLI, TTI, L, MSSAU, &SafetyInfo, Flags, ORE)
472477 : sinkRegion (DT->getNode (L->getHeader ()), AA, LI, DT, TLI, TTI, L,
473478 MSSAU, &SafetyInfo, Flags, ORE);
479+
480+ // sink pre-header defs that are unused in-loop into the unique exit to reduce
481+ // pressure.
482+ Changed |= sinkUnusedInvariantsFromPreheaderToExit (L, AA, &SafetyInfo, MSSAU,
483+ SE, DT, Flags, ORE);
484+
474485 Flags.setIsSink (false );
475486 if (Preheader)
476487 Changed |= hoistRegion (DT->getNode (L->getHeader ()), AA, LI, DT, AC, TLI, L,
@@ -1469,6 +1480,118 @@ static void moveInstructionBefore(Instruction &I, BasicBlock::iterator Dest,
14691480 SE->forgetBlockAndLoopDispositions (&I);
14701481}
14711482
1483+ // If there's a single exit block, sink any loop-invariant values that were
1484+ // defined in the preheader but not used inside the loop into the exit block
1485+ // to reduce register pressure in the loop.
1486+ static bool sinkUnusedInvariantsFromPreheaderToExit (
1487+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
1488+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
1489+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE) {
1490+ BasicBlock *ExitBlock = L->getExitBlock ();
1491+ if (!ExitBlock)
1492+ return false ;
1493+
1494+ BasicBlock *Preheader = L->getLoopPreheader ();
1495+ if (!Preheader)
1496+ return false ;
1497+
1498+ bool MadeAnyChanges = false ;
1499+ MemoryAccess *ExitDef = nullptr ;
1500+
1501+ for (Instruction &I : llvm::make_early_inc_range (llvm::reverse (*Preheader))) {
1502+
1503+ // Skip terminator.
1504+ if (Preheader->getTerminator () == &I)
1505+ continue ;
1506+
1507+ // New instructions were inserted at the end of the preheader.
1508+ if (isa<PHINode>(I))
1509+ break ;
1510+
1511+ // Don't move instructions which might have side effects, since the side
1512+ // effects need to complete before instructions inside the loop. Note that
1513+ // it's okay if the instruction might have undefined behavior: LoopSimplify
1514+ // guarantees that the preheader dominates the exit block.
1515+ if (I.mayHaveSideEffects ())
1516+ continue ;
1517+
1518+ if (!canSinkOrHoistInst (I, AA, DT, L, MSSAU, true , SinkFlags, nullptr ))
1519+ continue ;
1520+
1521+ // Determine if there is a use in or before the loop (direct or
1522+ // otherwise).
1523+ bool UsedInLoopOrPreheader = false ;
1524+ for (Use &U : I.uses ()) {
1525+ auto *UserI = cast<Instruction>(U.getUser ());
1526+ BasicBlock *UseBB = UserI->getParent ();
1527+ if (auto *PN = dyn_cast<PHINode>(UserI)) {
1528+ UseBB = PN->getIncomingBlock (U);
1529+ }
1530+ if (UseBB == Preheader || L->contains (UseBB)) {
1531+ UsedInLoopOrPreheader = true ;
1532+ break ;
1533+ }
1534+ }
1535+ if (UsedInLoopOrPreheader)
1536+ continue ;
1537+
1538+ // Move the instruction.
1539+ SafetyInfo->removeInstruction (&I);
1540+ SafetyInfo->insertInstructionTo (&I, ExitBlock);
1541+ I.moveBefore (*ExitBlock, ExitBlock->getFirstInsertionPt ());
1542+ if (SE)
1543+ SE->forgetBlockAndLoopDispositions (&I);
1544+
1545+ // Update MemorySSA.
1546+ if (auto *OldMA = MSSAU.getMemorySSA ()->getMemoryAccess (&I)) {
1547+ // apviding the expensive getPreviousDefRecursive call by manually
1548+ // setting the defining access.
1549+ if (!ExitDef) {
1550+ if (auto *MPhi = MSSAU.getMemorySSA ()->getMemoryAccess (ExitBlock)) {
1551+ ExitDef = MPhi;
1552+ } else {
1553+ BasicBlock *Current = *predecessors (ExitBlock).begin ();
1554+ while (true ) {
1555+ if (auto *Accesses =
1556+ MSSAU.getMemorySSA ()->getBlockAccesses (Current)) {
1557+ if (!Accesses->empty ()) {
1558+ MemoryAccess *Back =
1559+ const_cast <MemoryAccess *>(&Accesses->back ());
1560+ if (isa<MemoryDef>(Back) || isa<MemoryPhi>(Back))
1561+ ExitDef = Back;
1562+ else
1563+ ExitDef = MSSAU.getMemorySSA ()
1564+ ->getWalker ()
1565+ ->getClobberingMemoryAccess (Back);
1566+ break ;
1567+ }
1568+ }
1569+
1570+ if (Current == L->getHeader ()) {
1571+ Current = Preheader;
1572+ continue ;
1573+ }
1574+
1575+ if (pred_empty (Current)) {
1576+ ExitDef = MSSAU.getMemorySSA ()->getLiveOnEntryDef ();
1577+ break ;
1578+ }
1579+ Current = *pred_begin (Current);
1580+ }
1581+ }
1582+ }
1583+ MemoryAccess *NewMA = MSSAU.createMemoryAccessInBB (&I, ExitDef, ExitBlock,
1584+ MemorySSA::Beginning);
1585+ OldMA->replaceAllUsesWith (NewMA);
1586+ MSSAU.removeMemoryAccess (OldMA);
1587+ }
1588+
1589+ MadeAnyChanges = true ;
1590+ }
1591+
1592+ return MadeAnyChanges;
1593+ }
1594+
14721595static Instruction *sinkThroughTriviallyReplaceablePHI (
14731596 PHINode *TPN, Instruction *I, LoopInfo *LI,
14741597 SmallDenseMap<BasicBlock *, Instruction *, 32 > &SunkCopies,
0 commit comments