@@ -207,9 +207,15 @@ static Instruction *cloneInstructionInExitBlock(
207207static void eraseInstruction (Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
208208 MemorySSAUpdater &MSSAU);
209209
210- static void moveInstructionBefore (Instruction &I, BasicBlock::iterator Dest,
211- ICFLoopSafetyInfo &SafetyInfo,
212- MemorySSAUpdater &MSSAU, ScalarEvolution *SE);
210+ static void moveInstructionBefore (
211+ Instruction &I, BasicBlock::iterator Dest, ICFLoopSafetyInfo &SafetyInfo,
212+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
213+ MemorySSA::InsertionPlace Point = MemorySSA::BeforeTerminator);
214+
215+ static bool sinkUnusedInvariantsFromPreheaderToExit (
216+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
217+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
218+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE);
213219
214220static void foreachMemoryAccess (MemorySSA *MSSA, Loop *L,
215221 function_ref<void (Instruction *)> Fn);
@@ -468,6 +474,12 @@ bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI,
468474 TLI, TTI, L, MSSAU, &SafetyInfo, Flags, ORE)
469475 : sinkRegion (DT->getNode (L->getHeader ()), AA, LI, DT, TLI, TTI, L,
470476 MSSAU, &SafetyInfo, Flags, ORE);
477+
478+ // sink pre-header defs that are unused in-loop into the unique exit to reduce
479+ // pressure.
480+ Changed |= sinkUnusedInvariantsFromPreheaderToExit (L, AA, &SafetyInfo, MSSAU,
481+ SE, DT, Flags, ORE);
482+
471483 Flags.setIsSink (false );
472484 if (Preheader)
473485 Changed |= hoistRegion (DT->getNode (L->getHeader ()), AA, LI, DT, AC, TLI, L,
@@ -1441,19 +1453,80 @@ static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
14411453
14421454static void moveInstructionBefore (Instruction &I, BasicBlock::iterator Dest,
14431455 ICFLoopSafetyInfo &SafetyInfo,
1444- MemorySSAUpdater &MSSAU,
1445- ScalarEvolution *SE ) {
1456+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
1457+ MemorySSA::InsertionPlace Point ) {
14461458 SafetyInfo.removeInstruction (&I);
14471459 SafetyInfo.insertInstructionTo (&I, Dest->getParent ());
14481460 I.moveBefore (*Dest->getParent (), Dest);
14491461 if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
14501462 MSSAU.getMemorySSA ()->getMemoryAccess (&I)))
1451- MSSAU.moveToPlace (OldMemAcc, Dest->getParent (),
1452- MemorySSA::BeforeTerminator);
1463+ MSSAU.moveToPlace (OldMemAcc, Dest->getParent (), Point);
14531464 if (SE)
14541465 SE->forgetBlockAndLoopDispositions (&I);
14551466}
14561467
1468+ // If there's a single exit block, sink any loop-invariant values that were
1469+ // defined in the preheader but not used inside the loop into the exit block
1470+ // to reduce register pressure in the loop.
1471+ static bool sinkUnusedInvariantsFromPreheaderToExit (
1472+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
1473+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
1474+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE) {
1475+ BasicBlock *ExitBlock = L->getExitBlock ();
1476+ if (!ExitBlock)
1477+ return false ;
1478+
1479+ BasicBlock *Preheader = L->getLoopPreheader ();
1480+ if (!Preheader)
1481+ return false ;
1482+
1483+ bool MadeAnyChanges = false ;
1484+
1485+ for (Instruction &I : llvm::make_early_inc_range (llvm::reverse (*Preheader))) {
1486+
1487+ // Skip terminator.
1488+ if (Preheader->getTerminator () == &I)
1489+ continue ;
1490+
1491+ // New instructions were inserted at the end of the preheader.
1492+ if (isa<PHINode>(I))
1493+ break ;
1494+
1495+ // Don't move instructions which might have side effects, since the side
1496+ // effects need to complete before instructions inside the loop. Note that
1497+ // it's okay if the instruction might have undefined behavior: LoopSimplify
1498+ // guarantees that the preheader dominates the exit block.
1499+ if (I.mayHaveSideEffects ())
1500+ continue ;
1501+
1502+ if (!canSinkOrHoistInst (I, AA, DT, L, MSSAU, true , SinkFlags, nullptr ))
1503+ continue ;
1504+
1505+ // Determine if there is a use in or before the loop (direct or
1506+ // otherwise).
1507+ bool UsedInLoopOrPreheader = false ;
1508+ for (Use &U : I.uses ()) {
1509+ auto *UserI = cast<Instruction>(U.getUser ());
1510+ BasicBlock *UseBB = UserI->getParent ();
1511+ if (auto *PN = dyn_cast<PHINode>(UserI)) {
1512+ UseBB = PN->getIncomingBlock (U);
1513+ }
1514+ if (UseBB == Preheader || L->contains (UseBB)) {
1515+ UsedInLoopOrPreheader = true ;
1516+ break ;
1517+ }
1518+ }
1519+ if (UsedInLoopOrPreheader)
1520+ continue ;
1521+
1522+ moveInstructionBefore (I, ExitBlock->getFirstInsertionPt (), *SafetyInfo,
1523+ MSSAU, SE, MemorySSA::Beginning);
1524+ MadeAnyChanges = true ;
1525+ }
1526+
1527+ return MadeAnyChanges;
1528+ }
1529+
14571530static Instruction *sinkThroughTriviallyReplaceablePHI (
14581531 PHINode *TPN, Instruction *I, LoopInfo *LI,
14591532 SmallDenseMap<BasicBlock *, Instruction *, 32 > &SunkCopies,
0 commit comments