10b57cec5SDimitry Andric //===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This pass performs lightweight instruction simplification on loop bodies. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/LoopInstSimplify.h" 140b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 150b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 170b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 180b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h" 190b57cec5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h" 200b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 210b57cec5SDimitry Andric #include "llvm/Analysis/LoopIterator.h" 220b57cec5SDimitry Andric #include "llvm/Analysis/LoopPass.h" 230b57cec5SDimitry Andric #include "llvm/Analysis/MemorySSA.h" 240b57cec5SDimitry Andric #include "llvm/Analysis/MemorySSAUpdater.h" 250b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 260b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 270b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 280b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 290b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 300b57cec5SDimitry Andric #include "llvm/IR/Module.h" 310b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 320b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 330b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h" 340b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Local.h" 350b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h" 36bdd1243dSDimitry Andric #include <optional> 370b57cec5SDimitry Andric #include <utility> 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric using namespace llvm; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric #define DEBUG_TYPE "loop-instsimplify" 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric STATISTIC(NumSimplified, "Number of redundant instructions simplified"); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI, 460b57cec5SDimitry Andric AssumptionCache &AC, const TargetLibraryInfo &TLI, 470b57cec5SDimitry Andric MemorySSAUpdater *MSSAU) { 48*0fca6ea1SDimitry Andric const DataLayout &DL = L.getHeader()->getDataLayout(); 490b57cec5SDimitry Andric SimplifyQuery SQ(DL, &TLI, &DT, &AC); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric // On the first pass over the loop body we try to simplify every instruction. 520b57cec5SDimitry Andric // On subsequent passes, we can restrict this to only simplifying instructions 530b57cec5SDimitry Andric // where the inputs have been updated. We end up needing two sets: one 540b57cec5SDimitry Andric // containing the instructions we are simplifying in *this* pass, and one for 550b57cec5SDimitry Andric // the instructions we will want to simplify in the *next* pass. We use 560b57cec5SDimitry Andric // pointers so we can swap between two stably allocated sets. 570b57cec5SDimitry Andric SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric // Track the PHI nodes that have already been visited during each iteration so 600b57cec5SDimitry Andric // that we can identify when it is necessary to iterate. 610b57cec5SDimitry Andric SmallPtrSet<PHINode *, 4> VisitedPHIs; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // While simplifying we may discover dead code or cause code to become dead. 640b57cec5SDimitry Andric // Keep track of all such instructions and we will delete them at the end. 655ffd83dbSDimitry Andric SmallVector<WeakTrackingVH, 8> DeadInsts; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // First we want to create an RPO traversal of the loop body. By processing in 680b57cec5SDimitry Andric // RPO we can ensure that definitions are processed prior to uses (for non PHI 690b57cec5SDimitry Andric // uses) in all cases. This ensures we maximize the simplifications in each 700b57cec5SDimitry Andric // iteration over the loop and minimizes the possible causes for continuing to 710b57cec5SDimitry Andric // iterate. 720b57cec5SDimitry Andric LoopBlocksRPO RPOT(&L); 730b57cec5SDimitry Andric RPOT.perform(&LI); 740b57cec5SDimitry Andric MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric bool Changed = false; 770b57cec5SDimitry Andric for (;;) { 780b57cec5SDimitry Andric if (MSSAU && VerifyMemorySSA) 790b57cec5SDimitry Andric MSSA->verifyMemorySSA(); 800b57cec5SDimitry Andric for (BasicBlock *BB : RPOT) { 810b57cec5SDimitry Andric for (Instruction &I : *BB) { 820b57cec5SDimitry Andric if (auto *PI = dyn_cast<PHINode>(&I)) 830b57cec5SDimitry Andric VisitedPHIs.insert(PI); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric if (I.use_empty()) { 860b57cec5SDimitry Andric if (isInstructionTriviallyDead(&I, &TLI)) 870b57cec5SDimitry Andric DeadInsts.push_back(&I); 880b57cec5SDimitry Andric continue; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric // We special case the first iteration which we can detect due to the 920b57cec5SDimitry Andric // empty `ToSimplify` set. 930b57cec5SDimitry Andric bool IsFirstIteration = ToSimplify->empty(); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric if (!IsFirstIteration && !ToSimplify->count(&I)) 960b57cec5SDimitry Andric continue; 970b57cec5SDimitry Andric 9881ad6265SDimitry Andric Value *V = simplifyInstruction(&I, SQ.getWithInstruction(&I)); 990b57cec5SDimitry Andric if (!V || !LI.replacementPreservesLCSSAForm(&I, V)) 1000b57cec5SDimitry Andric continue; 1010b57cec5SDimitry Andric 102349cc55cSDimitry Andric for (Use &U : llvm::make_early_inc_range(I.uses())) { 1030b57cec5SDimitry Andric auto *UserI = cast<Instruction>(U.getUser()); 1040b57cec5SDimitry Andric U.set(V); 1050b57cec5SDimitry Andric 10681ad6265SDimitry Andric // Do not bother dealing with unreachable code. 10781ad6265SDimitry Andric if (!DT.isReachableFromEntry(UserI->getParent())) 10881ad6265SDimitry Andric continue; 10981ad6265SDimitry Andric 1100b57cec5SDimitry Andric // If the instruction is used by a PHI node we have already processed 1110b57cec5SDimitry Andric // we'll need to iterate on the loop body to converge, so add it to 1120b57cec5SDimitry Andric // the next set. 1130b57cec5SDimitry Andric if (auto *UserPI = dyn_cast<PHINode>(UserI)) 1140b57cec5SDimitry Andric if (VisitedPHIs.count(UserPI)) { 1150b57cec5SDimitry Andric Next->insert(UserPI); 1160b57cec5SDimitry Andric continue; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric // If we are only simplifying targeted instructions and the user is an 1200b57cec5SDimitry Andric // instruction in the loop body, add it to our set of targeted 1210b57cec5SDimitry Andric // instructions. Because we process defs before uses (outside of PHIs) 1220b57cec5SDimitry Andric // we won't have visited it yet. 1230b57cec5SDimitry Andric // 1240b57cec5SDimitry Andric // We also skip any uses outside of the loop being simplified. Those 1250b57cec5SDimitry Andric // should always be PHI nodes due to LCSSA form, and we don't want to 1260b57cec5SDimitry Andric // try to simplify those away. 1270b57cec5SDimitry Andric assert((L.contains(UserI) || isa<PHINode>(UserI)) && 1280b57cec5SDimitry Andric "Uses outside the loop should be PHI nodes due to LCSSA!"); 1290b57cec5SDimitry Andric if (!IsFirstIteration && L.contains(UserI)) 1300b57cec5SDimitry Andric ToSimplify->insert(UserI); 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric if (MSSAU) 1340b57cec5SDimitry Andric if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V)) 1350b57cec5SDimitry Andric if (MemoryAccess *MA = MSSA->getMemoryAccess(&I)) 1360b57cec5SDimitry Andric if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI)) 1370b57cec5SDimitry Andric MA->replaceAllUsesWith(ReplacementMA); 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric assert(I.use_empty() && "Should always have replaced all uses!"); 1400b57cec5SDimitry Andric if (isInstructionTriviallyDead(&I, &TLI)) 1410b57cec5SDimitry Andric DeadInsts.push_back(&I); 1420b57cec5SDimitry Andric ++NumSimplified; 1430b57cec5SDimitry Andric Changed = true; 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric // Delete any dead instructions found thus far now that we've finished an 1480b57cec5SDimitry Andric // iteration over all instructions in all the loop blocks. 1490b57cec5SDimitry Andric if (!DeadInsts.empty()) { 1500b57cec5SDimitry Andric Changed = true; 1510b57cec5SDimitry Andric RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric if (MSSAU && VerifyMemorySSA) 1550b57cec5SDimitry Andric MSSA->verifyMemorySSA(); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric // If we never found a PHI that needs to be simplified in the next 1580b57cec5SDimitry Andric // iteration, we're done. 1590b57cec5SDimitry Andric if (Next->empty()) 1600b57cec5SDimitry Andric break; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric // Otherwise, put the next set in place for the next iteration and reset it 1630b57cec5SDimitry Andric // and the visited PHIs for that iteration. 1640b57cec5SDimitry Andric std::swap(Next, ToSimplify); 1650b57cec5SDimitry Andric Next->clear(); 1660b57cec5SDimitry Andric VisitedPHIs.clear(); 1670b57cec5SDimitry Andric DeadInsts.clear(); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric return Changed; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM, 1740b57cec5SDimitry Andric LoopStandardAnalysisResults &AR, 1750b57cec5SDimitry Andric LPMUpdater &) { 176bdd1243dSDimitry Andric std::optional<MemorySSAUpdater> MSSAU; 1770b57cec5SDimitry Andric if (AR.MSSA) { 1780b57cec5SDimitry Andric MSSAU = MemorySSAUpdater(AR.MSSA); 179480093f4SDimitry Andric if (VerifyMemorySSA) 1800b57cec5SDimitry Andric AR.MSSA->verifyMemorySSA(); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI, 183bdd1243dSDimitry Andric MSSAU ? &*MSSAU : nullptr)) 1840b57cec5SDimitry Andric return PreservedAnalyses::all(); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric auto PA = getLoopPassPreservedAnalyses(); 1870b57cec5SDimitry Andric PA.preserveSet<CFGAnalyses>(); 1888bcb0991SDimitry Andric if (AR.MSSA) 1890b57cec5SDimitry Andric PA.preserve<MemorySSAAnalysis>(); 1900b57cec5SDimitry Andric return PA; 1910b57cec5SDimitry Andric } 192