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