@@ -211,9 +211,15 @@ static Instruction *cloneInstructionInExitBlock(
211211static void eraseInstruction (Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
212212 MemorySSAUpdater &MSSAU);
213213
214- static void moveInstructionBefore (Instruction &I, BasicBlock::iterator Dest,
215- ICFLoopSafetyInfo &SafetyInfo,
216- MemorySSAUpdater &MSSAU, ScalarEvolution *SE);
214+ static void moveInstructionBefore (
215+ Instruction &I, BasicBlock::iterator Dest, ICFLoopSafetyInfo &SafetyInfo,
216+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
217+ MemorySSA::InsertionPlace Point = MemorySSA::BeforeTerminator);
218+
219+ static bool sinkUnusedInvariantsFromPreheaderToExit (
220+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
221+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
222+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE);
217223
218224static void foreachMemoryAccess (MemorySSA *MSSA, Loop *L,
219225 function_ref<void (Instruction *)> Fn);
@@ -471,6 +477,12 @@ bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI,
471477 TLI, TTI, L, MSSAU, &SafetyInfo, Flags, ORE)
472478 : sinkRegion (DT->getNode (L->getHeader ()), AA, LI, DT, TLI, TTI, L,
473479 MSSAU, &SafetyInfo, Flags, ORE);
480+
481+ // sink pre-header defs that are unused in-loop into the unique exit to reduce
482+ // pressure.
483+ Changed |= sinkUnusedInvariantsFromPreheaderToExit (L, AA, &SafetyInfo, MSSAU,
484+ SE, DT, Flags, ORE);
485+
474486 Flags.setIsSink (false );
475487 if (Preheader)
476488 Changed |= hoistRegion (DT->getNode (L->getHeader ()), AA, LI, DT, AC, TLI, L,
@@ -1456,19 +1468,80 @@ static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
14561468
14571469static void moveInstructionBefore (Instruction &I, BasicBlock::iterator Dest,
14581470 ICFLoopSafetyInfo &SafetyInfo,
1459- MemorySSAUpdater &MSSAU,
1460- ScalarEvolution *SE ) {
1471+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
1472+ MemorySSA::InsertionPlace Point ) {
14611473 SafetyInfo.removeInstruction (&I);
14621474 SafetyInfo.insertInstructionTo (&I, Dest->getParent ());
14631475 I.moveBefore (*Dest->getParent (), Dest);
14641476 if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
14651477 MSSAU.getMemorySSA ()->getMemoryAccess (&I)))
1466- MSSAU.moveToPlace (OldMemAcc, Dest->getParent (),
1467- MemorySSA::BeforeTerminator);
1478+ MSSAU.moveToPlace (OldMemAcc, Dest->getParent (), Point);
14681479 if (SE)
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+
1500+ for (Instruction &I : llvm::make_early_inc_range (llvm::reverse (*Preheader))) {
1501+
1502+ // Skip terminator.
1503+ if (Preheader->getTerminator () == &I)
1504+ continue ;
1505+
1506+ // New instructions were inserted at the end of the preheader.
1507+ if (isa<PHINode>(I))
1508+ break ;
1509+
1510+ // Don't move instructions which might have side effects, since the side
1511+ // effects need to complete before instructions inside the loop. Note that
1512+ // it's okay if the instruction might have undefined behavior: LoopSimplify
1513+ // guarantees that the preheader dominates the exit block.
1514+ if (I.mayHaveSideEffects ())
1515+ continue ;
1516+
1517+ if (!canSinkOrHoistInst (I, AA, DT, L, MSSAU, true , SinkFlags, nullptr ))
1518+ continue ;
1519+
1520+ // Determine if there is a use in or before the loop (direct or
1521+ // otherwise).
1522+ bool UsedInLoopOrPreheader = false ;
1523+ for (Use &U : I.uses ()) {
1524+ auto *UserI = cast<Instruction>(U.getUser ());
1525+ BasicBlock *UseBB = UserI->getParent ();
1526+ if (auto *PN = dyn_cast<PHINode>(UserI)) {
1527+ UseBB = PN->getIncomingBlock (U);
1528+ }
1529+ if (UseBB == Preheader || L->contains (UseBB)) {
1530+ UsedInLoopOrPreheader = true ;
1531+ break ;
1532+ }
1533+ }
1534+ if (UsedInLoopOrPreheader)
1535+ continue ;
1536+
1537+ moveInstructionBefore (I, ExitBlock->getFirstInsertionPt (), *SafetyInfo,
1538+ MSSAU, SE, MemorySSA::Beginning);
1539+ MadeAnyChanges = true ;
1540+ }
1541+
1542+ return MadeAnyChanges;
1543+ }
1544+
14721545static Instruction *sinkThroughTriviallyReplaceablePHI (
14731546 PHINode *TPN, Instruction *I, LoopInfo *LI,
14741547 SmallDenseMap<BasicBlock *, Instruction *, 32 > &SunkCopies,
0 commit comments