12754fe60SDimitry Andric //===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric //                     The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
102754fe60SDimitry Andric // This pass performs lightweight instruction simplification on loop bodies.
112754fe60SDimitry Andric //
122754fe60SDimitry Andric //===----------------------------------------------------------------------===//
132754fe60SDimitry Andric 
143ca95b02SDimitry Andric #include "llvm/Transforms/Scalar/LoopInstSimplify.h"
152cab237bSDimitry Andric #include "llvm/ADT/PointerIntPair.h"
16139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
172cab237bSDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
182cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
1991bc56edSDimitry Andric #include "llvm/ADT/Statistic.h"
2039d628a0SDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
212754fe60SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
222754fe60SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
234ba319b5SDimitry Andric #include "llvm/Analysis/LoopIterator.h"
242754fe60SDimitry Andric #include "llvm/Analysis/LoopPass.h"
25*b5893f02SDimitry Andric #include "llvm/Analysis/MemorySSA.h"
26*b5893f02SDimitry Andric #include "llvm/Analysis/MemorySSAUpdater.h"
273ca95b02SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
282cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h"
292cab237bSDimitry Andric #include "llvm/IR/CFG.h"
30139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
3191bc56edSDimitry Andric #include "llvm/IR/Dominators.h"
322cab237bSDimitry Andric #include "llvm/IR/Instruction.h"
33139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h"
342cab237bSDimitry Andric #include "llvm/IR/Module.h"
352cab237bSDimitry Andric #include "llvm/IR/PassManager.h"
362cab237bSDimitry Andric #include "llvm/IR/User.h"
372cab237bSDimitry Andric #include "llvm/Pass.h"
382cab237bSDimitry Andric #include "llvm/Support/Casting.h"
393ca95b02SDimitry Andric #include "llvm/Transforms/Scalar.h"
40*b5893f02SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
413ca95b02SDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h"
422cab237bSDimitry Andric #include <algorithm>
432cab237bSDimitry Andric #include <utility>
442cab237bSDimitry Andric 
452754fe60SDimitry Andric using namespace llvm;
462754fe60SDimitry Andric 
4791bc56edSDimitry Andric #define DEBUG_TYPE "loop-instsimplify"
4891bc56edSDimitry Andric 
492754fe60SDimitry Andric STATISTIC(NumSimplified, "Number of redundant instructions simplified");
502754fe60SDimitry Andric 
simplifyLoopInst(Loop & L,DominatorTree & DT,LoopInfo & LI,AssumptionCache & AC,const TargetLibraryInfo & TLI,MemorySSAUpdater * MSSAU)514ba319b5SDimitry Andric static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI,
52*b5893f02SDimitry Andric                              AssumptionCache &AC, const TargetLibraryInfo &TLI,
53*b5893f02SDimitry Andric                              MemorySSAUpdater *MSSAU) {
544ba319b5SDimitry Andric   const DataLayout &DL = L.getHeader()->getModule()->getDataLayout();
554ba319b5SDimitry Andric   SimplifyQuery SQ(DL, &TLI, &DT, &AC);
562754fe60SDimitry Andric 
574ba319b5SDimitry Andric   // On the first pass over the loop body we try to simplify every instruction.
584ba319b5SDimitry Andric   // On subsequent passes, we can restrict this to only simplifying instructions
594ba319b5SDimitry Andric   // where the inputs have been updated. We end up needing two sets: one
604ba319b5SDimitry Andric   // containing the instructions we are simplifying in *this* pass, and one for
614ba319b5SDimitry Andric   // the instructions we will want to simplify in the *next* pass. We use
624ba319b5SDimitry Andric   // pointers so we can swap between two stably allocated sets.
632754fe60SDimitry Andric   SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
642754fe60SDimitry Andric 
654ba319b5SDimitry Andric   // Track the PHI nodes that have already been visited during each iteration so
664ba319b5SDimitry Andric   // that we can identify when it is necessary to iterate.
674ba319b5SDimitry Andric   SmallPtrSet<PHINode *, 4> VisitedPHIs;
684ba319b5SDimitry Andric 
694ba319b5SDimitry Andric   // While simplifying we may discover dead code or cause code to become dead.
704ba319b5SDimitry Andric   // Keep track of all such instructions and we will delete them at the end.
714ba319b5SDimitry Andric   SmallVector<Instruction *, 8> DeadInsts;
724ba319b5SDimitry Andric 
734ba319b5SDimitry Andric   // First we want to create an RPO traversal of the loop body. By processing in
744ba319b5SDimitry Andric   // RPO we can ensure that definitions are processed prior to uses (for non PHI
754ba319b5SDimitry Andric   // uses) in all cases. This ensures we maximize the simplifications in each
764ba319b5SDimitry Andric   // iteration over the loop and minimizes the possible causes for continuing to
774ba319b5SDimitry Andric   // iterate.
784ba319b5SDimitry Andric   LoopBlocksRPO RPOT(&L);
794ba319b5SDimitry Andric   RPOT.perform(&LI);
80*b5893f02SDimitry Andric   MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr;
812754fe60SDimitry Andric 
822754fe60SDimitry Andric   bool Changed = false;
834ba319b5SDimitry Andric   for (;;) {
84*b5893f02SDimitry Andric     if (MSSAU && VerifyMemorySSA)
85*b5893f02SDimitry Andric       MSSA->verifyMemorySSA();
864ba319b5SDimitry Andric     for (BasicBlock *BB : RPOT) {
874ba319b5SDimitry Andric       for (Instruction &I : *BB) {
884ba319b5SDimitry Andric         if (auto *PI = dyn_cast<PHINode>(&I))
894ba319b5SDimitry Andric           VisitedPHIs.insert(PI);
902754fe60SDimitry Andric 
914ba319b5SDimitry Andric         if (I.use_empty()) {
924ba319b5SDimitry Andric           if (isInstructionTriviallyDead(&I, &TLI))
934ba319b5SDimitry Andric             DeadInsts.push_back(&I);
944ba319b5SDimitry Andric           continue;
954ba319b5SDimitry Andric         }
962754fe60SDimitry Andric 
974ba319b5SDimitry Andric         // We special case the first iteration which we can detect due to the
984ba319b5SDimitry Andric         // empty `ToSimplify` set.
994ba319b5SDimitry Andric         bool IsFirstIteration = ToSimplify->empty();
1002754fe60SDimitry Andric 
1014ba319b5SDimitry Andric         if (!IsFirstIteration && !ToSimplify->count(&I))
1022754fe60SDimitry Andric           continue;
1032754fe60SDimitry Andric 
1044ba319b5SDimitry Andric         Value *V = SimplifyInstruction(&I, SQ.getWithInstruction(&I));
1054ba319b5SDimitry Andric         if (!V || !LI.replacementPreservesLCSSAForm(&I, V))
1064ba319b5SDimitry Andric           continue;
1072754fe60SDimitry Andric 
1084ba319b5SDimitry Andric         for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
1094ba319b5SDimitry Andric              UI != UE;) {
1104ba319b5SDimitry Andric           Use &U = *UI++;
1114ba319b5SDimitry Andric           auto *UserI = cast<Instruction>(U.getUser());
1124ba319b5SDimitry Andric           U.set(V);
1134ba319b5SDimitry Andric 
1144ba319b5SDimitry Andric           // If the instruction is used by a PHI node we have already processed
1154ba319b5SDimitry Andric           // we'll need to iterate on the loop body to converge, so add it to
1164ba319b5SDimitry Andric           // the next set.
1174ba319b5SDimitry Andric           if (auto *UserPI = dyn_cast<PHINode>(UserI))
1184ba319b5SDimitry Andric             if (VisitedPHIs.count(UserPI)) {
1194ba319b5SDimitry Andric               Next->insert(UserPI);
1204ba319b5SDimitry Andric               continue;
1214ba319b5SDimitry Andric             }
1224ba319b5SDimitry Andric 
1234ba319b5SDimitry Andric           // If we are only simplifying targeted instructions and the user is an
1244ba319b5SDimitry Andric           // instruction in the loop body, add it to our set of targeted
1254ba319b5SDimitry Andric           // instructions. Because we process defs before uses (outside of PHIs)
1264ba319b5SDimitry Andric           // we won't have visited it yet.
1274ba319b5SDimitry Andric           //
1284ba319b5SDimitry Andric           // We also skip any uses outside of the loop being simplified. Those
1294ba319b5SDimitry Andric           // should always be PHI nodes due to LCSSA form, and we don't want to
1304ba319b5SDimitry Andric           // try to simplify those away.
1314ba319b5SDimitry Andric           assert((L.contains(UserI) || isa<PHINode>(UserI)) &&
1324ba319b5SDimitry Andric                  "Uses outside the loop should be PHI nodes due to LCSSA!");
1334ba319b5SDimitry Andric           if (!IsFirstIteration && L.contains(UserI))
1344ba319b5SDimitry Andric             ToSimplify->insert(UserI);
1354ba319b5SDimitry Andric         }
1364ba319b5SDimitry Andric 
137*b5893f02SDimitry Andric         if (MSSAU)
138*b5893f02SDimitry Andric           if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V))
139*b5893f02SDimitry Andric             if (MemoryAccess *MA = MSSA->getMemoryAccess(&I))
140*b5893f02SDimitry Andric               if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI))
141*b5893f02SDimitry Andric                 MA->replaceAllUsesWith(ReplacementMA);
142*b5893f02SDimitry Andric 
1434ba319b5SDimitry Andric         assert(I.use_empty() && "Should always have replaced all uses!");
1444ba319b5SDimitry Andric         if (isInstructionTriviallyDead(&I, &TLI))
1454ba319b5SDimitry Andric           DeadInsts.push_back(&I);
1462754fe60SDimitry Andric         ++NumSimplified;
1474ba319b5SDimitry Andric         Changed = true;
1482754fe60SDimitry Andric       }
1492754fe60SDimitry Andric     }
1502754fe60SDimitry Andric 
1514ba319b5SDimitry Andric     // Delete any dead instructions found thus far now that we've finished an
1524ba319b5SDimitry Andric     // iteration over all instructions in all the loop blocks.
1534ba319b5SDimitry Andric     if (!DeadInsts.empty()) {
1544ba319b5SDimitry Andric       Changed = true;
155*b5893f02SDimitry Andric       RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU);
1564ba319b5SDimitry Andric     }
1574ba319b5SDimitry Andric 
158*b5893f02SDimitry Andric     if (MSSAU && VerifyMemorySSA)
159*b5893f02SDimitry Andric       MSSA->verifyMemorySSA();
160*b5893f02SDimitry Andric 
1614ba319b5SDimitry Andric     // If we never found a PHI that needs to be simplified in the next
1624ba319b5SDimitry Andric     // iteration, we're done.
1634ba319b5SDimitry Andric     if (Next->empty())
1642754fe60SDimitry Andric       break;
1652754fe60SDimitry Andric 
1664ba319b5SDimitry Andric     // Otherwise, put the next set in place for the next iteration and reset it
1674ba319b5SDimitry Andric     // and the visited PHIs for that iteration.
1684ba319b5SDimitry Andric     std::swap(Next, ToSimplify);
1692754fe60SDimitry Andric     Next->clear();
1704ba319b5SDimitry Andric     VisitedPHIs.clear();
1714ba319b5SDimitry Andric     DeadInsts.clear();
1724ba319b5SDimitry Andric   }
1732754fe60SDimitry Andric 
1742754fe60SDimitry Andric   return Changed;
1752754fe60SDimitry Andric }
1763ca95b02SDimitry Andric 
1773ca95b02SDimitry Andric namespace {
1782cab237bSDimitry Andric 
1793ca95b02SDimitry Andric class LoopInstSimplifyLegacyPass : public LoopPass {
1803ca95b02SDimitry Andric public:
1813ca95b02SDimitry Andric   static char ID; // Pass ID, replacement for typeid
1822cab237bSDimitry Andric 
LoopInstSimplifyLegacyPass()1833ca95b02SDimitry Andric   LoopInstSimplifyLegacyPass() : LoopPass(ID) {
1843ca95b02SDimitry Andric     initializeLoopInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry());
1853ca95b02SDimitry Andric   }
1863ca95b02SDimitry Andric 
runOnLoop(Loop * L,LPPassManager & LPM)1873ca95b02SDimitry Andric   bool runOnLoop(Loop *L, LPPassManager &LPM) override {
1883ca95b02SDimitry Andric     if (skipLoop(L))
1893ca95b02SDimitry Andric       return false;
1904ba319b5SDimitry Andric     DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1914ba319b5SDimitry Andric     LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1924ba319b5SDimitry Andric     AssumptionCache &AC =
1934ba319b5SDimitry Andric         getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
1943ca95b02SDimitry Andric             *L->getHeader()->getParent());
1954ba319b5SDimitry Andric     const TargetLibraryInfo &TLI =
1964ba319b5SDimitry Andric         getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
197*b5893f02SDimitry Andric     MemorySSA *MSSA = nullptr;
198*b5893f02SDimitry Andric     Optional<MemorySSAUpdater> MSSAU;
199*b5893f02SDimitry Andric     if (EnableMSSALoopDependency) {
200*b5893f02SDimitry Andric       MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
201*b5893f02SDimitry Andric       MSSAU = MemorySSAUpdater(MSSA);
202*b5893f02SDimitry Andric     }
2033ca95b02SDimitry Andric 
204*b5893f02SDimitry Andric     return simplifyLoopInst(*L, DT, LI, AC, TLI,
205*b5893f02SDimitry Andric                             MSSAU.hasValue() ? MSSAU.getPointer() : nullptr);
2063ca95b02SDimitry Andric   }
2073ca95b02SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const2083ca95b02SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
2093ca95b02SDimitry Andric     AU.addRequired<AssumptionCacheTracker>();
2104ba319b5SDimitry Andric     AU.addRequired<DominatorTreeWrapperPass>();
2113ca95b02SDimitry Andric     AU.addRequired<TargetLibraryInfoWrapperPass>();
2123ca95b02SDimitry Andric     AU.setPreservesCFG();
213*b5893f02SDimitry Andric     if (EnableMSSALoopDependency) {
214*b5893f02SDimitry Andric       AU.addRequired<MemorySSAWrapperPass>();
215*b5893f02SDimitry Andric       AU.addPreserved<MemorySSAWrapperPass>();
216*b5893f02SDimitry Andric     }
2173ca95b02SDimitry Andric     getLoopAnalysisUsage(AU);
2183ca95b02SDimitry Andric   }
2193ca95b02SDimitry Andric };
2202cab237bSDimitry Andric 
2212cab237bSDimitry Andric } // end anonymous namespace
2223ca95b02SDimitry Andric 
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater &)223f1a29dd3SDimitry Andric PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
224f1a29dd3SDimitry Andric                                             LoopStandardAnalysisResults &AR,
225f1a29dd3SDimitry Andric                                             LPMUpdater &) {
226*b5893f02SDimitry Andric   Optional<MemorySSAUpdater> MSSAU;
227*b5893f02SDimitry Andric   if (AR.MSSA) {
228*b5893f02SDimitry Andric     MSSAU = MemorySSAUpdater(AR.MSSA);
229*b5893f02SDimitry Andric     AR.MSSA->verifyMemorySSA();
230*b5893f02SDimitry Andric   }
231*b5893f02SDimitry Andric   if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI,
232*b5893f02SDimitry Andric                         MSSAU.hasValue() ? MSSAU.getPointer() : nullptr))
2333ca95b02SDimitry Andric     return PreservedAnalyses::all();
2343ca95b02SDimitry Andric 
2357a7e6055SDimitry Andric   auto PA = getLoopPassPreservedAnalyses();
2367a7e6055SDimitry Andric   PA.preserveSet<CFGAnalyses>();
2377a7e6055SDimitry Andric   return PA;
2383ca95b02SDimitry Andric }
2393ca95b02SDimitry Andric 
2403ca95b02SDimitry Andric char LoopInstSimplifyLegacyPass::ID = 0;
2412cab237bSDimitry Andric 
2423ca95b02SDimitry Andric INITIALIZE_PASS_BEGIN(LoopInstSimplifyLegacyPass, "loop-instsimplify",
2433ca95b02SDimitry Andric                       "Simplify instructions in loops", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)2443ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
2453ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopPass)
246*b5893f02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
2473ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
2483ca95b02SDimitry Andric INITIALIZE_PASS_END(LoopInstSimplifyLegacyPass, "loop-instsimplify",
2493ca95b02SDimitry Andric                     "Simplify instructions in loops", false, false)
2503ca95b02SDimitry Andric 
2513ca95b02SDimitry Andric Pass *llvm::createLoopInstSimplifyPass() {
2523ca95b02SDimitry Andric   return new LoopInstSimplifyLegacyPass();
2533ca95b02SDimitry Andric }
254