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. 715ffd83dbSDimitry Andric SmallVector<WeakTrackingVH, 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 108349cc55cSDimitry Andric for (Use &U : llvm::make_early_inc_range(I.uses())) { 109*0b57cec5SDimitry Andric auto *UserI = cast<Instruction>(U.getUser()); 110*0b57cec5SDimitry Andric U.set(V); 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric // If the instruction is used by a PHI node we have already processed 113*0b57cec5SDimitry Andric // we'll need to iterate on the loop body to converge, so add it to 114*0b57cec5SDimitry Andric // the next set. 115*0b57cec5SDimitry Andric if (auto *UserPI = dyn_cast<PHINode>(UserI)) 116*0b57cec5SDimitry Andric if (VisitedPHIs.count(UserPI)) { 117*0b57cec5SDimitry Andric Next->insert(UserPI); 118*0b57cec5SDimitry Andric continue; 119*0b57cec5SDimitry Andric } 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric // If we are only simplifying targeted instructions and the user is an 122*0b57cec5SDimitry Andric // instruction in the loop body, add it to our set of targeted 123*0b57cec5SDimitry Andric // instructions. Because we process defs before uses (outside of PHIs) 124*0b57cec5SDimitry Andric // we won't have visited it yet. 125*0b57cec5SDimitry Andric // 126*0b57cec5SDimitry Andric // We also skip any uses outside of the loop being simplified. Those 127*0b57cec5SDimitry Andric // should always be PHI nodes due to LCSSA form, and we don't want to 128*0b57cec5SDimitry Andric // try to simplify those away. 129*0b57cec5SDimitry Andric assert((L.contains(UserI) || isa<PHINode>(UserI)) && 130*0b57cec5SDimitry Andric "Uses outside the loop should be PHI nodes due to LCSSA!"); 131*0b57cec5SDimitry Andric if (!IsFirstIteration && L.contains(UserI)) 132*0b57cec5SDimitry Andric ToSimplify->insert(UserI); 133*0b57cec5SDimitry Andric } 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric if (MSSAU) 136*0b57cec5SDimitry Andric if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V)) 137*0b57cec5SDimitry Andric if (MemoryAccess *MA = MSSA->getMemoryAccess(&I)) 138*0b57cec5SDimitry Andric if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI)) 139*0b57cec5SDimitry Andric MA->replaceAllUsesWith(ReplacementMA); 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric assert(I.use_empty() && "Should always have replaced all uses!"); 142*0b57cec5SDimitry Andric if (isInstructionTriviallyDead(&I, &TLI)) 143*0b57cec5SDimitry Andric DeadInsts.push_back(&I); 144*0b57cec5SDimitry Andric ++NumSimplified; 145*0b57cec5SDimitry Andric Changed = true; 146*0b57cec5SDimitry Andric } 147*0b57cec5SDimitry Andric } 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric // Delete any dead instructions found thus far now that we've finished an 150*0b57cec5SDimitry Andric // iteration over all instructions in all the loop blocks. 151*0b57cec5SDimitry Andric if (!DeadInsts.empty()) { 152*0b57cec5SDimitry Andric Changed = true; 153*0b57cec5SDimitry Andric RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU); 154*0b57cec5SDimitry Andric } 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric if (MSSAU && VerifyMemorySSA) 157*0b57cec5SDimitry Andric MSSA->verifyMemorySSA(); 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric // If we never found a PHI that needs to be simplified in the next 160*0b57cec5SDimitry Andric // iteration, we're done. 161*0b57cec5SDimitry Andric if (Next->empty()) 162*0b57cec5SDimitry Andric break; 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric // Otherwise, put the next set in place for the next iteration and reset it 165*0b57cec5SDimitry Andric // and the visited PHIs for that iteration. 166*0b57cec5SDimitry Andric std::swap(Next, ToSimplify); 167*0b57cec5SDimitry Andric Next->clear(); 168*0b57cec5SDimitry Andric VisitedPHIs.clear(); 169*0b57cec5SDimitry Andric DeadInsts.clear(); 170*0b57cec5SDimitry Andric } 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric return Changed; 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric namespace { 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andric class LoopInstSimplifyLegacyPass : public LoopPass { 178*0b57cec5SDimitry Andric public: 179*0b57cec5SDimitry Andric static char ID; // Pass ID, replacement for typeid 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric LoopInstSimplifyLegacyPass() : LoopPass(ID) { 182*0b57cec5SDimitry Andric initializeLoopInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry()); 183*0b57cec5SDimitry Andric } 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric bool runOnLoop(Loop *L, LPPassManager &LPM) override { 186*0b57cec5SDimitry Andric if (skipLoop(L)) 187*0b57cec5SDimitry Andric return false; 188*0b57cec5SDimitry Andric DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 189*0b57cec5SDimitry Andric LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 190*0b57cec5SDimitry Andric AssumptionCache &AC = 191*0b57cec5SDimitry Andric getAnalysis<AssumptionCacheTracker>().getAssumptionCache( 192*0b57cec5SDimitry Andric *L->getHeader()->getParent()); 193*0b57cec5SDimitry Andric const TargetLibraryInfo &TLI = 1948bcb0991SDimitry Andric getAnalysis<TargetLibraryInfoWrapperPass>().getTLI( 1958bcb0991SDimitry Andric *L->getHeader()->getParent()); 196349cc55cSDimitry Andric MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); 197349cc55cSDimitry Andric MemorySSAUpdater MSSAU(MSSA); 198*0b57cec5SDimitry Andric 199349cc55cSDimitry Andric return simplifyLoopInst(*L, DT, LI, AC, TLI, &MSSAU); 200*0b57cec5SDimitry Andric } 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 203*0b57cec5SDimitry Andric AU.addRequired<AssumptionCacheTracker>(); 204*0b57cec5SDimitry Andric AU.addRequired<DominatorTreeWrapperPass>(); 205*0b57cec5SDimitry Andric AU.addRequired<TargetLibraryInfoWrapperPass>(); 206*0b57cec5SDimitry Andric AU.setPreservesCFG(); 207*0b57cec5SDimitry Andric AU.addRequired<MemorySSAWrapperPass>(); 208*0b57cec5SDimitry Andric AU.addPreserved<MemorySSAWrapperPass>(); 209*0b57cec5SDimitry Andric getLoopAnalysisUsage(AU); 210*0b57cec5SDimitry Andric } 211*0b57cec5SDimitry Andric }; 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric } // end anonymous namespace 214*0b57cec5SDimitry Andric 215*0b57cec5SDimitry Andric PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM, 216*0b57cec5SDimitry Andric LoopStandardAnalysisResults &AR, 217*0b57cec5SDimitry Andric LPMUpdater &) { 218*0b57cec5SDimitry Andric Optional<MemorySSAUpdater> MSSAU; 219*0b57cec5SDimitry Andric if (AR.MSSA) { 220*0b57cec5SDimitry Andric MSSAU = MemorySSAUpdater(AR.MSSA); 221480093f4SDimitry Andric if (VerifyMemorySSA) 222*0b57cec5SDimitry Andric AR.MSSA->verifyMemorySSA(); 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI, 225*0b57cec5SDimitry Andric MSSAU.hasValue() ? MSSAU.getPointer() : nullptr)) 226*0b57cec5SDimitry Andric return PreservedAnalyses::all(); 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric auto PA = getLoopPassPreservedAnalyses(); 229*0b57cec5SDimitry Andric PA.preserveSet<CFGAnalyses>(); 2308bcb0991SDimitry Andric if (AR.MSSA) 231*0b57cec5SDimitry Andric PA.preserve<MemorySSAAnalysis>(); 232*0b57cec5SDimitry Andric return PA; 233*0b57cec5SDimitry Andric } 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric char LoopInstSimplifyLegacyPass::ID = 0; 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(LoopInstSimplifyLegacyPass, "loop-instsimplify", 238*0b57cec5SDimitry Andric "Simplify instructions in loops", false, false) 239*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 240*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopPass) 241*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) 242*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 243*0b57cec5SDimitry Andric INITIALIZE_PASS_END(LoopInstSimplifyLegacyPass, "loop-instsimplify", 244*0b57cec5SDimitry Andric "Simplify instructions in loops", false, false) 245*0b57cec5SDimitry Andric 246*0b57cec5SDimitry Andric Pass *llvm::createLoopInstSimplifyPass() { 247*0b57cec5SDimitry Andric return new LoopInstSimplifyLegacyPass(); 248*0b57cec5SDimitry Andric } 249