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