1*0b57cec5SDimitry Andric //===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This pass performs lightweight instruction simplification on loop bodies. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/LoopInstSimplify.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/PointerIntPair.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 19*0b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h" 20*0b57cec5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h" 21*0b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 22*0b57cec5SDimitry Andric #include "llvm/Analysis/LoopIterator.h" 23*0b57cec5SDimitry Andric #include "llvm/Analysis/LoopPass.h" 24*0b57cec5SDimitry Andric #include "llvm/Analysis/MemorySSA.h" 25*0b57cec5SDimitry Andric #include "llvm/Analysis/MemorySSAUpdater.h" 26*0b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 27*0b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 28*0b57cec5SDimitry Andric #include "llvm/IR/CFG.h" 29*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 30*0b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 31*0b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 32*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 33*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 34*0b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 35*0b57cec5SDimitry Andric #include "llvm/IR/User.h" 36*0b57cec5SDimitry Andric #include "llvm/Pass.h" 37*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 38*0b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h" 39*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Local.h" 40*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h" 41*0b57cec5SDimitry Andric #include <algorithm> 42*0b57cec5SDimitry Andric #include <utility> 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric using namespace llvm; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric #define DEBUG_TYPE "loop-instsimplify" 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric STATISTIC(NumSimplified, "Number of redundant instructions simplified"); 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI, 51*0b57cec5SDimitry Andric AssumptionCache &AC, const TargetLibraryInfo &TLI, 52*0b57cec5SDimitry Andric MemorySSAUpdater *MSSAU) { 53*0b57cec5SDimitry Andric const DataLayout &DL = L.getHeader()->getModule()->getDataLayout(); 54*0b57cec5SDimitry Andric SimplifyQuery SQ(DL, &TLI, &DT, &AC); 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric // On the first pass over the loop body we try to simplify every instruction. 57*0b57cec5SDimitry Andric // On subsequent passes, we can restrict this to only simplifying instructions 58*0b57cec5SDimitry Andric // where the inputs have been updated. We end up needing two sets: one 59*0b57cec5SDimitry Andric // containing the instructions we are simplifying in *this* pass, and one for 60*0b57cec5SDimitry Andric // the instructions we will want to simplify in the *next* pass. We use 61*0b57cec5SDimitry Andric // pointers so we can swap between two stably allocated sets. 62*0b57cec5SDimitry Andric SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2; 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric // Track the PHI nodes that have already been visited during each iteration so 65*0b57cec5SDimitry Andric // that we can identify when it is necessary to iterate. 66*0b57cec5SDimitry Andric SmallPtrSet<PHINode *, 4> VisitedPHIs; 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric // While simplifying we may discover dead code or cause code to become dead. 69*0b57cec5SDimitry Andric // Keep track of all such instructions and we will delete them at the end. 70*0b57cec5SDimitry Andric SmallVector<Instruction *, 8> DeadInsts; 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric // First we want to create an RPO traversal of the loop body. By processing in 73*0b57cec5SDimitry Andric // RPO we can ensure that definitions are processed prior to uses (for non PHI 74*0b57cec5SDimitry Andric // uses) in all cases. This ensures we maximize the simplifications in each 75*0b57cec5SDimitry Andric // iteration over the loop and minimizes the possible causes for continuing to 76*0b57cec5SDimitry Andric // iterate. 77*0b57cec5SDimitry Andric LoopBlocksRPO RPOT(&L); 78*0b57cec5SDimitry Andric RPOT.perform(&LI); 79*0b57cec5SDimitry Andric MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr; 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric bool Changed = false; 82*0b57cec5SDimitry Andric for (;;) { 83*0b57cec5SDimitry Andric if (MSSAU && VerifyMemorySSA) 84*0b57cec5SDimitry Andric MSSA->verifyMemorySSA(); 85*0b57cec5SDimitry Andric for (BasicBlock *BB : RPOT) { 86*0b57cec5SDimitry Andric for (Instruction &I : *BB) { 87*0b57cec5SDimitry Andric if (auto *PI = dyn_cast<PHINode>(&I)) 88*0b57cec5SDimitry Andric VisitedPHIs.insert(PI); 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric if (I.use_empty()) { 91*0b57cec5SDimitry Andric if (isInstructionTriviallyDead(&I, &TLI)) 92*0b57cec5SDimitry Andric DeadInsts.push_back(&I); 93*0b57cec5SDimitry Andric continue; 94*0b57cec5SDimitry Andric } 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric // We special case the first iteration which we can detect due to the 97*0b57cec5SDimitry Andric // empty `ToSimplify` set. 98*0b57cec5SDimitry Andric bool IsFirstIteration = ToSimplify->empty(); 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric if (!IsFirstIteration && !ToSimplify->count(&I)) 101*0b57cec5SDimitry Andric continue; 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric Value *V = SimplifyInstruction(&I, SQ.getWithInstruction(&I)); 104*0b57cec5SDimitry Andric if (!V || !LI.replacementPreservesLCSSAForm(&I, V)) 105*0b57cec5SDimitry Andric continue; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); 108*0b57cec5SDimitry Andric UI != UE;) { 109*0b57cec5SDimitry Andric Use &U = *UI++; 110*0b57cec5SDimitry Andric auto *UserI = cast<Instruction>(U.getUser()); 111*0b57cec5SDimitry Andric U.set(V); 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric // If the instruction is used by a PHI node we have already processed 114*0b57cec5SDimitry Andric // we'll need to iterate on the loop body to converge, so add it to 115*0b57cec5SDimitry Andric // the next set. 116*0b57cec5SDimitry Andric if (auto *UserPI = dyn_cast<PHINode>(UserI)) 117*0b57cec5SDimitry Andric if (VisitedPHIs.count(UserPI)) { 118*0b57cec5SDimitry Andric Next->insert(UserPI); 119*0b57cec5SDimitry Andric continue; 120*0b57cec5SDimitry Andric } 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric // If we are only simplifying targeted instructions and the user is an 123*0b57cec5SDimitry Andric // instruction in the loop body, add it to our set of targeted 124*0b57cec5SDimitry Andric // instructions. Because we process defs before uses (outside of PHIs) 125*0b57cec5SDimitry Andric // we won't have visited it yet. 126*0b57cec5SDimitry Andric // 127*0b57cec5SDimitry Andric // We also skip any uses outside of the loop being simplified. Those 128*0b57cec5SDimitry Andric // should always be PHI nodes due to LCSSA form, and we don't want to 129*0b57cec5SDimitry Andric // try to simplify those away. 130*0b57cec5SDimitry Andric assert((L.contains(UserI) || isa<PHINode>(UserI)) && 131*0b57cec5SDimitry Andric "Uses outside the loop should be PHI nodes due to LCSSA!"); 132*0b57cec5SDimitry Andric if (!IsFirstIteration && L.contains(UserI)) 133*0b57cec5SDimitry Andric ToSimplify->insert(UserI); 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric if (MSSAU) 137*0b57cec5SDimitry Andric if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V)) 138*0b57cec5SDimitry Andric if (MemoryAccess *MA = MSSA->getMemoryAccess(&I)) 139*0b57cec5SDimitry Andric if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI)) 140*0b57cec5SDimitry Andric MA->replaceAllUsesWith(ReplacementMA); 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric assert(I.use_empty() && "Should always have replaced all uses!"); 143*0b57cec5SDimitry Andric if (isInstructionTriviallyDead(&I, &TLI)) 144*0b57cec5SDimitry Andric DeadInsts.push_back(&I); 145*0b57cec5SDimitry Andric ++NumSimplified; 146*0b57cec5SDimitry Andric Changed = true; 147*0b57cec5SDimitry Andric } 148*0b57cec5SDimitry Andric } 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric // Delete any dead instructions found thus far now that we've finished an 151*0b57cec5SDimitry Andric // iteration over all instructions in all the loop blocks. 152*0b57cec5SDimitry Andric if (!DeadInsts.empty()) { 153*0b57cec5SDimitry Andric Changed = true; 154*0b57cec5SDimitry Andric RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU); 155*0b57cec5SDimitry Andric } 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric if (MSSAU && VerifyMemorySSA) 158*0b57cec5SDimitry Andric MSSA->verifyMemorySSA(); 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric // If we never found a PHI that needs to be simplified in the next 161*0b57cec5SDimitry Andric // iteration, we're done. 162*0b57cec5SDimitry Andric if (Next->empty()) 163*0b57cec5SDimitry Andric break; 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric // Otherwise, put the next set in place for the next iteration and reset it 166*0b57cec5SDimitry Andric // and the visited PHIs for that iteration. 167*0b57cec5SDimitry Andric std::swap(Next, ToSimplify); 168*0b57cec5SDimitry Andric Next->clear(); 169*0b57cec5SDimitry Andric VisitedPHIs.clear(); 170*0b57cec5SDimitry Andric DeadInsts.clear(); 171*0b57cec5SDimitry Andric } 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric return Changed; 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric namespace { 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric class LoopInstSimplifyLegacyPass : public LoopPass { 179*0b57cec5SDimitry Andric public: 180*0b57cec5SDimitry Andric static char ID; // Pass ID, replacement for typeid 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric LoopInstSimplifyLegacyPass() : LoopPass(ID) { 183*0b57cec5SDimitry Andric initializeLoopInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry()); 184*0b57cec5SDimitry Andric } 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric bool runOnLoop(Loop *L, LPPassManager &LPM) override { 187*0b57cec5SDimitry Andric if (skipLoop(L)) 188*0b57cec5SDimitry Andric return false; 189*0b57cec5SDimitry Andric DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 190*0b57cec5SDimitry Andric LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 191*0b57cec5SDimitry Andric AssumptionCache &AC = 192*0b57cec5SDimitry Andric getAnalysis<AssumptionCacheTracker>().getAssumptionCache( 193*0b57cec5SDimitry Andric *L->getHeader()->getParent()); 194*0b57cec5SDimitry Andric const TargetLibraryInfo &TLI = 195*0b57cec5SDimitry Andric getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); 196*0b57cec5SDimitry Andric MemorySSA *MSSA = nullptr; 197*0b57cec5SDimitry Andric Optional<MemorySSAUpdater> MSSAU; 198*0b57cec5SDimitry Andric if (EnableMSSALoopDependency) { 199*0b57cec5SDimitry Andric MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); 200*0b57cec5SDimitry Andric MSSAU = MemorySSAUpdater(MSSA); 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric return simplifyLoopInst(*L, DT, LI, AC, TLI, 204*0b57cec5SDimitry Andric MSSAU.hasValue() ? MSSAU.getPointer() : nullptr); 205*0b57cec5SDimitry Andric } 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 208*0b57cec5SDimitry Andric AU.addRequired<AssumptionCacheTracker>(); 209*0b57cec5SDimitry Andric AU.addRequired<DominatorTreeWrapperPass>(); 210*0b57cec5SDimitry Andric AU.addRequired<TargetLibraryInfoWrapperPass>(); 211*0b57cec5SDimitry Andric AU.setPreservesCFG(); 212*0b57cec5SDimitry Andric if (EnableMSSALoopDependency) { 213*0b57cec5SDimitry Andric AU.addRequired<MemorySSAWrapperPass>(); 214*0b57cec5SDimitry Andric AU.addPreserved<MemorySSAWrapperPass>(); 215*0b57cec5SDimitry Andric } 216*0b57cec5SDimitry Andric getLoopAnalysisUsage(AU); 217*0b57cec5SDimitry Andric } 218*0b57cec5SDimitry Andric }; 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric } // end anonymous namespace 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM, 223*0b57cec5SDimitry Andric LoopStandardAnalysisResults &AR, 224*0b57cec5SDimitry Andric LPMUpdater &) { 225*0b57cec5SDimitry Andric Optional<MemorySSAUpdater> MSSAU; 226*0b57cec5SDimitry Andric if (AR.MSSA) { 227*0b57cec5SDimitry Andric MSSAU = MemorySSAUpdater(AR.MSSA); 228*0b57cec5SDimitry Andric AR.MSSA->verifyMemorySSA(); 229*0b57cec5SDimitry Andric } 230*0b57cec5SDimitry Andric if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI, 231*0b57cec5SDimitry Andric MSSAU.hasValue() ? MSSAU.getPointer() : nullptr)) 232*0b57cec5SDimitry Andric return PreservedAnalyses::all(); 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric auto PA = getLoopPassPreservedAnalyses(); 235*0b57cec5SDimitry Andric PA.preserveSet<CFGAnalyses>(); 236*0b57cec5SDimitry Andric if (EnableMSSALoopDependency) 237*0b57cec5SDimitry Andric PA.preserve<MemorySSAAnalysis>(); 238*0b57cec5SDimitry Andric return PA; 239*0b57cec5SDimitry Andric } 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andric char LoopInstSimplifyLegacyPass::ID = 0; 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(LoopInstSimplifyLegacyPass, "loop-instsimplify", 244*0b57cec5SDimitry Andric "Simplify instructions in loops", false, false) 245*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 246*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopPass) 247*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) 248*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 249*0b57cec5SDimitry Andric INITIALIZE_PASS_END(LoopInstSimplifyLegacyPass, "loop-instsimplify", 250*0b57cec5SDimitry Andric "Simplify instructions in loops", false, false) 251*0b57cec5SDimitry Andric 252*0b57cec5SDimitry Andric Pass *llvm::createLoopInstSimplifyPass() { 253*0b57cec5SDimitry Andric return new LoopInstSimplifyLegacyPass(); 254*0b57cec5SDimitry Andric } 255