1*9880d681SAndroid Build Coastguard Worker //===-- SimplifyIndVar.cpp - Induction variable simplification ------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements induction variable simplification. It does
11*9880d681SAndroid Build Coastguard Worker // not define any actual pass or policy, but provides a single function to
12*9880d681SAndroid Build Coastguard Worker // simplify a loop's induction variables based on ScalarEvolution.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/SimplifyIndVar.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopPass.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpressions.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker using namespace llvm;
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "indvars"
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker STATISTIC(NumElimIdentity, "Number of IV identities eliminated");
36*9880d681SAndroid Build Coastguard Worker STATISTIC(NumElimOperand, "Number of IV operands folded into a use");
37*9880d681SAndroid Build Coastguard Worker STATISTIC(NumElimRem , "Number of IV remainder operations eliminated");
38*9880d681SAndroid Build Coastguard Worker STATISTIC(NumElimCmp , "Number of IV comparisons eliminated");
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker namespace {
41*9880d681SAndroid Build Coastguard Worker /// This is a utility for simplifying induction variables
42*9880d681SAndroid Build Coastguard Worker /// based on ScalarEvolution. It is the primary instrument of the
43*9880d681SAndroid Build Coastguard Worker /// IndvarSimplify pass, but it may also be directly invoked to cleanup after
44*9880d681SAndroid Build Coastguard Worker /// other loop passes that preserve SCEV.
45*9880d681SAndroid Build Coastguard Worker class SimplifyIndvar {
46*9880d681SAndroid Build Coastguard Worker Loop *L;
47*9880d681SAndroid Build Coastguard Worker LoopInfo *LI;
48*9880d681SAndroid Build Coastguard Worker ScalarEvolution *SE;
49*9880d681SAndroid Build Coastguard Worker DominatorTree *DT;
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<WeakVH> &DeadInsts;
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker bool Changed;
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker public:
SimplifyIndvar(Loop * Loop,ScalarEvolution * SE,DominatorTree * DT,LoopInfo * LI,SmallVectorImpl<WeakVH> & Dead)56*9880d681SAndroid Build Coastguard Worker SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT,
57*9880d681SAndroid Build Coastguard Worker LoopInfo *LI,SmallVectorImpl<WeakVH> &Dead)
58*9880d681SAndroid Build Coastguard Worker : L(Loop), LI(LI), SE(SE), DT(DT), DeadInsts(Dead), Changed(false) {
59*9880d681SAndroid Build Coastguard Worker assert(LI && "IV simplification requires LoopInfo");
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
hasChanged() const62*9880d681SAndroid Build Coastguard Worker bool hasChanged() const { return Changed; }
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker /// Iteratively perform simplification on a worklist of users of the
65*9880d681SAndroid Build Coastguard Worker /// specified induction variable. This is the top-level driver that applies
66*9880d681SAndroid Build Coastguard Worker /// all simplifications to users of an IV.
67*9880d681SAndroid Build Coastguard Worker void simplifyUsers(PHINode *CurrIV, IVVisitor *V = nullptr);
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker Value *foldIVUser(Instruction *UseInst, Instruction *IVOperand);
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand);
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker bool eliminateOverflowIntrinsic(CallInst *CI);
74*9880d681SAndroid Build Coastguard Worker bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
75*9880d681SAndroid Build Coastguard Worker void eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand);
76*9880d681SAndroid Build Coastguard Worker void eliminateIVRemainder(BinaryOperator *Rem, Value *IVOperand,
77*9880d681SAndroid Build Coastguard Worker bool IsSigned);
78*9880d681SAndroid Build Coastguard Worker bool strengthenOverflowingOperation(BinaryOperator *OBO, Value *IVOperand);
79*9880d681SAndroid Build Coastguard Worker };
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker /// Fold an IV operand into its use. This removes increments of an
83*9880d681SAndroid Build Coastguard Worker /// aligned IV when used by a instruction that ignores the low bits.
84*9880d681SAndroid Build Coastguard Worker ///
85*9880d681SAndroid Build Coastguard Worker /// IVOperand is guaranteed SCEVable, but UseInst may not be.
86*9880d681SAndroid Build Coastguard Worker ///
87*9880d681SAndroid Build Coastguard Worker /// Return the operand of IVOperand for this induction variable if IVOperand can
88*9880d681SAndroid Build Coastguard Worker /// be folded (in case more folding opportunities have been exposed).
89*9880d681SAndroid Build Coastguard Worker /// Otherwise return null.
foldIVUser(Instruction * UseInst,Instruction * IVOperand)90*9880d681SAndroid Build Coastguard Worker Value *SimplifyIndvar::foldIVUser(Instruction *UseInst, Instruction *IVOperand) {
91*9880d681SAndroid Build Coastguard Worker Value *IVSrc = nullptr;
92*9880d681SAndroid Build Coastguard Worker unsigned OperIdx = 0;
93*9880d681SAndroid Build Coastguard Worker const SCEV *FoldedExpr = nullptr;
94*9880d681SAndroid Build Coastguard Worker switch (UseInst->getOpcode()) {
95*9880d681SAndroid Build Coastguard Worker default:
96*9880d681SAndroid Build Coastguard Worker return nullptr;
97*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv:
98*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
99*9880d681SAndroid Build Coastguard Worker // We're only interested in the case where we know something about
100*9880d681SAndroid Build Coastguard Worker // the numerator and have a constant denominator.
101*9880d681SAndroid Build Coastguard Worker if (IVOperand != UseInst->getOperand(OperIdx) ||
102*9880d681SAndroid Build Coastguard Worker !isa<ConstantInt>(UseInst->getOperand(1)))
103*9880d681SAndroid Build Coastguard Worker return nullptr;
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker // Attempt to fold a binary operator with constant operand.
106*9880d681SAndroid Build Coastguard Worker // e.g. ((I + 1) >> 2) => I >> 2
107*9880d681SAndroid Build Coastguard Worker if (!isa<BinaryOperator>(IVOperand)
108*9880d681SAndroid Build Coastguard Worker || !isa<ConstantInt>(IVOperand->getOperand(1)))
109*9880d681SAndroid Build Coastguard Worker return nullptr;
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker IVSrc = IVOperand->getOperand(0);
112*9880d681SAndroid Build Coastguard Worker // IVSrc must be the (SCEVable) IV, since the other operand is const.
113*9880d681SAndroid Build Coastguard Worker assert(SE->isSCEVable(IVSrc->getType()) && "Expect SCEVable IV operand");
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker ConstantInt *D = cast<ConstantInt>(UseInst->getOperand(1));
116*9880d681SAndroid Build Coastguard Worker if (UseInst->getOpcode() == Instruction::LShr) {
117*9880d681SAndroid Build Coastguard Worker // Get a constant for the divisor. See createSCEV.
118*9880d681SAndroid Build Coastguard Worker uint32_t BitWidth = cast<IntegerType>(UseInst->getType())->getBitWidth();
119*9880d681SAndroid Build Coastguard Worker if (D->getValue().uge(BitWidth))
120*9880d681SAndroid Build Coastguard Worker return nullptr;
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker D = ConstantInt::get(UseInst->getContext(),
123*9880d681SAndroid Build Coastguard Worker APInt::getOneBitSet(BitWidth, D->getZExtValue()));
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker FoldedExpr = SE->getUDivExpr(SE->getSCEV(IVSrc), SE->getSCEV(D));
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker // We have something that might fold it's operand. Compare SCEVs.
128*9880d681SAndroid Build Coastguard Worker if (!SE->isSCEVable(UseInst->getType()))
129*9880d681SAndroid Build Coastguard Worker return nullptr;
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker // Bypass the operand if SCEV can prove it has no effect.
132*9880d681SAndroid Build Coastguard Worker if (SE->getSCEV(UseInst) != FoldedExpr)
133*9880d681SAndroid Build Coastguard Worker return nullptr;
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "INDVARS: Eliminated IV operand: " << *IVOperand
136*9880d681SAndroid Build Coastguard Worker << " -> " << *UseInst << '\n');
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker UseInst->setOperand(OperIdx, IVSrc);
139*9880d681SAndroid Build Coastguard Worker assert(SE->getSCEV(UseInst) == FoldedExpr && "bad SCEV with folded oper");
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker ++NumElimOperand;
142*9880d681SAndroid Build Coastguard Worker Changed = true;
143*9880d681SAndroid Build Coastguard Worker if (IVOperand->use_empty())
144*9880d681SAndroid Build Coastguard Worker DeadInsts.emplace_back(IVOperand);
145*9880d681SAndroid Build Coastguard Worker return IVSrc;
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker /// SimplifyIVUsers helper for eliminating useless
149*9880d681SAndroid Build Coastguard Worker /// comparisons against an induction variable.
eliminateIVComparison(ICmpInst * ICmp,Value * IVOperand)150*9880d681SAndroid Build Coastguard Worker void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) {
151*9880d681SAndroid Build Coastguard Worker unsigned IVOperIdx = 0;
152*9880d681SAndroid Build Coastguard Worker ICmpInst::Predicate Pred = ICmp->getPredicate();
153*9880d681SAndroid Build Coastguard Worker if (IVOperand != ICmp->getOperand(0)) {
154*9880d681SAndroid Build Coastguard Worker // Swapped
155*9880d681SAndroid Build Coastguard Worker assert(IVOperand == ICmp->getOperand(1) && "Can't find IVOperand");
156*9880d681SAndroid Build Coastguard Worker IVOperIdx = 1;
157*9880d681SAndroid Build Coastguard Worker Pred = ICmpInst::getSwappedPredicate(Pred);
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker // Get the SCEVs for the ICmp operands.
161*9880d681SAndroid Build Coastguard Worker const SCEV *S = SE->getSCEV(ICmp->getOperand(IVOperIdx));
162*9880d681SAndroid Build Coastguard Worker const SCEV *X = SE->getSCEV(ICmp->getOperand(1 - IVOperIdx));
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker // Simplify unnecessary loops away.
165*9880d681SAndroid Build Coastguard Worker const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent());
166*9880d681SAndroid Build Coastguard Worker S = SE->getSCEVAtScope(S, ICmpLoop);
167*9880d681SAndroid Build Coastguard Worker X = SE->getSCEVAtScope(X, ICmpLoop);
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker ICmpInst::Predicate InvariantPredicate;
170*9880d681SAndroid Build Coastguard Worker const SCEV *InvariantLHS, *InvariantRHS;
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker // If the condition is always true or always false, replace it with
173*9880d681SAndroid Build Coastguard Worker // a constant value.
174*9880d681SAndroid Build Coastguard Worker if (SE->isKnownPredicate(Pred, S, X)) {
175*9880d681SAndroid Build Coastguard Worker ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext()));
176*9880d681SAndroid Build Coastguard Worker DeadInsts.emplace_back(ICmp);
177*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
178*9880d681SAndroid Build Coastguard Worker } else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) {
179*9880d681SAndroid Build Coastguard Worker ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext()));
180*9880d681SAndroid Build Coastguard Worker DeadInsts.emplace_back(ICmp);
181*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
182*9880d681SAndroid Build Coastguard Worker } else if (isa<PHINode>(IVOperand) &&
183*9880d681SAndroid Build Coastguard Worker SE->isLoopInvariantPredicate(Pred, S, X, L, InvariantPredicate,
184*9880d681SAndroid Build Coastguard Worker InvariantLHS, InvariantRHS)) {
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker // Rewrite the comparison to a loop invariant comparison if it can be done
187*9880d681SAndroid Build Coastguard Worker // cheaply, where cheaply means "we don't need to emit any new
188*9880d681SAndroid Build Coastguard Worker // instructions".
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker Value *NewLHS = nullptr, *NewRHS = nullptr;
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker if (S == InvariantLHS || X == InvariantLHS)
193*9880d681SAndroid Build Coastguard Worker NewLHS =
194*9880d681SAndroid Build Coastguard Worker ICmp->getOperand(S == InvariantLHS ? IVOperIdx : (1 - IVOperIdx));
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker if (S == InvariantRHS || X == InvariantRHS)
197*9880d681SAndroid Build Coastguard Worker NewRHS =
198*9880d681SAndroid Build Coastguard Worker ICmp->getOperand(S == InvariantRHS ? IVOperIdx : (1 - IVOperIdx));
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker auto *PN = cast<PHINode>(IVOperand);
201*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = PN->getNumIncomingValues();
202*9880d681SAndroid Build Coastguard Worker i != e && (!NewLHS || !NewRHS);
203*9880d681SAndroid Build Coastguard Worker ++i) {
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker // If this is a value incoming from the backedge, then it cannot be a loop
206*9880d681SAndroid Build Coastguard Worker // invariant value (since we know that IVOperand is an induction variable).
207*9880d681SAndroid Build Coastguard Worker if (L->contains(PN->getIncomingBlock(i)))
208*9880d681SAndroid Build Coastguard Worker continue;
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker // NB! This following assert does not fundamentally have to be true, but
211*9880d681SAndroid Build Coastguard Worker // it is true today given how SCEV analyzes induction variables.
212*9880d681SAndroid Build Coastguard Worker // Specifically, today SCEV will *not* recognize %iv as an induction
213*9880d681SAndroid Build Coastguard Worker // variable in the following case:
214*9880d681SAndroid Build Coastguard Worker //
215*9880d681SAndroid Build Coastguard Worker // define void @f(i32 %k) {
216*9880d681SAndroid Build Coastguard Worker // entry:
217*9880d681SAndroid Build Coastguard Worker // br i1 undef, label %r, label %l
218*9880d681SAndroid Build Coastguard Worker //
219*9880d681SAndroid Build Coastguard Worker // l:
220*9880d681SAndroid Build Coastguard Worker // %k.inc.l = add i32 %k, 1
221*9880d681SAndroid Build Coastguard Worker // br label %loop
222*9880d681SAndroid Build Coastguard Worker //
223*9880d681SAndroid Build Coastguard Worker // r:
224*9880d681SAndroid Build Coastguard Worker // %k.inc.r = add i32 %k, 1
225*9880d681SAndroid Build Coastguard Worker // br label %loop
226*9880d681SAndroid Build Coastguard Worker //
227*9880d681SAndroid Build Coastguard Worker // loop:
228*9880d681SAndroid Build Coastguard Worker // %iv = phi i32 [ %k.inc.l, %l ], [ %k.inc.r, %r ], [ %iv.inc, %loop ]
229*9880d681SAndroid Build Coastguard Worker // %iv.inc = add i32 %iv, 1
230*9880d681SAndroid Build Coastguard Worker // br label %loop
231*9880d681SAndroid Build Coastguard Worker // }
232*9880d681SAndroid Build Coastguard Worker //
233*9880d681SAndroid Build Coastguard Worker // but if it starts to, at some point, then the assertion below will have
234*9880d681SAndroid Build Coastguard Worker // to be changed to a runtime check.
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker Value *Incoming = PN->getIncomingValue(i);
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
239*9880d681SAndroid Build Coastguard Worker if (auto *I = dyn_cast<Instruction>(Incoming))
240*9880d681SAndroid Build Coastguard Worker assert(DT->dominates(I, ICmp) && "Should be a unique loop dominating value!");
241*9880d681SAndroid Build Coastguard Worker #endif
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker const SCEV *IncomingS = SE->getSCEV(Incoming);
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker if (!NewLHS && IncomingS == InvariantLHS)
246*9880d681SAndroid Build Coastguard Worker NewLHS = Incoming;
247*9880d681SAndroid Build Coastguard Worker if (!NewRHS && IncomingS == InvariantRHS)
248*9880d681SAndroid Build Coastguard Worker NewRHS = Incoming;
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker if (!NewLHS || !NewRHS)
252*9880d681SAndroid Build Coastguard Worker // We could not find an existing value to replace either LHS or RHS.
253*9880d681SAndroid Build Coastguard Worker // Generating new instructions has subtler tradeoffs, so avoid doing that
254*9880d681SAndroid Build Coastguard Worker // for now.
255*9880d681SAndroid Build Coastguard Worker return;
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "INDVARS: Simplified comparison: " << *ICmp << '\n');
258*9880d681SAndroid Build Coastguard Worker ICmp->setPredicate(InvariantPredicate);
259*9880d681SAndroid Build Coastguard Worker ICmp->setOperand(0, NewLHS);
260*9880d681SAndroid Build Coastguard Worker ICmp->setOperand(1, NewRHS);
261*9880d681SAndroid Build Coastguard Worker } else
262*9880d681SAndroid Build Coastguard Worker return;
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker ++NumElimCmp;
265*9880d681SAndroid Build Coastguard Worker Changed = true;
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker /// SimplifyIVUsers helper for eliminating useless
269*9880d681SAndroid Build Coastguard Worker /// remainder operations operating on an induction variable.
eliminateIVRemainder(BinaryOperator * Rem,Value * IVOperand,bool IsSigned)270*9880d681SAndroid Build Coastguard Worker void SimplifyIndvar::eliminateIVRemainder(BinaryOperator *Rem,
271*9880d681SAndroid Build Coastguard Worker Value *IVOperand,
272*9880d681SAndroid Build Coastguard Worker bool IsSigned) {
273*9880d681SAndroid Build Coastguard Worker // We're only interested in the case where we know something about
274*9880d681SAndroid Build Coastguard Worker // the numerator.
275*9880d681SAndroid Build Coastguard Worker if (IVOperand != Rem->getOperand(0))
276*9880d681SAndroid Build Coastguard Worker return;
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker // Get the SCEVs for the ICmp operands.
279*9880d681SAndroid Build Coastguard Worker const SCEV *S = SE->getSCEV(Rem->getOperand(0));
280*9880d681SAndroid Build Coastguard Worker const SCEV *X = SE->getSCEV(Rem->getOperand(1));
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker // Simplify unnecessary loops away.
283*9880d681SAndroid Build Coastguard Worker const Loop *ICmpLoop = LI->getLoopFor(Rem->getParent());
284*9880d681SAndroid Build Coastguard Worker S = SE->getSCEVAtScope(S, ICmpLoop);
285*9880d681SAndroid Build Coastguard Worker X = SE->getSCEVAtScope(X, ICmpLoop);
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker // i % n --> i if i is in [0,n).
288*9880d681SAndroid Build Coastguard Worker if ((!IsSigned || SE->isKnownNonNegative(S)) &&
289*9880d681SAndroid Build Coastguard Worker SE->isKnownPredicate(IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
290*9880d681SAndroid Build Coastguard Worker S, X))
291*9880d681SAndroid Build Coastguard Worker Rem->replaceAllUsesWith(Rem->getOperand(0));
292*9880d681SAndroid Build Coastguard Worker else {
293*9880d681SAndroid Build Coastguard Worker // (i+1) % n --> (i+1)==n?0:(i+1) if i is in [0,n).
294*9880d681SAndroid Build Coastguard Worker const SCEV *LessOne = SE->getMinusSCEV(S, SE->getOne(S->getType()));
295*9880d681SAndroid Build Coastguard Worker if (IsSigned && !SE->isKnownNonNegative(LessOne))
296*9880d681SAndroid Build Coastguard Worker return;
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker if (!SE->isKnownPredicate(IsSigned ?
299*9880d681SAndroid Build Coastguard Worker ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
300*9880d681SAndroid Build Coastguard Worker LessOne, X))
301*9880d681SAndroid Build Coastguard Worker return;
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Worker ICmpInst *ICmp = new ICmpInst(Rem, ICmpInst::ICMP_EQ,
304*9880d681SAndroid Build Coastguard Worker Rem->getOperand(0), Rem->getOperand(1));
305*9880d681SAndroid Build Coastguard Worker SelectInst *Sel =
306*9880d681SAndroid Build Coastguard Worker SelectInst::Create(ICmp,
307*9880d681SAndroid Build Coastguard Worker ConstantInt::get(Rem->getType(), 0),
308*9880d681SAndroid Build Coastguard Worker Rem->getOperand(0), "tmp", Rem);
309*9880d681SAndroid Build Coastguard Worker Rem->replaceAllUsesWith(Sel);
310*9880d681SAndroid Build Coastguard Worker }
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n');
313*9880d681SAndroid Build Coastguard Worker ++NumElimRem;
314*9880d681SAndroid Build Coastguard Worker Changed = true;
315*9880d681SAndroid Build Coastguard Worker DeadInsts.emplace_back(Rem);
316*9880d681SAndroid Build Coastguard Worker }
317*9880d681SAndroid Build Coastguard Worker
eliminateOverflowIntrinsic(CallInst * CI)318*9880d681SAndroid Build Coastguard Worker bool SimplifyIndvar::eliminateOverflowIntrinsic(CallInst *CI) {
319*9880d681SAndroid Build Coastguard Worker auto *F = CI->getCalledFunction();
320*9880d681SAndroid Build Coastguard Worker if (!F)
321*9880d681SAndroid Build Coastguard Worker return false;
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker typedef const SCEV *(ScalarEvolution::*OperationFunctionTy)(
324*9880d681SAndroid Build Coastguard Worker const SCEV *, const SCEV *, SCEV::NoWrapFlags);
325*9880d681SAndroid Build Coastguard Worker typedef const SCEV *(ScalarEvolution::*ExtensionFunctionTy)(
326*9880d681SAndroid Build Coastguard Worker const SCEV *, Type *);
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker OperationFunctionTy Operation;
329*9880d681SAndroid Build Coastguard Worker ExtensionFunctionTy Extension;
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Worker Instruction::BinaryOps RawOp;
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker // We always have exactly one of nsw or nuw. If NoSignedOverflow is false, we
334*9880d681SAndroid Build Coastguard Worker // have nuw.
335*9880d681SAndroid Build Coastguard Worker bool NoSignedOverflow;
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker switch (F->getIntrinsicID()) {
338*9880d681SAndroid Build Coastguard Worker default:
339*9880d681SAndroid Build Coastguard Worker return false;
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker case Intrinsic::sadd_with_overflow:
342*9880d681SAndroid Build Coastguard Worker Operation = &ScalarEvolution::getAddExpr;
343*9880d681SAndroid Build Coastguard Worker Extension = &ScalarEvolution::getSignExtendExpr;
344*9880d681SAndroid Build Coastguard Worker RawOp = Instruction::Add;
345*9880d681SAndroid Build Coastguard Worker NoSignedOverflow = true;
346*9880d681SAndroid Build Coastguard Worker break;
347*9880d681SAndroid Build Coastguard Worker
348*9880d681SAndroid Build Coastguard Worker case Intrinsic::uadd_with_overflow:
349*9880d681SAndroid Build Coastguard Worker Operation = &ScalarEvolution::getAddExpr;
350*9880d681SAndroid Build Coastguard Worker Extension = &ScalarEvolution::getZeroExtendExpr;
351*9880d681SAndroid Build Coastguard Worker RawOp = Instruction::Add;
352*9880d681SAndroid Build Coastguard Worker NoSignedOverflow = false;
353*9880d681SAndroid Build Coastguard Worker break;
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker case Intrinsic::ssub_with_overflow:
356*9880d681SAndroid Build Coastguard Worker Operation = &ScalarEvolution::getMinusSCEV;
357*9880d681SAndroid Build Coastguard Worker Extension = &ScalarEvolution::getSignExtendExpr;
358*9880d681SAndroid Build Coastguard Worker RawOp = Instruction::Sub;
359*9880d681SAndroid Build Coastguard Worker NoSignedOverflow = true;
360*9880d681SAndroid Build Coastguard Worker break;
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker case Intrinsic::usub_with_overflow:
363*9880d681SAndroid Build Coastguard Worker Operation = &ScalarEvolution::getMinusSCEV;
364*9880d681SAndroid Build Coastguard Worker Extension = &ScalarEvolution::getZeroExtendExpr;
365*9880d681SAndroid Build Coastguard Worker RawOp = Instruction::Sub;
366*9880d681SAndroid Build Coastguard Worker NoSignedOverflow = false;
367*9880d681SAndroid Build Coastguard Worker break;
368*9880d681SAndroid Build Coastguard Worker }
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker const SCEV *LHS = SE->getSCEV(CI->getArgOperand(0));
371*9880d681SAndroid Build Coastguard Worker const SCEV *RHS = SE->getSCEV(CI->getArgOperand(1));
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Worker auto *NarrowTy = cast<IntegerType>(LHS->getType());
374*9880d681SAndroid Build Coastguard Worker auto *WideTy =
375*9880d681SAndroid Build Coastguard Worker IntegerType::get(NarrowTy->getContext(), NarrowTy->getBitWidth() * 2);
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard Worker const SCEV *A =
378*9880d681SAndroid Build Coastguard Worker (SE->*Extension)((SE->*Operation)(LHS, RHS, SCEV::FlagAnyWrap), WideTy);
379*9880d681SAndroid Build Coastguard Worker const SCEV *B =
380*9880d681SAndroid Build Coastguard Worker (SE->*Operation)((SE->*Extension)(LHS, WideTy),
381*9880d681SAndroid Build Coastguard Worker (SE->*Extension)(RHS, WideTy), SCEV::FlagAnyWrap);
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Worker if (A != B)
384*9880d681SAndroid Build Coastguard Worker return false;
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker // Proved no overflow, nuke the overflow check and, if possible, the overflow
387*9880d681SAndroid Build Coastguard Worker // intrinsic as well.
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker BinaryOperator *NewResult = BinaryOperator::Create(
390*9880d681SAndroid Build Coastguard Worker RawOp, CI->getArgOperand(0), CI->getArgOperand(1), "", CI);
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Worker if (NoSignedOverflow)
393*9880d681SAndroid Build Coastguard Worker NewResult->setHasNoSignedWrap(true);
394*9880d681SAndroid Build Coastguard Worker else
395*9880d681SAndroid Build Coastguard Worker NewResult->setHasNoUnsignedWrap(true);
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker SmallVector<ExtractValueInst *, 4> ToDelete;
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker for (auto *U : CI->users()) {
400*9880d681SAndroid Build Coastguard Worker if (auto *EVI = dyn_cast<ExtractValueInst>(U)) {
401*9880d681SAndroid Build Coastguard Worker if (EVI->getIndices()[0] == 1)
402*9880d681SAndroid Build Coastguard Worker EVI->replaceAllUsesWith(ConstantInt::getFalse(CI->getContext()));
403*9880d681SAndroid Build Coastguard Worker else {
404*9880d681SAndroid Build Coastguard Worker assert(EVI->getIndices()[0] == 0 && "Only two possibilities!");
405*9880d681SAndroid Build Coastguard Worker EVI->replaceAllUsesWith(NewResult);
406*9880d681SAndroid Build Coastguard Worker }
407*9880d681SAndroid Build Coastguard Worker ToDelete.push_back(EVI);
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker }
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker for (auto *EVI : ToDelete)
412*9880d681SAndroid Build Coastguard Worker EVI->eraseFromParent();
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker if (CI->use_empty())
415*9880d681SAndroid Build Coastguard Worker CI->eraseFromParent();
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker return true;
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Worker /// Eliminate an operation that consumes a simple IV and has no observable
421*9880d681SAndroid Build Coastguard Worker /// side-effect given the range of IV values. IVOperand is guaranteed SCEVable,
422*9880d681SAndroid Build Coastguard Worker /// but UseInst may not be.
eliminateIVUser(Instruction * UseInst,Instruction * IVOperand)423*9880d681SAndroid Build Coastguard Worker bool SimplifyIndvar::eliminateIVUser(Instruction *UseInst,
424*9880d681SAndroid Build Coastguard Worker Instruction *IVOperand) {
425*9880d681SAndroid Build Coastguard Worker if (ICmpInst *ICmp = dyn_cast<ICmpInst>(UseInst)) {
426*9880d681SAndroid Build Coastguard Worker eliminateIVComparison(ICmp, IVOperand);
427*9880d681SAndroid Build Coastguard Worker return true;
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker if (BinaryOperator *Rem = dyn_cast<BinaryOperator>(UseInst)) {
430*9880d681SAndroid Build Coastguard Worker bool IsSigned = Rem->getOpcode() == Instruction::SRem;
431*9880d681SAndroid Build Coastguard Worker if (IsSigned || Rem->getOpcode() == Instruction::URem) {
432*9880d681SAndroid Build Coastguard Worker eliminateIVRemainder(Rem, IVOperand, IsSigned);
433*9880d681SAndroid Build Coastguard Worker return true;
434*9880d681SAndroid Build Coastguard Worker }
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker if (auto *CI = dyn_cast<CallInst>(UseInst))
438*9880d681SAndroid Build Coastguard Worker if (eliminateOverflowIntrinsic(CI))
439*9880d681SAndroid Build Coastguard Worker return true;
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker if (eliminateIdentitySCEV(UseInst, IVOperand))
442*9880d681SAndroid Build Coastguard Worker return true;
443*9880d681SAndroid Build Coastguard Worker
444*9880d681SAndroid Build Coastguard Worker return false;
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker
447*9880d681SAndroid Build Coastguard Worker /// Eliminate any operation that SCEV can prove is an identity function.
eliminateIdentitySCEV(Instruction * UseInst,Instruction * IVOperand)448*9880d681SAndroid Build Coastguard Worker bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
449*9880d681SAndroid Build Coastguard Worker Instruction *IVOperand) {
450*9880d681SAndroid Build Coastguard Worker if (!SE->isSCEVable(UseInst->getType()) ||
451*9880d681SAndroid Build Coastguard Worker (UseInst->getType() != IVOperand->getType()) ||
452*9880d681SAndroid Build Coastguard Worker (SE->getSCEV(UseInst) != SE->getSCEV(IVOperand)))
453*9880d681SAndroid Build Coastguard Worker return false;
454*9880d681SAndroid Build Coastguard Worker
455*9880d681SAndroid Build Coastguard Worker // getSCEV(X) == getSCEV(Y) does not guarantee that X and Y are related in the
456*9880d681SAndroid Build Coastguard Worker // dominator tree, even if X is an operand to Y. For instance, in
457*9880d681SAndroid Build Coastguard Worker //
458*9880d681SAndroid Build Coastguard Worker // %iv = phi i32 {0,+,1}
459*9880d681SAndroid Build Coastguard Worker // br %cond, label %left, label %merge
460*9880d681SAndroid Build Coastguard Worker //
461*9880d681SAndroid Build Coastguard Worker // left:
462*9880d681SAndroid Build Coastguard Worker // %X = add i32 %iv, 0
463*9880d681SAndroid Build Coastguard Worker // br label %merge
464*9880d681SAndroid Build Coastguard Worker //
465*9880d681SAndroid Build Coastguard Worker // merge:
466*9880d681SAndroid Build Coastguard Worker // %M = phi (%X, %iv)
467*9880d681SAndroid Build Coastguard Worker //
468*9880d681SAndroid Build Coastguard Worker // getSCEV(%M) == getSCEV(%X) == {0,+,1}, but %X does not dominate %M, and
469*9880d681SAndroid Build Coastguard Worker // %M.replaceAllUsesWith(%X) would be incorrect.
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker if (isa<PHINode>(UseInst))
472*9880d681SAndroid Build Coastguard Worker // If UseInst is not a PHI node then we know that IVOperand dominates
473*9880d681SAndroid Build Coastguard Worker // UseInst directly from the legality of SSA.
474*9880d681SAndroid Build Coastguard Worker if (!DT || !DT->dominates(IVOperand, UseInst))
475*9880d681SAndroid Build Coastguard Worker return false;
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker if (!LI->replacementPreservesLCSSAForm(UseInst, IVOperand))
478*9880d681SAndroid Build Coastguard Worker return false;
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "INDVARS: Eliminated identity: " << *UseInst << '\n');
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker UseInst->replaceAllUsesWith(IVOperand);
483*9880d681SAndroid Build Coastguard Worker ++NumElimIdentity;
484*9880d681SAndroid Build Coastguard Worker Changed = true;
485*9880d681SAndroid Build Coastguard Worker DeadInsts.emplace_back(UseInst);
486*9880d681SAndroid Build Coastguard Worker return true;
487*9880d681SAndroid Build Coastguard Worker }
488*9880d681SAndroid Build Coastguard Worker
489*9880d681SAndroid Build Coastguard Worker /// Annotate BO with nsw / nuw if it provably does not signed-overflow /
490*9880d681SAndroid Build Coastguard Worker /// unsigned-overflow. Returns true if anything changed, false otherwise.
strengthenOverflowingOperation(BinaryOperator * BO,Value * IVOperand)491*9880d681SAndroid Build Coastguard Worker bool SimplifyIndvar::strengthenOverflowingOperation(BinaryOperator *BO,
492*9880d681SAndroid Build Coastguard Worker Value *IVOperand) {
493*9880d681SAndroid Build Coastguard Worker
494*9880d681SAndroid Build Coastguard Worker // Fastpath: we don't have any work to do if `BO` is `nuw` and `nsw`.
495*9880d681SAndroid Build Coastguard Worker if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())
496*9880d681SAndroid Build Coastguard Worker return false;
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker const SCEV *(ScalarEvolution::*GetExprForBO)(const SCEV *, const SCEV *,
499*9880d681SAndroid Build Coastguard Worker SCEV::NoWrapFlags);
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker switch (BO->getOpcode()) {
502*9880d681SAndroid Build Coastguard Worker default:
503*9880d681SAndroid Build Coastguard Worker return false;
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker case Instruction::Add:
506*9880d681SAndroid Build Coastguard Worker GetExprForBO = &ScalarEvolution::getAddExpr;
507*9880d681SAndroid Build Coastguard Worker break;
508*9880d681SAndroid Build Coastguard Worker
509*9880d681SAndroid Build Coastguard Worker case Instruction::Sub:
510*9880d681SAndroid Build Coastguard Worker GetExprForBO = &ScalarEvolution::getMinusSCEV;
511*9880d681SAndroid Build Coastguard Worker break;
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker case Instruction::Mul:
514*9880d681SAndroid Build Coastguard Worker GetExprForBO = &ScalarEvolution::getMulExpr;
515*9880d681SAndroid Build Coastguard Worker break;
516*9880d681SAndroid Build Coastguard Worker }
517*9880d681SAndroid Build Coastguard Worker
518*9880d681SAndroid Build Coastguard Worker unsigned BitWidth = cast<IntegerType>(BO->getType())->getBitWidth();
519*9880d681SAndroid Build Coastguard Worker Type *WideTy = IntegerType::get(BO->getContext(), BitWidth * 2);
520*9880d681SAndroid Build Coastguard Worker const SCEV *LHS = SE->getSCEV(BO->getOperand(0));
521*9880d681SAndroid Build Coastguard Worker const SCEV *RHS = SE->getSCEV(BO->getOperand(1));
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker bool Changed = false;
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Worker if (!BO->hasNoUnsignedWrap()) {
526*9880d681SAndroid Build Coastguard Worker const SCEV *ExtendAfterOp = SE->getZeroExtendExpr(SE->getSCEV(BO), WideTy);
527*9880d681SAndroid Build Coastguard Worker const SCEV *OpAfterExtend = (SE->*GetExprForBO)(
528*9880d681SAndroid Build Coastguard Worker SE->getZeroExtendExpr(LHS, WideTy), SE->getZeroExtendExpr(RHS, WideTy),
529*9880d681SAndroid Build Coastguard Worker SCEV::FlagAnyWrap);
530*9880d681SAndroid Build Coastguard Worker if (ExtendAfterOp == OpAfterExtend) {
531*9880d681SAndroid Build Coastguard Worker BO->setHasNoUnsignedWrap();
532*9880d681SAndroid Build Coastguard Worker SE->forgetValue(BO);
533*9880d681SAndroid Build Coastguard Worker Changed = true;
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker }
536*9880d681SAndroid Build Coastguard Worker
537*9880d681SAndroid Build Coastguard Worker if (!BO->hasNoSignedWrap()) {
538*9880d681SAndroid Build Coastguard Worker const SCEV *ExtendAfterOp = SE->getSignExtendExpr(SE->getSCEV(BO), WideTy);
539*9880d681SAndroid Build Coastguard Worker const SCEV *OpAfterExtend = (SE->*GetExprForBO)(
540*9880d681SAndroid Build Coastguard Worker SE->getSignExtendExpr(LHS, WideTy), SE->getSignExtendExpr(RHS, WideTy),
541*9880d681SAndroid Build Coastguard Worker SCEV::FlagAnyWrap);
542*9880d681SAndroid Build Coastguard Worker if (ExtendAfterOp == OpAfterExtend) {
543*9880d681SAndroid Build Coastguard Worker BO->setHasNoSignedWrap();
544*9880d681SAndroid Build Coastguard Worker SE->forgetValue(BO);
545*9880d681SAndroid Build Coastguard Worker Changed = true;
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker }
548*9880d681SAndroid Build Coastguard Worker
549*9880d681SAndroid Build Coastguard Worker return Changed;
550*9880d681SAndroid Build Coastguard Worker }
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker /// Add all uses of Def to the current IV's worklist.
pushIVUsers(Instruction * Def,SmallPtrSet<Instruction *,16> & Simplified,SmallVectorImpl<std::pair<Instruction *,Instruction * >> & SimpleIVUsers)553*9880d681SAndroid Build Coastguard Worker static void pushIVUsers(
554*9880d681SAndroid Build Coastguard Worker Instruction *Def,
555*9880d681SAndroid Build Coastguard Worker SmallPtrSet<Instruction*,16> &Simplified,
556*9880d681SAndroid Build Coastguard Worker SmallVectorImpl< std::pair<Instruction*,Instruction*> > &SimpleIVUsers) {
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker for (User *U : Def->users()) {
559*9880d681SAndroid Build Coastguard Worker Instruction *UI = cast<Instruction>(U);
560*9880d681SAndroid Build Coastguard Worker
561*9880d681SAndroid Build Coastguard Worker // Avoid infinite or exponential worklist processing.
562*9880d681SAndroid Build Coastguard Worker // Also ensure unique worklist users.
563*9880d681SAndroid Build Coastguard Worker // If Def is a LoopPhi, it may not be in the Simplified set, so check for
564*9880d681SAndroid Build Coastguard Worker // self edges first.
565*9880d681SAndroid Build Coastguard Worker if (UI != Def && Simplified.insert(UI).second)
566*9880d681SAndroid Build Coastguard Worker SimpleIVUsers.push_back(std::make_pair(UI, Def));
567*9880d681SAndroid Build Coastguard Worker }
568*9880d681SAndroid Build Coastguard Worker }
569*9880d681SAndroid Build Coastguard Worker
570*9880d681SAndroid Build Coastguard Worker /// Return true if this instruction generates a simple SCEV
571*9880d681SAndroid Build Coastguard Worker /// expression in terms of that IV.
572*9880d681SAndroid Build Coastguard Worker ///
573*9880d681SAndroid Build Coastguard Worker /// This is similar to IVUsers' isInteresting() but processes each instruction
574*9880d681SAndroid Build Coastguard Worker /// non-recursively when the operand is already known to be a simpleIVUser.
575*9880d681SAndroid Build Coastguard Worker ///
isSimpleIVUser(Instruction * I,const Loop * L,ScalarEvolution * SE)576*9880d681SAndroid Build Coastguard Worker static bool isSimpleIVUser(Instruction *I, const Loop *L, ScalarEvolution *SE) {
577*9880d681SAndroid Build Coastguard Worker if (!SE->isSCEVable(I->getType()))
578*9880d681SAndroid Build Coastguard Worker return false;
579*9880d681SAndroid Build Coastguard Worker
580*9880d681SAndroid Build Coastguard Worker // Get the symbolic expression for this instruction.
581*9880d681SAndroid Build Coastguard Worker const SCEV *S = SE->getSCEV(I);
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker // Only consider affine recurrences.
584*9880d681SAndroid Build Coastguard Worker const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S);
585*9880d681SAndroid Build Coastguard Worker if (AR && AR->getLoop() == L)
586*9880d681SAndroid Build Coastguard Worker return true;
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker return false;
589*9880d681SAndroid Build Coastguard Worker }
590*9880d681SAndroid Build Coastguard Worker
591*9880d681SAndroid Build Coastguard Worker /// Iteratively perform simplification on a worklist of users
592*9880d681SAndroid Build Coastguard Worker /// of the specified induction variable. Each successive simplification may push
593*9880d681SAndroid Build Coastguard Worker /// more users which may themselves be candidates for simplification.
594*9880d681SAndroid Build Coastguard Worker ///
595*9880d681SAndroid Build Coastguard Worker /// This algorithm does not require IVUsers analysis. Instead, it simplifies
596*9880d681SAndroid Build Coastguard Worker /// instructions in-place during analysis. Rather than rewriting induction
597*9880d681SAndroid Build Coastguard Worker /// variables bottom-up from their users, it transforms a chain of IVUsers
598*9880d681SAndroid Build Coastguard Worker /// top-down, updating the IR only when it encounters a clear optimization
599*9880d681SAndroid Build Coastguard Worker /// opportunity.
600*9880d681SAndroid Build Coastguard Worker ///
601*9880d681SAndroid Build Coastguard Worker /// Once DisableIVRewrite is default, LSR will be the only client of IVUsers.
602*9880d681SAndroid Build Coastguard Worker ///
simplifyUsers(PHINode * CurrIV,IVVisitor * V)603*9880d681SAndroid Build Coastguard Worker void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
604*9880d681SAndroid Build Coastguard Worker if (!SE->isSCEVable(CurrIV->getType()))
605*9880d681SAndroid Build Coastguard Worker return;
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker // Instructions processed by SimplifyIndvar for CurrIV.
608*9880d681SAndroid Build Coastguard Worker SmallPtrSet<Instruction*,16> Simplified;
609*9880d681SAndroid Build Coastguard Worker
610*9880d681SAndroid Build Coastguard Worker // Use-def pairs if IV users waiting to be processed for CurrIV.
611*9880d681SAndroid Build Coastguard Worker SmallVector<std::pair<Instruction*, Instruction*>, 8> SimpleIVUsers;
612*9880d681SAndroid Build Coastguard Worker
613*9880d681SAndroid Build Coastguard Worker // Push users of the current LoopPhi. In rare cases, pushIVUsers may be
614*9880d681SAndroid Build Coastguard Worker // called multiple times for the same LoopPhi. This is the proper thing to
615*9880d681SAndroid Build Coastguard Worker // do for loop header phis that use each other.
616*9880d681SAndroid Build Coastguard Worker pushIVUsers(CurrIV, Simplified, SimpleIVUsers);
617*9880d681SAndroid Build Coastguard Worker
618*9880d681SAndroid Build Coastguard Worker while (!SimpleIVUsers.empty()) {
619*9880d681SAndroid Build Coastguard Worker std::pair<Instruction*, Instruction*> UseOper =
620*9880d681SAndroid Build Coastguard Worker SimpleIVUsers.pop_back_val();
621*9880d681SAndroid Build Coastguard Worker Instruction *UseInst = UseOper.first;
622*9880d681SAndroid Build Coastguard Worker
623*9880d681SAndroid Build Coastguard Worker // Bypass back edges to avoid extra work.
624*9880d681SAndroid Build Coastguard Worker if (UseInst == CurrIV) continue;
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker Instruction *IVOperand = UseOper.second;
627*9880d681SAndroid Build Coastguard Worker for (unsigned N = 0; IVOperand; ++N) {
628*9880d681SAndroid Build Coastguard Worker assert(N <= Simplified.size() && "runaway iteration");
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker Value *NewOper = foldIVUser(UseOper.first, IVOperand);
631*9880d681SAndroid Build Coastguard Worker if (!NewOper)
632*9880d681SAndroid Build Coastguard Worker break; // done folding
633*9880d681SAndroid Build Coastguard Worker IVOperand = dyn_cast<Instruction>(NewOper);
634*9880d681SAndroid Build Coastguard Worker }
635*9880d681SAndroid Build Coastguard Worker if (!IVOperand)
636*9880d681SAndroid Build Coastguard Worker continue;
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker if (eliminateIVUser(UseOper.first, IVOperand)) {
639*9880d681SAndroid Build Coastguard Worker pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
640*9880d681SAndroid Build Coastguard Worker continue;
641*9880d681SAndroid Build Coastguard Worker }
642*9880d681SAndroid Build Coastguard Worker
643*9880d681SAndroid Build Coastguard Worker if (BinaryOperator *BO = dyn_cast<BinaryOperator>(UseOper.first)) {
644*9880d681SAndroid Build Coastguard Worker if (isa<OverflowingBinaryOperator>(BO) &&
645*9880d681SAndroid Build Coastguard Worker strengthenOverflowingOperation(BO, IVOperand)) {
646*9880d681SAndroid Build Coastguard Worker // re-queue uses of the now modified binary operator and fall
647*9880d681SAndroid Build Coastguard Worker // through to the checks that remain.
648*9880d681SAndroid Build Coastguard Worker pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
649*9880d681SAndroid Build Coastguard Worker }
650*9880d681SAndroid Build Coastguard Worker }
651*9880d681SAndroid Build Coastguard Worker
652*9880d681SAndroid Build Coastguard Worker CastInst *Cast = dyn_cast<CastInst>(UseOper.first);
653*9880d681SAndroid Build Coastguard Worker if (V && Cast) {
654*9880d681SAndroid Build Coastguard Worker V->visitCast(Cast);
655*9880d681SAndroid Build Coastguard Worker continue;
656*9880d681SAndroid Build Coastguard Worker }
657*9880d681SAndroid Build Coastguard Worker if (isSimpleIVUser(UseOper.first, L, SE)) {
658*9880d681SAndroid Build Coastguard Worker pushIVUsers(UseOper.first, Simplified, SimpleIVUsers);
659*9880d681SAndroid Build Coastguard Worker }
660*9880d681SAndroid Build Coastguard Worker }
661*9880d681SAndroid Build Coastguard Worker }
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker namespace llvm {
664*9880d681SAndroid Build Coastguard Worker
anchor()665*9880d681SAndroid Build Coastguard Worker void IVVisitor::anchor() { }
666*9880d681SAndroid Build Coastguard Worker
667*9880d681SAndroid Build Coastguard Worker /// Simplify instructions that use this induction variable
668*9880d681SAndroid Build Coastguard Worker /// by using ScalarEvolution to analyze the IV's recurrence.
simplifyUsersOfIV(PHINode * CurrIV,ScalarEvolution * SE,DominatorTree * DT,LoopInfo * LI,SmallVectorImpl<WeakVH> & Dead,IVVisitor * V)669*9880d681SAndroid Build Coastguard Worker bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
670*9880d681SAndroid Build Coastguard Worker LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead,
671*9880d681SAndroid Build Coastguard Worker IVVisitor *V) {
672*9880d681SAndroid Build Coastguard Worker SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, Dead);
673*9880d681SAndroid Build Coastguard Worker SIV.simplifyUsers(CurrIV, V);
674*9880d681SAndroid Build Coastguard Worker return SIV.hasChanged();
675*9880d681SAndroid Build Coastguard Worker }
676*9880d681SAndroid Build Coastguard Worker
677*9880d681SAndroid Build Coastguard Worker /// Simplify users of induction variables within this
678*9880d681SAndroid Build Coastguard Worker /// loop. This does not actually change or add IVs.
simplifyLoopIVs(Loop * L,ScalarEvolution * SE,DominatorTree * DT,LoopInfo * LI,SmallVectorImpl<WeakVH> & Dead)679*9880d681SAndroid Build Coastguard Worker bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
680*9880d681SAndroid Build Coastguard Worker LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead) {
681*9880d681SAndroid Build Coastguard Worker bool Changed = false;
682*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) {
683*9880d681SAndroid Build Coastguard Worker Changed |= simplifyUsersOfIV(cast<PHINode>(I), SE, DT, LI, Dead);
684*9880d681SAndroid Build Coastguard Worker }
685*9880d681SAndroid Build Coastguard Worker return Changed;
686*9880d681SAndroid Build Coastguard Worker }
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker } // namespace llvm
689