@@ -213,9 +213,15 @@ static Instruction *cloneInstructionInExitBlock(
213213static void eraseInstruction (Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
214214 MemorySSAUpdater &MSSAU);
215215
216- static void moveInstructionBefore (Instruction &I, BasicBlock::iterator Dest,
217- ICFLoopSafetyInfo &SafetyInfo,
218- MemorySSAUpdater &MSSAU, ScalarEvolution *SE);
216+ static void moveInstructionBefore (
217+ Instruction &I, BasicBlock::iterator Dest, ICFLoopSafetyInfo &SafetyInfo,
218+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
219+ MemorySSA::InsertionPlace Point = MemorySSA::BeforeTerminator);
220+
221+ static bool sinkUnusedInvariantsFromPreheaderToExit (
222+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
223+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
224+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE);
219225
220226static void foreachMemoryAccess (MemorySSA *MSSA, Loop *L,
221227 function_ref<void (Instruction *)> Fn);
@@ -473,6 +479,12 @@ bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI,
473479 TLI, TTI, L, MSSAU, &SafetyInfo, Flags, ORE)
474480 : sinkRegion (DT->getNode (L->getHeader ()), AA, LI, DT, TLI, TTI, L,
475481 MSSAU, &SafetyInfo, Flags, ORE);
482+
483+ // sink pre-header defs that are unused in-loop into the unique exit to reduce
484+ // pressure.
485+ Changed |= sinkUnusedInvariantsFromPreheaderToExit (L, AA, &SafetyInfo, MSSAU,
486+ SE, DT, Flags, ORE);
487+
476488 Flags.setIsSink (false );
477489 if (Preheader)
478490 Changed |= hoistRegion (DT->getNode (L->getHeader ()), AA, LI, DT, AC, TLI, L,
@@ -1460,19 +1472,80 @@ static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo,
14601472
14611473static void moveInstructionBefore (Instruction &I, BasicBlock::iterator Dest,
14621474 ICFLoopSafetyInfo &SafetyInfo,
1463- MemorySSAUpdater &MSSAU,
1464- ScalarEvolution *SE ) {
1475+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
1476+ MemorySSA::InsertionPlace Point ) {
14651477 SafetyInfo.removeInstruction (&I);
14661478 SafetyInfo.insertInstructionTo (&I, Dest->getParent ());
14671479 I.moveBefore (*Dest->getParent (), Dest);
14681480 if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
14691481 MSSAU.getMemorySSA ()->getMemoryAccess (&I)))
1470- MSSAU.moveToPlace (OldMemAcc, Dest->getParent (),
1471- MemorySSA::BeforeTerminator);
1482+ MSSAU.moveToPlace (OldMemAcc, Dest->getParent (), Point);
14721483 if (SE)
14731484 SE->forgetBlockAndLoopDispositions (&I);
14741485}
14751486
1487+ // If there's a single exit block, sink any loop-invariant values that were
1488+ // defined in the preheader but not used inside the loop into the exit block
1489+ // to reduce register pressure in the loop.
1490+ static bool sinkUnusedInvariantsFromPreheaderToExit (
1491+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
1492+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
1493+ SinkAndHoistLICMFlags &SinkFlags, OptimizationRemarkEmitter *ORE) {
1494+ BasicBlock *ExitBlock = L->getExitBlock ();
1495+ if (!ExitBlock)
1496+ return false ;
1497+
1498+ BasicBlock *Preheader = L->getLoopPreheader ();
1499+ if (!Preheader)
1500+ return false ;
1501+
1502+ bool MadeAnyChanges = false ;
1503+
1504+ for (Instruction &I : llvm::make_early_inc_range (llvm::reverse (*Preheader))) {
1505+
1506+ // Skip terminator.
1507+ if (Preheader->getTerminator () == &I)
1508+ continue ;
1509+
1510+ // New instructions were inserted at the end of the preheader.
1511+ if (isa<PHINode>(I))
1512+ break ;
1513+
1514+ // Don't move instructions which might have side effects, since the side
1515+ // effects need to complete before instructions inside the loop. Note that
1516+ // it's okay if the instruction might have undefined behavior: LoopSimplify
1517+ // guarantees that the preheader dominates the exit block.
1518+ if (I.mayHaveSideEffects ())
1519+ continue ;
1520+
1521+ if (!canSinkOrHoistInst (I, AA, DT, L, MSSAU, true , SinkFlags, nullptr ))
1522+ continue ;
1523+
1524+ // Determine if there is a use in or before the loop (direct or
1525+ // otherwise).
1526+ bool UsedInLoopOrPreheader = false ;
1527+ for (Use &U : I.uses ()) {
1528+ auto *UserI = cast<Instruction>(U.getUser ());
1529+ BasicBlock *UseBB = UserI->getParent ();
1530+ if (auto *PN = dyn_cast<PHINode>(UserI)) {
1531+ UseBB = PN->getIncomingBlock (U);
1532+ }
1533+ if (UseBB == Preheader || L->contains (UseBB)) {
1534+ UsedInLoopOrPreheader = true ;
1535+ break ;
1536+ }
1537+ }
1538+ if (UsedInLoopOrPreheader)
1539+ continue ;
1540+
1541+ moveInstructionBefore (I, ExitBlock->getFirstInsertionPt (), *SafetyInfo,
1542+ MSSAU, SE, MemorySSA::Beginning);
1543+ MadeAnyChanges = true ;
1544+ }
1545+
1546+ return MadeAnyChanges;
1547+ }
1548+
14761549static Instruction *sinkThroughTriviallyReplaceablePHI (
14771550 PHINode *TPN, Instruction *I, LoopInfo *LI,
14781551 SmallDenseMap<BasicBlock *, Instruction *, 32 > &SunkCopies,
0 commit comments