xref: /aosp_15_r20/external/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- InductiveRangeCheckElimination.cpp - ------------------------------===//
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 // The InductiveRangeCheckElimination pass splits a loop's iteration space into
10*9880d681SAndroid Build Coastguard Worker // three disjoint ranges.  It does that in a way such that the loop running in
11*9880d681SAndroid Build Coastguard Worker // the middle loop provably does not need range checks. As an example, it will
12*9880d681SAndroid Build Coastguard Worker // convert
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //   len = < known positive >
15*9880d681SAndroid Build Coastguard Worker //   for (i = 0; i < n; i++) {
16*9880d681SAndroid Build Coastguard Worker //     if (0 <= i && i < len) {
17*9880d681SAndroid Build Coastguard Worker //       do_something();
18*9880d681SAndroid Build Coastguard Worker //     } else {
19*9880d681SAndroid Build Coastguard Worker //       throw_out_of_bounds();
20*9880d681SAndroid Build Coastguard Worker //     }
21*9880d681SAndroid Build Coastguard Worker //   }
22*9880d681SAndroid Build Coastguard Worker //
23*9880d681SAndroid Build Coastguard Worker // to
24*9880d681SAndroid Build Coastguard Worker //
25*9880d681SAndroid Build Coastguard Worker //   len = < known positive >
26*9880d681SAndroid Build Coastguard Worker //   limit = smin(n, len)
27*9880d681SAndroid Build Coastguard Worker //   // no first segment
28*9880d681SAndroid Build Coastguard Worker //   for (i = 0; i < limit; i++) {
29*9880d681SAndroid Build Coastguard Worker //     if (0 <= i && i < len) { // this check is fully redundant
30*9880d681SAndroid Build Coastguard Worker //       do_something();
31*9880d681SAndroid Build Coastguard Worker //     } else {
32*9880d681SAndroid Build Coastguard Worker //       throw_out_of_bounds();
33*9880d681SAndroid Build Coastguard Worker //     }
34*9880d681SAndroid Build Coastguard Worker //   }
35*9880d681SAndroid Build Coastguard Worker //   for (i = limit; i < n; i++) {
36*9880d681SAndroid Build Coastguard Worker //     if (0 <= i && i < len) {
37*9880d681SAndroid Build Coastguard Worker //       do_something();
38*9880d681SAndroid Build Coastguard Worker //     } else {
39*9880d681SAndroid Build Coastguard Worker //       throw_out_of_bounds();
40*9880d681SAndroid Build Coastguard Worker //     }
41*9880d681SAndroid Build Coastguard Worker //   }
42*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Optional.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/BranchProbabilityInfo.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/InstructionSimplify.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopPass.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolution.h"
50*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpander.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpressions.h"
52*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
53*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
54*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
55*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
56*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
57*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
58*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/PatternMatch.h"
59*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ValueHandle.h"
60*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Verifier.h"
61*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
62*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
63*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
64*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Scalar.h"
65*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
66*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Cloning.h"
67*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/LoopUtils.h"
68*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/SimplifyIndVar.h"
69*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/UnrollLoop.h"
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker using namespace llvm;
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned> LoopSizeCutoff("irce-loop-size-cutoff", cl::Hidden,
74*9880d681SAndroid Build Coastguard Worker                                         cl::init(64));
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> PrintChangedLoops("irce-print-changed-loops", cl::Hidden,
77*9880d681SAndroid Build Coastguard Worker                                        cl::init(false));
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> PrintRangeChecks("irce-print-range-checks", cl::Hidden,
80*9880d681SAndroid Build Coastguard Worker                                       cl::init(false));
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker static cl::opt<int> MaxExitProbReciprocal("irce-max-exit-prob-reciprocal",
83*9880d681SAndroid Build Coastguard Worker                                           cl::Hidden, cl::init(10));
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "irce"
86*9880d681SAndroid Build Coastguard Worker 
87*9880d681SAndroid Build Coastguard Worker namespace {
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker /// An inductive range check is conditional branch in a loop with
90*9880d681SAndroid Build Coastguard Worker ///
91*9880d681SAndroid Build Coastguard Worker ///  1. a very cold successor (i.e. the branch jumps to that successor very
92*9880d681SAndroid Build Coastguard Worker ///     rarely)
93*9880d681SAndroid Build Coastguard Worker ///
94*9880d681SAndroid Build Coastguard Worker ///  and
95*9880d681SAndroid Build Coastguard Worker ///
96*9880d681SAndroid Build Coastguard Worker ///  2. a condition that is provably true for some contiguous range of values
97*9880d681SAndroid Build Coastguard Worker ///     taken by the containing loop's induction variable.
98*9880d681SAndroid Build Coastguard Worker ///
99*9880d681SAndroid Build Coastguard Worker class InductiveRangeCheck {
100*9880d681SAndroid Build Coastguard Worker   // Classifies a range check
101*9880d681SAndroid Build Coastguard Worker   enum RangeCheckKind : unsigned {
102*9880d681SAndroid Build Coastguard Worker     // Range check of the form "0 <= I".
103*9880d681SAndroid Build Coastguard Worker     RANGE_CHECK_LOWER = 1,
104*9880d681SAndroid Build Coastguard Worker 
105*9880d681SAndroid Build Coastguard Worker     // Range check of the form "I < L" where L is known positive.
106*9880d681SAndroid Build Coastguard Worker     RANGE_CHECK_UPPER = 2,
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker     // The logical and of the RANGE_CHECK_LOWER and RANGE_CHECK_UPPER
109*9880d681SAndroid Build Coastguard Worker     // conditions.
110*9880d681SAndroid Build Coastguard Worker     RANGE_CHECK_BOTH = RANGE_CHECK_LOWER | RANGE_CHECK_UPPER,
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker     // Unrecognized range check condition.
113*9880d681SAndroid Build Coastguard Worker     RANGE_CHECK_UNKNOWN = (unsigned)-1
114*9880d681SAndroid Build Coastguard Worker   };
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   static StringRef rangeCheckKindToStr(RangeCheckKind);
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   const SCEV *Offset = nullptr;
119*9880d681SAndroid Build Coastguard Worker   const SCEV *Scale = nullptr;
120*9880d681SAndroid Build Coastguard Worker   Value *Length = nullptr;
121*9880d681SAndroid Build Coastguard Worker   Use *CheckUse = nullptr;
122*9880d681SAndroid Build Coastguard Worker   RangeCheckKind Kind = RANGE_CHECK_UNKNOWN;
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   static RangeCheckKind parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
125*9880d681SAndroid Build Coastguard Worker                                             ScalarEvolution &SE, Value *&Index,
126*9880d681SAndroid Build Coastguard Worker                                             Value *&Length);
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   static void
129*9880d681SAndroid Build Coastguard Worker   extractRangeChecksFromCond(Loop *L, ScalarEvolution &SE, Use &ConditionUse,
130*9880d681SAndroid Build Coastguard Worker                              SmallVectorImpl<InductiveRangeCheck> &Checks,
131*9880d681SAndroid Build Coastguard Worker                              SmallPtrSetImpl<Value *> &Visited);
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker public:
getOffset() const134*9880d681SAndroid Build Coastguard Worker   const SCEV *getOffset() const { return Offset; }
getScale() const135*9880d681SAndroid Build Coastguard Worker   const SCEV *getScale() const { return Scale; }
getLength() const136*9880d681SAndroid Build Coastguard Worker   Value *getLength() const { return Length; }
137*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS) const138*9880d681SAndroid Build Coastguard Worker   void print(raw_ostream &OS) const {
139*9880d681SAndroid Build Coastguard Worker     OS << "InductiveRangeCheck:\n";
140*9880d681SAndroid Build Coastguard Worker     OS << "  Kind: " << rangeCheckKindToStr(Kind) << "\n";
141*9880d681SAndroid Build Coastguard Worker     OS << "  Offset: ";
142*9880d681SAndroid Build Coastguard Worker     Offset->print(OS);
143*9880d681SAndroid Build Coastguard Worker     OS << "  Scale: ";
144*9880d681SAndroid Build Coastguard Worker     Scale->print(OS);
145*9880d681SAndroid Build Coastguard Worker     OS << "  Length: ";
146*9880d681SAndroid Build Coastguard Worker     if (Length)
147*9880d681SAndroid Build Coastguard Worker       Length->print(OS);
148*9880d681SAndroid Build Coastguard Worker     else
149*9880d681SAndroid Build Coastguard Worker       OS << "(null)";
150*9880d681SAndroid Build Coastguard Worker     OS << "\n  CheckUse: ";
151*9880d681SAndroid Build Coastguard Worker     getCheckUse()->getUser()->print(OS);
152*9880d681SAndroid Build Coastguard Worker     OS << " Operand: " << getCheckUse()->getOperandNo() << "\n";
153*9880d681SAndroid Build Coastguard Worker   }
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump()156*9880d681SAndroid Build Coastguard Worker   void dump() {
157*9880d681SAndroid Build Coastguard Worker     print(dbgs());
158*9880d681SAndroid Build Coastguard Worker   }
159*9880d681SAndroid Build Coastguard Worker #endif
160*9880d681SAndroid Build Coastguard Worker 
getCheckUse() const161*9880d681SAndroid Build Coastguard Worker   Use *getCheckUse() const { return CheckUse; }
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker   /// Represents an signed integer range [Range.getBegin(), Range.getEnd()).  If
164*9880d681SAndroid Build Coastguard Worker   /// R.getEnd() sle R.getBegin(), then R denotes the empty range.
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker   class Range {
167*9880d681SAndroid Build Coastguard Worker     const SCEV *Begin;
168*9880d681SAndroid Build Coastguard Worker     const SCEV *End;
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker   public:
Range(const SCEV * Begin,const SCEV * End)171*9880d681SAndroid Build Coastguard Worker     Range(const SCEV *Begin, const SCEV *End) : Begin(Begin), End(End) {
172*9880d681SAndroid Build Coastguard Worker       assert(Begin->getType() == End->getType() && "ill-typed range!");
173*9880d681SAndroid Build Coastguard Worker     }
174*9880d681SAndroid Build Coastguard Worker 
getType() const175*9880d681SAndroid Build Coastguard Worker     Type *getType() const { return Begin->getType(); }
getBegin() const176*9880d681SAndroid Build Coastguard Worker     const SCEV *getBegin() const { return Begin; }
getEnd() const177*9880d681SAndroid Build Coastguard Worker     const SCEV *getEnd() const { return End; }
178*9880d681SAndroid Build Coastguard Worker   };
179*9880d681SAndroid Build Coastguard Worker 
180*9880d681SAndroid Build Coastguard Worker   /// This is the value the condition of the branch needs to evaluate to for the
181*9880d681SAndroid Build Coastguard Worker   /// branch to take the hot successor (see (1) above).
getPassingDirection()182*9880d681SAndroid Build Coastguard Worker   bool getPassingDirection() { return true; }
183*9880d681SAndroid Build Coastguard Worker 
184*9880d681SAndroid Build Coastguard Worker   /// Computes a range for the induction variable (IndVar) in which the range
185*9880d681SAndroid Build Coastguard Worker   /// check is redundant and can be constant-folded away.  The induction
186*9880d681SAndroid Build Coastguard Worker   /// variable is not required to be the canonical {0,+,1} induction variable.
187*9880d681SAndroid Build Coastguard Worker   Optional<Range> computeSafeIterationSpace(ScalarEvolution &SE,
188*9880d681SAndroid Build Coastguard Worker                                             const SCEVAddRecExpr *IndVar) const;
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker   /// Parse out a set of inductive range checks from \p BI and append them to \p
191*9880d681SAndroid Build Coastguard Worker   /// Checks.
192*9880d681SAndroid Build Coastguard Worker   ///
193*9880d681SAndroid Build Coastguard Worker   /// NB! There may be conditions feeding into \p BI that aren't inductive range
194*9880d681SAndroid Build Coastguard Worker   /// checks, and hence don't end up in \p Checks.
195*9880d681SAndroid Build Coastguard Worker   static void
196*9880d681SAndroid Build Coastguard Worker   extractRangeChecksFromBranch(BranchInst *BI, Loop *L, ScalarEvolution &SE,
197*9880d681SAndroid Build Coastguard Worker                                BranchProbabilityInfo &BPI,
198*9880d681SAndroid Build Coastguard Worker                                SmallVectorImpl<InductiveRangeCheck> &Checks);
199*9880d681SAndroid Build Coastguard Worker };
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker class InductiveRangeCheckElimination : public LoopPass {
202*9880d681SAndroid Build Coastguard Worker public:
203*9880d681SAndroid Build Coastguard Worker   static char ID;
InductiveRangeCheckElimination()204*9880d681SAndroid Build Coastguard Worker   InductiveRangeCheckElimination() : LoopPass(ID) {
205*9880d681SAndroid Build Coastguard Worker     initializeInductiveRangeCheckEliminationPass(
206*9880d681SAndroid Build Coastguard Worker         *PassRegistry::getPassRegistry());
207*9880d681SAndroid Build Coastguard Worker   }
208*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const209*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
210*9880d681SAndroid Build Coastguard Worker     AU.addRequired<BranchProbabilityInfoWrapperPass>();
211*9880d681SAndroid Build Coastguard Worker     getLoopAnalysisUsage(AU);
212*9880d681SAndroid Build Coastguard Worker   }
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker   bool runOnLoop(Loop *L, LPPassManager &LPM) override;
215*9880d681SAndroid Build Coastguard Worker };
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker char InductiveRangeCheckElimination::ID = 0;
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(InductiveRangeCheckElimination, "irce",
221*9880d681SAndroid Build Coastguard Worker                       "Inductive range check elimination", false, false)
INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)222*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
223*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LoopPass)
224*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(InductiveRangeCheckElimination, "irce",
225*9880d681SAndroid Build Coastguard Worker                     "Inductive range check elimination", false, false)
226*9880d681SAndroid Build Coastguard Worker 
227*9880d681SAndroid Build Coastguard Worker StringRef InductiveRangeCheck::rangeCheckKindToStr(
228*9880d681SAndroid Build Coastguard Worker     InductiveRangeCheck::RangeCheckKind RCK) {
229*9880d681SAndroid Build Coastguard Worker   switch (RCK) {
230*9880d681SAndroid Build Coastguard Worker   case InductiveRangeCheck::RANGE_CHECK_UNKNOWN:
231*9880d681SAndroid Build Coastguard Worker     return "RANGE_CHECK_UNKNOWN";
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker   case InductiveRangeCheck::RANGE_CHECK_UPPER:
234*9880d681SAndroid Build Coastguard Worker     return "RANGE_CHECK_UPPER";
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   case InductiveRangeCheck::RANGE_CHECK_LOWER:
237*9880d681SAndroid Build Coastguard Worker     return "RANGE_CHECK_LOWER";
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker   case InductiveRangeCheck::RANGE_CHECK_BOTH:
240*9880d681SAndroid Build Coastguard Worker     return "RANGE_CHECK_BOTH";
241*9880d681SAndroid Build Coastguard Worker   }
242*9880d681SAndroid Build Coastguard Worker 
243*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("unknown range check type!");
244*9880d681SAndroid Build Coastguard Worker }
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker /// Parse a single ICmp instruction, `ICI`, into a range check.  If `ICI` cannot
247*9880d681SAndroid Build Coastguard Worker /// be interpreted as a range check, return `RANGE_CHECK_UNKNOWN` and set
248*9880d681SAndroid Build Coastguard Worker /// `Index` and `Length` to `nullptr`.  Otherwise set `Index` to the value being
249*9880d681SAndroid Build Coastguard Worker /// range checked, and set `Length` to the upper limit `Index` is being range
250*9880d681SAndroid Build Coastguard Worker /// checked with if (and only if) the range check type is stronger or equal to
251*9880d681SAndroid Build Coastguard Worker /// RANGE_CHECK_UPPER.
252*9880d681SAndroid Build Coastguard Worker ///
253*9880d681SAndroid Build Coastguard Worker InductiveRangeCheck::RangeCheckKind
parseRangeCheckICmp(Loop * L,ICmpInst * ICI,ScalarEvolution & SE,Value * & Index,Value * & Length)254*9880d681SAndroid Build Coastguard Worker InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
255*9880d681SAndroid Build Coastguard Worker                                          ScalarEvolution &SE, Value *&Index,
256*9880d681SAndroid Build Coastguard Worker                                          Value *&Length) {
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker   auto IsNonNegativeAndNotLoopVarying = [&SE, L](Value *V) {
259*9880d681SAndroid Build Coastguard Worker     const SCEV *S = SE.getSCEV(V);
260*9880d681SAndroid Build Coastguard Worker     if (isa<SCEVCouldNotCompute>(S))
261*9880d681SAndroid Build Coastguard Worker       return false;
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker     return SE.getLoopDisposition(S, L) == ScalarEvolution::LoopInvariant &&
264*9880d681SAndroid Build Coastguard Worker            SE.isKnownNonNegative(S);
265*9880d681SAndroid Build Coastguard Worker   };
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker   using namespace llvm::PatternMatch;
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker   ICmpInst::Predicate Pred = ICI->getPredicate();
270*9880d681SAndroid Build Coastguard Worker   Value *LHS = ICI->getOperand(0);
271*9880d681SAndroid Build Coastguard Worker   Value *RHS = ICI->getOperand(1);
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker   switch (Pred) {
274*9880d681SAndroid Build Coastguard Worker   default:
275*9880d681SAndroid Build Coastguard Worker     return RANGE_CHECK_UNKNOWN;
276*9880d681SAndroid Build Coastguard Worker 
277*9880d681SAndroid Build Coastguard Worker   case ICmpInst::ICMP_SLE:
278*9880d681SAndroid Build Coastguard Worker     std::swap(LHS, RHS);
279*9880d681SAndroid Build Coastguard Worker   // fallthrough
280*9880d681SAndroid Build Coastguard Worker   case ICmpInst::ICMP_SGE:
281*9880d681SAndroid Build Coastguard Worker     if (match(RHS, m_ConstantInt<0>())) {
282*9880d681SAndroid Build Coastguard Worker       Index = LHS;
283*9880d681SAndroid Build Coastguard Worker       return RANGE_CHECK_LOWER;
284*9880d681SAndroid Build Coastguard Worker     }
285*9880d681SAndroid Build Coastguard Worker     return RANGE_CHECK_UNKNOWN;
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker   case ICmpInst::ICMP_SLT:
288*9880d681SAndroid Build Coastguard Worker     std::swap(LHS, RHS);
289*9880d681SAndroid Build Coastguard Worker   // fallthrough
290*9880d681SAndroid Build Coastguard Worker   case ICmpInst::ICMP_SGT:
291*9880d681SAndroid Build Coastguard Worker     if (match(RHS, m_ConstantInt<-1>())) {
292*9880d681SAndroid Build Coastguard Worker       Index = LHS;
293*9880d681SAndroid Build Coastguard Worker       return RANGE_CHECK_LOWER;
294*9880d681SAndroid Build Coastguard Worker     }
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker     if (IsNonNegativeAndNotLoopVarying(LHS)) {
297*9880d681SAndroid Build Coastguard Worker       Index = RHS;
298*9880d681SAndroid Build Coastguard Worker       Length = LHS;
299*9880d681SAndroid Build Coastguard Worker       return RANGE_CHECK_UPPER;
300*9880d681SAndroid Build Coastguard Worker     }
301*9880d681SAndroid Build Coastguard Worker     return RANGE_CHECK_UNKNOWN;
302*9880d681SAndroid Build Coastguard Worker 
303*9880d681SAndroid Build Coastguard Worker   case ICmpInst::ICMP_ULT:
304*9880d681SAndroid Build Coastguard Worker     std::swap(LHS, RHS);
305*9880d681SAndroid Build Coastguard Worker   // fallthrough
306*9880d681SAndroid Build Coastguard Worker   case ICmpInst::ICMP_UGT:
307*9880d681SAndroid Build Coastguard Worker     if (IsNonNegativeAndNotLoopVarying(LHS)) {
308*9880d681SAndroid Build Coastguard Worker       Index = RHS;
309*9880d681SAndroid Build Coastguard Worker       Length = LHS;
310*9880d681SAndroid Build Coastguard Worker       return RANGE_CHECK_BOTH;
311*9880d681SAndroid Build Coastguard Worker     }
312*9880d681SAndroid Build Coastguard Worker     return RANGE_CHECK_UNKNOWN;
313*9880d681SAndroid Build Coastguard Worker   }
314*9880d681SAndroid Build Coastguard Worker 
315*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("default clause returns!");
316*9880d681SAndroid Build Coastguard Worker }
317*9880d681SAndroid Build Coastguard Worker 
extractRangeChecksFromCond(Loop * L,ScalarEvolution & SE,Use & ConditionUse,SmallVectorImpl<InductiveRangeCheck> & Checks,SmallPtrSetImpl<Value * > & Visited)318*9880d681SAndroid Build Coastguard Worker void InductiveRangeCheck::extractRangeChecksFromCond(
319*9880d681SAndroid Build Coastguard Worker     Loop *L, ScalarEvolution &SE, Use &ConditionUse,
320*9880d681SAndroid Build Coastguard Worker     SmallVectorImpl<InductiveRangeCheck> &Checks,
321*9880d681SAndroid Build Coastguard Worker     SmallPtrSetImpl<Value *> &Visited) {
322*9880d681SAndroid Build Coastguard Worker   using namespace llvm::PatternMatch;
323*9880d681SAndroid Build Coastguard Worker 
324*9880d681SAndroid Build Coastguard Worker   Value *Condition = ConditionUse.get();
325*9880d681SAndroid Build Coastguard Worker   if (!Visited.insert(Condition).second)
326*9880d681SAndroid Build Coastguard Worker     return;
327*9880d681SAndroid Build Coastguard Worker 
328*9880d681SAndroid Build Coastguard Worker   if (match(Condition, m_And(m_Value(), m_Value()))) {
329*9880d681SAndroid Build Coastguard Worker     SmallVector<InductiveRangeCheck, 8> SubChecks;
330*9880d681SAndroid Build Coastguard Worker     extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(0),
331*9880d681SAndroid Build Coastguard Worker                                SubChecks, Visited);
332*9880d681SAndroid Build Coastguard Worker     extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(1),
333*9880d681SAndroid Build Coastguard Worker                                SubChecks, Visited);
334*9880d681SAndroid Build Coastguard Worker 
335*9880d681SAndroid Build Coastguard Worker     if (SubChecks.size() == 2) {
336*9880d681SAndroid Build Coastguard Worker       // Handle a special case where we know how to merge two checks separately
337*9880d681SAndroid Build Coastguard Worker       // checking the upper and lower bounds into a full range check.
338*9880d681SAndroid Build Coastguard Worker       const auto &RChkA = SubChecks[0];
339*9880d681SAndroid Build Coastguard Worker       const auto &RChkB = SubChecks[1];
340*9880d681SAndroid Build Coastguard Worker       if ((RChkA.Length == RChkB.Length || !RChkA.Length || !RChkB.Length) &&
341*9880d681SAndroid Build Coastguard Worker           RChkA.Offset == RChkB.Offset && RChkA.Scale == RChkB.Scale) {
342*9880d681SAndroid Build Coastguard Worker 
343*9880d681SAndroid Build Coastguard Worker         // If RChkA.Kind == RChkB.Kind then we just found two identical checks.
344*9880d681SAndroid Build Coastguard Worker         // But if one of them is a RANGE_CHECK_LOWER and the other is a
345*9880d681SAndroid Build Coastguard Worker         // RANGE_CHECK_UPPER (only possibility if they're different) then
346*9880d681SAndroid Build Coastguard Worker         // together they form a RANGE_CHECK_BOTH.
347*9880d681SAndroid Build Coastguard Worker         SubChecks[0].Kind =
348*9880d681SAndroid Build Coastguard Worker             (InductiveRangeCheck::RangeCheckKind)(RChkA.Kind | RChkB.Kind);
349*9880d681SAndroid Build Coastguard Worker         SubChecks[0].Length = RChkA.Length ? RChkA.Length : RChkB.Length;
350*9880d681SAndroid Build Coastguard Worker         SubChecks[0].CheckUse = &ConditionUse;
351*9880d681SAndroid Build Coastguard Worker 
352*9880d681SAndroid Build Coastguard Worker         // We updated one of the checks in place, now erase the other.
353*9880d681SAndroid Build Coastguard Worker         SubChecks.pop_back();
354*9880d681SAndroid Build Coastguard Worker       }
355*9880d681SAndroid Build Coastguard Worker     }
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker     Checks.insert(Checks.end(), SubChecks.begin(), SubChecks.end());
358*9880d681SAndroid Build Coastguard Worker     return;
359*9880d681SAndroid Build Coastguard Worker   }
360*9880d681SAndroid Build Coastguard Worker 
361*9880d681SAndroid Build Coastguard Worker   ICmpInst *ICI = dyn_cast<ICmpInst>(Condition);
362*9880d681SAndroid Build Coastguard Worker   if (!ICI)
363*9880d681SAndroid Build Coastguard Worker     return;
364*9880d681SAndroid Build Coastguard Worker 
365*9880d681SAndroid Build Coastguard Worker   Value *Length = nullptr, *Index;
366*9880d681SAndroid Build Coastguard Worker   auto RCKind = parseRangeCheckICmp(L, ICI, SE, Index, Length);
367*9880d681SAndroid Build Coastguard Worker   if (RCKind == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
368*9880d681SAndroid Build Coastguard Worker     return;
369*9880d681SAndroid Build Coastguard Worker 
370*9880d681SAndroid Build Coastguard Worker   const auto *IndexAddRec = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(Index));
371*9880d681SAndroid Build Coastguard Worker   bool IsAffineIndex =
372*9880d681SAndroid Build Coastguard Worker       IndexAddRec && (IndexAddRec->getLoop() == L) && IndexAddRec->isAffine();
373*9880d681SAndroid Build Coastguard Worker 
374*9880d681SAndroid Build Coastguard Worker   if (!IsAffineIndex)
375*9880d681SAndroid Build Coastguard Worker     return;
376*9880d681SAndroid Build Coastguard Worker 
377*9880d681SAndroid Build Coastguard Worker   InductiveRangeCheck IRC;
378*9880d681SAndroid Build Coastguard Worker   IRC.Length = Length;
379*9880d681SAndroid Build Coastguard Worker   IRC.Offset = IndexAddRec->getStart();
380*9880d681SAndroid Build Coastguard Worker   IRC.Scale = IndexAddRec->getStepRecurrence(SE);
381*9880d681SAndroid Build Coastguard Worker   IRC.CheckUse = &ConditionUse;
382*9880d681SAndroid Build Coastguard Worker   IRC.Kind = RCKind;
383*9880d681SAndroid Build Coastguard Worker   Checks.push_back(IRC);
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker 
extractRangeChecksFromBranch(BranchInst * BI,Loop * L,ScalarEvolution & SE,BranchProbabilityInfo & BPI,SmallVectorImpl<InductiveRangeCheck> & Checks)386*9880d681SAndroid Build Coastguard Worker void InductiveRangeCheck::extractRangeChecksFromBranch(
387*9880d681SAndroid Build Coastguard Worker     BranchInst *BI, Loop *L, ScalarEvolution &SE, BranchProbabilityInfo &BPI,
388*9880d681SAndroid Build Coastguard Worker     SmallVectorImpl<InductiveRangeCheck> &Checks) {
389*9880d681SAndroid Build Coastguard Worker 
390*9880d681SAndroid Build Coastguard Worker   if (BI->isUnconditional() || BI->getParent() == L->getLoopLatch())
391*9880d681SAndroid Build Coastguard Worker     return;
392*9880d681SAndroid Build Coastguard Worker 
393*9880d681SAndroid Build Coastguard Worker   BranchProbability LikelyTaken(15, 16);
394*9880d681SAndroid Build Coastguard Worker 
395*9880d681SAndroid Build Coastguard Worker   if (BPI.getEdgeProbability(BI->getParent(), (unsigned)0) < LikelyTaken)
396*9880d681SAndroid Build Coastguard Worker     return;
397*9880d681SAndroid Build Coastguard Worker 
398*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<Value *, 8> Visited;
399*9880d681SAndroid Build Coastguard Worker   InductiveRangeCheck::extractRangeChecksFromCond(L, SE, BI->getOperandUse(0),
400*9880d681SAndroid Build Coastguard Worker                                                   Checks, Visited);
401*9880d681SAndroid Build Coastguard Worker }
402*9880d681SAndroid Build Coastguard Worker 
403*9880d681SAndroid Build Coastguard Worker namespace {
404*9880d681SAndroid Build Coastguard Worker 
405*9880d681SAndroid Build Coastguard Worker // Keeps track of the structure of a loop.  This is similar to llvm::Loop,
406*9880d681SAndroid Build Coastguard Worker // except that it is more lightweight and can track the state of a loop through
407*9880d681SAndroid Build Coastguard Worker // changing and potentially invalid IR.  This structure also formalizes the
408*9880d681SAndroid Build Coastguard Worker // kinds of loops we can deal with -- ones that have a single latch that is also
409*9880d681SAndroid Build Coastguard Worker // an exiting block *and* have a canonical induction variable.
410*9880d681SAndroid Build Coastguard Worker struct LoopStructure {
411*9880d681SAndroid Build Coastguard Worker   const char *Tag;
412*9880d681SAndroid Build Coastguard Worker 
413*9880d681SAndroid Build Coastguard Worker   BasicBlock *Header;
414*9880d681SAndroid Build Coastguard Worker   BasicBlock *Latch;
415*9880d681SAndroid Build Coastguard Worker 
416*9880d681SAndroid Build Coastguard Worker   // `Latch's terminator instruction is `LatchBr', and it's `LatchBrExitIdx'th
417*9880d681SAndroid Build Coastguard Worker   // successor is `LatchExit', the exit block of the loop.
418*9880d681SAndroid Build Coastguard Worker   BranchInst *LatchBr;
419*9880d681SAndroid Build Coastguard Worker   BasicBlock *LatchExit;
420*9880d681SAndroid Build Coastguard Worker   unsigned LatchBrExitIdx;
421*9880d681SAndroid Build Coastguard Worker 
422*9880d681SAndroid Build Coastguard Worker   Value *IndVarNext;
423*9880d681SAndroid Build Coastguard Worker   Value *IndVarStart;
424*9880d681SAndroid Build Coastguard Worker   Value *LoopExitAt;
425*9880d681SAndroid Build Coastguard Worker   bool IndVarIncreasing;
426*9880d681SAndroid Build Coastguard Worker 
LoopStructure__anon16a840fa0311::LoopStructure427*9880d681SAndroid Build Coastguard Worker   LoopStructure()
428*9880d681SAndroid Build Coastguard Worker       : Tag(""), Header(nullptr), Latch(nullptr), LatchBr(nullptr),
429*9880d681SAndroid Build Coastguard Worker         LatchExit(nullptr), LatchBrExitIdx(-1), IndVarNext(nullptr),
430*9880d681SAndroid Build Coastguard Worker         IndVarStart(nullptr), LoopExitAt(nullptr), IndVarIncreasing(false) {}
431*9880d681SAndroid Build Coastguard Worker 
map__anon16a840fa0311::LoopStructure432*9880d681SAndroid Build Coastguard Worker   template <typename M> LoopStructure map(M Map) const {
433*9880d681SAndroid Build Coastguard Worker     LoopStructure Result;
434*9880d681SAndroid Build Coastguard Worker     Result.Tag = Tag;
435*9880d681SAndroid Build Coastguard Worker     Result.Header = cast<BasicBlock>(Map(Header));
436*9880d681SAndroid Build Coastguard Worker     Result.Latch = cast<BasicBlock>(Map(Latch));
437*9880d681SAndroid Build Coastguard Worker     Result.LatchBr = cast<BranchInst>(Map(LatchBr));
438*9880d681SAndroid Build Coastguard Worker     Result.LatchExit = cast<BasicBlock>(Map(LatchExit));
439*9880d681SAndroid Build Coastguard Worker     Result.LatchBrExitIdx = LatchBrExitIdx;
440*9880d681SAndroid Build Coastguard Worker     Result.IndVarNext = Map(IndVarNext);
441*9880d681SAndroid Build Coastguard Worker     Result.IndVarStart = Map(IndVarStart);
442*9880d681SAndroid Build Coastguard Worker     Result.LoopExitAt = Map(LoopExitAt);
443*9880d681SAndroid Build Coastguard Worker     Result.IndVarIncreasing = IndVarIncreasing;
444*9880d681SAndroid Build Coastguard Worker     return Result;
445*9880d681SAndroid Build Coastguard Worker   }
446*9880d681SAndroid Build Coastguard Worker 
447*9880d681SAndroid Build Coastguard Worker   static Optional<LoopStructure> parseLoopStructure(ScalarEvolution &,
448*9880d681SAndroid Build Coastguard Worker                                                     BranchProbabilityInfo &BPI,
449*9880d681SAndroid Build Coastguard Worker                                                     Loop &,
450*9880d681SAndroid Build Coastguard Worker                                                     const char *&);
451*9880d681SAndroid Build Coastguard Worker };
452*9880d681SAndroid Build Coastguard Worker 
453*9880d681SAndroid Build Coastguard Worker /// This class is used to constrain loops to run within a given iteration space.
454*9880d681SAndroid Build Coastguard Worker /// The algorithm this class implements is given a Loop and a range [Begin,
455*9880d681SAndroid Build Coastguard Worker /// End).  The algorithm then tries to break out a "main loop" out of the loop
456*9880d681SAndroid Build Coastguard Worker /// it is given in a way that the "main loop" runs with the induction variable
457*9880d681SAndroid Build Coastguard Worker /// in a subset of [Begin, End).  The algorithm emits appropriate pre and post
458*9880d681SAndroid Build Coastguard Worker /// loops to run any remaining iterations.  The pre loop runs any iterations in
459*9880d681SAndroid Build Coastguard Worker /// which the induction variable is < Begin, and the post loop runs any
460*9880d681SAndroid Build Coastguard Worker /// iterations in which the induction variable is >= End.
461*9880d681SAndroid Build Coastguard Worker ///
462*9880d681SAndroid Build Coastguard Worker class LoopConstrainer {
463*9880d681SAndroid Build Coastguard Worker   // The representation of a clone of the original loop we started out with.
464*9880d681SAndroid Build Coastguard Worker   struct ClonedLoop {
465*9880d681SAndroid Build Coastguard Worker     // The cloned blocks
466*9880d681SAndroid Build Coastguard Worker     std::vector<BasicBlock *> Blocks;
467*9880d681SAndroid Build Coastguard Worker 
468*9880d681SAndroid Build Coastguard Worker     // `Map` maps values in the clonee into values in the cloned version
469*9880d681SAndroid Build Coastguard Worker     ValueToValueMapTy Map;
470*9880d681SAndroid Build Coastguard Worker 
471*9880d681SAndroid Build Coastguard Worker     // An instance of `LoopStructure` for the cloned loop
472*9880d681SAndroid Build Coastguard Worker     LoopStructure Structure;
473*9880d681SAndroid Build Coastguard Worker   };
474*9880d681SAndroid Build Coastguard Worker 
475*9880d681SAndroid Build Coastguard Worker   // Result of rewriting the range of a loop.  See changeIterationSpaceEnd for
476*9880d681SAndroid Build Coastguard Worker   // more details on what these fields mean.
477*9880d681SAndroid Build Coastguard Worker   struct RewrittenRangeInfo {
478*9880d681SAndroid Build Coastguard Worker     BasicBlock *PseudoExit;
479*9880d681SAndroid Build Coastguard Worker     BasicBlock *ExitSelector;
480*9880d681SAndroid Build Coastguard Worker     std::vector<PHINode *> PHIValuesAtPseudoExit;
481*9880d681SAndroid Build Coastguard Worker     PHINode *IndVarEnd;
482*9880d681SAndroid Build Coastguard Worker 
RewrittenRangeInfo__anon16a840fa0311::LoopConstrainer::RewrittenRangeInfo483*9880d681SAndroid Build Coastguard Worker     RewrittenRangeInfo()
484*9880d681SAndroid Build Coastguard Worker         : PseudoExit(nullptr), ExitSelector(nullptr), IndVarEnd(nullptr) {}
485*9880d681SAndroid Build Coastguard Worker   };
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker   // Calculated subranges we restrict the iteration space of the main loop to.
488*9880d681SAndroid Build Coastguard Worker   // See the implementation of `calculateSubRanges' for more details on how
489*9880d681SAndroid Build Coastguard Worker   // these fields are computed.  `LowLimit` is None if there is no restriction
490*9880d681SAndroid Build Coastguard Worker   // on low end of the restricted iteration space of the main loop.  `HighLimit`
491*9880d681SAndroid Build Coastguard Worker   // is None if there is no restriction on high end of the restricted iteration
492*9880d681SAndroid Build Coastguard Worker   // space of the main loop.
493*9880d681SAndroid Build Coastguard Worker 
494*9880d681SAndroid Build Coastguard Worker   struct SubRanges {
495*9880d681SAndroid Build Coastguard Worker     Optional<const SCEV *> LowLimit;
496*9880d681SAndroid Build Coastguard Worker     Optional<const SCEV *> HighLimit;
497*9880d681SAndroid Build Coastguard Worker   };
498*9880d681SAndroid Build Coastguard Worker 
499*9880d681SAndroid Build Coastguard Worker   // A utility function that does a `replaceUsesOfWith' on the incoming block
500*9880d681SAndroid Build Coastguard Worker   // set of a `PHINode' -- replaces instances of `Block' in the `PHINode's
501*9880d681SAndroid Build Coastguard Worker   // incoming block list with `ReplaceBy'.
502*9880d681SAndroid Build Coastguard Worker   static void replacePHIBlock(PHINode *PN, BasicBlock *Block,
503*9880d681SAndroid Build Coastguard Worker                               BasicBlock *ReplaceBy);
504*9880d681SAndroid Build Coastguard Worker 
505*9880d681SAndroid Build Coastguard Worker   // Compute a safe set of limits for the main loop to run in -- effectively the
506*9880d681SAndroid Build Coastguard Worker   // intersection of `Range' and the iteration space of the original loop.
507*9880d681SAndroid Build Coastguard Worker   // Return None if unable to compute the set of subranges.
508*9880d681SAndroid Build Coastguard Worker   //
509*9880d681SAndroid Build Coastguard Worker   Optional<SubRanges> calculateSubRanges() const;
510*9880d681SAndroid Build Coastguard Worker 
511*9880d681SAndroid Build Coastguard Worker   // Clone `OriginalLoop' and return the result in CLResult.  The IR after
512*9880d681SAndroid Build Coastguard Worker   // running `cloneLoop' is well formed except for the PHI nodes in CLResult --
513*9880d681SAndroid Build Coastguard Worker   // the PHI nodes say that there is an incoming edge from `OriginalPreheader`
514*9880d681SAndroid Build Coastguard Worker   // but there is no such edge.
515*9880d681SAndroid Build Coastguard Worker   //
516*9880d681SAndroid Build Coastguard Worker   void cloneLoop(ClonedLoop &CLResult, const char *Tag) const;
517*9880d681SAndroid Build Coastguard Worker 
518*9880d681SAndroid Build Coastguard Worker   // Rewrite the iteration space of the loop denoted by (LS, Preheader). The
519*9880d681SAndroid Build Coastguard Worker   // iteration space of the rewritten loop ends at ExitLoopAt.  The start of the
520*9880d681SAndroid Build Coastguard Worker   // iteration space is not changed.  `ExitLoopAt' is assumed to be slt
521*9880d681SAndroid Build Coastguard Worker   // `OriginalHeaderCount'.
522*9880d681SAndroid Build Coastguard Worker   //
523*9880d681SAndroid Build Coastguard Worker   // If there are iterations left to execute, control is made to jump to
524*9880d681SAndroid Build Coastguard Worker   // `ContinuationBlock', otherwise they take the normal loop exit.  The
525*9880d681SAndroid Build Coastguard Worker   // returned `RewrittenRangeInfo' object is populated as follows:
526*9880d681SAndroid Build Coastguard Worker   //
527*9880d681SAndroid Build Coastguard Worker   //  .PseudoExit is a basic block that unconditionally branches to
528*9880d681SAndroid Build Coastguard Worker   //      `ContinuationBlock'.
529*9880d681SAndroid Build Coastguard Worker   //
530*9880d681SAndroid Build Coastguard Worker   //  .ExitSelector is a basic block that decides, on exit from the loop,
531*9880d681SAndroid Build Coastguard Worker   //      whether to branch to the "true" exit or to `PseudoExit'.
532*9880d681SAndroid Build Coastguard Worker   //
533*9880d681SAndroid Build Coastguard Worker   //  .PHIValuesAtPseudoExit are PHINodes in `PseudoExit' that compute the value
534*9880d681SAndroid Build Coastguard Worker   //      for each PHINode in the loop header on taking the pseudo exit.
535*9880d681SAndroid Build Coastguard Worker   //
536*9880d681SAndroid Build Coastguard Worker   // After changeIterationSpaceEnd, `Preheader' is no longer a legitimate
537*9880d681SAndroid Build Coastguard Worker   // preheader because it is made to branch to the loop header only
538*9880d681SAndroid Build Coastguard Worker   // conditionally.
539*9880d681SAndroid Build Coastguard Worker   //
540*9880d681SAndroid Build Coastguard Worker   RewrittenRangeInfo
541*9880d681SAndroid Build Coastguard Worker   changeIterationSpaceEnd(const LoopStructure &LS, BasicBlock *Preheader,
542*9880d681SAndroid Build Coastguard Worker                           Value *ExitLoopAt,
543*9880d681SAndroid Build Coastguard Worker                           BasicBlock *ContinuationBlock) const;
544*9880d681SAndroid Build Coastguard Worker 
545*9880d681SAndroid Build Coastguard Worker   // The loop denoted by `LS' has `OldPreheader' as its preheader.  This
546*9880d681SAndroid Build Coastguard Worker   // function creates a new preheader for `LS' and returns it.
547*9880d681SAndroid Build Coastguard Worker   //
548*9880d681SAndroid Build Coastguard Worker   BasicBlock *createPreheader(const LoopStructure &LS, BasicBlock *OldPreheader,
549*9880d681SAndroid Build Coastguard Worker                               const char *Tag) const;
550*9880d681SAndroid Build Coastguard Worker 
551*9880d681SAndroid Build Coastguard Worker   // `ContinuationBlockAndPreheader' was the continuation block for some call to
552*9880d681SAndroid Build Coastguard Worker   // `changeIterationSpaceEnd' and is the preheader to the loop denoted by `LS'.
553*9880d681SAndroid Build Coastguard Worker   // This function rewrites the PHI nodes in `LS.Header' to start with the
554*9880d681SAndroid Build Coastguard Worker   // correct value.
555*9880d681SAndroid Build Coastguard Worker   void rewriteIncomingValuesForPHIs(
556*9880d681SAndroid Build Coastguard Worker       LoopStructure &LS, BasicBlock *ContinuationBlockAndPreheader,
557*9880d681SAndroid Build Coastguard Worker       const LoopConstrainer::RewrittenRangeInfo &RRI) const;
558*9880d681SAndroid Build Coastguard Worker 
559*9880d681SAndroid Build Coastguard Worker   // Even though we do not preserve any passes at this time, we at least need to
560*9880d681SAndroid Build Coastguard Worker   // keep the parent loop structure consistent.  The `LPPassManager' seems to
561*9880d681SAndroid Build Coastguard Worker   // verify this after running a loop pass.  This function adds the list of
562*9880d681SAndroid Build Coastguard Worker   // blocks denoted by BBs to this loops parent loop if required.
563*9880d681SAndroid Build Coastguard Worker   void addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs);
564*9880d681SAndroid Build Coastguard Worker 
565*9880d681SAndroid Build Coastguard Worker   // Some global state.
566*9880d681SAndroid Build Coastguard Worker   Function &F;
567*9880d681SAndroid Build Coastguard Worker   LLVMContext &Ctx;
568*9880d681SAndroid Build Coastguard Worker   ScalarEvolution &SE;
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker   // Information about the original loop we started out with.
571*9880d681SAndroid Build Coastguard Worker   Loop &OriginalLoop;
572*9880d681SAndroid Build Coastguard Worker   LoopInfo &OriginalLoopInfo;
573*9880d681SAndroid Build Coastguard Worker   const SCEV *LatchTakenCount;
574*9880d681SAndroid Build Coastguard Worker   BasicBlock *OriginalPreheader;
575*9880d681SAndroid Build Coastguard Worker 
576*9880d681SAndroid Build Coastguard Worker   // The preheader of the main loop.  This may or may not be different from
577*9880d681SAndroid Build Coastguard Worker   // `OriginalPreheader'.
578*9880d681SAndroid Build Coastguard Worker   BasicBlock *MainLoopPreheader;
579*9880d681SAndroid Build Coastguard Worker 
580*9880d681SAndroid Build Coastguard Worker   // The range we need to run the main loop in.
581*9880d681SAndroid Build Coastguard Worker   InductiveRangeCheck::Range Range;
582*9880d681SAndroid Build Coastguard Worker 
583*9880d681SAndroid Build Coastguard Worker   // The structure of the main loop (see comment at the beginning of this class
584*9880d681SAndroid Build Coastguard Worker   // for a definition)
585*9880d681SAndroid Build Coastguard Worker   LoopStructure MainLoopStructure;
586*9880d681SAndroid Build Coastguard Worker 
587*9880d681SAndroid Build Coastguard Worker public:
LoopConstrainer(Loop & L,LoopInfo & LI,const LoopStructure & LS,ScalarEvolution & SE,InductiveRangeCheck::Range R)588*9880d681SAndroid Build Coastguard Worker   LoopConstrainer(Loop &L, LoopInfo &LI, const LoopStructure &LS,
589*9880d681SAndroid Build Coastguard Worker                   ScalarEvolution &SE, InductiveRangeCheck::Range R)
590*9880d681SAndroid Build Coastguard Worker       : F(*L.getHeader()->getParent()), Ctx(L.getHeader()->getContext()),
591*9880d681SAndroid Build Coastguard Worker         SE(SE), OriginalLoop(L), OriginalLoopInfo(LI), LatchTakenCount(nullptr),
592*9880d681SAndroid Build Coastguard Worker         OriginalPreheader(nullptr), MainLoopPreheader(nullptr), Range(R),
593*9880d681SAndroid Build Coastguard Worker         MainLoopStructure(LS) {}
594*9880d681SAndroid Build Coastguard Worker 
595*9880d681SAndroid Build Coastguard Worker   // Entry point for the algorithm.  Returns true on success.
596*9880d681SAndroid Build Coastguard Worker   bool run();
597*9880d681SAndroid Build Coastguard Worker };
598*9880d681SAndroid Build Coastguard Worker 
599*9880d681SAndroid Build Coastguard Worker }
600*9880d681SAndroid Build Coastguard Worker 
replacePHIBlock(PHINode * PN,BasicBlock * Block,BasicBlock * ReplaceBy)601*9880d681SAndroid Build Coastguard Worker void LoopConstrainer::replacePHIBlock(PHINode *PN, BasicBlock *Block,
602*9880d681SAndroid Build Coastguard Worker                                       BasicBlock *ReplaceBy) {
603*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
604*9880d681SAndroid Build Coastguard Worker     if (PN->getIncomingBlock(i) == Block)
605*9880d681SAndroid Build Coastguard Worker       PN->setIncomingBlock(i, ReplaceBy);
606*9880d681SAndroid Build Coastguard Worker }
607*9880d681SAndroid Build Coastguard Worker 
CanBeSMax(ScalarEvolution & SE,const SCEV * S)608*9880d681SAndroid Build Coastguard Worker static bool CanBeSMax(ScalarEvolution &SE, const SCEV *S) {
609*9880d681SAndroid Build Coastguard Worker   APInt SMax =
610*9880d681SAndroid Build Coastguard Worker       APInt::getSignedMaxValue(cast<IntegerType>(S->getType())->getBitWidth());
611*9880d681SAndroid Build Coastguard Worker   return SE.getSignedRange(S).contains(SMax) &&
612*9880d681SAndroid Build Coastguard Worker          SE.getUnsignedRange(S).contains(SMax);
613*9880d681SAndroid Build Coastguard Worker }
614*9880d681SAndroid Build Coastguard Worker 
CanBeSMin(ScalarEvolution & SE,const SCEV * S)615*9880d681SAndroid Build Coastguard Worker static bool CanBeSMin(ScalarEvolution &SE, const SCEV *S) {
616*9880d681SAndroid Build Coastguard Worker   APInt SMin =
617*9880d681SAndroid Build Coastguard Worker       APInt::getSignedMinValue(cast<IntegerType>(S->getType())->getBitWidth());
618*9880d681SAndroid Build Coastguard Worker   return SE.getSignedRange(S).contains(SMin) &&
619*9880d681SAndroid Build Coastguard Worker          SE.getUnsignedRange(S).contains(SMin);
620*9880d681SAndroid Build Coastguard Worker }
621*9880d681SAndroid Build Coastguard Worker 
622*9880d681SAndroid Build Coastguard Worker Optional<LoopStructure>
parseLoopStructure(ScalarEvolution & SE,BranchProbabilityInfo & BPI,Loop & L,const char * & FailureReason)623*9880d681SAndroid Build Coastguard Worker LoopStructure::parseLoopStructure(ScalarEvolution &SE, BranchProbabilityInfo &BPI,
624*9880d681SAndroid Build Coastguard Worker                                   Loop &L, const char *&FailureReason) {
625*9880d681SAndroid Build Coastguard Worker   assert(L.isLoopSimplifyForm() && "should follow from addRequired<>");
626*9880d681SAndroid Build Coastguard Worker 
627*9880d681SAndroid Build Coastguard Worker   BasicBlock *Latch = L.getLoopLatch();
628*9880d681SAndroid Build Coastguard Worker   if (!L.isLoopExiting(Latch)) {
629*9880d681SAndroid Build Coastguard Worker     FailureReason = "no loop latch";
630*9880d681SAndroid Build Coastguard Worker     return None;
631*9880d681SAndroid Build Coastguard Worker   }
632*9880d681SAndroid Build Coastguard Worker 
633*9880d681SAndroid Build Coastguard Worker   BasicBlock *Header = L.getHeader();
634*9880d681SAndroid Build Coastguard Worker   BasicBlock *Preheader = L.getLoopPreheader();
635*9880d681SAndroid Build Coastguard Worker   if (!Preheader) {
636*9880d681SAndroid Build Coastguard Worker     FailureReason = "no preheader";
637*9880d681SAndroid Build Coastguard Worker     return None;
638*9880d681SAndroid Build Coastguard Worker   }
639*9880d681SAndroid Build Coastguard Worker 
640*9880d681SAndroid Build Coastguard Worker   BranchInst *LatchBr = dyn_cast<BranchInst>(Latch->getTerminator());
641*9880d681SAndroid Build Coastguard Worker   if (!LatchBr || LatchBr->isUnconditional()) {
642*9880d681SAndroid Build Coastguard Worker     FailureReason = "latch terminator not conditional branch";
643*9880d681SAndroid Build Coastguard Worker     return None;
644*9880d681SAndroid Build Coastguard Worker   }
645*9880d681SAndroid Build Coastguard Worker 
646*9880d681SAndroid Build Coastguard Worker   unsigned LatchBrExitIdx = LatchBr->getSuccessor(0) == Header ? 1 : 0;
647*9880d681SAndroid Build Coastguard Worker 
648*9880d681SAndroid Build Coastguard Worker   BranchProbability ExitProbability =
649*9880d681SAndroid Build Coastguard Worker     BPI.getEdgeProbability(LatchBr->getParent(), LatchBrExitIdx);
650*9880d681SAndroid Build Coastguard Worker 
651*9880d681SAndroid Build Coastguard Worker   if (ExitProbability > BranchProbability(1, MaxExitProbReciprocal)) {
652*9880d681SAndroid Build Coastguard Worker     FailureReason = "short running loop, not profitable";
653*9880d681SAndroid Build Coastguard Worker     return None;
654*9880d681SAndroid Build Coastguard Worker   }
655*9880d681SAndroid Build Coastguard Worker 
656*9880d681SAndroid Build Coastguard Worker   ICmpInst *ICI = dyn_cast<ICmpInst>(LatchBr->getCondition());
657*9880d681SAndroid Build Coastguard Worker   if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType())) {
658*9880d681SAndroid Build Coastguard Worker     FailureReason = "latch terminator branch not conditional on integral icmp";
659*9880d681SAndroid Build Coastguard Worker     return None;
660*9880d681SAndroid Build Coastguard Worker   }
661*9880d681SAndroid Build Coastguard Worker 
662*9880d681SAndroid Build Coastguard Worker   const SCEV *LatchCount = SE.getExitCount(&L, Latch);
663*9880d681SAndroid Build Coastguard Worker   if (isa<SCEVCouldNotCompute>(LatchCount)) {
664*9880d681SAndroid Build Coastguard Worker     FailureReason = "could not compute latch count";
665*9880d681SAndroid Build Coastguard Worker     return None;
666*9880d681SAndroid Build Coastguard Worker   }
667*9880d681SAndroid Build Coastguard Worker 
668*9880d681SAndroid Build Coastguard Worker   ICmpInst::Predicate Pred = ICI->getPredicate();
669*9880d681SAndroid Build Coastguard Worker   Value *LeftValue = ICI->getOperand(0);
670*9880d681SAndroid Build Coastguard Worker   const SCEV *LeftSCEV = SE.getSCEV(LeftValue);
671*9880d681SAndroid Build Coastguard Worker   IntegerType *IndVarTy = cast<IntegerType>(LeftValue->getType());
672*9880d681SAndroid Build Coastguard Worker 
673*9880d681SAndroid Build Coastguard Worker   Value *RightValue = ICI->getOperand(1);
674*9880d681SAndroid Build Coastguard Worker   const SCEV *RightSCEV = SE.getSCEV(RightValue);
675*9880d681SAndroid Build Coastguard Worker 
676*9880d681SAndroid Build Coastguard Worker   // We canonicalize `ICI` such that `LeftSCEV` is an add recurrence.
677*9880d681SAndroid Build Coastguard Worker   if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
678*9880d681SAndroid Build Coastguard Worker     if (isa<SCEVAddRecExpr>(RightSCEV)) {
679*9880d681SAndroid Build Coastguard Worker       std::swap(LeftSCEV, RightSCEV);
680*9880d681SAndroid Build Coastguard Worker       std::swap(LeftValue, RightValue);
681*9880d681SAndroid Build Coastguard Worker       Pred = ICmpInst::getSwappedPredicate(Pred);
682*9880d681SAndroid Build Coastguard Worker     } else {
683*9880d681SAndroid Build Coastguard Worker       FailureReason = "no add recurrences in the icmp";
684*9880d681SAndroid Build Coastguard Worker       return None;
685*9880d681SAndroid Build Coastguard Worker     }
686*9880d681SAndroid Build Coastguard Worker   }
687*9880d681SAndroid Build Coastguard Worker 
688*9880d681SAndroid Build Coastguard Worker   auto HasNoSignedWrap = [&](const SCEVAddRecExpr *AR) {
689*9880d681SAndroid Build Coastguard Worker     if (AR->getNoWrapFlags(SCEV::FlagNSW))
690*9880d681SAndroid Build Coastguard Worker       return true;
691*9880d681SAndroid Build Coastguard Worker 
692*9880d681SAndroid Build Coastguard Worker     IntegerType *Ty = cast<IntegerType>(AR->getType());
693*9880d681SAndroid Build Coastguard Worker     IntegerType *WideTy =
694*9880d681SAndroid Build Coastguard Worker         IntegerType::get(Ty->getContext(), Ty->getBitWidth() * 2);
695*9880d681SAndroid Build Coastguard Worker 
696*9880d681SAndroid Build Coastguard Worker     const SCEVAddRecExpr *ExtendAfterOp =
697*9880d681SAndroid Build Coastguard Worker         dyn_cast<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy));
698*9880d681SAndroid Build Coastguard Worker     if (ExtendAfterOp) {
699*9880d681SAndroid Build Coastguard Worker       const SCEV *ExtendedStart = SE.getSignExtendExpr(AR->getStart(), WideTy);
700*9880d681SAndroid Build Coastguard Worker       const SCEV *ExtendedStep =
701*9880d681SAndroid Build Coastguard Worker           SE.getSignExtendExpr(AR->getStepRecurrence(SE), WideTy);
702*9880d681SAndroid Build Coastguard Worker 
703*9880d681SAndroid Build Coastguard Worker       bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart &&
704*9880d681SAndroid Build Coastguard Worker                           ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep;
705*9880d681SAndroid Build Coastguard Worker 
706*9880d681SAndroid Build Coastguard Worker       if (NoSignedWrap)
707*9880d681SAndroid Build Coastguard Worker         return true;
708*9880d681SAndroid Build Coastguard Worker     }
709*9880d681SAndroid Build Coastguard Worker 
710*9880d681SAndroid Build Coastguard Worker     // We may have proved this when computing the sign extension above.
711*9880d681SAndroid Build Coastguard Worker     return AR->getNoWrapFlags(SCEV::FlagNSW) != SCEV::FlagAnyWrap;
712*9880d681SAndroid Build Coastguard Worker   };
713*9880d681SAndroid Build Coastguard Worker 
714*9880d681SAndroid Build Coastguard Worker   auto IsInductionVar = [&](const SCEVAddRecExpr *AR, bool &IsIncreasing) {
715*9880d681SAndroid Build Coastguard Worker     if (!AR->isAffine())
716*9880d681SAndroid Build Coastguard Worker       return false;
717*9880d681SAndroid Build Coastguard Worker 
718*9880d681SAndroid Build Coastguard Worker     // Currently we only work with induction variables that have been proved to
719*9880d681SAndroid Build Coastguard Worker     // not wrap.  This restriction can potentially be lifted in the future.
720*9880d681SAndroid Build Coastguard Worker 
721*9880d681SAndroid Build Coastguard Worker     if (!HasNoSignedWrap(AR))
722*9880d681SAndroid Build Coastguard Worker       return false;
723*9880d681SAndroid Build Coastguard Worker 
724*9880d681SAndroid Build Coastguard Worker     if (const SCEVConstant *StepExpr =
725*9880d681SAndroid Build Coastguard Worker             dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE))) {
726*9880d681SAndroid Build Coastguard Worker       ConstantInt *StepCI = StepExpr->getValue();
727*9880d681SAndroid Build Coastguard Worker       if (StepCI->isOne() || StepCI->isMinusOne()) {
728*9880d681SAndroid Build Coastguard Worker         IsIncreasing = StepCI->isOne();
729*9880d681SAndroid Build Coastguard Worker         return true;
730*9880d681SAndroid Build Coastguard Worker       }
731*9880d681SAndroid Build Coastguard Worker     }
732*9880d681SAndroid Build Coastguard Worker 
733*9880d681SAndroid Build Coastguard Worker     return false;
734*9880d681SAndroid Build Coastguard Worker   };
735*9880d681SAndroid Build Coastguard Worker 
736*9880d681SAndroid Build Coastguard Worker   // `ICI` is interpreted as taking the backedge if the *next* value of the
737*9880d681SAndroid Build Coastguard Worker   // induction variable satisfies some constraint.
738*9880d681SAndroid Build Coastguard Worker 
739*9880d681SAndroid Build Coastguard Worker   const SCEVAddRecExpr *IndVarNext = cast<SCEVAddRecExpr>(LeftSCEV);
740*9880d681SAndroid Build Coastguard Worker   bool IsIncreasing = false;
741*9880d681SAndroid Build Coastguard Worker   if (!IsInductionVar(IndVarNext, IsIncreasing)) {
742*9880d681SAndroid Build Coastguard Worker     FailureReason = "LHS in icmp not induction variable";
743*9880d681SAndroid Build Coastguard Worker     return None;
744*9880d681SAndroid Build Coastguard Worker   }
745*9880d681SAndroid Build Coastguard Worker 
746*9880d681SAndroid Build Coastguard Worker   ConstantInt *One = ConstantInt::get(IndVarTy, 1);
747*9880d681SAndroid Build Coastguard Worker   // TODO: generalize the predicates here to also match their unsigned variants.
748*9880d681SAndroid Build Coastguard Worker   if (IsIncreasing) {
749*9880d681SAndroid Build Coastguard Worker     bool FoundExpectedPred =
750*9880d681SAndroid Build Coastguard Worker         (Pred == ICmpInst::ICMP_SLT && LatchBrExitIdx == 1) ||
751*9880d681SAndroid Build Coastguard Worker         (Pred == ICmpInst::ICMP_SGT && LatchBrExitIdx == 0);
752*9880d681SAndroid Build Coastguard Worker 
753*9880d681SAndroid Build Coastguard Worker     if (!FoundExpectedPred) {
754*9880d681SAndroid Build Coastguard Worker       FailureReason = "expected icmp slt semantically, found something else";
755*9880d681SAndroid Build Coastguard Worker       return None;
756*9880d681SAndroid Build Coastguard Worker     }
757*9880d681SAndroid Build Coastguard Worker 
758*9880d681SAndroid Build Coastguard Worker     if (LatchBrExitIdx == 0) {
759*9880d681SAndroid Build Coastguard Worker       if (CanBeSMax(SE, RightSCEV)) {
760*9880d681SAndroid Build Coastguard Worker         // TODO: this restriction is easily removable -- we just have to
761*9880d681SAndroid Build Coastguard Worker         // remember that the icmp was an slt and not an sle.
762*9880d681SAndroid Build Coastguard Worker         FailureReason = "limit may overflow when coercing sle to slt";
763*9880d681SAndroid Build Coastguard Worker         return None;
764*9880d681SAndroid Build Coastguard Worker       }
765*9880d681SAndroid Build Coastguard Worker 
766*9880d681SAndroid Build Coastguard Worker       IRBuilder<> B(Preheader->getTerminator());
767*9880d681SAndroid Build Coastguard Worker       RightValue = B.CreateAdd(RightValue, One);
768*9880d681SAndroid Build Coastguard Worker     }
769*9880d681SAndroid Build Coastguard Worker 
770*9880d681SAndroid Build Coastguard Worker   } else {
771*9880d681SAndroid Build Coastguard Worker     bool FoundExpectedPred =
772*9880d681SAndroid Build Coastguard Worker         (Pred == ICmpInst::ICMP_SGT && LatchBrExitIdx == 1) ||
773*9880d681SAndroid Build Coastguard Worker         (Pred == ICmpInst::ICMP_SLT && LatchBrExitIdx == 0);
774*9880d681SAndroid Build Coastguard Worker 
775*9880d681SAndroid Build Coastguard Worker     if (!FoundExpectedPred) {
776*9880d681SAndroid Build Coastguard Worker       FailureReason = "expected icmp sgt semantically, found something else";
777*9880d681SAndroid Build Coastguard Worker       return None;
778*9880d681SAndroid Build Coastguard Worker     }
779*9880d681SAndroid Build Coastguard Worker 
780*9880d681SAndroid Build Coastguard Worker     if (LatchBrExitIdx == 0) {
781*9880d681SAndroid Build Coastguard Worker       if (CanBeSMin(SE, RightSCEV)) {
782*9880d681SAndroid Build Coastguard Worker         // TODO: this restriction is easily removable -- we just have to
783*9880d681SAndroid Build Coastguard Worker         // remember that the icmp was an sgt and not an sge.
784*9880d681SAndroid Build Coastguard Worker         FailureReason = "limit may overflow when coercing sge to sgt";
785*9880d681SAndroid Build Coastguard Worker         return None;
786*9880d681SAndroid Build Coastguard Worker       }
787*9880d681SAndroid Build Coastguard Worker 
788*9880d681SAndroid Build Coastguard Worker       IRBuilder<> B(Preheader->getTerminator());
789*9880d681SAndroid Build Coastguard Worker       RightValue = B.CreateSub(RightValue, One);
790*9880d681SAndroid Build Coastguard Worker     }
791*9880d681SAndroid Build Coastguard Worker   }
792*9880d681SAndroid Build Coastguard Worker 
793*9880d681SAndroid Build Coastguard Worker   const SCEV *StartNext = IndVarNext->getStart();
794*9880d681SAndroid Build Coastguard Worker   const SCEV *Addend = SE.getNegativeSCEV(IndVarNext->getStepRecurrence(SE));
795*9880d681SAndroid Build Coastguard Worker   const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend);
796*9880d681SAndroid Build Coastguard Worker 
797*9880d681SAndroid Build Coastguard Worker   BasicBlock *LatchExit = LatchBr->getSuccessor(LatchBrExitIdx);
798*9880d681SAndroid Build Coastguard Worker 
799*9880d681SAndroid Build Coastguard Worker   assert(SE.getLoopDisposition(LatchCount, &L) ==
800*9880d681SAndroid Build Coastguard Worker              ScalarEvolution::LoopInvariant &&
801*9880d681SAndroid Build Coastguard Worker          "loop variant exit count doesn't make sense!");
802*9880d681SAndroid Build Coastguard Worker 
803*9880d681SAndroid Build Coastguard Worker   assert(!L.contains(LatchExit) && "expected an exit block!");
804*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = Preheader->getModule()->getDataLayout();
805*9880d681SAndroid Build Coastguard Worker   Value *IndVarStartV =
806*9880d681SAndroid Build Coastguard Worker       SCEVExpander(SE, DL, "irce")
807*9880d681SAndroid Build Coastguard Worker           .expandCodeFor(IndVarStart, IndVarTy, Preheader->getTerminator());
808*9880d681SAndroid Build Coastguard Worker   IndVarStartV->setName("indvar.start");
809*9880d681SAndroid Build Coastguard Worker 
810*9880d681SAndroid Build Coastguard Worker   LoopStructure Result;
811*9880d681SAndroid Build Coastguard Worker 
812*9880d681SAndroid Build Coastguard Worker   Result.Tag = "main";
813*9880d681SAndroid Build Coastguard Worker   Result.Header = Header;
814*9880d681SAndroid Build Coastguard Worker   Result.Latch = Latch;
815*9880d681SAndroid Build Coastguard Worker   Result.LatchBr = LatchBr;
816*9880d681SAndroid Build Coastguard Worker   Result.LatchExit = LatchExit;
817*9880d681SAndroid Build Coastguard Worker   Result.LatchBrExitIdx = LatchBrExitIdx;
818*9880d681SAndroid Build Coastguard Worker   Result.IndVarStart = IndVarStartV;
819*9880d681SAndroid Build Coastguard Worker   Result.IndVarNext = LeftValue;
820*9880d681SAndroid Build Coastguard Worker   Result.IndVarIncreasing = IsIncreasing;
821*9880d681SAndroid Build Coastguard Worker   Result.LoopExitAt = RightValue;
822*9880d681SAndroid Build Coastguard Worker 
823*9880d681SAndroid Build Coastguard Worker   FailureReason = nullptr;
824*9880d681SAndroid Build Coastguard Worker 
825*9880d681SAndroid Build Coastguard Worker   return Result;
826*9880d681SAndroid Build Coastguard Worker }
827*9880d681SAndroid Build Coastguard Worker 
828*9880d681SAndroid Build Coastguard Worker Optional<LoopConstrainer::SubRanges>
calculateSubRanges() const829*9880d681SAndroid Build Coastguard Worker LoopConstrainer::calculateSubRanges() const {
830*9880d681SAndroid Build Coastguard Worker   IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
831*9880d681SAndroid Build Coastguard Worker 
832*9880d681SAndroid Build Coastguard Worker   if (Range.getType() != Ty)
833*9880d681SAndroid Build Coastguard Worker     return None;
834*9880d681SAndroid Build Coastguard Worker 
835*9880d681SAndroid Build Coastguard Worker   LoopConstrainer::SubRanges Result;
836*9880d681SAndroid Build Coastguard Worker 
837*9880d681SAndroid Build Coastguard Worker   // I think we can be more aggressive here and make this nuw / nsw if the
838*9880d681SAndroid Build Coastguard Worker   // addition that feeds into the icmp for the latch's terminating branch is nuw
839*9880d681SAndroid Build Coastguard Worker   // / nsw.  In any case, a wrapping 2's complement addition is safe.
840*9880d681SAndroid Build Coastguard Worker   ConstantInt *One = ConstantInt::get(Ty, 1);
841*9880d681SAndroid Build Coastguard Worker   const SCEV *Start = SE.getSCEV(MainLoopStructure.IndVarStart);
842*9880d681SAndroid Build Coastguard Worker   const SCEV *End = SE.getSCEV(MainLoopStructure.LoopExitAt);
843*9880d681SAndroid Build Coastguard Worker 
844*9880d681SAndroid Build Coastguard Worker   bool Increasing = MainLoopStructure.IndVarIncreasing;
845*9880d681SAndroid Build Coastguard Worker 
846*9880d681SAndroid Build Coastguard Worker   // We compute `Smallest` and `Greatest` such that [Smallest, Greatest) is the
847*9880d681SAndroid Build Coastguard Worker   // range of values the induction variable takes.
848*9880d681SAndroid Build Coastguard Worker 
849*9880d681SAndroid Build Coastguard Worker   const SCEV *Smallest = nullptr, *Greatest = nullptr;
850*9880d681SAndroid Build Coastguard Worker 
851*9880d681SAndroid Build Coastguard Worker   if (Increasing) {
852*9880d681SAndroid Build Coastguard Worker     Smallest = Start;
853*9880d681SAndroid Build Coastguard Worker     Greatest = End;
854*9880d681SAndroid Build Coastguard Worker   } else {
855*9880d681SAndroid Build Coastguard Worker     // These two computations may sign-overflow.  Here is why that is okay:
856*9880d681SAndroid Build Coastguard Worker     //
857*9880d681SAndroid Build Coastguard Worker     // We know that the induction variable does not sign-overflow on any
858*9880d681SAndroid Build Coastguard Worker     // iteration except the last one, and it starts at `Start` and ends at
859*9880d681SAndroid Build Coastguard Worker     // `End`, decrementing by one every time.
860*9880d681SAndroid Build Coastguard Worker     //
861*9880d681SAndroid Build Coastguard Worker     //  * if `Smallest` sign-overflows we know `End` is `INT_SMAX`. Since the
862*9880d681SAndroid Build Coastguard Worker     //    induction variable is decreasing we know that that the smallest value
863*9880d681SAndroid Build Coastguard Worker     //    the loop body is actually executed with is `INT_SMIN` == `Smallest`.
864*9880d681SAndroid Build Coastguard Worker     //
865*9880d681SAndroid Build Coastguard Worker     //  * if `Greatest` sign-overflows, we know it can only be `INT_SMIN`.  In
866*9880d681SAndroid Build Coastguard Worker     //    that case, `Clamp` will always return `Smallest` and
867*9880d681SAndroid Build Coastguard Worker     //    [`Result.LowLimit`, `Result.HighLimit`) = [`Smallest`, `Smallest`)
868*9880d681SAndroid Build Coastguard Worker     //    will be an empty range.  Returning an empty range is always safe.
869*9880d681SAndroid Build Coastguard Worker     //
870*9880d681SAndroid Build Coastguard Worker 
871*9880d681SAndroid Build Coastguard Worker     Smallest = SE.getAddExpr(End, SE.getSCEV(One));
872*9880d681SAndroid Build Coastguard Worker     Greatest = SE.getAddExpr(Start, SE.getSCEV(One));
873*9880d681SAndroid Build Coastguard Worker   }
874*9880d681SAndroid Build Coastguard Worker 
875*9880d681SAndroid Build Coastguard Worker   auto Clamp = [this, Smallest, Greatest](const SCEV *S) {
876*9880d681SAndroid Build Coastguard Worker     return SE.getSMaxExpr(Smallest, SE.getSMinExpr(Greatest, S));
877*9880d681SAndroid Build Coastguard Worker   };
878*9880d681SAndroid Build Coastguard Worker 
879*9880d681SAndroid Build Coastguard Worker   // In some cases we can prove that we don't need a pre or post loop
880*9880d681SAndroid Build Coastguard Worker 
881*9880d681SAndroid Build Coastguard Worker   bool ProvablyNoPreloop =
882*9880d681SAndroid Build Coastguard Worker       SE.isKnownPredicate(ICmpInst::ICMP_SLE, Range.getBegin(), Smallest);
883*9880d681SAndroid Build Coastguard Worker   if (!ProvablyNoPreloop)
884*9880d681SAndroid Build Coastguard Worker     Result.LowLimit = Clamp(Range.getBegin());
885*9880d681SAndroid Build Coastguard Worker 
886*9880d681SAndroid Build Coastguard Worker   bool ProvablyNoPostLoop =
887*9880d681SAndroid Build Coastguard Worker       SE.isKnownPredicate(ICmpInst::ICMP_SLE, Greatest, Range.getEnd());
888*9880d681SAndroid Build Coastguard Worker   if (!ProvablyNoPostLoop)
889*9880d681SAndroid Build Coastguard Worker     Result.HighLimit = Clamp(Range.getEnd());
890*9880d681SAndroid Build Coastguard Worker 
891*9880d681SAndroid Build Coastguard Worker   return Result;
892*9880d681SAndroid Build Coastguard Worker }
893*9880d681SAndroid Build Coastguard Worker 
cloneLoop(LoopConstrainer::ClonedLoop & Result,const char * Tag) const894*9880d681SAndroid Build Coastguard Worker void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result,
895*9880d681SAndroid Build Coastguard Worker                                 const char *Tag) const {
896*9880d681SAndroid Build Coastguard Worker   for (BasicBlock *BB : OriginalLoop.getBlocks()) {
897*9880d681SAndroid Build Coastguard Worker     BasicBlock *Clone = CloneBasicBlock(BB, Result.Map, Twine(".") + Tag, &F);
898*9880d681SAndroid Build Coastguard Worker     Result.Blocks.push_back(Clone);
899*9880d681SAndroid Build Coastguard Worker     Result.Map[BB] = Clone;
900*9880d681SAndroid Build Coastguard Worker   }
901*9880d681SAndroid Build Coastguard Worker 
902*9880d681SAndroid Build Coastguard Worker   auto GetClonedValue = [&Result](Value *V) {
903*9880d681SAndroid Build Coastguard Worker     assert(V && "null values not in domain!");
904*9880d681SAndroid Build Coastguard Worker     auto It = Result.Map.find(V);
905*9880d681SAndroid Build Coastguard Worker     if (It == Result.Map.end())
906*9880d681SAndroid Build Coastguard Worker       return V;
907*9880d681SAndroid Build Coastguard Worker     return static_cast<Value *>(It->second);
908*9880d681SAndroid Build Coastguard Worker   };
909*9880d681SAndroid Build Coastguard Worker 
910*9880d681SAndroid Build Coastguard Worker   Result.Structure = MainLoopStructure.map(GetClonedValue);
911*9880d681SAndroid Build Coastguard Worker   Result.Structure.Tag = Tag;
912*9880d681SAndroid Build Coastguard Worker 
913*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = Result.Blocks.size(); i != e; ++i) {
914*9880d681SAndroid Build Coastguard Worker     BasicBlock *ClonedBB = Result.Blocks[i];
915*9880d681SAndroid Build Coastguard Worker     BasicBlock *OriginalBB = OriginalLoop.getBlocks()[i];
916*9880d681SAndroid Build Coastguard Worker 
917*9880d681SAndroid Build Coastguard Worker     assert(Result.Map[OriginalBB] == ClonedBB && "invariant!");
918*9880d681SAndroid Build Coastguard Worker 
919*9880d681SAndroid Build Coastguard Worker     for (Instruction &I : *ClonedBB)
920*9880d681SAndroid Build Coastguard Worker       RemapInstruction(&I, Result.Map,
921*9880d681SAndroid Build Coastguard Worker                        RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
922*9880d681SAndroid Build Coastguard Worker 
923*9880d681SAndroid Build Coastguard Worker     // Exit blocks will now have one more predecessor and their PHI nodes need
924*9880d681SAndroid Build Coastguard Worker     // to be edited to reflect that.  No phi nodes need to be introduced because
925*9880d681SAndroid Build Coastguard Worker     // the loop is in LCSSA.
926*9880d681SAndroid Build Coastguard Worker 
927*9880d681SAndroid Build Coastguard Worker     for (auto SBBI = succ_begin(OriginalBB), SBBE = succ_end(OriginalBB);
928*9880d681SAndroid Build Coastguard Worker          SBBI != SBBE; ++SBBI) {
929*9880d681SAndroid Build Coastguard Worker 
930*9880d681SAndroid Build Coastguard Worker       if (OriginalLoop.contains(*SBBI))
931*9880d681SAndroid Build Coastguard Worker         continue; // not an exit block
932*9880d681SAndroid Build Coastguard Worker 
933*9880d681SAndroid Build Coastguard Worker       for (Instruction &I : **SBBI) {
934*9880d681SAndroid Build Coastguard Worker         if (!isa<PHINode>(&I))
935*9880d681SAndroid Build Coastguard Worker           break;
936*9880d681SAndroid Build Coastguard Worker 
937*9880d681SAndroid Build Coastguard Worker         PHINode *PN = cast<PHINode>(&I);
938*9880d681SAndroid Build Coastguard Worker         Value *OldIncoming = PN->getIncomingValueForBlock(OriginalBB);
939*9880d681SAndroid Build Coastguard Worker         PN->addIncoming(GetClonedValue(OldIncoming), ClonedBB);
940*9880d681SAndroid Build Coastguard Worker       }
941*9880d681SAndroid Build Coastguard Worker     }
942*9880d681SAndroid Build Coastguard Worker   }
943*9880d681SAndroid Build Coastguard Worker }
944*9880d681SAndroid Build Coastguard Worker 
changeIterationSpaceEnd(const LoopStructure & LS,BasicBlock * Preheader,Value * ExitSubloopAt,BasicBlock * ContinuationBlock) const945*9880d681SAndroid Build Coastguard Worker LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd(
946*9880d681SAndroid Build Coastguard Worker     const LoopStructure &LS, BasicBlock *Preheader, Value *ExitSubloopAt,
947*9880d681SAndroid Build Coastguard Worker     BasicBlock *ContinuationBlock) const {
948*9880d681SAndroid Build Coastguard Worker 
949*9880d681SAndroid Build Coastguard Worker   // We start with a loop with a single latch:
950*9880d681SAndroid Build Coastguard Worker   //
951*9880d681SAndroid Build Coastguard Worker   //    +--------------------+
952*9880d681SAndroid Build Coastguard Worker   //    |                    |
953*9880d681SAndroid Build Coastguard Worker   //    |     preheader      |
954*9880d681SAndroid Build Coastguard Worker   //    |                    |
955*9880d681SAndroid Build Coastguard Worker   //    +--------+-----------+
956*9880d681SAndroid Build Coastguard Worker   //             |      ----------------\
957*9880d681SAndroid Build Coastguard Worker   //             |     /                |
958*9880d681SAndroid Build Coastguard Worker   //    +--------v----v------+          |
959*9880d681SAndroid Build Coastguard Worker   //    |                    |          |
960*9880d681SAndroid Build Coastguard Worker   //    |      header        |          |
961*9880d681SAndroid Build Coastguard Worker   //    |                    |          |
962*9880d681SAndroid Build Coastguard Worker   //    +--------------------+          |
963*9880d681SAndroid Build Coastguard Worker   //                                    |
964*9880d681SAndroid Build Coastguard Worker   //            .....                   |
965*9880d681SAndroid Build Coastguard Worker   //                                    |
966*9880d681SAndroid Build Coastguard Worker   //    +--------------------+          |
967*9880d681SAndroid Build Coastguard Worker   //    |                    |          |
968*9880d681SAndroid Build Coastguard Worker   //    |       latch        >----------/
969*9880d681SAndroid Build Coastguard Worker   //    |                    |
970*9880d681SAndroid Build Coastguard Worker   //    +-------v------------+
971*9880d681SAndroid Build Coastguard Worker   //            |
972*9880d681SAndroid Build Coastguard Worker   //            |
973*9880d681SAndroid Build Coastguard Worker   //            |   +--------------------+
974*9880d681SAndroid Build Coastguard Worker   //            |   |                    |
975*9880d681SAndroid Build Coastguard Worker   //            +--->   original exit    |
976*9880d681SAndroid Build Coastguard Worker   //                |                    |
977*9880d681SAndroid Build Coastguard Worker   //                +--------------------+
978*9880d681SAndroid Build Coastguard Worker   //
979*9880d681SAndroid Build Coastguard Worker   // We change the control flow to look like
980*9880d681SAndroid Build Coastguard Worker   //
981*9880d681SAndroid Build Coastguard Worker   //
982*9880d681SAndroid Build Coastguard Worker   //    +--------------------+
983*9880d681SAndroid Build Coastguard Worker   //    |                    |
984*9880d681SAndroid Build Coastguard Worker   //    |     preheader      >-------------------------+
985*9880d681SAndroid Build Coastguard Worker   //    |                    |                         |
986*9880d681SAndroid Build Coastguard Worker   //    +--------v-----------+                         |
987*9880d681SAndroid Build Coastguard Worker   //             |    /-------------+                  |
988*9880d681SAndroid Build Coastguard Worker   //             |   /              |                  |
989*9880d681SAndroid Build Coastguard Worker   //    +--------v--v--------+      |                  |
990*9880d681SAndroid Build Coastguard Worker   //    |                    |      |                  |
991*9880d681SAndroid Build Coastguard Worker   //    |      header        |      |   +--------+     |
992*9880d681SAndroid Build Coastguard Worker   //    |                    |      |   |        |     |
993*9880d681SAndroid Build Coastguard Worker   //    +--------------------+      |   |  +-----v-----v-----------+
994*9880d681SAndroid Build Coastguard Worker   //                                |   |  |                       |
995*9880d681SAndroid Build Coastguard Worker   //                                |   |  |     .pseudo.exit      |
996*9880d681SAndroid Build Coastguard Worker   //                                |   |  |                       |
997*9880d681SAndroid Build Coastguard Worker   //                                |   |  +-----------v-----------+
998*9880d681SAndroid Build Coastguard Worker   //                                |   |              |
999*9880d681SAndroid Build Coastguard Worker   //            .....               |   |              |
1000*9880d681SAndroid Build Coastguard Worker   //                                |   |     +--------v-------------+
1001*9880d681SAndroid Build Coastguard Worker   //    +--------------------+      |   |     |                      |
1002*9880d681SAndroid Build Coastguard Worker   //    |                    |      |   |     |   ContinuationBlock  |
1003*9880d681SAndroid Build Coastguard Worker   //    |       latch        >------+   |     |                      |
1004*9880d681SAndroid Build Coastguard Worker   //    |                    |          |     +----------------------+
1005*9880d681SAndroid Build Coastguard Worker   //    +---------v----------+          |
1006*9880d681SAndroid Build Coastguard Worker   //              |                     |
1007*9880d681SAndroid Build Coastguard Worker   //              |                     |
1008*9880d681SAndroid Build Coastguard Worker   //              |     +---------------^-----+
1009*9880d681SAndroid Build Coastguard Worker   //              |     |                     |
1010*9880d681SAndroid Build Coastguard Worker   //              +----->    .exit.selector   |
1011*9880d681SAndroid Build Coastguard Worker   //                    |                     |
1012*9880d681SAndroid Build Coastguard Worker   //                    +----------v----------+
1013*9880d681SAndroid Build Coastguard Worker   //                               |
1014*9880d681SAndroid Build Coastguard Worker   //     +--------------------+    |
1015*9880d681SAndroid Build Coastguard Worker   //     |                    |    |
1016*9880d681SAndroid Build Coastguard Worker   //     |   original exit    <----+
1017*9880d681SAndroid Build Coastguard Worker   //     |                    |
1018*9880d681SAndroid Build Coastguard Worker   //     +--------------------+
1019*9880d681SAndroid Build Coastguard Worker   //
1020*9880d681SAndroid Build Coastguard Worker 
1021*9880d681SAndroid Build Coastguard Worker   RewrittenRangeInfo RRI;
1022*9880d681SAndroid Build Coastguard Worker 
1023*9880d681SAndroid Build Coastguard Worker   auto BBInsertLocation = std::next(Function::iterator(LS.Latch));
1024*9880d681SAndroid Build Coastguard Worker   RRI.ExitSelector = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".exit.selector",
1025*9880d681SAndroid Build Coastguard Worker                                         &F, &*BBInsertLocation);
1026*9880d681SAndroid Build Coastguard Worker   RRI.PseudoExit = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".pseudo.exit", &F,
1027*9880d681SAndroid Build Coastguard Worker                                       &*BBInsertLocation);
1028*9880d681SAndroid Build Coastguard Worker 
1029*9880d681SAndroid Build Coastguard Worker   BranchInst *PreheaderJump = cast<BranchInst>(Preheader->getTerminator());
1030*9880d681SAndroid Build Coastguard Worker   bool Increasing = LS.IndVarIncreasing;
1031*9880d681SAndroid Build Coastguard Worker 
1032*9880d681SAndroid Build Coastguard Worker   IRBuilder<> B(PreheaderJump);
1033*9880d681SAndroid Build Coastguard Worker 
1034*9880d681SAndroid Build Coastguard Worker   // EnterLoopCond - is it okay to start executing this `LS'?
1035*9880d681SAndroid Build Coastguard Worker   Value *EnterLoopCond = Increasing
1036*9880d681SAndroid Build Coastguard Worker                              ? B.CreateICmpSLT(LS.IndVarStart, ExitSubloopAt)
1037*9880d681SAndroid Build Coastguard Worker                              : B.CreateICmpSGT(LS.IndVarStart, ExitSubloopAt);
1038*9880d681SAndroid Build Coastguard Worker 
1039*9880d681SAndroid Build Coastguard Worker   B.CreateCondBr(EnterLoopCond, LS.Header, RRI.PseudoExit);
1040*9880d681SAndroid Build Coastguard Worker   PreheaderJump->eraseFromParent();
1041*9880d681SAndroid Build Coastguard Worker 
1042*9880d681SAndroid Build Coastguard Worker   LS.LatchBr->setSuccessor(LS.LatchBrExitIdx, RRI.ExitSelector);
1043*9880d681SAndroid Build Coastguard Worker   B.SetInsertPoint(LS.LatchBr);
1044*9880d681SAndroid Build Coastguard Worker   Value *TakeBackedgeLoopCond =
1045*9880d681SAndroid Build Coastguard Worker       Increasing ? B.CreateICmpSLT(LS.IndVarNext, ExitSubloopAt)
1046*9880d681SAndroid Build Coastguard Worker                  : B.CreateICmpSGT(LS.IndVarNext, ExitSubloopAt);
1047*9880d681SAndroid Build Coastguard Worker   Value *CondForBranch = LS.LatchBrExitIdx == 1
1048*9880d681SAndroid Build Coastguard Worker                              ? TakeBackedgeLoopCond
1049*9880d681SAndroid Build Coastguard Worker                              : B.CreateNot(TakeBackedgeLoopCond);
1050*9880d681SAndroid Build Coastguard Worker 
1051*9880d681SAndroid Build Coastguard Worker   LS.LatchBr->setCondition(CondForBranch);
1052*9880d681SAndroid Build Coastguard Worker 
1053*9880d681SAndroid Build Coastguard Worker   B.SetInsertPoint(RRI.ExitSelector);
1054*9880d681SAndroid Build Coastguard Worker 
1055*9880d681SAndroid Build Coastguard Worker   // IterationsLeft - are there any more iterations left, given the original
1056*9880d681SAndroid Build Coastguard Worker   // upper bound on the induction variable?  If not, we branch to the "real"
1057*9880d681SAndroid Build Coastguard Worker   // exit.
1058*9880d681SAndroid Build Coastguard Worker   Value *IterationsLeft = Increasing
1059*9880d681SAndroid Build Coastguard Worker                               ? B.CreateICmpSLT(LS.IndVarNext, LS.LoopExitAt)
1060*9880d681SAndroid Build Coastguard Worker                               : B.CreateICmpSGT(LS.IndVarNext, LS.LoopExitAt);
1061*9880d681SAndroid Build Coastguard Worker   B.CreateCondBr(IterationsLeft, RRI.PseudoExit, LS.LatchExit);
1062*9880d681SAndroid Build Coastguard Worker 
1063*9880d681SAndroid Build Coastguard Worker   BranchInst *BranchToContinuation =
1064*9880d681SAndroid Build Coastguard Worker       BranchInst::Create(ContinuationBlock, RRI.PseudoExit);
1065*9880d681SAndroid Build Coastguard Worker 
1066*9880d681SAndroid Build Coastguard Worker   // We emit PHI nodes into `RRI.PseudoExit' that compute the "latest" value of
1067*9880d681SAndroid Build Coastguard Worker   // each of the PHI nodes in the loop header.  This feeds into the initial
1068*9880d681SAndroid Build Coastguard Worker   // value of the same PHI nodes if/when we continue execution.
1069*9880d681SAndroid Build Coastguard Worker   for (Instruction &I : *LS.Header) {
1070*9880d681SAndroid Build Coastguard Worker     if (!isa<PHINode>(&I))
1071*9880d681SAndroid Build Coastguard Worker       break;
1072*9880d681SAndroid Build Coastguard Worker 
1073*9880d681SAndroid Build Coastguard Worker     PHINode *PN = cast<PHINode>(&I);
1074*9880d681SAndroid Build Coastguard Worker 
1075*9880d681SAndroid Build Coastguard Worker     PHINode *NewPHI = PHINode::Create(PN->getType(), 2, PN->getName() + ".copy",
1076*9880d681SAndroid Build Coastguard Worker                                       BranchToContinuation);
1077*9880d681SAndroid Build Coastguard Worker 
1078*9880d681SAndroid Build Coastguard Worker     NewPHI->addIncoming(PN->getIncomingValueForBlock(Preheader), Preheader);
1079*9880d681SAndroid Build Coastguard Worker     NewPHI->addIncoming(PN->getIncomingValueForBlock(LS.Latch),
1080*9880d681SAndroid Build Coastguard Worker                         RRI.ExitSelector);
1081*9880d681SAndroid Build Coastguard Worker     RRI.PHIValuesAtPseudoExit.push_back(NewPHI);
1082*9880d681SAndroid Build Coastguard Worker   }
1083*9880d681SAndroid Build Coastguard Worker 
1084*9880d681SAndroid Build Coastguard Worker   RRI.IndVarEnd = PHINode::Create(LS.IndVarNext->getType(), 2, "indvar.end",
1085*9880d681SAndroid Build Coastguard Worker                                   BranchToContinuation);
1086*9880d681SAndroid Build Coastguard Worker   RRI.IndVarEnd->addIncoming(LS.IndVarStart, Preheader);
1087*9880d681SAndroid Build Coastguard Worker   RRI.IndVarEnd->addIncoming(LS.IndVarNext, RRI.ExitSelector);
1088*9880d681SAndroid Build Coastguard Worker 
1089*9880d681SAndroid Build Coastguard Worker   // The latch exit now has a branch from `RRI.ExitSelector' instead of
1090*9880d681SAndroid Build Coastguard Worker   // `LS.Latch'.  The PHI nodes need to be updated to reflect that.
1091*9880d681SAndroid Build Coastguard Worker   for (Instruction &I : *LS.LatchExit) {
1092*9880d681SAndroid Build Coastguard Worker     if (PHINode *PN = dyn_cast<PHINode>(&I))
1093*9880d681SAndroid Build Coastguard Worker       replacePHIBlock(PN, LS.Latch, RRI.ExitSelector);
1094*9880d681SAndroid Build Coastguard Worker     else
1095*9880d681SAndroid Build Coastguard Worker       break;
1096*9880d681SAndroid Build Coastguard Worker   }
1097*9880d681SAndroid Build Coastguard Worker 
1098*9880d681SAndroid Build Coastguard Worker   return RRI;
1099*9880d681SAndroid Build Coastguard Worker }
1100*9880d681SAndroid Build Coastguard Worker 
rewriteIncomingValuesForPHIs(LoopStructure & LS,BasicBlock * ContinuationBlock,const LoopConstrainer::RewrittenRangeInfo & RRI) const1101*9880d681SAndroid Build Coastguard Worker void LoopConstrainer::rewriteIncomingValuesForPHIs(
1102*9880d681SAndroid Build Coastguard Worker     LoopStructure &LS, BasicBlock *ContinuationBlock,
1103*9880d681SAndroid Build Coastguard Worker     const LoopConstrainer::RewrittenRangeInfo &RRI) const {
1104*9880d681SAndroid Build Coastguard Worker 
1105*9880d681SAndroid Build Coastguard Worker   unsigned PHIIndex = 0;
1106*9880d681SAndroid Build Coastguard Worker   for (Instruction &I : *LS.Header) {
1107*9880d681SAndroid Build Coastguard Worker     if (!isa<PHINode>(&I))
1108*9880d681SAndroid Build Coastguard Worker       break;
1109*9880d681SAndroid Build Coastguard Worker 
1110*9880d681SAndroid Build Coastguard Worker     PHINode *PN = cast<PHINode>(&I);
1111*9880d681SAndroid Build Coastguard Worker 
1112*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i)
1113*9880d681SAndroid Build Coastguard Worker       if (PN->getIncomingBlock(i) == ContinuationBlock)
1114*9880d681SAndroid Build Coastguard Worker         PN->setIncomingValue(i, RRI.PHIValuesAtPseudoExit[PHIIndex++]);
1115*9880d681SAndroid Build Coastguard Worker   }
1116*9880d681SAndroid Build Coastguard Worker 
1117*9880d681SAndroid Build Coastguard Worker   LS.IndVarStart = RRI.IndVarEnd;
1118*9880d681SAndroid Build Coastguard Worker }
1119*9880d681SAndroid Build Coastguard Worker 
createPreheader(const LoopStructure & LS,BasicBlock * OldPreheader,const char * Tag) const1120*9880d681SAndroid Build Coastguard Worker BasicBlock *LoopConstrainer::createPreheader(const LoopStructure &LS,
1121*9880d681SAndroid Build Coastguard Worker                                              BasicBlock *OldPreheader,
1122*9880d681SAndroid Build Coastguard Worker                                              const char *Tag) const {
1123*9880d681SAndroid Build Coastguard Worker 
1124*9880d681SAndroid Build Coastguard Worker   BasicBlock *Preheader = BasicBlock::Create(Ctx, Tag, &F, LS.Header);
1125*9880d681SAndroid Build Coastguard Worker   BranchInst::Create(LS.Header, Preheader);
1126*9880d681SAndroid Build Coastguard Worker 
1127*9880d681SAndroid Build Coastguard Worker   for (Instruction &I : *LS.Header) {
1128*9880d681SAndroid Build Coastguard Worker     if (!isa<PHINode>(&I))
1129*9880d681SAndroid Build Coastguard Worker       break;
1130*9880d681SAndroid Build Coastguard Worker 
1131*9880d681SAndroid Build Coastguard Worker     PHINode *PN = cast<PHINode>(&I);
1132*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i)
1133*9880d681SAndroid Build Coastguard Worker       replacePHIBlock(PN, OldPreheader, Preheader);
1134*9880d681SAndroid Build Coastguard Worker   }
1135*9880d681SAndroid Build Coastguard Worker 
1136*9880d681SAndroid Build Coastguard Worker   return Preheader;
1137*9880d681SAndroid Build Coastguard Worker }
1138*9880d681SAndroid Build Coastguard Worker 
addToParentLoopIfNeeded(ArrayRef<BasicBlock * > BBs)1139*9880d681SAndroid Build Coastguard Worker void LoopConstrainer::addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs) {
1140*9880d681SAndroid Build Coastguard Worker   Loop *ParentLoop = OriginalLoop.getParentLoop();
1141*9880d681SAndroid Build Coastguard Worker   if (!ParentLoop)
1142*9880d681SAndroid Build Coastguard Worker     return;
1143*9880d681SAndroid Build Coastguard Worker 
1144*9880d681SAndroid Build Coastguard Worker   for (BasicBlock *BB : BBs)
1145*9880d681SAndroid Build Coastguard Worker     ParentLoop->addBasicBlockToLoop(BB, OriginalLoopInfo);
1146*9880d681SAndroid Build Coastguard Worker }
1147*9880d681SAndroid Build Coastguard Worker 
run()1148*9880d681SAndroid Build Coastguard Worker bool LoopConstrainer::run() {
1149*9880d681SAndroid Build Coastguard Worker   BasicBlock *Preheader = nullptr;
1150*9880d681SAndroid Build Coastguard Worker   LatchTakenCount = SE.getExitCount(&OriginalLoop, MainLoopStructure.Latch);
1151*9880d681SAndroid Build Coastguard Worker   Preheader = OriginalLoop.getLoopPreheader();
1152*9880d681SAndroid Build Coastguard Worker   assert(!isa<SCEVCouldNotCompute>(LatchTakenCount) && Preheader != nullptr &&
1153*9880d681SAndroid Build Coastguard Worker          "preconditions!");
1154*9880d681SAndroid Build Coastguard Worker 
1155*9880d681SAndroid Build Coastguard Worker   OriginalPreheader = Preheader;
1156*9880d681SAndroid Build Coastguard Worker   MainLoopPreheader = Preheader;
1157*9880d681SAndroid Build Coastguard Worker 
1158*9880d681SAndroid Build Coastguard Worker   Optional<SubRanges> MaybeSR = calculateSubRanges();
1159*9880d681SAndroid Build Coastguard Worker   if (!MaybeSR.hasValue()) {
1160*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "irce: could not compute subranges\n");
1161*9880d681SAndroid Build Coastguard Worker     return false;
1162*9880d681SAndroid Build Coastguard Worker   }
1163*9880d681SAndroid Build Coastguard Worker 
1164*9880d681SAndroid Build Coastguard Worker   SubRanges SR = MaybeSR.getValue();
1165*9880d681SAndroid Build Coastguard Worker   bool Increasing = MainLoopStructure.IndVarIncreasing;
1166*9880d681SAndroid Build Coastguard Worker   IntegerType *IVTy =
1167*9880d681SAndroid Build Coastguard Worker       cast<IntegerType>(MainLoopStructure.IndVarNext->getType());
1168*9880d681SAndroid Build Coastguard Worker 
1169*9880d681SAndroid Build Coastguard Worker   SCEVExpander Expander(SE, F.getParent()->getDataLayout(), "irce");
1170*9880d681SAndroid Build Coastguard Worker   Instruction *InsertPt = OriginalPreheader->getTerminator();
1171*9880d681SAndroid Build Coastguard Worker 
1172*9880d681SAndroid Build Coastguard Worker   // It would have been better to make `PreLoop' and `PostLoop'
1173*9880d681SAndroid Build Coastguard Worker   // `Optional<ClonedLoop>'s, but `ValueToValueMapTy' does not have a copy
1174*9880d681SAndroid Build Coastguard Worker   // constructor.
1175*9880d681SAndroid Build Coastguard Worker   ClonedLoop PreLoop, PostLoop;
1176*9880d681SAndroid Build Coastguard Worker   bool NeedsPreLoop =
1177*9880d681SAndroid Build Coastguard Worker       Increasing ? SR.LowLimit.hasValue() : SR.HighLimit.hasValue();
1178*9880d681SAndroid Build Coastguard Worker   bool NeedsPostLoop =
1179*9880d681SAndroid Build Coastguard Worker       Increasing ? SR.HighLimit.hasValue() : SR.LowLimit.hasValue();
1180*9880d681SAndroid Build Coastguard Worker 
1181*9880d681SAndroid Build Coastguard Worker   Value *ExitPreLoopAt = nullptr;
1182*9880d681SAndroid Build Coastguard Worker   Value *ExitMainLoopAt = nullptr;
1183*9880d681SAndroid Build Coastguard Worker   const SCEVConstant *MinusOneS =
1184*9880d681SAndroid Build Coastguard Worker       cast<SCEVConstant>(SE.getConstant(IVTy, -1, true /* isSigned */));
1185*9880d681SAndroid Build Coastguard Worker 
1186*9880d681SAndroid Build Coastguard Worker   if (NeedsPreLoop) {
1187*9880d681SAndroid Build Coastguard Worker     const SCEV *ExitPreLoopAtSCEV = nullptr;
1188*9880d681SAndroid Build Coastguard Worker 
1189*9880d681SAndroid Build Coastguard Worker     if (Increasing)
1190*9880d681SAndroid Build Coastguard Worker       ExitPreLoopAtSCEV = *SR.LowLimit;
1191*9880d681SAndroid Build Coastguard Worker     else {
1192*9880d681SAndroid Build Coastguard Worker       if (CanBeSMin(SE, *SR.HighLimit)) {
1193*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "irce: could not prove no-overflow when computing "
1194*9880d681SAndroid Build Coastguard Worker                      << "preloop exit limit.  HighLimit = " << *(*SR.HighLimit)
1195*9880d681SAndroid Build Coastguard Worker                      << "\n");
1196*9880d681SAndroid Build Coastguard Worker         return false;
1197*9880d681SAndroid Build Coastguard Worker       }
1198*9880d681SAndroid Build Coastguard Worker       ExitPreLoopAtSCEV = SE.getAddExpr(*SR.HighLimit, MinusOneS);
1199*9880d681SAndroid Build Coastguard Worker     }
1200*9880d681SAndroid Build Coastguard Worker 
1201*9880d681SAndroid Build Coastguard Worker     ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt);
1202*9880d681SAndroid Build Coastguard Worker     ExitPreLoopAt->setName("exit.preloop.at");
1203*9880d681SAndroid Build Coastguard Worker   }
1204*9880d681SAndroid Build Coastguard Worker 
1205*9880d681SAndroid Build Coastguard Worker   if (NeedsPostLoop) {
1206*9880d681SAndroid Build Coastguard Worker     const SCEV *ExitMainLoopAtSCEV = nullptr;
1207*9880d681SAndroid Build Coastguard Worker 
1208*9880d681SAndroid Build Coastguard Worker     if (Increasing)
1209*9880d681SAndroid Build Coastguard Worker       ExitMainLoopAtSCEV = *SR.HighLimit;
1210*9880d681SAndroid Build Coastguard Worker     else {
1211*9880d681SAndroid Build Coastguard Worker       if (CanBeSMin(SE, *SR.LowLimit)) {
1212*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "irce: could not prove no-overflow when computing "
1213*9880d681SAndroid Build Coastguard Worker                      << "mainloop exit limit.  LowLimit = " << *(*SR.LowLimit)
1214*9880d681SAndroid Build Coastguard Worker                      << "\n");
1215*9880d681SAndroid Build Coastguard Worker         return false;
1216*9880d681SAndroid Build Coastguard Worker       }
1217*9880d681SAndroid Build Coastguard Worker       ExitMainLoopAtSCEV = SE.getAddExpr(*SR.LowLimit, MinusOneS);
1218*9880d681SAndroid Build Coastguard Worker     }
1219*9880d681SAndroid Build Coastguard Worker 
1220*9880d681SAndroid Build Coastguard Worker     ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt);
1221*9880d681SAndroid Build Coastguard Worker     ExitMainLoopAt->setName("exit.mainloop.at");
1222*9880d681SAndroid Build Coastguard Worker   }
1223*9880d681SAndroid Build Coastguard Worker 
1224*9880d681SAndroid Build Coastguard Worker   // We clone these ahead of time so that we don't have to deal with changing
1225*9880d681SAndroid Build Coastguard Worker   // and temporarily invalid IR as we transform the loops.
1226*9880d681SAndroid Build Coastguard Worker   if (NeedsPreLoop)
1227*9880d681SAndroid Build Coastguard Worker     cloneLoop(PreLoop, "preloop");
1228*9880d681SAndroid Build Coastguard Worker   if (NeedsPostLoop)
1229*9880d681SAndroid Build Coastguard Worker     cloneLoop(PostLoop, "postloop");
1230*9880d681SAndroid Build Coastguard Worker 
1231*9880d681SAndroid Build Coastguard Worker   RewrittenRangeInfo PreLoopRRI;
1232*9880d681SAndroid Build Coastguard Worker 
1233*9880d681SAndroid Build Coastguard Worker   if (NeedsPreLoop) {
1234*9880d681SAndroid Build Coastguard Worker     Preheader->getTerminator()->replaceUsesOfWith(MainLoopStructure.Header,
1235*9880d681SAndroid Build Coastguard Worker                                                   PreLoop.Structure.Header);
1236*9880d681SAndroid Build Coastguard Worker 
1237*9880d681SAndroid Build Coastguard Worker     MainLoopPreheader =
1238*9880d681SAndroid Build Coastguard Worker         createPreheader(MainLoopStructure, Preheader, "mainloop");
1239*9880d681SAndroid Build Coastguard Worker     PreLoopRRI = changeIterationSpaceEnd(PreLoop.Structure, Preheader,
1240*9880d681SAndroid Build Coastguard Worker                                          ExitPreLoopAt, MainLoopPreheader);
1241*9880d681SAndroid Build Coastguard Worker     rewriteIncomingValuesForPHIs(MainLoopStructure, MainLoopPreheader,
1242*9880d681SAndroid Build Coastguard Worker                                  PreLoopRRI);
1243*9880d681SAndroid Build Coastguard Worker   }
1244*9880d681SAndroid Build Coastguard Worker 
1245*9880d681SAndroid Build Coastguard Worker   BasicBlock *PostLoopPreheader = nullptr;
1246*9880d681SAndroid Build Coastguard Worker   RewrittenRangeInfo PostLoopRRI;
1247*9880d681SAndroid Build Coastguard Worker 
1248*9880d681SAndroid Build Coastguard Worker   if (NeedsPostLoop) {
1249*9880d681SAndroid Build Coastguard Worker     PostLoopPreheader =
1250*9880d681SAndroid Build Coastguard Worker         createPreheader(PostLoop.Structure, Preheader, "postloop");
1251*9880d681SAndroid Build Coastguard Worker     PostLoopRRI = changeIterationSpaceEnd(MainLoopStructure, MainLoopPreheader,
1252*9880d681SAndroid Build Coastguard Worker                                           ExitMainLoopAt, PostLoopPreheader);
1253*9880d681SAndroid Build Coastguard Worker     rewriteIncomingValuesForPHIs(PostLoop.Structure, PostLoopPreheader,
1254*9880d681SAndroid Build Coastguard Worker                                  PostLoopRRI);
1255*9880d681SAndroid Build Coastguard Worker   }
1256*9880d681SAndroid Build Coastguard Worker 
1257*9880d681SAndroid Build Coastguard Worker   BasicBlock *NewMainLoopPreheader =
1258*9880d681SAndroid Build Coastguard Worker       MainLoopPreheader != Preheader ? MainLoopPreheader : nullptr;
1259*9880d681SAndroid Build Coastguard Worker   BasicBlock *NewBlocks[] = {PostLoopPreheader,        PreLoopRRI.PseudoExit,
1260*9880d681SAndroid Build Coastguard Worker                              PreLoopRRI.ExitSelector,  PostLoopRRI.PseudoExit,
1261*9880d681SAndroid Build Coastguard Worker                              PostLoopRRI.ExitSelector, NewMainLoopPreheader};
1262*9880d681SAndroid Build Coastguard Worker 
1263*9880d681SAndroid Build Coastguard Worker   // Some of the above may be nullptr, filter them out before passing to
1264*9880d681SAndroid Build Coastguard Worker   // addToParentLoopIfNeeded.
1265*9880d681SAndroid Build Coastguard Worker   auto NewBlocksEnd =
1266*9880d681SAndroid Build Coastguard Worker       std::remove(std::begin(NewBlocks), std::end(NewBlocks), nullptr);
1267*9880d681SAndroid Build Coastguard Worker 
1268*9880d681SAndroid Build Coastguard Worker   addToParentLoopIfNeeded(makeArrayRef(std::begin(NewBlocks), NewBlocksEnd));
1269*9880d681SAndroid Build Coastguard Worker   addToParentLoopIfNeeded(PreLoop.Blocks);
1270*9880d681SAndroid Build Coastguard Worker   addToParentLoopIfNeeded(PostLoop.Blocks);
1271*9880d681SAndroid Build Coastguard Worker 
1272*9880d681SAndroid Build Coastguard Worker   return true;
1273*9880d681SAndroid Build Coastguard Worker }
1274*9880d681SAndroid Build Coastguard Worker 
1275*9880d681SAndroid Build Coastguard Worker /// Computes and returns a range of values for the induction variable (IndVar)
1276*9880d681SAndroid Build Coastguard Worker /// in which the range check can be safely elided.  If it cannot compute such a
1277*9880d681SAndroid Build Coastguard Worker /// range, returns None.
1278*9880d681SAndroid Build Coastguard Worker Optional<InductiveRangeCheck::Range>
computeSafeIterationSpace(ScalarEvolution & SE,const SCEVAddRecExpr * IndVar) const1279*9880d681SAndroid Build Coastguard Worker InductiveRangeCheck::computeSafeIterationSpace(
1280*9880d681SAndroid Build Coastguard Worker     ScalarEvolution &SE, const SCEVAddRecExpr *IndVar) const {
1281*9880d681SAndroid Build Coastguard Worker   // IndVar is of the form "A + B * I" (where "I" is the canonical induction
1282*9880d681SAndroid Build Coastguard Worker   // variable, that may or may not exist as a real llvm::Value in the loop) and
1283*9880d681SAndroid Build Coastguard Worker   // this inductive range check is a range check on the "C + D * I" ("C" is
1284*9880d681SAndroid Build Coastguard Worker   // getOffset() and "D" is getScale()).  We rewrite the value being range
1285*9880d681SAndroid Build Coastguard Worker   // checked to "M + N * IndVar" where "N" = "D * B^(-1)" and "M" = "C - NA".
1286*9880d681SAndroid Build Coastguard Worker   // Currently we support this only for "B" = "D" = { 1 or -1 }, but the code
1287*9880d681SAndroid Build Coastguard Worker   // can be generalized as needed.
1288*9880d681SAndroid Build Coastguard Worker   //
1289*9880d681SAndroid Build Coastguard Worker   // The actual inequalities we solve are of the form
1290*9880d681SAndroid Build Coastguard Worker   //
1291*9880d681SAndroid Build Coastguard Worker   //   0 <= M + 1 * IndVar < L given L >= 0  (i.e. N == 1)
1292*9880d681SAndroid Build Coastguard Worker   //
1293*9880d681SAndroid Build Coastguard Worker   // The inequality is satisfied by -M <= IndVar < (L - M) [^1].  All additions
1294*9880d681SAndroid Build Coastguard Worker   // and subtractions are twos-complement wrapping and comparisons are signed.
1295*9880d681SAndroid Build Coastguard Worker   //
1296*9880d681SAndroid Build Coastguard Worker   // Proof:
1297*9880d681SAndroid Build Coastguard Worker   //
1298*9880d681SAndroid Build Coastguard Worker   //   If there exists IndVar such that -M <= IndVar < (L - M) then it follows
1299*9880d681SAndroid Build Coastguard Worker   //   that -M <= (-M + L) [== Eq. 1].  Since L >= 0, if (-M + L) sign-overflows
1300*9880d681SAndroid Build Coastguard Worker   //   then (-M + L) < (-M).  Hence by [Eq. 1], (-M + L) could not have
1301*9880d681SAndroid Build Coastguard Worker   //   overflown.
1302*9880d681SAndroid Build Coastguard Worker   //
1303*9880d681SAndroid Build Coastguard Worker   //   This means IndVar = t + (-M) for t in [0, L).  Hence (IndVar + M) = t.
1304*9880d681SAndroid Build Coastguard Worker   //   Hence 0 <= (IndVar + M) < L
1305*9880d681SAndroid Build Coastguard Worker 
1306*9880d681SAndroid Build Coastguard Worker   // [^1]: Note that the solution does _not_ apply if L < 0; consider values M =
1307*9880d681SAndroid Build Coastguard Worker   // 127, IndVar = 126 and L = -2 in an i8 world.
1308*9880d681SAndroid Build Coastguard Worker 
1309*9880d681SAndroid Build Coastguard Worker   if (!IndVar->isAffine())
1310*9880d681SAndroid Build Coastguard Worker     return None;
1311*9880d681SAndroid Build Coastguard Worker 
1312*9880d681SAndroid Build Coastguard Worker   const SCEV *A = IndVar->getStart();
1313*9880d681SAndroid Build Coastguard Worker   const SCEVConstant *B = dyn_cast<SCEVConstant>(IndVar->getStepRecurrence(SE));
1314*9880d681SAndroid Build Coastguard Worker   if (!B)
1315*9880d681SAndroid Build Coastguard Worker     return None;
1316*9880d681SAndroid Build Coastguard Worker 
1317*9880d681SAndroid Build Coastguard Worker   const SCEV *C = getOffset();
1318*9880d681SAndroid Build Coastguard Worker   const SCEVConstant *D = dyn_cast<SCEVConstant>(getScale());
1319*9880d681SAndroid Build Coastguard Worker   if (D != B)
1320*9880d681SAndroid Build Coastguard Worker     return None;
1321*9880d681SAndroid Build Coastguard Worker 
1322*9880d681SAndroid Build Coastguard Worker   ConstantInt *ConstD = D->getValue();
1323*9880d681SAndroid Build Coastguard Worker   if (!(ConstD->isMinusOne() || ConstD->isOne()))
1324*9880d681SAndroid Build Coastguard Worker     return None;
1325*9880d681SAndroid Build Coastguard Worker 
1326*9880d681SAndroid Build Coastguard Worker   const SCEV *M = SE.getMinusSCEV(C, A);
1327*9880d681SAndroid Build Coastguard Worker 
1328*9880d681SAndroid Build Coastguard Worker   const SCEV *Begin = SE.getNegativeSCEV(M);
1329*9880d681SAndroid Build Coastguard Worker   const SCEV *UpperLimit = nullptr;
1330*9880d681SAndroid Build Coastguard Worker 
1331*9880d681SAndroid Build Coastguard Worker   // We strengthen "0 <= I" to "0 <= I < INT_SMAX" and "I < L" to "0 <= I < L".
1332*9880d681SAndroid Build Coastguard Worker   // We can potentially do much better here.
1333*9880d681SAndroid Build Coastguard Worker   if (Value *V = getLength()) {
1334*9880d681SAndroid Build Coastguard Worker     UpperLimit = SE.getSCEV(V);
1335*9880d681SAndroid Build Coastguard Worker   } else {
1336*9880d681SAndroid Build Coastguard Worker     assert(Kind == InductiveRangeCheck::RANGE_CHECK_LOWER && "invariant!");
1337*9880d681SAndroid Build Coastguard Worker     unsigned BitWidth = cast<IntegerType>(IndVar->getType())->getBitWidth();
1338*9880d681SAndroid Build Coastguard Worker     UpperLimit = SE.getConstant(APInt::getSignedMaxValue(BitWidth));
1339*9880d681SAndroid Build Coastguard Worker   }
1340*9880d681SAndroid Build Coastguard Worker 
1341*9880d681SAndroid Build Coastguard Worker   const SCEV *End = SE.getMinusSCEV(UpperLimit, M);
1342*9880d681SAndroid Build Coastguard Worker   return InductiveRangeCheck::Range(Begin, End);
1343*9880d681SAndroid Build Coastguard Worker }
1344*9880d681SAndroid Build Coastguard Worker 
1345*9880d681SAndroid Build Coastguard Worker static Optional<InductiveRangeCheck::Range>
IntersectRange(ScalarEvolution & SE,const Optional<InductiveRangeCheck::Range> & R1,const InductiveRangeCheck::Range & R2)1346*9880d681SAndroid Build Coastguard Worker IntersectRange(ScalarEvolution &SE,
1347*9880d681SAndroid Build Coastguard Worker                const Optional<InductiveRangeCheck::Range> &R1,
1348*9880d681SAndroid Build Coastguard Worker                const InductiveRangeCheck::Range &R2) {
1349*9880d681SAndroid Build Coastguard Worker   if (!R1.hasValue())
1350*9880d681SAndroid Build Coastguard Worker     return R2;
1351*9880d681SAndroid Build Coastguard Worker   auto &R1Value = R1.getValue();
1352*9880d681SAndroid Build Coastguard Worker 
1353*9880d681SAndroid Build Coastguard Worker   // TODO: we could widen the smaller range and have this work; but for now we
1354*9880d681SAndroid Build Coastguard Worker   // bail out to keep things simple.
1355*9880d681SAndroid Build Coastguard Worker   if (R1Value.getType() != R2.getType())
1356*9880d681SAndroid Build Coastguard Worker     return None;
1357*9880d681SAndroid Build Coastguard Worker 
1358*9880d681SAndroid Build Coastguard Worker   const SCEV *NewBegin = SE.getSMaxExpr(R1Value.getBegin(), R2.getBegin());
1359*9880d681SAndroid Build Coastguard Worker   const SCEV *NewEnd = SE.getSMinExpr(R1Value.getEnd(), R2.getEnd());
1360*9880d681SAndroid Build Coastguard Worker 
1361*9880d681SAndroid Build Coastguard Worker   return InductiveRangeCheck::Range(NewBegin, NewEnd);
1362*9880d681SAndroid Build Coastguard Worker }
1363*9880d681SAndroid Build Coastguard Worker 
runOnLoop(Loop * L,LPPassManager & LPM)1364*9880d681SAndroid Build Coastguard Worker bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
1365*9880d681SAndroid Build Coastguard Worker   if (skipLoop(L))
1366*9880d681SAndroid Build Coastguard Worker     return false;
1367*9880d681SAndroid Build Coastguard Worker 
1368*9880d681SAndroid Build Coastguard Worker   if (L->getBlocks().size() >= LoopSizeCutoff) {
1369*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "irce: giving up constraining loop, too large\n";);
1370*9880d681SAndroid Build Coastguard Worker     return false;
1371*9880d681SAndroid Build Coastguard Worker   }
1372*9880d681SAndroid Build Coastguard Worker 
1373*9880d681SAndroid Build Coastguard Worker   BasicBlock *Preheader = L->getLoopPreheader();
1374*9880d681SAndroid Build Coastguard Worker   if (!Preheader) {
1375*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "irce: loop has no preheader, leaving\n");
1376*9880d681SAndroid Build Coastguard Worker     return false;
1377*9880d681SAndroid Build Coastguard Worker   }
1378*9880d681SAndroid Build Coastguard Worker 
1379*9880d681SAndroid Build Coastguard Worker   LLVMContext &Context = Preheader->getContext();
1380*9880d681SAndroid Build Coastguard Worker   SmallVector<InductiveRangeCheck, 16> RangeChecks;
1381*9880d681SAndroid Build Coastguard Worker   ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1382*9880d681SAndroid Build Coastguard Worker   BranchProbabilityInfo &BPI =
1383*9880d681SAndroid Build Coastguard Worker       getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
1384*9880d681SAndroid Build Coastguard Worker 
1385*9880d681SAndroid Build Coastguard Worker   for (auto BBI : L->getBlocks())
1386*9880d681SAndroid Build Coastguard Worker     if (BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator()))
1387*9880d681SAndroid Build Coastguard Worker       InductiveRangeCheck::extractRangeChecksFromBranch(TBI, L, SE, BPI,
1388*9880d681SAndroid Build Coastguard Worker                                                         RangeChecks);
1389*9880d681SAndroid Build Coastguard Worker 
1390*9880d681SAndroid Build Coastguard Worker   if (RangeChecks.empty())
1391*9880d681SAndroid Build Coastguard Worker     return false;
1392*9880d681SAndroid Build Coastguard Worker 
1393*9880d681SAndroid Build Coastguard Worker   auto PrintRecognizedRangeChecks = [&](raw_ostream &OS) {
1394*9880d681SAndroid Build Coastguard Worker     OS << "irce: looking at loop "; L->print(OS);
1395*9880d681SAndroid Build Coastguard Worker     OS << "irce: loop has " << RangeChecks.size()
1396*9880d681SAndroid Build Coastguard Worker        << " inductive range checks: \n";
1397*9880d681SAndroid Build Coastguard Worker     for (InductiveRangeCheck &IRC : RangeChecks)
1398*9880d681SAndroid Build Coastguard Worker       IRC.print(OS);
1399*9880d681SAndroid Build Coastguard Worker   };
1400*9880d681SAndroid Build Coastguard Worker 
1401*9880d681SAndroid Build Coastguard Worker   DEBUG(PrintRecognizedRangeChecks(dbgs()));
1402*9880d681SAndroid Build Coastguard Worker 
1403*9880d681SAndroid Build Coastguard Worker   if (PrintRangeChecks)
1404*9880d681SAndroid Build Coastguard Worker     PrintRecognizedRangeChecks(errs());
1405*9880d681SAndroid Build Coastguard Worker 
1406*9880d681SAndroid Build Coastguard Worker   const char *FailureReason = nullptr;
1407*9880d681SAndroid Build Coastguard Worker   Optional<LoopStructure> MaybeLoopStructure =
1408*9880d681SAndroid Build Coastguard Worker       LoopStructure::parseLoopStructure(SE, BPI, *L, FailureReason);
1409*9880d681SAndroid Build Coastguard Worker   if (!MaybeLoopStructure.hasValue()) {
1410*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "irce: could not parse loop structure: " << FailureReason
1411*9880d681SAndroid Build Coastguard Worker                  << "\n";);
1412*9880d681SAndroid Build Coastguard Worker     return false;
1413*9880d681SAndroid Build Coastguard Worker   }
1414*9880d681SAndroid Build Coastguard Worker   LoopStructure LS = MaybeLoopStructure.getValue();
1415*9880d681SAndroid Build Coastguard Worker   bool Increasing = LS.IndVarIncreasing;
1416*9880d681SAndroid Build Coastguard Worker   const SCEV *MinusOne =
1417*9880d681SAndroid Build Coastguard Worker       SE.getConstant(LS.IndVarNext->getType(), Increasing ? -1 : 1, true);
1418*9880d681SAndroid Build Coastguard Worker   const SCEVAddRecExpr *IndVar =
1419*9880d681SAndroid Build Coastguard Worker       cast<SCEVAddRecExpr>(SE.getAddExpr(SE.getSCEV(LS.IndVarNext), MinusOne));
1420*9880d681SAndroid Build Coastguard Worker 
1421*9880d681SAndroid Build Coastguard Worker   Optional<InductiveRangeCheck::Range> SafeIterRange;
1422*9880d681SAndroid Build Coastguard Worker   Instruction *ExprInsertPt = Preheader->getTerminator();
1423*9880d681SAndroid Build Coastguard Worker 
1424*9880d681SAndroid Build Coastguard Worker   SmallVector<InductiveRangeCheck, 4> RangeChecksToEliminate;
1425*9880d681SAndroid Build Coastguard Worker 
1426*9880d681SAndroid Build Coastguard Worker   IRBuilder<> B(ExprInsertPt);
1427*9880d681SAndroid Build Coastguard Worker   for (InductiveRangeCheck &IRC : RangeChecks) {
1428*9880d681SAndroid Build Coastguard Worker     auto Result = IRC.computeSafeIterationSpace(SE, IndVar);
1429*9880d681SAndroid Build Coastguard Worker     if (Result.hasValue()) {
1430*9880d681SAndroid Build Coastguard Worker       auto MaybeSafeIterRange =
1431*9880d681SAndroid Build Coastguard Worker           IntersectRange(SE, SafeIterRange, Result.getValue());
1432*9880d681SAndroid Build Coastguard Worker       if (MaybeSafeIterRange.hasValue()) {
1433*9880d681SAndroid Build Coastguard Worker         RangeChecksToEliminate.push_back(IRC);
1434*9880d681SAndroid Build Coastguard Worker         SafeIterRange = MaybeSafeIterRange.getValue();
1435*9880d681SAndroid Build Coastguard Worker       }
1436*9880d681SAndroid Build Coastguard Worker     }
1437*9880d681SAndroid Build Coastguard Worker   }
1438*9880d681SAndroid Build Coastguard Worker 
1439*9880d681SAndroid Build Coastguard Worker   if (!SafeIterRange.hasValue())
1440*9880d681SAndroid Build Coastguard Worker     return false;
1441*9880d681SAndroid Build Coastguard Worker 
1442*9880d681SAndroid Build Coastguard Worker   LoopConstrainer LC(*L, getAnalysis<LoopInfoWrapperPass>().getLoopInfo(), LS,
1443*9880d681SAndroid Build Coastguard Worker                      SE, SafeIterRange.getValue());
1444*9880d681SAndroid Build Coastguard Worker   bool Changed = LC.run();
1445*9880d681SAndroid Build Coastguard Worker 
1446*9880d681SAndroid Build Coastguard Worker   if (Changed) {
1447*9880d681SAndroid Build Coastguard Worker     auto PrintConstrainedLoopInfo = [L]() {
1448*9880d681SAndroid Build Coastguard Worker       dbgs() << "irce: in function ";
1449*9880d681SAndroid Build Coastguard Worker       dbgs() << L->getHeader()->getParent()->getName() << ": ";
1450*9880d681SAndroid Build Coastguard Worker       dbgs() << "constrained ";
1451*9880d681SAndroid Build Coastguard Worker       L->print(dbgs());
1452*9880d681SAndroid Build Coastguard Worker     };
1453*9880d681SAndroid Build Coastguard Worker 
1454*9880d681SAndroid Build Coastguard Worker     DEBUG(PrintConstrainedLoopInfo());
1455*9880d681SAndroid Build Coastguard Worker 
1456*9880d681SAndroid Build Coastguard Worker     if (PrintChangedLoops)
1457*9880d681SAndroid Build Coastguard Worker       PrintConstrainedLoopInfo();
1458*9880d681SAndroid Build Coastguard Worker 
1459*9880d681SAndroid Build Coastguard Worker     // Optimize away the now-redundant range checks.
1460*9880d681SAndroid Build Coastguard Worker 
1461*9880d681SAndroid Build Coastguard Worker     for (InductiveRangeCheck &IRC : RangeChecksToEliminate) {
1462*9880d681SAndroid Build Coastguard Worker       ConstantInt *FoldedRangeCheck = IRC.getPassingDirection()
1463*9880d681SAndroid Build Coastguard Worker                                           ? ConstantInt::getTrue(Context)
1464*9880d681SAndroid Build Coastguard Worker                                           : ConstantInt::getFalse(Context);
1465*9880d681SAndroid Build Coastguard Worker       IRC.getCheckUse()->set(FoldedRangeCheck);
1466*9880d681SAndroid Build Coastguard Worker     }
1467*9880d681SAndroid Build Coastguard Worker   }
1468*9880d681SAndroid Build Coastguard Worker 
1469*9880d681SAndroid Build Coastguard Worker   return Changed;
1470*9880d681SAndroid Build Coastguard Worker }
1471*9880d681SAndroid Build Coastguard Worker 
createInductiveRangeCheckEliminationPass()1472*9880d681SAndroid Build Coastguard Worker Pass *llvm::createInductiveRangeCheckEliminationPass() {
1473*9880d681SAndroid Build Coastguard Worker   return new InductiveRangeCheckElimination;
1474*9880d681SAndroid Build Coastguard Worker }
1475