17f0f9bc5SEugene Zelenko //===- InductiveRangeCheckElimination.cpp - -------------------------------===//
2a1837a34SSanjoy Das //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a1837a34SSanjoy Das //
7a1837a34SSanjoy Das //===----------------------------------------------------------------------===//
87f0f9bc5SEugene Zelenko //
9a1837a34SSanjoy Das // The InductiveRangeCheckElimination pass splits a loop's iteration space into
10a1837a34SSanjoy Das // three disjoint ranges. It does that in a way such that the loop running in
11a1837a34SSanjoy Das // the middle loop provably does not need range checks. As an example, it will
12a1837a34SSanjoy Das // convert
13a1837a34SSanjoy Das //
14a1837a34SSanjoy Das // len = < known positive >
15a1837a34SSanjoy Das // for (i = 0; i < n; i++) {
16a1837a34SSanjoy Das // if (0 <= i && i < len) {
17a1837a34SSanjoy Das // do_something();
18a1837a34SSanjoy Das // } else {
19a1837a34SSanjoy Das // throw_out_of_bounds();
20a1837a34SSanjoy Das // }
21a1837a34SSanjoy Das // }
22a1837a34SSanjoy Das //
23a1837a34SSanjoy Das // to
24a1837a34SSanjoy Das //
25a1837a34SSanjoy Das // len = < known positive >
26a1837a34SSanjoy Das // limit = smin(n, len)
27a1837a34SSanjoy Das // // no first segment
28a1837a34SSanjoy Das // for (i = 0; i < limit; i++) {
29a1837a34SSanjoy Das // if (0 <= i && i < len) { // this check is fully redundant
30a1837a34SSanjoy Das // do_something();
31a1837a34SSanjoy Das // } else {
32a1837a34SSanjoy Das // throw_out_of_bounds();
33a1837a34SSanjoy Das // }
34a1837a34SSanjoy Das // }
35a1837a34SSanjoy Das // for (i = limit; i < n; i++) {
36a1837a34SSanjoy Das // if (0 <= i && i < len) {
37a1837a34SSanjoy Das // do_something();
38a1837a34SSanjoy Das // } else {
39a1837a34SSanjoy Das // throw_out_of_bounds();
40a1837a34SSanjoy Das // }
41a1837a34SSanjoy Das // }
427f0f9bc5SEugene Zelenko //
43a1837a34SSanjoy Das //===----------------------------------------------------------------------===//
44a1837a34SSanjoy Das
45194a407bSFedor Sergeev #include "llvm/Transforms/Scalar/InductiveRangeCheckElimination.h"
467f0f9bc5SEugene Zelenko #include "llvm/ADT/APInt.h"
477f0f9bc5SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
487f0f9bc5SEugene Zelenko #include "llvm/ADT/None.h"
49a1837a34SSanjoy Das #include "llvm/ADT/Optional.h"
505006e551SSimon Pilgrim #include "llvm/ADT/PriorityWorklist.h"
517f0f9bc5SEugene Zelenko #include "llvm/ADT/SmallPtrSet.h"
527f0f9bc5SEugene Zelenko #include "llvm/ADT/SmallVector.h"
537f0f9bc5SEugene Zelenko #include "llvm/ADT/StringRef.h"
547f0f9bc5SEugene Zelenko #include "llvm/ADT/Twine.h"
5538799975SSerguei Katkov #include "llvm/Analysis/BlockFrequencyInfo.h"
56dcf26510SSanjoy Das #include "llvm/Analysis/BranchProbabilityInfo.h"
57194a407bSFedor Sergeev #include "llvm/Analysis/LoopAnalysisManager.h"
58a1837a34SSanjoy Das #include "llvm/Analysis/LoopInfo.h"
59a1837a34SSanjoy Das #include "llvm/Analysis/ScalarEvolution.h"
60a1837a34SSanjoy Das #include "llvm/Analysis/ScalarEvolutionExpressions.h"
617f0f9bc5SEugene Zelenko #include "llvm/IR/BasicBlock.h"
627f0f9bc5SEugene Zelenko #include "llvm/IR/CFG.h"
637f0f9bc5SEugene Zelenko #include "llvm/IR/Constants.h"
647f0f9bc5SEugene Zelenko #include "llvm/IR/DerivedTypes.h"
65a1837a34SSanjoy Das #include "llvm/IR/Dominators.h"
66a1837a34SSanjoy Das #include "llvm/IR/Function.h"
67a1837a34SSanjoy Das #include "llvm/IR/IRBuilder.h"
687f0f9bc5SEugene Zelenko #include "llvm/IR/InstrTypes.h"
69799003bfSBenjamin Kramer #include "llvm/IR/Instructions.h"
707f0f9bc5SEugene Zelenko #include "llvm/IR/Metadata.h"
717f0f9bc5SEugene Zelenko #include "llvm/IR/Module.h"
72a1837a34SSanjoy Das #include "llvm/IR/PatternMatch.h"
737f0f9bc5SEugene Zelenko #include "llvm/IR/Type.h"
747f0f9bc5SEugene Zelenko #include "llvm/IR/Use.h"
757f0f9bc5SEugene Zelenko #include "llvm/IR/User.h"
767f0f9bc5SEugene Zelenko #include "llvm/IR/Value.h"
7705da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
78799003bfSBenjamin Kramer #include "llvm/Pass.h"
797f0f9bc5SEugene Zelenko #include "llvm/Support/BranchProbability.h"
807f0f9bc5SEugene Zelenko #include "llvm/Support/Casting.h"
817f0f9bc5SEugene Zelenko #include "llvm/Support/CommandLine.h"
827f0f9bc5SEugene Zelenko #include "llvm/Support/Compiler.h"
83a1837a34SSanjoy Das #include "llvm/Support/Debug.h"
847f0f9bc5SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
85799003bfSBenjamin Kramer #include "llvm/Support/raw_ostream.h"
86a1837a34SSanjoy Das #include "llvm/Transforms/Scalar.h"
87a1837a34SSanjoy Das #include "llvm/Transforms/Utils/Cloning.h"
88cf181867SSanjoy Das #include "llvm/Transforms/Utils/LoopSimplify.h"
896bda14b3SChandler Carruth #include "llvm/Transforms/Utils/LoopUtils.h"
90bcbd26bfSFlorian Hahn #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
917f0f9bc5SEugene Zelenko #include "llvm/Transforms/Utils/ValueMapper.h"
927f0f9bc5SEugene Zelenko #include <algorithm>
937f0f9bc5SEugene Zelenko #include <cassert>
947f0f9bc5SEugene Zelenko #include <iterator>
957f0f9bc5SEugene Zelenko #include <limits>
967f0f9bc5SEugene Zelenko #include <utility>
977f0f9bc5SEugene Zelenko #include <vector>
98a1837a34SSanjoy Das
99a1837a34SSanjoy Das using namespace llvm;
1007f0f9bc5SEugene Zelenko using namespace llvm::PatternMatch;
101a1837a34SSanjoy Das
102970eac40SBenjamin Kramer static cl::opt<unsigned> LoopSizeCutoff("irce-loop-size-cutoff", cl::Hidden,
103a1837a34SSanjoy Das cl::init(64));
104a1837a34SSanjoy Das
105970eac40SBenjamin Kramer static cl::opt<bool> PrintChangedLoops("irce-print-changed-loops", cl::Hidden,
106a1837a34SSanjoy Das cl::init(false));
107a1837a34SSanjoy Das
1089c1bfae6SSanjoy Das static cl::opt<bool> PrintRangeChecks("irce-print-range-checks", cl::Hidden,
1099c1bfae6SSanjoy Das cl::init(false));
1109c1bfae6SSanjoy Das
111bb969791SSanjoy Das static cl::opt<bool> SkipProfitabilityChecks("irce-skip-profitability-checks",
112bb969791SSanjoy Das cl::Hidden, cl::init(false));
113bb969791SSanjoy Das
114400f6edcSSerguei Katkov static cl::opt<unsigned> MinRuntimeIterations("irce-min-runtime-iterations",
115400f6edcSSerguei Katkov cl::Hidden, cl::init(10));
11638799975SSerguei Katkov
1178aacef6cSMax Kazantsev static cl::opt<bool> AllowUnsignedLatchCondition("irce-allow-unsigned-latch",
1189ac7021aSMax Kazantsev cl::Hidden, cl::init(true));
1198aacef6cSMax Kazantsev
120d9aee3c0SMax Kazantsev static cl::opt<bool> AllowNarrowLatchCondition(
12134eeeec3SMax Kazantsev "irce-allow-narrow-latch", cl::Hidden, cl::init(true),
122d9aee3c0SMax Kazantsev cl::desc("If set to true, IRCE may eliminate wide range checks in loops "
123d9aee3c0SMax Kazantsev "with narrow latch condition."));
124d9aee3c0SMax Kazantsev
1257a18a238SSanjoy Das static const char *ClonedLoopTag = "irce.loop.clone";
1267a18a238SSanjoy Das
127a1837a34SSanjoy Das #define DEBUG_TYPE "irce"
128a1837a34SSanjoy Das
129a1837a34SSanjoy Das namespace {
130a1837a34SSanjoy Das
131a1837a34SSanjoy Das /// An inductive range check is conditional branch in a loop with
132a1837a34SSanjoy Das ///
133a1837a34SSanjoy Das /// 1. a very cold successor (i.e. the branch jumps to that successor very
134a1837a34SSanjoy Das /// rarely)
135a1837a34SSanjoy Das ///
136a1837a34SSanjoy Das /// and
137a1837a34SSanjoy Das ///
138e2cde6f1SSanjoy Das /// 2. a condition that is provably true for some contiguous range of values
139e2cde6f1SSanjoy Das /// taken by the containing loop's induction variable.
140a1837a34SSanjoy Das ///
141a1837a34SSanjoy Das class InductiveRangeCheck {
142e2cde6f1SSanjoy Das
14384286ce5SMax Kazantsev const SCEV *Begin = nullptr;
14484286ce5SMax Kazantsev const SCEV *Step = nullptr;
14584286ce5SMax Kazantsev const SCEV *End = nullptr;
146ee77a482SSanjoy Das Use *CheckUse = nullptr;
147e2cde6f1SSanjoy Das
14880242ee8SMax Kazantsev static bool parseRangeCheckICmp(Loop *L, ICmpInst *ICI, ScalarEvolution &SE,
14980242ee8SMax Kazantsev Value *&Index, Value *&Length,
15080242ee8SMax Kazantsev bool &IsSigned);
151e2cde6f1SSanjoy Das
152a099268eSSanjoy Das static void
153a099268eSSanjoy Das extractRangeChecksFromCond(Loop *L, ScalarEvolution &SE, Use &ConditionUse,
154a099268eSSanjoy Das SmallVectorImpl<InductiveRangeCheck> &Checks,
155a099268eSSanjoy Das SmallPtrSetImpl<Value *> &Visited);
156a1837a34SSanjoy Das
157a1837a34SSanjoy Das public:
getBegin() const15884286ce5SMax Kazantsev const SCEV *getBegin() const { return Begin; }
getStep() const15984286ce5SMax Kazantsev const SCEV *getStep() const { return Step; }
getEnd() const16084286ce5SMax Kazantsev const SCEV *getEnd() const { return End; }
161a1837a34SSanjoy Das
print(raw_ostream & OS) const162a1837a34SSanjoy Das void print(raw_ostream &OS) const {
163a1837a34SSanjoy Das OS << "InductiveRangeCheck:\n";
16484286ce5SMax Kazantsev OS << " Begin: ";
16584286ce5SMax Kazantsev Begin->print(OS);
16684286ce5SMax Kazantsev OS << " Step: ";
16784286ce5SMax Kazantsev Step->print(OS);
16884286ce5SMax Kazantsev OS << " End: ";
16984286ce5SMax Kazantsev End->print(OS);
170aa83c47bSSanjoy Das OS << "\n CheckUse: ";
171aa83c47bSSanjoy Das getCheckUse()->getUser()->print(OS);
172aa83c47bSSanjoy Das OS << " Operand: " << getCheckUse()->getOperandNo() << "\n";
173a1837a34SSanjoy Das }
174a1837a34SSanjoy Das
175d1279df7SDavide Italiano LLVM_DUMP_METHOD
dump()176a1837a34SSanjoy Das void dump() {
177a1837a34SSanjoy Das print(dbgs());
178a1837a34SSanjoy Das }
179a1837a34SSanjoy Das
getCheckUse() const180aa83c47bSSanjoy Das Use *getCheckUse() const { return CheckUse; }
181a1837a34SSanjoy Das
182351db053SSanjoy Das /// Represents an signed integer range [Range.getBegin(), Range.getEnd()). If
183d0fe5023SMax Kazantsev /// R.getEnd() le R.getBegin(), then R denotes the empty range.
184351db053SSanjoy Das
185351db053SSanjoy Das class Range {
1867fc60da2SSanjoy Das const SCEV *Begin;
1877fc60da2SSanjoy Das const SCEV *End;
188351db053SSanjoy Das
189351db053SSanjoy Das public:
Range(const SCEV * Begin,const SCEV * End)1907fc60da2SSanjoy Das Range(const SCEV *Begin, const SCEV *End) : Begin(Begin), End(End) {
191351db053SSanjoy Das assert(Begin->getType() == End->getType() && "ill-typed range!");
192351db053SSanjoy Das }
193351db053SSanjoy Das
getType() const194351db053SSanjoy Das Type *getType() const { return Begin->getType(); }
getBegin() const1957fc60da2SSanjoy Das const SCEV *getBegin() const { return Begin; }
getEnd() const1967fc60da2SSanjoy Das const SCEV *getEnd() const { return End; }
isEmpty(ScalarEvolution & SE,bool IsSigned) const1974332a943SMax Kazantsev bool isEmpty(ScalarEvolution &SE, bool IsSigned) const {
1984332a943SMax Kazantsev if (Begin == End)
1994332a943SMax Kazantsev return true;
2004332a943SMax Kazantsev if (IsSigned)
2014332a943SMax Kazantsev return SE.isKnownPredicate(ICmpInst::ICMP_SGE, Begin, End);
2024332a943SMax Kazantsev else
2034332a943SMax Kazantsev return SE.isKnownPredicate(ICmpInst::ICMP_UGE, Begin, End);
2044332a943SMax Kazantsev }
205351db053SSanjoy Das };
206351db053SSanjoy Das
207a1837a34SSanjoy Das /// This is the value the condition of the branch needs to evaluate to for the
208a1837a34SSanjoy Das /// branch to take the hot successor (see (1) above).
getPassingDirection()209a1837a34SSanjoy Das bool getPassingDirection() { return true; }
210a1837a34SSanjoy Das
21195c476dbSSanjoy Das /// Computes a range for the induction variable (IndVar) in which the range
21295c476dbSSanjoy Das /// check is redundant and can be constant-folded away. The induction
21395c476dbSSanjoy Das /// variable is not required to be the canonical {0,+,1} induction variable.
214a1837a34SSanjoy Das Optional<Range> computeSafeIterationSpace(ScalarEvolution &SE,
21526846786SMax Kazantsev const SCEVAddRecExpr *IndVar,
21626846786SMax Kazantsev bool IsLatchSigned) const;
217a1837a34SSanjoy Das
218a099268eSSanjoy Das /// Parse out a set of inductive range checks from \p BI and append them to \p
219a099268eSSanjoy Das /// Checks.
220a099268eSSanjoy Das ///
221a099268eSSanjoy Das /// NB! There may be conditions feeding into \p BI that aren't inductive range
222a099268eSSanjoy Das /// checks, and hence don't end up in \p Checks.
223a099268eSSanjoy Das static void
224a099268eSSanjoy Das extractRangeChecksFromBranch(BranchInst *BI, Loop *L, ScalarEvolution &SE,
225194a407bSFedor Sergeev BranchProbabilityInfo *BPI,
226a099268eSSanjoy Das SmallVectorImpl<InductiveRangeCheck> &Checks);
227a1837a34SSanjoy Das };
228a1837a34SSanjoy Das
22975d0e0cdSSerguei Katkov struct LoopStructure;
23075d0e0cdSSerguei Katkov
231194a407bSFedor Sergeev class InductiveRangeCheckElimination {
232194a407bSFedor Sergeev ScalarEvolution &SE;
233194a407bSFedor Sergeev BranchProbabilityInfo *BPI;
234194a407bSFedor Sergeev DominatorTree &DT;
235194a407bSFedor Sergeev LoopInfo &LI;
236194a407bSFedor Sergeev
23738799975SSerguei Katkov using GetBFIFunc =
23838799975SSerguei Katkov llvm::Optional<llvm::function_ref<llvm::BlockFrequencyInfo &()> >;
23938799975SSerguei Katkov GetBFIFunc GetBFI;
24038799975SSerguei Katkov
24175d0e0cdSSerguei Katkov // Returns true if it is profitable to do a transform basing on estimation of
24275d0e0cdSSerguei Katkov // number of iterations.
24375d0e0cdSSerguei Katkov bool isProfitableToTransform(const Loop &L, LoopStructure &LS);
24475d0e0cdSSerguei Katkov
245194a407bSFedor Sergeev public:
InductiveRangeCheckElimination(ScalarEvolution & SE,BranchProbabilityInfo * BPI,DominatorTree & DT,LoopInfo & LI,GetBFIFunc GetBFI=None)246194a407bSFedor Sergeev InductiveRangeCheckElimination(ScalarEvolution &SE,
247194a407bSFedor Sergeev BranchProbabilityInfo *BPI, DominatorTree &DT,
24838799975SSerguei Katkov LoopInfo &LI, GetBFIFunc GetBFI = None)
24938799975SSerguei Katkov : SE(SE), BPI(BPI), DT(DT), LI(LI), GetBFI(GetBFI) {}
250194a407bSFedor Sergeev
251194a407bSFedor Sergeev bool run(Loop *L, function_ref<void(Loop *, bool)> LPMAddNewLoop);
252194a407bSFedor Sergeev };
253194a407bSFedor Sergeev
25467904db2SAlina Sbirlea class IRCELegacyPass : public FunctionPass {
255a1837a34SSanjoy Das public:
256a1837a34SSanjoy Das static char ID;
2577f0f9bc5SEugene Zelenko
IRCELegacyPass()25867904db2SAlina Sbirlea IRCELegacyPass() : FunctionPass(ID) {
259194a407bSFedor Sergeev initializeIRCELegacyPassPass(*PassRegistry::getPassRegistry());
260a1837a34SSanjoy Das }
261a1837a34SSanjoy Das
getAnalysisUsage(AnalysisUsage & AU) const262a1837a34SSanjoy Das void getAnalysisUsage(AnalysisUsage &AU) const override {
263ab23bfbcSCong Hou AU.addRequired<BranchProbabilityInfoWrapperPass>();
26467904db2SAlina Sbirlea AU.addRequired<DominatorTreeWrapperPass>();
26567904db2SAlina Sbirlea AU.addPreserved<DominatorTreeWrapperPass>();
26667904db2SAlina Sbirlea AU.addRequired<LoopInfoWrapperPass>();
26767904db2SAlina Sbirlea AU.addPreserved<LoopInfoWrapperPass>();
26867904db2SAlina Sbirlea AU.addRequired<ScalarEvolutionWrapperPass>();
26967904db2SAlina Sbirlea AU.addPreserved<ScalarEvolutionWrapperPass>();
270a1837a34SSanjoy Das }
271a1837a34SSanjoy Das
27267904db2SAlina Sbirlea bool runOnFunction(Function &F) override;
273a1837a34SSanjoy Das };
274a1837a34SSanjoy Das
2757f0f9bc5SEugene Zelenko } // end anonymous namespace
2767f0f9bc5SEugene Zelenko
277194a407bSFedor Sergeev char IRCELegacyPass::ID = 0;
278a1837a34SSanjoy Das
279194a407bSFedor Sergeev INITIALIZE_PASS_BEGIN(IRCELegacyPass, "irce",
280da0d79e0SSanjoy Das "Inductive range check elimination", false, false)
INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)281da0d79e0SSanjoy Das INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
28267904db2SAlina Sbirlea INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
28367904db2SAlina Sbirlea INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
28467904db2SAlina Sbirlea INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
285194a407bSFedor Sergeev INITIALIZE_PASS_END(IRCELegacyPass, "irce", "Inductive range check elimination",
286194a407bSFedor Sergeev false, false)
287a1837a34SSanjoy Das
288f13900f8SSanjoy Das /// Parse a single ICmp instruction, `ICI`, into a range check. If `ICI` cannot
28980242ee8SMax Kazantsev /// be interpreted as a range check, return false and set `Index` and `Length`
29080242ee8SMax Kazantsev /// to `nullptr`. Otherwise set `Index` to the value being range checked, and
29180242ee8SMax Kazantsev /// set `Length` to the upper limit `Index` is being range checked.
29280242ee8SMax Kazantsev bool
293337d46b3SSanjoy Das InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
294337d46b3SSanjoy Das ScalarEvolution &SE, Value *&Index,
2959ac7021aSMax Kazantsev Value *&Length, bool &IsSigned) {
2968624a478SMax Kazantsev auto IsLoopInvariant = [&SE, L](Value *V) {
2978624a478SMax Kazantsev return SE.isLoopInvariant(SE.getSCEV(V), L);
298337d46b3SSanjoy Das };
299e2cde6f1SSanjoy Das
300e2cde6f1SSanjoy Das ICmpInst::Predicate Pred = ICI->getPredicate();
301e2cde6f1SSanjoy Das Value *LHS = ICI->getOperand(0);
302e2cde6f1SSanjoy Das Value *RHS = ICI->getOperand(1);
303a1837a34SSanjoy Das
304a1837a34SSanjoy Das switch (Pred) {
305a1837a34SSanjoy Das default:
30680242ee8SMax Kazantsev return false;
307a1837a34SSanjoy Das
308a1837a34SSanjoy Das case ICmpInst::ICMP_SLE:
309a1837a34SSanjoy Das std::swap(LHS, RHS);
310b03fd12cSJustin Bogner LLVM_FALLTHROUGH;
311a1837a34SSanjoy Das case ICmpInst::ICMP_SGE:
3129ac7021aSMax Kazantsev IsSigned = true;
313e2cde6f1SSanjoy Das if (match(RHS, m_ConstantInt<0>())) {
314e2cde6f1SSanjoy Das Index = LHS;
31580242ee8SMax Kazantsev return true; // Lower.
316e2cde6f1SSanjoy Das }
31780242ee8SMax Kazantsev return false;
318a1837a34SSanjoy Das
319a1837a34SSanjoy Das case ICmpInst::ICMP_SLT:
320a1837a34SSanjoy Das std::swap(LHS, RHS);
321b03fd12cSJustin Bogner LLVM_FALLTHROUGH;
322a1837a34SSanjoy Das case ICmpInst::ICMP_SGT:
3239ac7021aSMax Kazantsev IsSigned = true;
324e2cde6f1SSanjoy Das if (match(RHS, m_ConstantInt<-1>())) {
325e2cde6f1SSanjoy Das Index = LHS;
32680242ee8SMax Kazantsev return true; // Lower.
327a1837a34SSanjoy Das }
328a1837a34SSanjoy Das
3298624a478SMax Kazantsev if (IsLoopInvariant(LHS)) {
330e2cde6f1SSanjoy Das Index = RHS;
331e2cde6f1SSanjoy Das Length = LHS;
33280242ee8SMax Kazantsev return true; // Upper.
333e2cde6f1SSanjoy Das }
33480242ee8SMax Kazantsev return false;
335a1837a34SSanjoy Das
336a1837a34SSanjoy Das case ICmpInst::ICMP_ULT:
337e2cde6f1SSanjoy Das std::swap(LHS, RHS);
338b03fd12cSJustin Bogner LLVM_FALLTHROUGH;
339e2cde6f1SSanjoy Das case ICmpInst::ICMP_UGT:
3409ac7021aSMax Kazantsev IsSigned = false;
3418624a478SMax Kazantsev if (IsLoopInvariant(LHS)) {
342e2cde6f1SSanjoy Das Index = RHS;
343e2cde6f1SSanjoy Das Length = LHS;
34480242ee8SMax Kazantsev return true; // Both lower and upper.
345a1837a34SSanjoy Das }
34680242ee8SMax Kazantsev return false;
347a1837a34SSanjoy Das }
348a1837a34SSanjoy Das
349e2cde6f1SSanjoy Das llvm_unreachable("default clause returns!");
350e2cde6f1SSanjoy Das }
351e2cde6f1SSanjoy Das
extractRangeChecksFromCond(Loop * L,ScalarEvolution & SE,Use & ConditionUse,SmallVectorImpl<InductiveRangeCheck> & Checks,SmallPtrSetImpl<Value * > & Visited)352a099268eSSanjoy Das void InductiveRangeCheck::extractRangeChecksFromCond(
353a099268eSSanjoy Das Loop *L, ScalarEvolution &SE, Use &ConditionUse,
354a099268eSSanjoy Das SmallVectorImpl<InductiveRangeCheck> &Checks,
355a099268eSSanjoy Das SmallPtrSetImpl<Value *> &Visited) {
3568fe8892cSSanjoy Das Value *Condition = ConditionUse.get();
357a099268eSSanjoy Das if (!Visited.insert(Condition).second)
358a099268eSSanjoy Das return;
3598fe8892cSSanjoy Das
3601ac6e8aeSMax Kazantsev // TODO: Do the same for OR, XOR, NOT etc?
361fc3f0c9cSJuneyoung Lee if (match(Condition, m_LogicalAnd(m_Value(), m_Value()))) {
362a099268eSSanjoy Das extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(0),
3631ac6e8aeSMax Kazantsev Checks, Visited);
364a099268eSSanjoy Das extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(1),
3651ac6e8aeSMax Kazantsev Checks, Visited);
366a099268eSSanjoy Das return;
367a099268eSSanjoy Das }
368a099268eSSanjoy Das
369a099268eSSanjoy Das ICmpInst *ICI = dyn_cast<ICmpInst>(Condition);
370a099268eSSanjoy Das if (!ICI)
371a099268eSSanjoy Das return;
372a099268eSSanjoy Das
373a099268eSSanjoy Das Value *Length = nullptr, *Index;
3749ac7021aSMax Kazantsev bool IsSigned;
37580242ee8SMax Kazantsev if (!parseRangeCheckICmp(L, ICI, SE, Index, Length, IsSigned))
376a099268eSSanjoy Das return;
377a1837a34SSanjoy Das
3788fe8892cSSanjoy Das const auto *IndexAddRec = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(Index));
3798fe8892cSSanjoy Das bool IsAffineIndex =
3808fe8892cSSanjoy Das IndexAddRec && (IndexAddRec->getLoop() == L) && IndexAddRec->isAffine();
381a1837a34SSanjoy Das
3828fe8892cSSanjoy Das if (!IsAffineIndex)
383a099268eSSanjoy Das return;
3848fe8892cSSanjoy Das
385ef057600SMax Kazantsev const SCEV *End = nullptr;
386ef057600SMax Kazantsev // We strengthen "0 <= I" to "0 <= I < INT_SMAX" and "I < L" to "0 <= I < L".
387ef057600SMax Kazantsev // We can potentially do much better here.
388ef057600SMax Kazantsev if (Length)
389ef057600SMax Kazantsev End = SE.getSCEV(Length);
390ef057600SMax Kazantsev else {
391ef057600SMax Kazantsev // So far we can only reach this point for Signed range check. This may
392ef057600SMax Kazantsev // change in future. In this case we will need to pick Unsigned max for the
393ef057600SMax Kazantsev // unsigned range check.
394ef057600SMax Kazantsev unsigned BitWidth = cast<IntegerType>(IndexAddRec->getType())->getBitWidth();
395ef057600SMax Kazantsev const SCEV *SIntMax = SE.getConstant(APInt::getSignedMaxValue(BitWidth));
396ef057600SMax Kazantsev End = SIntMax;
397ef057600SMax Kazantsev }
398ef057600SMax Kazantsev
3998fe8892cSSanjoy Das InductiveRangeCheck IRC;
400ef057600SMax Kazantsev IRC.End = End;
40184286ce5SMax Kazantsev IRC.Begin = IndexAddRec->getStart();
40284286ce5SMax Kazantsev IRC.Step = IndexAddRec->getStepRecurrence(SE);
4038fe8892cSSanjoy Das IRC.CheckUse = &ConditionUse;
404a099268eSSanjoy Das Checks.push_back(IRC);
405a1837a34SSanjoy Das }
406a1837a34SSanjoy Das
extractRangeChecksFromBranch(BranchInst * BI,Loop * L,ScalarEvolution & SE,BranchProbabilityInfo * BPI,SmallVectorImpl<InductiveRangeCheck> & Checks)407a099268eSSanjoy Das void InductiveRangeCheck::extractRangeChecksFromBranch(
408194a407bSFedor Sergeev BranchInst *BI, Loop *L, ScalarEvolution &SE, BranchProbabilityInfo *BPI,
409a099268eSSanjoy Das SmallVectorImpl<InductiveRangeCheck> &Checks) {
410a1837a34SSanjoy Das if (BI->isUnconditional() || BI->getParent() == L->getLoopLatch())
411a099268eSSanjoy Das return;
412a1837a34SSanjoy Das
413dcf26510SSanjoy Das BranchProbability LikelyTaken(15, 16);
414dcf26510SSanjoy Das
415194a407bSFedor Sergeev if (!SkipProfitabilityChecks && BPI &&
416194a407bSFedor Sergeev BPI->getEdgeProbability(BI->getParent(), (unsigned)0) < LikelyTaken)
417a099268eSSanjoy Das return;
418dcf26510SSanjoy Das
419a099268eSSanjoy Das SmallPtrSet<Value *, 8> Visited;
420a099268eSSanjoy Das InductiveRangeCheck::extractRangeChecksFromCond(L, SE, BI->getOperandUse(0),
421a099268eSSanjoy Das Checks, Visited);
422a1837a34SSanjoy Das }
423a1837a34SSanjoy Das
42465ca8e91SAnna Thomas // Add metadata to the loop L to disable loop optimizations. Callers need to
42565ca8e91SAnna Thomas // confirm that optimizing loop L is not beneficial.
DisableAllLoopOptsOnLoop(Loop & L)42665ca8e91SAnna Thomas static void DisableAllLoopOptsOnLoop(Loop &L) {
42765ca8e91SAnna Thomas // We do not care about any existing loopID related metadata for L, since we
42865ca8e91SAnna Thomas // are setting all loop metadata to false.
42965ca8e91SAnna Thomas LLVMContext &Context = L.getHeader()->getContext();
43065ca8e91SAnna Thomas // Reserve first location for self reference to the LoopID metadata node.
43165ca8e91SAnna Thomas MDNode *Dummy = MDNode::get(Context, {});
43265ca8e91SAnna Thomas MDNode *DisableUnroll = MDNode::get(
43365ca8e91SAnna Thomas Context, {MDString::get(Context, "llvm.loop.unroll.disable")});
43465ca8e91SAnna Thomas Metadata *FalseVal =
43565ca8e91SAnna Thomas ConstantAsMetadata::get(ConstantInt::get(Type::getInt1Ty(Context), 0));
43665ca8e91SAnna Thomas MDNode *DisableVectorize = MDNode::get(
43765ca8e91SAnna Thomas Context,
43865ca8e91SAnna Thomas {MDString::get(Context, "llvm.loop.vectorize.enable"), FalseVal});
43965ca8e91SAnna Thomas MDNode *DisableLICMVersioning = MDNode::get(
44065ca8e91SAnna Thomas Context, {MDString::get(Context, "llvm.loop.licm_versioning.disable")});
44165ca8e91SAnna Thomas MDNode *DisableDistribution= MDNode::get(
44265ca8e91SAnna Thomas Context,
44365ca8e91SAnna Thomas {MDString::get(Context, "llvm.loop.distribute.enable"), FalseVal});
44465ca8e91SAnna Thomas MDNode *NewLoopID =
44565ca8e91SAnna Thomas MDNode::get(Context, {Dummy, DisableUnroll, DisableVectorize,
44665ca8e91SAnna Thomas DisableLICMVersioning, DisableDistribution});
44765ca8e91SAnna Thomas // Set operand 0 to refer to the loop id itself.
44865ca8e91SAnna Thomas NewLoopID->replaceOperandWith(0, NewLoopID);
44965ca8e91SAnna Thomas L.setLoopID(NewLoopID);
45065ca8e91SAnna Thomas }
45165ca8e91SAnna Thomas
452a1837a34SSanjoy Das namespace {
453a1837a34SSanjoy Das
454a1837a34SSanjoy Das // Keeps track of the structure of a loop. This is similar to llvm::Loop,
455e75ed926SSanjoy Das // except that it is more lightweight and can track the state of a loop through
456e75ed926SSanjoy Das // changing and potentially invalid IR. This structure also formalizes the
457e75ed926SSanjoy Das // kinds of loops we can deal with -- ones that have a single latch that is also
458e75ed926SSanjoy Das // an exiting block *and* have a canonical induction variable.
459a1837a34SSanjoy Das struct LoopStructure {
4607f0f9bc5SEugene Zelenko const char *Tag = "";
461a1837a34SSanjoy Das
4627f0f9bc5SEugene Zelenko BasicBlock *Header = nullptr;
4637f0f9bc5SEugene Zelenko BasicBlock *Latch = nullptr;
464a1837a34SSanjoy Das
465a1837a34SSanjoy Das // `Latch's terminator instruction is `LatchBr', and it's `LatchBrExitIdx'th
466a1837a34SSanjoy Das // successor is `LatchExit', the exit block of the loop.
4677f0f9bc5SEugene Zelenko BranchInst *LatchBr = nullptr;
4687f0f9bc5SEugene Zelenko BasicBlock *LatchExit = nullptr;
4697f0f9bc5SEugene Zelenko unsigned LatchBrExitIdx = std::numeric_limits<unsigned>::max();
470a1837a34SSanjoy Das
471ec892139SSanjoy Das // The loop represented by this instance of LoopStructure is semantically
472ec892139SSanjoy Das // equivalent to:
473ec892139SSanjoy Das //
474ec892139SSanjoy Das // intN_ty inc = IndVarIncreasing ? 1 : -1;
475675e304eSSerguei Katkov // pred_ty predicate = IndVarIncreasing ? ICMP_SLT : ICMP_SGT;
476ec892139SSanjoy Das //
477675e304eSSerguei Katkov // for (intN_ty iv = IndVarStart; predicate(iv, LoopExitAt); iv = IndVarBase)
478ec892139SSanjoy Das // ... body ...
479ec892139SSanjoy Das
4807f0f9bc5SEugene Zelenko Value *IndVarBase = nullptr;
4817f0f9bc5SEugene Zelenko Value *IndVarStart = nullptr;
4827f0f9bc5SEugene Zelenko Value *IndVarStep = nullptr;
4837f0f9bc5SEugene Zelenko Value *LoopExitAt = nullptr;
4847f0f9bc5SEugene Zelenko bool IndVarIncreasing = false;
4857f0f9bc5SEugene Zelenko bool IsSignedPredicate = true;
486a1837a34SSanjoy Das
4877f0f9bc5SEugene Zelenko LoopStructure() = default;
488a1837a34SSanjoy Das
map__anonfaeb45920311::LoopStructure489a1837a34SSanjoy Das template <typename M> LoopStructure map(M Map) const {
490a1837a34SSanjoy Das LoopStructure Result;
491a1837a34SSanjoy Das Result.Tag = Tag;
492a1837a34SSanjoy Das Result.Header = cast<BasicBlock>(Map(Header));
493a1837a34SSanjoy Das Result.Latch = cast<BasicBlock>(Map(Latch));
494a1837a34SSanjoy Das Result.LatchBr = cast<BranchInst>(Map(LatchBr));
495a1837a34SSanjoy Das Result.LatchExit = cast<BasicBlock>(Map(LatchExit));
496a1837a34SSanjoy Das Result.LatchBrExitIdx = LatchBrExitIdx;
497a22742beSMax Kazantsev Result.IndVarBase = Map(IndVarBase);
498e75ed926SSanjoy Das Result.IndVarStart = Map(IndVarStart);
4992f6ae281SMax Kazantsev Result.IndVarStep = Map(IndVarStep);
500e75ed926SSanjoy Das Result.LoopExitAt = Map(LoopExitAt);
501e75ed926SSanjoy Das Result.IndVarIncreasing = IndVarIncreasing;
50207da1ab2SMax Kazantsev Result.IsSignedPredicate = IsSignedPredicate;
503a1837a34SSanjoy Das return Result;
504a1837a34SSanjoy Das }
505e75ed926SSanjoy Das
50675d0e0cdSSerguei Katkov static Optional<LoopStructure> parseLoopStructure(ScalarEvolution &, Loop &,
50775d0e0cdSSerguei Katkov const char *&);
508a1837a34SSanjoy Das };
509a1837a34SSanjoy Das
510e75ed926SSanjoy Das /// This class is used to constrain loops to run within a given iteration space.
511e75ed926SSanjoy Das /// The algorithm this class implements is given a Loop and a range [Begin,
512e75ed926SSanjoy Das /// End). The algorithm then tries to break out a "main loop" out of the loop
513e75ed926SSanjoy Das /// it is given in a way that the "main loop" runs with the induction variable
514e75ed926SSanjoy Das /// in a subset of [Begin, End). The algorithm emits appropriate pre and post
515e75ed926SSanjoy Das /// loops to run any remaining iterations. The pre loop runs any iterations in
516e75ed926SSanjoy Das /// which the induction variable is < Begin, and the post loop runs any
517e75ed926SSanjoy Das /// iterations in which the induction variable is >= End.
518e75ed926SSanjoy Das class LoopConstrainer {
519a1837a34SSanjoy Das // The representation of a clone of the original loop we started out with.
520a1837a34SSanjoy Das struct ClonedLoop {
521a1837a34SSanjoy Das // The cloned blocks
522a1837a34SSanjoy Das std::vector<BasicBlock *> Blocks;
523a1837a34SSanjoy Das
524a1837a34SSanjoy Das // `Map` maps values in the clonee into values in the cloned version
525a1837a34SSanjoy Das ValueToValueMapTy Map;
526a1837a34SSanjoy Das
527a1837a34SSanjoy Das // An instance of `LoopStructure` for the cloned loop
528a1837a34SSanjoy Das LoopStructure Structure;
529a1837a34SSanjoy Das };
530a1837a34SSanjoy Das
531a1837a34SSanjoy Das // Result of rewriting the range of a loop. See changeIterationSpaceEnd for
532a1837a34SSanjoy Das // more details on what these fields mean.
533a1837a34SSanjoy Das struct RewrittenRangeInfo {
5347f0f9bc5SEugene Zelenko BasicBlock *PseudoExit = nullptr;
5357f0f9bc5SEugene Zelenko BasicBlock *ExitSelector = nullptr;
536a1837a34SSanjoy Das std::vector<PHINode *> PHIValuesAtPseudoExit;
5377f0f9bc5SEugene Zelenko PHINode *IndVarEnd = nullptr;
538a1837a34SSanjoy Das
5397f0f9bc5SEugene Zelenko RewrittenRangeInfo() = default;
540a1837a34SSanjoy Das };
541a1837a34SSanjoy Das
542a1837a34SSanjoy Das // Calculated subranges we restrict the iteration space of the main loop to.
543a1837a34SSanjoy Das // See the implementation of `calculateSubRanges' for more details on how
544e75ed926SSanjoy Das // these fields are computed. `LowLimit` is None if there is no restriction
545e75ed926SSanjoy Das // on low end of the restricted iteration space of the main loop. `HighLimit`
546e75ed926SSanjoy Das // is None if there is no restriction on high end of the restricted iteration
547e75ed926SSanjoy Das // space of the main loop.
548e75ed926SSanjoy Das
549a1837a34SSanjoy Das struct SubRanges {
550e75ed926SSanjoy Das Optional<const SCEV *> LowLimit;
551e75ed926SSanjoy Das Optional<const SCEV *> HighLimit;
552a1837a34SSanjoy Das };
553a1837a34SSanjoy Das
554a1837a34SSanjoy Das // Compute a safe set of limits for the main loop to run in -- effectively the
555a1837a34SSanjoy Das // intersection of `Range' and the iteration space of the original loop.
556d1fb13ceSSanjoy Das // Return None if unable to compute the set of subranges.
55707da1ab2SMax Kazantsev Optional<SubRanges> calculateSubRanges(bool IsSignedPredicate) const;
558a1837a34SSanjoy Das
559a1837a34SSanjoy Das // Clone `OriginalLoop' and return the result in CLResult. The IR after
560a1837a34SSanjoy Das // running `cloneLoop' is well formed except for the PHI nodes in CLResult --
561a1837a34SSanjoy Das // the PHI nodes say that there is an incoming edge from `OriginalPreheader`
562a1837a34SSanjoy Das // but there is no such edge.
563a1837a34SSanjoy Das void cloneLoop(ClonedLoop &CLResult, const char *Tag) const;
564a1837a34SSanjoy Das
5652143447cSSanjoy Das // Create the appropriate loop structure needed to describe a cloned copy of
5662143447cSSanjoy Das // `Original`. The clone is described by `VM`.
5672143447cSSanjoy Das Loop *createClonedLoopStructure(Loop *Original, Loop *Parent,
568194a407bSFedor Sergeev ValueToValueMapTy &VM, bool IsSubloop);
5692143447cSSanjoy Das
570a1837a34SSanjoy Das // Rewrite the iteration space of the loop denoted by (LS, Preheader). The
571a1837a34SSanjoy Das // iteration space of the rewritten loop ends at ExitLoopAt. The start of the
572a1837a34SSanjoy Das // iteration space is not changed. `ExitLoopAt' is assumed to be slt
573a1837a34SSanjoy Das // `OriginalHeaderCount'.
574a1837a34SSanjoy Das //
575a1837a34SSanjoy Das // If there are iterations left to execute, control is made to jump to
576a1837a34SSanjoy Das // `ContinuationBlock', otherwise they take the normal loop exit. The
577a1837a34SSanjoy Das // returned `RewrittenRangeInfo' object is populated as follows:
578a1837a34SSanjoy Das //
579a1837a34SSanjoy Das // .PseudoExit is a basic block that unconditionally branches to
580a1837a34SSanjoy Das // `ContinuationBlock'.
581a1837a34SSanjoy Das //
582a1837a34SSanjoy Das // .ExitSelector is a basic block that decides, on exit from the loop,
583a1837a34SSanjoy Das // whether to branch to the "true" exit or to `PseudoExit'.
584a1837a34SSanjoy Das //
585a1837a34SSanjoy Das // .PHIValuesAtPseudoExit are PHINodes in `PseudoExit' that compute the value
586a1837a34SSanjoy Das // for each PHINode in the loop header on taking the pseudo exit.
587a1837a34SSanjoy Das //
588a1837a34SSanjoy Das // After changeIterationSpaceEnd, `Preheader' is no longer a legitimate
589a1837a34SSanjoy Das // preheader because it is made to branch to the loop header only
590a1837a34SSanjoy Das // conditionally.
591a1837a34SSanjoy Das RewrittenRangeInfo
592a1837a34SSanjoy Das changeIterationSpaceEnd(const LoopStructure &LS, BasicBlock *Preheader,
593a1837a34SSanjoy Das Value *ExitLoopAt,
594a1837a34SSanjoy Das BasicBlock *ContinuationBlock) const;
595a1837a34SSanjoy Das
596a1837a34SSanjoy Das // The loop denoted by `LS' has `OldPreheader' as its preheader. This
597a1837a34SSanjoy Das // function creates a new preheader for `LS' and returns it.
598e75ed926SSanjoy Das BasicBlock *createPreheader(const LoopStructure &LS, BasicBlock *OldPreheader,
599e75ed926SSanjoy Das const char *Tag) const;
600a1837a34SSanjoy Das
601a1837a34SSanjoy Das // `ContinuationBlockAndPreheader' was the continuation block for some call to
602a1837a34SSanjoy Das // `changeIterationSpaceEnd' and is the preheader to the loop denoted by `LS'.
603a1837a34SSanjoy Das // This function rewrites the PHI nodes in `LS.Header' to start with the
604a1837a34SSanjoy Das // correct value.
605a1837a34SSanjoy Das void rewriteIncomingValuesForPHIs(
606e75ed926SSanjoy Das LoopStructure &LS, BasicBlock *ContinuationBlockAndPreheader,
607a1837a34SSanjoy Das const LoopConstrainer::RewrittenRangeInfo &RRI) const;
608a1837a34SSanjoy Das
609a1837a34SSanjoy Das // Even though we do not preserve any passes at this time, we at least need to
610a1837a34SSanjoy Das // keep the parent loop structure consistent. The `LPPassManager' seems to
611a1837a34SSanjoy Das // verify this after running a loop pass. This function adds the list of
61239f76acbSBenjamin Kramer // blocks denoted by BBs to this loops parent loop if required.
61339f76acbSBenjamin Kramer void addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs);
614a1837a34SSanjoy Das
615a1837a34SSanjoy Das // Some global state.
616a1837a34SSanjoy Das Function &F;
617a1837a34SSanjoy Das LLVMContext &Ctx;
618a1837a34SSanjoy Das ScalarEvolution &SE;
619f45e03e2SSanjoy Das DominatorTree &DT;
62035459f0eSSanjoy Das LoopInfo &LI;
621194a407bSFedor Sergeev function_ref<void(Loop *, bool)> LPMAddNewLoop;
622a1837a34SSanjoy Das
623a1837a34SSanjoy Das // Information about the original loop we started out with.
624a1837a34SSanjoy Das Loop &OriginalLoop;
6257f0f9bc5SEugene Zelenko
6267f0f9bc5SEugene Zelenko const SCEV *LatchTakenCount = nullptr;
6277f0f9bc5SEugene Zelenko BasicBlock *OriginalPreheader = nullptr;
628a1837a34SSanjoy Das
629a1837a34SSanjoy Das // The preheader of the main loop. This may or may not be different from
630a1837a34SSanjoy Das // `OriginalPreheader'.
6317f0f9bc5SEugene Zelenko BasicBlock *MainLoopPreheader = nullptr;
632a1837a34SSanjoy Das
633a1837a34SSanjoy Das // The range we need to run the main loop in.
634a1837a34SSanjoy Das InductiveRangeCheck::Range Range;
635a1837a34SSanjoy Das
636a1837a34SSanjoy Das // The structure of the main loop (see comment at the beginning of this class
637a1837a34SSanjoy Das // for a definition)
638a1837a34SSanjoy Das LoopStructure MainLoopStructure;
639a1837a34SSanjoy Das
640a1837a34SSanjoy Das public:
LoopConstrainer(Loop & L,LoopInfo & LI,function_ref<void (Loop *,bool)> LPMAddNewLoop,const LoopStructure & LS,ScalarEvolution & SE,DominatorTree & DT,InductiveRangeCheck::Range R)641194a407bSFedor Sergeev LoopConstrainer(Loop &L, LoopInfo &LI,
642194a407bSFedor Sergeev function_ref<void(Loop *, bool)> LPMAddNewLoop,
6432143447cSSanjoy Das const LoopStructure &LS, ScalarEvolution &SE,
6442143447cSSanjoy Das DominatorTree &DT, InductiveRangeCheck::Range R)
645e75ed926SSanjoy Das : F(*L.getHeader()->getParent()), Ctx(L.getHeader()->getContext()),
646194a407bSFedor Sergeev SE(SE), DT(DT), LI(LI), LPMAddNewLoop(LPMAddNewLoop), OriginalLoop(L),
647194a407bSFedor Sergeev Range(R), MainLoopStructure(LS) {}
648a1837a34SSanjoy Das
649a1837a34SSanjoy Das // Entry point for the algorithm. Returns true on success.
650a1837a34SSanjoy Das bool run();
651a1837a34SSanjoy Das };
652a1837a34SSanjoy Das
6537f0f9bc5SEugene Zelenko } // end anonymous namespace
654a1837a34SSanjoy Das
65590b7f4f7SSam Parker /// Given a loop with an deccreasing induction variable, is it possible to
65690b7f4f7SSam Parker /// safely calculate the bounds of a new loop using the given Predicate.
isSafeDecreasingBound(const SCEV * Start,const SCEV * BoundSCEV,const SCEV * Step,ICmpInst::Predicate Pred,unsigned LatchBrExitIdx,Loop * L,ScalarEvolution & SE)65790b7f4f7SSam Parker static bool isSafeDecreasingBound(const SCEV *Start,
65890b7f4f7SSam Parker const SCEV *BoundSCEV, const SCEV *Step,
65990b7f4f7SSam Parker ICmpInst::Predicate Pred,
66090b7f4f7SSam Parker unsigned LatchBrExitIdx,
66190b7f4f7SSam Parker Loop *L, ScalarEvolution &SE) {
66290b7f4f7SSam Parker if (Pred != ICmpInst::ICMP_SLT && Pred != ICmpInst::ICMP_SGT &&
66390b7f4f7SSam Parker Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_UGT)
66490b7f4f7SSam Parker return false;
66590b7f4f7SSam Parker
66690b7f4f7SSam Parker if (!SE.isAvailableAtLoopEntry(BoundSCEV, L))
66790b7f4f7SSam Parker return false;
66890b7f4f7SSam Parker
66990b7f4f7SSam Parker assert(SE.isKnownNegative(Step) && "expecting negative step");
67090b7f4f7SSam Parker
671d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: isSafeDecreasingBound with:\n");
672d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: Start: " << *Start << "\n");
673d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: Step: " << *Step << "\n");
674d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: BoundSCEV: " << *BoundSCEV << "\n");
675d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: Pred: " << ICmpInst::getPredicateName(Pred)
676d34e60caSNicola Zaghen << "\n");
677d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: LatchExitBrIdx: " << LatchBrExitIdx << "\n");
67890b7f4f7SSam Parker
67990b7f4f7SSam Parker bool IsSigned = ICmpInst::isSigned(Pred);
68090b7f4f7SSam Parker // The predicate that we need to check that the induction variable lies
68190b7f4f7SSam Parker // within bounds.
68290b7f4f7SSam Parker ICmpInst::Predicate BoundPred =
68390b7f4f7SSam Parker IsSigned ? CmpInst::ICMP_SGT : CmpInst::ICMP_UGT;
68490b7f4f7SSam Parker
68590b7f4f7SSam Parker if (LatchBrExitIdx == 1)
68690b7f4f7SSam Parker return SE.isLoopEntryGuardedByCond(L, BoundPred, Start, BoundSCEV);
68790b7f4f7SSam Parker
68890b7f4f7SSam Parker assert(LatchBrExitIdx == 0 &&
68990b7f4f7SSam Parker "LatchBrExitIdx should be either 0 or 1");
69090b7f4f7SSam Parker
69190b7f4f7SSam Parker const SCEV *StepPlusOne = SE.getAddExpr(Step, SE.getOne(Step->getType()));
69290b7f4f7SSam Parker unsigned BitWidth = cast<IntegerType>(BoundSCEV->getType())->getBitWidth();
69390b7f4f7SSam Parker APInt Min = IsSigned ? APInt::getSignedMinValue(BitWidth) :
69490b7f4f7SSam Parker APInt::getMinValue(BitWidth);
69590b7f4f7SSam Parker const SCEV *Limit = SE.getMinusSCEV(SE.getConstant(Min), StepPlusOne);
69690b7f4f7SSam Parker
69790b7f4f7SSam Parker const SCEV *MinusOne =
69890b7f4f7SSam Parker SE.getMinusSCEV(BoundSCEV, SE.getOne(BoundSCEV->getType()));
69990b7f4f7SSam Parker
70090b7f4f7SSam Parker return SE.isLoopEntryGuardedByCond(L, BoundPred, Start, MinusOne) &&
70190b7f4f7SSam Parker SE.isLoopEntryGuardedByCond(L, BoundPred, BoundSCEV, Limit);
70290b7f4f7SSam Parker
703a1837a34SSanjoy Das }
704a1837a34SSanjoy Das
70553a423a4SSam Parker /// Given a loop with an increasing induction variable, is it possible to
70653a423a4SSam Parker /// safely calculate the bounds of a new loop using the given Predicate.
isSafeIncreasingBound(const SCEV * Start,const SCEV * BoundSCEV,const SCEV * Step,ICmpInst::Predicate Pred,unsigned LatchBrExitIdx,Loop * L,ScalarEvolution & SE)70753a423a4SSam Parker static bool isSafeIncreasingBound(const SCEV *Start,
70853a423a4SSam Parker const SCEV *BoundSCEV, const SCEV *Step,
70953a423a4SSam Parker ICmpInst::Predicate Pred,
71053a423a4SSam Parker unsigned LatchBrExitIdx,
71153a423a4SSam Parker Loop *L, ScalarEvolution &SE) {
71253a423a4SSam Parker if (Pred != ICmpInst::ICMP_SLT && Pred != ICmpInst::ICMP_SGT &&
71353a423a4SSam Parker Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_UGT)
71453a423a4SSam Parker return false;
71553a423a4SSam Parker
71653a423a4SSam Parker if (!SE.isAvailableAtLoopEntry(BoundSCEV, L))
71753a423a4SSam Parker return false;
71853a423a4SSam Parker
719d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: isSafeIncreasingBound with:\n");
720d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: Start: " << *Start << "\n");
721d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: Step: " << *Step << "\n");
722d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: BoundSCEV: " << *BoundSCEV << "\n");
723d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: Pred: " << ICmpInst::getPredicateName(Pred)
724d34e60caSNicola Zaghen << "\n");
725d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: LatchExitBrIdx: " << LatchBrExitIdx << "\n");
72653a423a4SSam Parker
72753a423a4SSam Parker bool IsSigned = ICmpInst::isSigned(Pred);
72853a423a4SSam Parker // The predicate that we need to check that the induction variable lies
72953a423a4SSam Parker // within bounds.
73053a423a4SSam Parker ICmpInst::Predicate BoundPred =
73153a423a4SSam Parker IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT;
73253a423a4SSam Parker
73353a423a4SSam Parker if (LatchBrExitIdx == 1)
73453a423a4SSam Parker return SE.isLoopEntryGuardedByCond(L, BoundPred, Start, BoundSCEV);
73553a423a4SSam Parker
73653a423a4SSam Parker assert(LatchBrExitIdx == 0 && "LatchBrExitIdx should be 0 or 1");
73753a423a4SSam Parker
73853a423a4SSam Parker const SCEV *StepMinusOne =
73953a423a4SSam Parker SE.getMinusSCEV(Step, SE.getOne(Step->getType()));
74053a423a4SSam Parker unsigned BitWidth = cast<IntegerType>(BoundSCEV->getType())->getBitWidth();
74153a423a4SSam Parker APInt Max = IsSigned ? APInt::getSignedMaxValue(BitWidth) :
74253a423a4SSam Parker APInt::getMaxValue(BitWidth);
74353a423a4SSam Parker const SCEV *Limit = SE.getMinusSCEV(SE.getConstant(Max), StepMinusOne);
74453a423a4SSam Parker
74553a423a4SSam Parker return (SE.isLoopEntryGuardedByCond(L, BoundPred, Start,
74653a423a4SSam Parker SE.getAddExpr(BoundSCEV, Step)) &&
74753a423a4SSam Parker SE.isLoopEntryGuardedByCond(L, BoundPred, BoundSCEV, Limit));
7482f6ae281SMax Kazantsev }
7492f6ae281SMax Kazantsev
750e75ed926SSanjoy Das Optional<LoopStructure>
parseLoopStructure(ScalarEvolution & SE,Loop & L,const char * & FailureReason)75175d0e0cdSSerguei Katkov LoopStructure::parseLoopStructure(ScalarEvolution &SE, Loop &L,
752194a407bSFedor Sergeev const char *&FailureReason) {
75343fdc543SSanjoy Das if (!L.isLoopSimplifyForm()) {
75443fdc543SSanjoy Das FailureReason = "loop not in LoopSimplify form";
7552a2f14d7SSanjoy Das return None;
75643fdc543SSanjoy Das }
757e75ed926SSanjoy Das
758e75ed926SSanjoy Das BasicBlock *Latch = L.getLoopLatch();
7592a2f14d7SSanjoy Das assert(Latch && "Simplified loops only have one latch!");
7602a2f14d7SSanjoy Das
7617a18a238SSanjoy Das if (Latch->getTerminator()->getMetadata(ClonedLoopTag)) {
7627a18a238SSanjoy Das FailureReason = "loop has already been cloned";
7637a18a238SSanjoy Das return None;
7647a18a238SSanjoy Das }
7657a18a238SSanjoy Das
766e75ed926SSanjoy Das if (!L.isLoopExiting(Latch)) {
767e75ed926SSanjoy Das FailureReason = "no loop latch";
768e75ed926SSanjoy Das return None;
769e75ed926SSanjoy Das }
770e75ed926SSanjoy Das
771e75ed926SSanjoy Das BasicBlock *Header = L.getHeader();
772e75ed926SSanjoy Das BasicBlock *Preheader = L.getLoopPreheader();
773a1837a34SSanjoy Das if (!Preheader) {
774a1837a34SSanjoy Das FailureReason = "no preheader";
775e75ed926SSanjoy Das return None;
776a1837a34SSanjoy Das }
777a1837a34SSanjoy Das
77881c00fe0SSanjoy Das BranchInst *LatchBr = dyn_cast<BranchInst>(Latch->getTerminator());
779a1837a34SSanjoy Das if (!LatchBr || LatchBr->isUnconditional()) {
780a1837a34SSanjoy Das FailureReason = "latch terminator not conditional branch";
781e75ed926SSanjoy Das return None;
782a1837a34SSanjoy Das }
783a1837a34SSanjoy Das
784e75ed926SSanjoy Das unsigned LatchBrExitIdx = LatchBr->getSuccessor(0) == Header ? 1 : 0;
785a1837a34SSanjoy Das
786e75ed926SSanjoy Das ICmpInst *ICI = dyn_cast<ICmpInst>(LatchBr->getCondition());
787e75ed926SSanjoy Das if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType())) {
788e75ed926SSanjoy Das FailureReason = "latch terminator branch not conditional on integral icmp";
789e75ed926SSanjoy Das return None;
790a1837a34SSanjoy Das }
791a1837a34SSanjoy Das
792e75ed926SSanjoy Das const SCEV *LatchCount = SE.getExitCount(&L, Latch);
793e75ed926SSanjoy Das if (isa<SCEVCouldNotCompute>(LatchCount)) {
794e75ed926SSanjoy Das FailureReason = "could not compute latch count";
795e75ed926SSanjoy Das return None;
796a1837a34SSanjoy Das }
797a1837a34SSanjoy Das
798e75ed926SSanjoy Das ICmpInst::Predicate Pred = ICI->getPredicate();
799e75ed926SSanjoy Das Value *LeftValue = ICI->getOperand(0);
800e75ed926SSanjoy Das const SCEV *LeftSCEV = SE.getSCEV(LeftValue);
801e75ed926SSanjoy Das IntegerType *IndVarTy = cast<IntegerType>(LeftValue->getType());
802e75ed926SSanjoy Das
803e75ed926SSanjoy Das Value *RightValue = ICI->getOperand(1);
804e75ed926SSanjoy Das const SCEV *RightSCEV = SE.getSCEV(RightValue);
805e75ed926SSanjoy Das
806e75ed926SSanjoy Das // We canonicalize `ICI` such that `LeftSCEV` is an add recurrence.
807e75ed926SSanjoy Das if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
808e75ed926SSanjoy Das if (isa<SCEVAddRecExpr>(RightSCEV)) {
809e75ed926SSanjoy Das std::swap(LeftSCEV, RightSCEV);
810e75ed926SSanjoy Das std::swap(LeftValue, RightValue);
811e75ed926SSanjoy Das Pred = ICmpInst::getSwappedPredicate(Pred);
812e75ed926SSanjoy Das } else {
813e75ed926SSanjoy Das FailureReason = "no add recurrences in the icmp";
814e75ed926SSanjoy Das return None;
815e75ed926SSanjoy Das }
816a1837a34SSanjoy Das }
817a1837a34SSanjoy Das
81845dc94a8SSanjoy Das auto HasNoSignedWrap = [&](const SCEVAddRecExpr *AR) {
81945dc94a8SSanjoy Das if (AR->getNoWrapFlags(SCEV::FlagNSW))
82045dc94a8SSanjoy Das return true;
821e75ed926SSanjoy Das
822e75ed926SSanjoy Das IntegerType *Ty = cast<IntegerType>(AR->getType());
823e75ed926SSanjoy Das IntegerType *WideTy =
824e75ed926SSanjoy Das IntegerType::get(Ty->getContext(), Ty->getBitWidth() * 2);
825e75ed926SSanjoy Das
826e75ed926SSanjoy Das const SCEVAddRecExpr *ExtendAfterOp =
827e75ed926SSanjoy Das dyn_cast<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy));
82845dc94a8SSanjoy Das if (ExtendAfterOp) {
829e75ed926SSanjoy Das const SCEV *ExtendedStart = SE.getSignExtendExpr(AR->getStart(), WideTy);
830e75ed926SSanjoy Das const SCEV *ExtendedStep =
831e75ed926SSanjoy Das SE.getSignExtendExpr(AR->getStepRecurrence(SE), WideTy);
832e75ed926SSanjoy Das
833e75ed926SSanjoy Das bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart &&
834e75ed926SSanjoy Das ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep;
835e75ed926SSanjoy Das
83645dc94a8SSanjoy Das if (NoSignedWrap)
83745dc94a8SSanjoy Das return true;
83845dc94a8SSanjoy Das }
83945dc94a8SSanjoy Das
84045dc94a8SSanjoy Das // We may have proved this when computing the sign extension above.
84145dc94a8SSanjoy Das return AR->getNoWrapFlags(SCEV::FlagNSW) != SCEV::FlagAnyWrap;
84245dc94a8SSanjoy Das };
84345dc94a8SSanjoy Das
844675e304eSSerguei Katkov // `ICI` is interpreted as taking the backedge if the *next* value of the
845675e304eSSerguei Katkov // induction variable satisfies some constraint.
846e75ed926SSanjoy Das
847a22742beSMax Kazantsev const SCEVAddRecExpr *IndVarBase = cast<SCEVAddRecExpr>(LeftSCEV);
8483c19051bSSam Parker if (!IndVarBase->isAffine()) {
849e75ed926SSanjoy Das FailureReason = "LHS in icmp not induction variable";
850e75ed926SSanjoy Das return None;
851e75ed926SSanjoy Das }
8523c19051bSSam Parker const SCEV* StepRec = IndVarBase->getStepRecurrence(SE);
853786032c1SMax Kazantsev if (!isa<SCEVConstant>(StepRec)) {
8543c19051bSSam Parker FailureReason = "LHS in icmp not induction variable";
8553c19051bSSam Parker return None;
8563c19051bSSam Parker }
857786032c1SMax Kazantsev ConstantInt *StepCI = cast<SCEVConstant>(StepRec)->getValue();
858786032c1SMax Kazantsev
8593c19051bSSam Parker if (ICI->isEquality() && !HasNoSignedWrap(IndVarBase)) {
8603c19051bSSam Parker FailureReason = "LHS in icmp needs nsw for equality predicates";
8613c19051bSSam Parker return None;
8623c19051bSSam Parker }
863e75ed926SSanjoy Das
8643c19051bSSam Parker assert(!StepCI->isZero() && "Zero step?");
8653c19051bSSam Parker bool IsIncreasing = !StepCI->isNegative();
866b251cc0dSFangrui Song bool IsSignedPredicate;
867a22742beSMax Kazantsev const SCEV *StartNext = IndVarBase->getStart();
868a22742beSMax Kazantsev const SCEV *Addend = SE.getNegativeSCEV(IndVarBase->getStepRecurrence(SE));
869675e304eSSerguei Katkov const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend);
8702f6ae281SMax Kazantsev const SCEV *Step = SE.getSCEV(StepCI);
871ec892139SSanjoy Das
87299a6e405SDenis Antrushin const SCEV *FixedRightSCEV = nullptr;
87399a6e405SDenis Antrushin
87499a6e405SDenis Antrushin // If RightValue resides within loop (but still being loop invariant),
87599a6e405SDenis Antrushin // regenerate it as preheader.
87699a6e405SDenis Antrushin if (auto *I = dyn_cast<Instruction>(RightValue))
87799a6e405SDenis Antrushin if (L.contains(I->getParent()))
87899a6e405SDenis Antrushin FixedRightSCEV = RightSCEV;
87999a6e405SDenis Antrushin
880e75ed926SSanjoy Das if (IsIncreasing) {
8812c627a97SMax Kazantsev bool DecreasedRightValueByOne = false;
8822f6ae281SMax Kazantsev if (StepCI->isOne()) {
8832c627a97SMax Kazantsev // Try to turn eq/ne predicates to those we can work with.
8842c627a97SMax Kazantsev if (Pred == ICmpInst::ICMP_NE && LatchBrExitIdx == 1)
8852c627a97SMax Kazantsev // while (++i != len) { while (++i < len) {
8862c627a97SMax Kazantsev // ... ---> ...
8872c627a97SMax Kazantsev // } }
8882f6ae281SMax Kazantsev // If both parts are known non-negative, it is profitable to use
8892f6ae281SMax Kazantsev // unsigned comparison in increasing loop. This allows us to make the
8902f6ae281SMax Kazantsev // comparison check against "RightSCEV + 1" more optimistic.
89197375359SSam Parker if (isKnownNonNegativeInLoop(IndVarStart, &L, SE) &&
89297375359SSam Parker isKnownNonNegativeInLoop(RightSCEV, &L, SE))
89307da1ab2SMax Kazantsev Pred = ICmpInst::ICMP_ULT;
89407da1ab2SMax Kazantsev else
8952c627a97SMax Kazantsev Pred = ICmpInst::ICMP_SLT;
89653a423a4SSam Parker else if (Pred == ICmpInst::ICMP_EQ && LatchBrExitIdx == 0) {
8972c627a97SMax Kazantsev // while (true) { while (true) {
8982c627a97SMax Kazantsev // if (++i == len) ---> if (++i > len - 1)
8992c627a97SMax Kazantsev // break; break;
9002c627a97SMax Kazantsev // ... ...
9012c627a97SMax Kazantsev // } }
90253a423a4SSam Parker if (IndVarBase->getNoWrapFlags(SCEV::FlagNUW) &&
903a78dc4d6SMax Kazantsev cannotBeMinInLoop(RightSCEV, &L, SE, /*Signed*/false)) {
90453a423a4SSam Parker Pred = ICmpInst::ICMP_UGT;
90553a423a4SSam Parker RightSCEV = SE.getMinusSCEV(RightSCEV,
90653a423a4SSam Parker SE.getOne(RightSCEV->getType()));
9072c627a97SMax Kazantsev DecreasedRightValueByOne = true;
908a78dc4d6SMax Kazantsev } else if (cannotBeMinInLoop(RightSCEV, &L, SE, /*Signed*/true)) {
90953a423a4SSam Parker Pred = ICmpInst::ICMP_SGT;
91053a423a4SSam Parker RightSCEV = SE.getMinusSCEV(RightSCEV,
91153a423a4SSam Parker SE.getOne(RightSCEV->getType()));
91253a423a4SSam Parker DecreasedRightValueByOne = true;
91353a423a4SSam Parker }
9142c627a97SMax Kazantsev }
9152f6ae281SMax Kazantsev }
9162c627a97SMax Kazantsev
91707da1ab2SMax Kazantsev bool LTPred = (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT);
91807da1ab2SMax Kazantsev bool GTPred = (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT);
919e75ed926SSanjoy Das bool FoundExpectedPred =
92007da1ab2SMax Kazantsev (LTPred && LatchBrExitIdx == 1) || (GTPred && LatchBrExitIdx == 0);
921e75ed926SSanjoy Das
922e75ed926SSanjoy Das if (!FoundExpectedPred) {
923e75ed926SSanjoy Das FailureReason = "expected icmp slt semantically, found something else";
924e75ed926SSanjoy Das return None;
925e75ed926SSanjoy Das }
926e75ed926SSanjoy Das
92753a423a4SSam Parker IsSignedPredicate = ICmpInst::isSigned(Pred);
9288aacef6cSMax Kazantsev if (!IsSignedPredicate && !AllowUnsignedLatchCondition) {
9298aacef6cSMax Kazantsev FailureReason = "unsigned latch conditions are explicitly prohibited";
9308aacef6cSMax Kazantsev return None;
9318aacef6cSMax Kazantsev }
9328aacef6cSMax Kazantsev
93353a423a4SSam Parker if (!isSafeIncreasingBound(IndVarStart, RightSCEV, Step, Pred,
93453a423a4SSam Parker LatchBrExitIdx, &L, SE)) {
93553a423a4SSam Parker FailureReason = "Unsafe loop bounds";
93653a423a4SSam Parker return None;
93753a423a4SSam Parker }
938e75ed926SSanjoy Das if (LatchBrExitIdx == 0) {
9392c627a97SMax Kazantsev // We need to increase the right value unless we have already decreased
9402c627a97SMax Kazantsev // it virtually when we replaced EQ with SGT.
94199a6e405SDenis Antrushin if (!DecreasedRightValueByOne)
94299a6e405SDenis Antrushin FixedRightSCEV =
94399a6e405SDenis Antrushin SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));
944ec892139SSanjoy Das } else {
9452c627a97SMax Kazantsev assert(!DecreasedRightValueByOne &&
9462c627a97SMax Kazantsev "Right value can be decreased only for LatchBrExitIdx == 0!");
947ec892139SSanjoy Das }
948e75ed926SSanjoy Das } else {
9492c627a97SMax Kazantsev bool IncreasedRightValueByOne = false;
9502f6ae281SMax Kazantsev if (StepCI->isMinusOne()) {
9512c627a97SMax Kazantsev // Try to turn eq/ne predicates to those we can work with.
9522c627a97SMax Kazantsev if (Pred == ICmpInst::ICMP_NE && LatchBrExitIdx == 1)
9532c627a97SMax Kazantsev // while (--i != len) { while (--i > len) {
9542c627a97SMax Kazantsev // ... ---> ...
9552c627a97SMax Kazantsev // } }
9562f6ae281SMax Kazantsev // We intentionally don't turn the predicate into UGT even if we know
9572f6ae281SMax Kazantsev // that both operands are non-negative, because it will only pessimize
9582f6ae281SMax Kazantsev // our check against "RightSCEV - 1".
9592c627a97SMax Kazantsev Pred = ICmpInst::ICMP_SGT;
96090b7f4f7SSam Parker else if (Pred == ICmpInst::ICMP_EQ && LatchBrExitIdx == 0) {
9612c627a97SMax Kazantsev // while (true) { while (true) {
9622c627a97SMax Kazantsev // if (--i == len) ---> if (--i < len + 1)
9632c627a97SMax Kazantsev // break; break;
9642c627a97SMax Kazantsev // ... ...
9652c627a97SMax Kazantsev // } }
96690b7f4f7SSam Parker if (IndVarBase->getNoWrapFlags(SCEV::FlagNUW) &&
967a78dc4d6SMax Kazantsev cannotBeMaxInLoop(RightSCEV, &L, SE, /* Signed */ false)) {
96890b7f4f7SSam Parker Pred = ICmpInst::ICMP_ULT;
96990b7f4f7SSam Parker RightSCEV = SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));
97090b7f4f7SSam Parker IncreasedRightValueByOne = true;
971a78dc4d6SMax Kazantsev } else if (cannotBeMaxInLoop(RightSCEV, &L, SE, /* Signed */ true)) {
9722c627a97SMax Kazantsev Pred = ICmpInst::ICMP_SLT;
9732c627a97SMax Kazantsev RightSCEV = SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));
9742c627a97SMax Kazantsev IncreasedRightValueByOne = true;
9752c627a97SMax Kazantsev }
9762f6ae281SMax Kazantsev }
97790b7f4f7SSam Parker }
9782c627a97SMax Kazantsev
97907da1ab2SMax Kazantsev bool LTPred = (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT);
98007da1ab2SMax Kazantsev bool GTPred = (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT);
98107da1ab2SMax Kazantsev
982e75ed926SSanjoy Das bool FoundExpectedPred =
98307da1ab2SMax Kazantsev (GTPred && LatchBrExitIdx == 1) || (LTPred && LatchBrExitIdx == 0);
984e75ed926SSanjoy Das
985e75ed926SSanjoy Das if (!FoundExpectedPred) {
986e75ed926SSanjoy Das FailureReason = "expected icmp sgt semantically, found something else";
987e75ed926SSanjoy Das return None;
988e75ed926SSanjoy Das }
989e75ed926SSanjoy Das
99007da1ab2SMax Kazantsev IsSignedPredicate =
99107da1ab2SMax Kazantsev Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT;
9928aacef6cSMax Kazantsev
9938aacef6cSMax Kazantsev if (!IsSignedPredicate && !AllowUnsignedLatchCondition) {
9948aacef6cSMax Kazantsev FailureReason = "unsigned latch conditions are explicitly prohibited";
9958aacef6cSMax Kazantsev return None;
9968aacef6cSMax Kazantsev }
9978aacef6cSMax Kazantsev
99890b7f4f7SSam Parker if (!isSafeDecreasingBound(IndVarStart, RightSCEV, Step, Pred,
99990b7f4f7SSam Parker LatchBrExitIdx, &L, SE)) {
100090b7f4f7SSam Parker FailureReason = "Unsafe bounds";
100190b7f4f7SSam Parker return None;
100290b7f4f7SSam Parker }
100307da1ab2SMax Kazantsev
1004e75ed926SSanjoy Das if (LatchBrExitIdx == 0) {
10052c627a97SMax Kazantsev // We need to decrease the right value unless we have already increased
10062c627a97SMax Kazantsev // it virtually when we replaced EQ with SLT.
100799a6e405SDenis Antrushin if (!IncreasedRightValueByOne)
100899a6e405SDenis Antrushin FixedRightSCEV =
100999a6e405SDenis Antrushin SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType()));
1010ec892139SSanjoy Das } else {
10112c627a97SMax Kazantsev assert(!IncreasedRightValueByOne &&
10122c627a97SMax Kazantsev "Right value can be increased only for LatchBrExitIdx == 0!");
1013ec892139SSanjoy Das }
1014ec892139SSanjoy Das }
1015a1837a34SSanjoy Das BasicBlock *LatchExit = LatchBr->getSuccessor(LatchBrExitIdx);
1016a1837a34SSanjoy Das
1017e75ed926SSanjoy Das assert(SE.getLoopDisposition(LatchCount, &L) ==
1018a1837a34SSanjoy Das ScalarEvolution::LoopInvariant &&
1019a1837a34SSanjoy Das "loop variant exit count doesn't make sense!");
1020a1837a34SSanjoy Das
1021e75ed926SSanjoy Das assert(!L.contains(LatchExit) && "expected an exit block!");
1022a28d91d8SMehdi Amini const DataLayout &DL = Preheader->getModule()->getDataLayout();
102399a6e405SDenis Antrushin SCEVExpander Expander(SE, DL, "irce");
102499a6e405SDenis Antrushin Instruction *Ins = Preheader->getTerminator();
102599a6e405SDenis Antrushin
102699a6e405SDenis Antrushin if (FixedRightSCEV)
102799a6e405SDenis Antrushin RightValue =
102899a6e405SDenis Antrushin Expander.expandCodeFor(FixedRightSCEV, FixedRightSCEV->getType(), Ins);
102999a6e405SDenis Antrushin
103099a6e405SDenis Antrushin Value *IndVarStartV = Expander.expandCodeFor(IndVarStart, IndVarTy, Ins);
1031e75ed926SSanjoy Das IndVarStartV->setName("indvar.start");
1032a1837a34SSanjoy Das
1033e75ed926SSanjoy Das LoopStructure Result;
1034e75ed926SSanjoy Das
1035e75ed926SSanjoy Das Result.Tag = "main";
1036e75ed926SSanjoy Das Result.Header = Header;
1037e75ed926SSanjoy Das Result.Latch = Latch;
1038e75ed926SSanjoy Das Result.LatchBr = LatchBr;
1039e75ed926SSanjoy Das Result.LatchExit = LatchExit;
1040e75ed926SSanjoy Das Result.LatchBrExitIdx = LatchBrExitIdx;
1041e75ed926SSanjoy Das Result.IndVarStart = IndVarStartV;
10422f6ae281SMax Kazantsev Result.IndVarStep = StepCI;
1043a22742beSMax Kazantsev Result.IndVarBase = LeftValue;
1044e75ed926SSanjoy Das Result.IndVarIncreasing = IsIncreasing;
1045e75ed926SSanjoy Das Result.LoopExitAt = RightValue;
104607da1ab2SMax Kazantsev Result.IsSignedPredicate = IsSignedPredicate;
1047e75ed926SSanjoy Das
1048a1837a34SSanjoy Das FailureReason = nullptr;
1049a1837a34SSanjoy Das
1050e75ed926SSanjoy Das return Result;
1051a1837a34SSanjoy Das }
1052a1837a34SSanjoy Das
1053d9aee3c0SMax Kazantsev /// If the type of \p S matches with \p Ty, return \p S. Otherwise, return
1054d9aee3c0SMax Kazantsev /// signed or unsigned extension of \p S to type \p Ty.
NoopOrExtend(const SCEV * S,Type * Ty,ScalarEvolution & SE,bool Signed)1055d9aee3c0SMax Kazantsev static const SCEV *NoopOrExtend(const SCEV *S, Type *Ty, ScalarEvolution &SE,
1056d9aee3c0SMax Kazantsev bool Signed) {
1057d9aee3c0SMax Kazantsev return Signed ? SE.getNoopOrSignExtend(S, Ty) : SE.getNoopOrZeroExtend(S, Ty);
1058d9aee3c0SMax Kazantsev }
1059d9aee3c0SMax Kazantsev
1060d1fb13ceSSanjoy Das Optional<LoopConstrainer::SubRanges>
calculateSubRanges(bool IsSignedPredicate) const106107da1ab2SMax Kazantsev LoopConstrainer::calculateSubRanges(bool IsSignedPredicate) const {
1062a1837a34SSanjoy Das IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
1063a1837a34SSanjoy Das
1064d9aee3c0SMax Kazantsev auto *RTy = cast<IntegerType>(Range.getType());
1065d9aee3c0SMax Kazantsev
1066d9aee3c0SMax Kazantsev // We only support wide range checks and narrow latches.
1067d9aee3c0SMax Kazantsev if (!AllowNarrowLatchCondition && RTy != Ty)
1068d9aee3c0SMax Kazantsev return None;
1069d9aee3c0SMax Kazantsev if (RTy->getBitWidth() < Ty->getBitWidth())
1070d1fb13ceSSanjoy Das return None;
1071d1fb13ceSSanjoy Das
1072a1837a34SSanjoy Das LoopConstrainer::SubRanges Result;
1073a1837a34SSanjoy Das
1074a1837a34SSanjoy Das // I think we can be more aggressive here and make this nuw / nsw if the
1075a1837a34SSanjoy Das // addition that feeds into the icmp for the latch's terminating branch is nuw
1076a1837a34SSanjoy Das // / nsw. In any case, a wrapping 2's complement addition is safe.
1077d9aee3c0SMax Kazantsev const SCEV *Start = NoopOrExtend(SE.getSCEV(MainLoopStructure.IndVarStart),
1078d9aee3c0SMax Kazantsev RTy, SE, IsSignedPredicate);
1079d9aee3c0SMax Kazantsev const SCEV *End = NoopOrExtend(SE.getSCEV(MainLoopStructure.LoopExitAt), RTy,
1080d9aee3c0SMax Kazantsev SE, IsSignedPredicate);
1081a1837a34SSanjoy Das
1082e75ed926SSanjoy Das bool Increasing = MainLoopStructure.IndVarIncreasing;
10837a0b7f59SSanjoy Das
1084f80ffa1aSMax Kazantsev // We compute `Smallest` and `Greatest` such that [Smallest, Greatest), or
1085f80ffa1aSMax Kazantsev // [Smallest, GreatestSeen] is the range of values the induction variable
1086f80ffa1aSMax Kazantsev // takes.
10877a0b7f59SSanjoy Das
1088f80ffa1aSMax Kazantsev const SCEV *Smallest = nullptr, *Greatest = nullptr, *GreatestSeen = nullptr;
10897a0b7f59SSanjoy Das
1090d9aee3c0SMax Kazantsev const SCEV *One = SE.getOne(RTy);
10917a0b7f59SSanjoy Das if (Increasing) {
10927a0b7f59SSanjoy Das Smallest = Start;
10937a0b7f59SSanjoy Das Greatest = End;
1094f80ffa1aSMax Kazantsev // No overflow, because the range [Smallest, GreatestSeen] is not empty.
1095f80ffa1aSMax Kazantsev GreatestSeen = SE.getMinusSCEV(End, One);
10967a0b7f59SSanjoy Das } else {
10977a0b7f59SSanjoy Das // These two computations may sign-overflow. Here is why that is okay:
10987a0b7f59SSanjoy Das //
10997a0b7f59SSanjoy Das // We know that the induction variable does not sign-overflow on any
11007a0b7f59SSanjoy Das // iteration except the last one, and it starts at `Start` and ends at
11017a0b7f59SSanjoy Das // `End`, decrementing by one every time.
11027a0b7f59SSanjoy Das //
11037a0b7f59SSanjoy Das // * if `Smallest` sign-overflows we know `End` is `INT_SMAX`. Since the
11047a0b7f59SSanjoy Das // induction variable is decreasing we know that that the smallest value
11057a0b7f59SSanjoy Das // the loop body is actually executed with is `INT_SMIN` == `Smallest`.
11067a0b7f59SSanjoy Das //
11077a0b7f59SSanjoy Das // * if `Greatest` sign-overflows, we know it can only be `INT_SMIN`. In
11087a0b7f59SSanjoy Das // that case, `Clamp` will always return `Smallest` and
11097a0b7f59SSanjoy Das // [`Result.LowLimit`, `Result.HighLimit`) = [`Smallest`, `Smallest`)
11107a0b7f59SSanjoy Das // will be an empty range. Returning an empty range is always safe.
11117a0b7f59SSanjoy Das
11126c466a37SMax Kazantsev Smallest = SE.getAddExpr(End, One);
11136c466a37SMax Kazantsev Greatest = SE.getAddExpr(Start, One);
1114f80ffa1aSMax Kazantsev GreatestSeen = Start;
11157a0b7f59SSanjoy Das }
1116e75ed926SSanjoy Das
111707da1ab2SMax Kazantsev auto Clamp = [this, Smallest, Greatest, IsSignedPredicate](const SCEV *S) {
11186f5229d7SMax Kazantsev return IsSignedPredicate
111907da1ab2SMax Kazantsev ? SE.getSMaxExpr(Smallest, SE.getSMinExpr(Greatest, S))
112007da1ab2SMax Kazantsev : SE.getUMaxExpr(Smallest, SE.getUMinExpr(Greatest, S));
1121e75ed926SSanjoy Das };
1122a1837a34SSanjoy Das
112307da1ab2SMax Kazantsev // In some cases we can prove that we don't need a pre or post loop.
112407da1ab2SMax Kazantsev ICmpInst::Predicate PredLE =
112507da1ab2SMax Kazantsev IsSignedPredicate ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
112607da1ab2SMax Kazantsev ICmpInst::Predicate PredLT =
112707da1ab2SMax Kazantsev IsSignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
1128a1837a34SSanjoy Das
1129a1837a34SSanjoy Das bool ProvablyNoPreloop =
113007da1ab2SMax Kazantsev SE.isKnownPredicate(PredLE, Range.getBegin(), Smallest);
1131e75ed926SSanjoy Das if (!ProvablyNoPreloop)
1132e75ed926SSanjoy Das Result.LowLimit = Clamp(Range.getBegin());
1133a1837a34SSanjoy Das
1134a1837a34SSanjoy Das bool ProvablyNoPostLoop =
113507da1ab2SMax Kazantsev SE.isKnownPredicate(PredLT, GreatestSeen, Range.getEnd());
1136e75ed926SSanjoy Das if (!ProvablyNoPostLoop)
1137e75ed926SSanjoy Das Result.HighLimit = Clamp(Range.getEnd());
1138a1837a34SSanjoy Das
1139a1837a34SSanjoy Das return Result;
1140a1837a34SSanjoy Das }
1141a1837a34SSanjoy Das
cloneLoop(LoopConstrainer::ClonedLoop & Result,const char * Tag) const1142a1837a34SSanjoy Das void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result,
1143a1837a34SSanjoy Das const char *Tag) const {
1144a1837a34SSanjoy Das for (BasicBlock *BB : OriginalLoop.getBlocks()) {
1145a1837a34SSanjoy Das BasicBlock *Clone = CloneBasicBlock(BB, Result.Map, Twine(".") + Tag, &F);
1146a1837a34SSanjoy Das Result.Blocks.push_back(Clone);
1147a1837a34SSanjoy Das Result.Map[BB] = Clone;
1148a1837a34SSanjoy Das }
1149a1837a34SSanjoy Das
1150a1837a34SSanjoy Das auto GetClonedValue = [&Result](Value *V) {
1151a1837a34SSanjoy Das assert(V && "null values not in domain!");
1152a1837a34SSanjoy Das auto It = Result.Map.find(V);
1153a1837a34SSanjoy Das if (It == Result.Map.end())
1154a1837a34SSanjoy Das return V;
1155a1837a34SSanjoy Das return static_cast<Value *>(It->second);
1156a1837a34SSanjoy Das };
1157a1837a34SSanjoy Das
11587a18a238SSanjoy Das auto *ClonedLatch =
11597a18a238SSanjoy Das cast<BasicBlock>(GetClonedValue(OriginalLoop.getLoopLatch()));
11607a18a238SSanjoy Das ClonedLatch->getTerminator()->setMetadata(ClonedLoopTag,
11617a18a238SSanjoy Das MDNode::get(Ctx, {}));
11627a18a238SSanjoy Das
1163a1837a34SSanjoy Das Result.Structure = MainLoopStructure.map(GetClonedValue);
1164a1837a34SSanjoy Das Result.Structure.Tag = Tag;
1165a1837a34SSanjoy Das
1166a1837a34SSanjoy Das for (unsigned i = 0, e = Result.Blocks.size(); i != e; ++i) {
1167a1837a34SSanjoy Das BasicBlock *ClonedBB = Result.Blocks[i];
1168a1837a34SSanjoy Das BasicBlock *OriginalBB = OriginalLoop.getBlocks()[i];
1169a1837a34SSanjoy Das
1170a1837a34SSanjoy Das assert(Result.Map[OriginalBB] == ClonedBB && "invariant!");
1171a1837a34SSanjoy Das
1172a1837a34SSanjoy Das for (Instruction &I : *ClonedBB)
1173a1837a34SSanjoy Das RemapInstruction(&I, Result.Map,
1174da68cbc4SDuncan P. N. Exon Smith RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
1175a1837a34SSanjoy Das
1176a1837a34SSanjoy Das // Exit blocks will now have one more predecessor and their PHI nodes need
1177a1837a34SSanjoy Das // to be edited to reflect that. No phi nodes need to be introduced because
1178a1837a34SSanjoy Das // the loop is in LCSSA.
1179a1837a34SSanjoy Das
1180d1d62a13SSanjoy Das for (auto *SBB : successors(OriginalBB)) {
1181d1d62a13SSanjoy Das if (OriginalLoop.contains(SBB))
1182a1837a34SSanjoy Das continue; // not an exit block
1183a1837a34SSanjoy Das
1184c7fc81e6SBenjamin Kramer for (PHINode &PN : SBB->phis()) {
1185c7fc81e6SBenjamin Kramer Value *OldIncoming = PN.getIncomingValueForBlock(OriginalBB);
1186c7fc81e6SBenjamin Kramer PN.addIncoming(GetClonedValue(OldIncoming), ClonedBB);
1187a1837a34SSanjoy Das }
1188a1837a34SSanjoy Das }
1189a1837a34SSanjoy Das }
1190a1837a34SSanjoy Das }
1191a1837a34SSanjoy Das
changeIterationSpaceEnd(const LoopStructure & LS,BasicBlock * Preheader,Value * ExitSubloopAt,BasicBlock * ContinuationBlock) const1192a1837a34SSanjoy Das LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd(
1193e75ed926SSanjoy Das const LoopStructure &LS, BasicBlock *Preheader, Value *ExitSubloopAt,
1194a1837a34SSanjoy Das BasicBlock *ContinuationBlock) const {
1195a1837a34SSanjoy Das // We start with a loop with a single latch:
1196a1837a34SSanjoy Das //
1197a1837a34SSanjoy Das // +--------------------+
1198a1837a34SSanjoy Das // | |
1199a1837a34SSanjoy Das // | preheader |
1200a1837a34SSanjoy Das // | |
1201a1837a34SSanjoy Das // +--------+-----------+
1202a1837a34SSanjoy Das // | ----------------\
1203a1837a34SSanjoy Das // | / |
1204a1837a34SSanjoy Das // +--------v----v------+ |
1205a1837a34SSanjoy Das // | | |
1206a1837a34SSanjoy Das // | header | |
1207a1837a34SSanjoy Das // | | |
1208a1837a34SSanjoy Das // +--------------------+ |
1209a1837a34SSanjoy Das // |
1210a1837a34SSanjoy Das // ..... |
1211a1837a34SSanjoy Das // |
1212a1837a34SSanjoy Das // +--------------------+ |
1213a1837a34SSanjoy Das // | | |
1214a1837a34SSanjoy Das // | latch >----------/
1215a1837a34SSanjoy Das // | |
1216a1837a34SSanjoy Das // +-------v------------+
1217a1837a34SSanjoy Das // |
1218a1837a34SSanjoy Das // |
1219a1837a34SSanjoy Das // | +--------------------+
1220a1837a34SSanjoy Das // | | |
1221a1837a34SSanjoy Das // +---> original exit |
1222a1837a34SSanjoy Das // | |
1223a1837a34SSanjoy Das // +--------------------+
1224a1837a34SSanjoy Das //
1225a1837a34SSanjoy Das // We change the control flow to look like
1226a1837a34SSanjoy Das //
1227a1837a34SSanjoy Das //
1228a1837a34SSanjoy Das // +--------------------+
1229a1837a34SSanjoy Das // | |
1230a1837a34SSanjoy Das // | preheader >-------------------------+
1231a1837a34SSanjoy Das // | | |
1232a1837a34SSanjoy Das // +--------v-----------+ |
1233a1837a34SSanjoy Das // | /-------------+ |
1234a1837a34SSanjoy Das // | / | |
1235a1837a34SSanjoy Das // +--------v--v--------+ | |
1236a1837a34SSanjoy Das // | | | |
1237a1837a34SSanjoy Das // | header | | +--------+ |
1238a1837a34SSanjoy Das // | | | | | |
1239a1837a34SSanjoy Das // +--------------------+ | | +-----v-----v-----------+
1240a1837a34SSanjoy Das // | | | |
1241a1837a34SSanjoy Das // | | | .pseudo.exit |
1242a1837a34SSanjoy Das // | | | |
1243a1837a34SSanjoy Das // | | +-----------v-----------+
1244a1837a34SSanjoy Das // | | |
1245a1837a34SSanjoy Das // ..... | | |
1246a1837a34SSanjoy Das // | | +--------v-------------+
1247a1837a34SSanjoy Das // +--------------------+ | | | |
1248a1837a34SSanjoy Das // | | | | | ContinuationBlock |
1249a1837a34SSanjoy Das // | latch >------+ | | |
1250a1837a34SSanjoy Das // | | | +----------------------+
1251a1837a34SSanjoy Das // +---------v----------+ |
1252a1837a34SSanjoy Das // | |
1253a1837a34SSanjoy Das // | |
1254a1837a34SSanjoy Das // | +---------------^-----+
1255a1837a34SSanjoy Das // | | |
1256a1837a34SSanjoy Das // +-----> .exit.selector |
1257a1837a34SSanjoy Das // | |
1258a1837a34SSanjoy Das // +----------v----------+
1259a1837a34SSanjoy Das // |
1260a1837a34SSanjoy Das // +--------------------+ |
1261a1837a34SSanjoy Das // | | |
1262a1837a34SSanjoy Das // | original exit <----+
1263a1837a34SSanjoy Das // | |
1264a1837a34SSanjoy Das // +--------------------+
1265a1837a34SSanjoy Das
1266a1837a34SSanjoy Das RewrittenRangeInfo RRI;
1267a1837a34SSanjoy Das
12683bcaa812SDuncan P. N. Exon Smith BasicBlock *BBInsertLocation = LS.Latch->getNextNode();
1269a1837a34SSanjoy Das RRI.ExitSelector = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".exit.selector",
12703bcaa812SDuncan P. N. Exon Smith &F, BBInsertLocation);
1271a1837a34SSanjoy Das RRI.PseudoExit = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".pseudo.exit", &F,
12723bcaa812SDuncan P. N. Exon Smith BBInsertLocation);
1273a1837a34SSanjoy Das
127481c00fe0SSanjoy Das BranchInst *PreheaderJump = cast<BranchInst>(Preheader->getTerminator());
1275e75ed926SSanjoy Das bool Increasing = LS.IndVarIncreasing;
127607da1ab2SMax Kazantsev bool IsSignedPredicate = LS.IsSignedPredicate;
1277a1837a34SSanjoy Das
1278a1837a34SSanjoy Das IRBuilder<> B(PreheaderJump);
1279d9aee3c0SMax Kazantsev auto *RangeTy = Range.getBegin()->getType();
1280d9aee3c0SMax Kazantsev auto NoopOrExt = [&](Value *V) {
1281d9aee3c0SMax Kazantsev if (V->getType() == RangeTy)
1282d9aee3c0SMax Kazantsev return V;
1283d9aee3c0SMax Kazantsev return IsSignedPredicate ? B.CreateSExt(V, RangeTy, "wide." + V->getName())
1284d9aee3c0SMax Kazantsev : B.CreateZExt(V, RangeTy, "wide." + V->getName());
1285d9aee3c0SMax Kazantsev };
1286a1837a34SSanjoy Das
1287a1837a34SSanjoy Das // EnterLoopCond - is it okay to start executing this `LS'?
128807da1ab2SMax Kazantsev Value *EnterLoopCond = nullptr;
1289f8a0e0ddSMax Kazantsev auto Pred =
1290f8a0e0ddSMax Kazantsev Increasing
1291f8a0e0ddSMax Kazantsev ? (IsSignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT)
1292f8a0e0ddSMax Kazantsev : (IsSignedPredicate ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT);
1293d9aee3c0SMax Kazantsev Value *IndVarStart = NoopOrExt(LS.IndVarStart);
1294ee613085SMax Kazantsev EnterLoopCond = B.CreateICmp(Pred, IndVarStart, ExitSubloopAt);
1295e75ed926SSanjoy Das
1296a1837a34SSanjoy Das B.CreateCondBr(EnterLoopCond, LS.Header, RRI.PseudoExit);
1297a1837a34SSanjoy Das PreheaderJump->eraseFromParent();
1298a1837a34SSanjoy Das
1299a1837a34SSanjoy Das LS.LatchBr->setSuccessor(LS.LatchBrExitIdx, RRI.ExitSelector);
1300e75ed926SSanjoy Das B.SetInsertPoint(LS.LatchBr);
1301d9aee3c0SMax Kazantsev Value *IndVarBase = NoopOrExt(LS.IndVarBase);
1302ee613085SMax Kazantsev Value *TakeBackedgeLoopCond = B.CreateICmp(Pred, IndVarBase, ExitSubloopAt);
1303f8a0e0ddSMax Kazantsev
1304e75ed926SSanjoy Das Value *CondForBranch = LS.LatchBrExitIdx == 1
1305e75ed926SSanjoy Das ? TakeBackedgeLoopCond
1306e75ed926SSanjoy Das : B.CreateNot(TakeBackedgeLoopCond);
1307e75ed926SSanjoy Das
1308e75ed926SSanjoy Das LS.LatchBr->setCondition(CondForBranch);
1309a1837a34SSanjoy Das
1310a1837a34SSanjoy Das B.SetInsertPoint(RRI.ExitSelector);
1311a1837a34SSanjoy Das
1312a1837a34SSanjoy Das // IterationsLeft - are there any more iterations left, given the original
1313a1837a34SSanjoy Das // upper bound on the induction variable? If not, we branch to the "real"
1314a1837a34SSanjoy Das // exit.
1315d9aee3c0SMax Kazantsev Value *LoopExitAt = NoopOrExt(LS.LoopExitAt);
1316ee613085SMax Kazantsev Value *IterationsLeft = B.CreateICmp(Pred, IndVarBase, LoopExitAt);
1317a1837a34SSanjoy Das B.CreateCondBr(IterationsLeft, RRI.PseudoExit, LS.LatchExit);
1318a1837a34SSanjoy Das
1319a1837a34SSanjoy Das BranchInst *BranchToContinuation =
1320a1837a34SSanjoy Das BranchInst::Create(ContinuationBlock, RRI.PseudoExit);
1321a1837a34SSanjoy Das
1322a1837a34SSanjoy Das // We emit PHI nodes into `RRI.PseudoExit' that compute the "latest" value of
1323a1837a34SSanjoy Das // each of the PHI nodes in the loop header. This feeds into the initial
1324a1837a34SSanjoy Das // value of the same PHI nodes if/when we continue execution.
1325c7fc81e6SBenjamin Kramer for (PHINode &PN : LS.Header->phis()) {
1326c7fc81e6SBenjamin Kramer PHINode *NewPHI = PHINode::Create(PN.getType(), 2, PN.getName() + ".copy",
1327a1837a34SSanjoy Das BranchToContinuation);
1328a1837a34SSanjoy Das
1329c7fc81e6SBenjamin Kramer NewPHI->addIncoming(PN.getIncomingValueForBlock(Preheader), Preheader);
1330c7fc81e6SBenjamin Kramer NewPHI->addIncoming(PN.getIncomingValueForBlock(LS.Latch),
1331675e304eSSerguei Katkov RRI.ExitSelector);
1332a1837a34SSanjoy Das RRI.PHIValuesAtPseudoExit.push_back(NewPHI);
1333a1837a34SSanjoy Das }
1334a1837a34SSanjoy Das
1335ee613085SMax Kazantsev RRI.IndVarEnd = PHINode::Create(IndVarBase->getType(), 2, "indvar.end",
1336e75ed926SSanjoy Das BranchToContinuation);
1337ee613085SMax Kazantsev RRI.IndVarEnd->addIncoming(IndVarStart, Preheader);
1338ee613085SMax Kazantsev RRI.IndVarEnd->addIncoming(IndVarBase, RRI.ExitSelector);
1339e75ed926SSanjoy Das
1340a1837a34SSanjoy Das // The latch exit now has a branch from `RRI.ExitSelector' instead of
1341a1837a34SSanjoy Das // `LS.Latch'. The PHI nodes need to be updated to reflect that.
13421a1b9221SRoman Lebedev LS.LatchExit->replacePhiUsesWith(LS.Latch, RRI.ExitSelector);
1343a1837a34SSanjoy Das
1344a1837a34SSanjoy Das return RRI;
1345a1837a34SSanjoy Das }
1346a1837a34SSanjoy Das
rewriteIncomingValuesForPHIs(LoopStructure & LS,BasicBlock * ContinuationBlock,const LoopConstrainer::RewrittenRangeInfo & RRI) const1347a1837a34SSanjoy Das void LoopConstrainer::rewriteIncomingValuesForPHIs(
1348e75ed926SSanjoy Das LoopStructure &LS, BasicBlock *ContinuationBlock,
1349a1837a34SSanjoy Das const LoopConstrainer::RewrittenRangeInfo &RRI) const {
1350a1837a34SSanjoy Das unsigned PHIIndex = 0;
1351c7fc81e6SBenjamin Kramer for (PHINode &PN : LS.Header->phis())
135215b7f5b7SWhitney Tsang PN.setIncomingValueForBlock(ContinuationBlock,
135315b7f5b7SWhitney Tsang RRI.PHIValuesAtPseudoExit[PHIIndex++]);
1354a1837a34SSanjoy Das
1355e75ed926SSanjoy Das LS.IndVarStart = RRI.IndVarEnd;
1356a1837a34SSanjoy Das }
1357a1837a34SSanjoy Das
createPreheader(const LoopStructure & LS,BasicBlock * OldPreheader,const char * Tag) const1358e75ed926SSanjoy Das BasicBlock *LoopConstrainer::createPreheader(const LoopStructure &LS,
1359a1837a34SSanjoy Das BasicBlock *OldPreheader,
1360a1837a34SSanjoy Das const char *Tag) const {
1361a1837a34SSanjoy Das BasicBlock *Preheader = BasicBlock::Create(Ctx, Tag, &F, LS.Header);
1362a1837a34SSanjoy Das BranchInst::Create(LS.Header, Preheader);
1363a1837a34SSanjoy Das
13641a1b9221SRoman Lebedev LS.Header->replacePhiUsesWith(OldPreheader, Preheader);
1365a1837a34SSanjoy Das
1366a1837a34SSanjoy Das return Preheader;
1367a1837a34SSanjoy Das }
1368a1837a34SSanjoy Das
addToParentLoopIfNeeded(ArrayRef<BasicBlock * > BBs)136939f76acbSBenjamin Kramer void LoopConstrainer::addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs) {
1370a1837a34SSanjoy Das Loop *ParentLoop = OriginalLoop.getParentLoop();
1371a1837a34SSanjoy Das if (!ParentLoop)
1372a1837a34SSanjoy Das return;
1373a1837a34SSanjoy Das
137439f76acbSBenjamin Kramer for (BasicBlock *BB : BBs)
137583a72850SSanjoy Das ParentLoop->addBasicBlockToLoop(BB, LI);
1376a1837a34SSanjoy Das }
1377a1837a34SSanjoy Das
createClonedLoopStructure(Loop * Original,Loop * Parent,ValueToValueMapTy & VM,bool IsSubloop)13782143447cSSanjoy Das Loop *LoopConstrainer::createClonedLoopStructure(Loop *Original, Loop *Parent,
1379194a407bSFedor Sergeev ValueToValueMapTy &VM,
1380194a407bSFedor Sergeev bool IsSubloop) {
1381def1729dSSanjoy Das Loop &New = *LI.AllocateLoop();
138229c22d28SChandler Carruth if (Parent)
138329c22d28SChandler Carruth Parent->addChildLoop(&New);
138429c22d28SChandler Carruth else
138529c22d28SChandler Carruth LI.addTopLevelLoop(&New);
1386194a407bSFedor Sergeev LPMAddNewLoop(&New, IsSubloop);
13872143447cSSanjoy Das
13882143447cSSanjoy Das // Add all of the blocks in Original to the new loop.
13892143447cSSanjoy Das for (auto *BB : Original->blocks())
13902143447cSSanjoy Das if (LI.getLoopFor(BB) == Original)
13912143447cSSanjoy Das New.addBasicBlockToLoop(cast<BasicBlock>(VM[BB]), LI);
13922143447cSSanjoy Das
13932143447cSSanjoy Das // Add all of the subloops to the new loop.
13942143447cSSanjoy Das for (Loop *SubLoop : *Original)
1395194a407bSFedor Sergeev createClonedLoopStructure(SubLoop, &New, VM, /* IsSubloop */ true);
13962143447cSSanjoy Das
13972143447cSSanjoy Das return &New;
13982143447cSSanjoy Das }
13992143447cSSanjoy Das
run()1400a1837a34SSanjoy Das bool LoopConstrainer::run() {
1401a1837a34SSanjoy Das BasicBlock *Preheader = nullptr;
1402e75ed926SSanjoy Das LatchTakenCount = SE.getExitCount(&OriginalLoop, MainLoopStructure.Latch);
1403e75ed926SSanjoy Das Preheader = OriginalLoop.getLoopPreheader();
1404e75ed926SSanjoy Das assert(!isa<SCEVCouldNotCompute>(LatchTakenCount) && Preheader != nullptr &&
1405e75ed926SSanjoy Das "preconditions!");
1406a1837a34SSanjoy Das
1407a1837a34SSanjoy Das OriginalPreheader = Preheader;
1408a1837a34SSanjoy Das MainLoopPreheader = Preheader;
1409a1837a34SSanjoy Das
141007da1ab2SMax Kazantsev bool IsSignedPredicate = MainLoopStructure.IsSignedPredicate;
141107da1ab2SMax Kazantsev Optional<SubRanges> MaybeSR = calculateSubRanges(IsSignedPredicate);
1412e0e687a6SKazu Hirata if (!MaybeSR) {
1413d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: could not compute subranges\n");
1414d1fb13ceSSanjoy Das return false;
1415d1fb13ceSSanjoy Das }
1416e75ed926SSanjoy Das
14177a47ee51SKazu Hirata SubRanges SR = *MaybeSR;
1418e75ed926SSanjoy Das bool Increasing = MainLoopStructure.IndVarIncreasing;
1419e75ed926SSanjoy Das IntegerType *IVTy =
1420d9aee3c0SMax Kazantsev cast<IntegerType>(Range.getBegin()->getType());
1421e75ed926SSanjoy Das
1422a28d91d8SMehdi Amini SCEVExpander Expander(SE, F.getParent()->getDataLayout(), "irce");
1423e75ed926SSanjoy Das Instruction *InsertPt = OriginalPreheader->getTerminator();
1424a1837a34SSanjoy Das
1425a1837a34SSanjoy Das // It would have been better to make `PreLoop' and `PostLoop'
1426a1837a34SSanjoy Das // `Optional<ClonedLoop>'s, but `ValueToValueMapTy' does not have a copy
1427a1837a34SSanjoy Das // constructor.
1428a1837a34SSanjoy Das ClonedLoop PreLoop, PostLoop;
1429e75ed926SSanjoy Das bool NeedsPreLoop =
1430a81b64a1SKazu Hirata Increasing ? SR.LowLimit.has_value() : SR.HighLimit.has_value();
1431e75ed926SSanjoy Das bool NeedsPostLoop =
1432a81b64a1SKazu Hirata Increasing ? SR.HighLimit.has_value() : SR.LowLimit.has_value();
1433e75ed926SSanjoy Das
1434e75ed926SSanjoy Das Value *ExitPreLoopAt = nullptr;
1435e75ed926SSanjoy Das Value *ExitMainLoopAt = nullptr;
1436e75ed926SSanjoy Das const SCEVConstant *MinusOneS =
1437e75ed926SSanjoy Das cast<SCEVConstant>(SE.getConstant(IVTy, -1, true /* isSigned */));
1438e75ed926SSanjoy Das
1439e75ed926SSanjoy Das if (NeedsPreLoop) {
1440e75ed926SSanjoy Das const SCEV *ExitPreLoopAtSCEV = nullptr;
1441e75ed926SSanjoy Das
1442e75ed926SSanjoy Das if (Increasing)
1443e75ed926SSanjoy Das ExitPreLoopAtSCEV = *SR.LowLimit;
144478a54352SMax Kazantsev else if (cannotBeMinInLoop(*SR.HighLimit, &OriginalLoop, SE,
144553a423a4SSam Parker IsSignedPredicate))
144653a423a4SSam Parker ExitPreLoopAtSCEV = SE.getAddExpr(*SR.HighLimit, MinusOneS);
144753a423a4SSam Parker else {
1448d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: could not prove no-overflow when computing "
1449d34e60caSNicola Zaghen << "preloop exit limit. HighLimit = "
1450d34e60caSNicola Zaghen << *(*SR.HighLimit) << "\n");
1451e75ed926SSanjoy Das return false;
1452e75ed926SSanjoy Das }
1453675e304eSSerguei Katkov
1454*dcf4b733SNikita Popov if (!Expander.isSafeToExpandAt(ExitPreLoopAtSCEV, InsertPt)) {
1455d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: could not prove that it is safe to expand the"
1456b1b8aff2SMax Kazantsev << " preloop exit limit " << *ExitPreLoopAtSCEV
1457d34e60caSNicola Zaghen << " at block " << InsertPt->getParent()->getName()
1458d34e60caSNicola Zaghen << "\n");
1459b1b8aff2SMax Kazantsev return false;
1460b1b8aff2SMax Kazantsev }
1461b1b8aff2SMax Kazantsev
1462e75ed926SSanjoy Das ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt);
1463e75ed926SSanjoy Das ExitPreLoopAt->setName("exit.preloop.at");
1464e75ed926SSanjoy Das }
1465e75ed926SSanjoy Das
1466e75ed926SSanjoy Das if (NeedsPostLoop) {
1467e75ed926SSanjoy Das const SCEV *ExitMainLoopAtSCEV = nullptr;
1468e75ed926SSanjoy Das
1469e75ed926SSanjoy Das if (Increasing)
1470e75ed926SSanjoy Das ExitMainLoopAtSCEV = *SR.HighLimit;
147178a54352SMax Kazantsev else if (cannotBeMinInLoop(*SR.LowLimit, &OriginalLoop, SE,
147253a423a4SSam Parker IsSignedPredicate))
147353a423a4SSam Parker ExitMainLoopAtSCEV = SE.getAddExpr(*SR.LowLimit, MinusOneS);
147453a423a4SSam Parker else {
1475d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: could not prove no-overflow when computing "
1476d34e60caSNicola Zaghen << "mainloop exit limit. LowLimit = "
1477d34e60caSNicola Zaghen << *(*SR.LowLimit) << "\n");
1478e75ed926SSanjoy Das return false;
1479e75ed926SSanjoy Das }
1480675e304eSSerguei Katkov
1481*dcf4b733SNikita Popov if (!Expander.isSafeToExpandAt(ExitMainLoopAtSCEV, InsertPt)) {
1482d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: could not prove that it is safe to expand the"
1483b1b8aff2SMax Kazantsev << " main loop exit limit " << *ExitMainLoopAtSCEV
1484d34e60caSNicola Zaghen << " at block " << InsertPt->getParent()->getName()
1485d34e60caSNicola Zaghen << "\n");
1486b1b8aff2SMax Kazantsev return false;
1487b1b8aff2SMax Kazantsev }
1488b1b8aff2SMax Kazantsev
1489e75ed926SSanjoy Das ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt);
1490e75ed926SSanjoy Das ExitMainLoopAt->setName("exit.mainloop.at");
1491e75ed926SSanjoy Das }
1492a1837a34SSanjoy Das
1493a1837a34SSanjoy Das // We clone these ahead of time so that we don't have to deal with changing
1494a1837a34SSanjoy Das // and temporarily invalid IR as we transform the loops.
1495a1837a34SSanjoy Das if (NeedsPreLoop)
1496a1837a34SSanjoy Das cloneLoop(PreLoop, "preloop");
1497a1837a34SSanjoy Das if (NeedsPostLoop)
1498a1837a34SSanjoy Das cloneLoop(PostLoop, "postloop");
1499a1837a34SSanjoy Das
1500a1837a34SSanjoy Das RewrittenRangeInfo PreLoopRRI;
1501a1837a34SSanjoy Das
1502a1837a34SSanjoy Das if (NeedsPreLoop) {
1503a1837a34SSanjoy Das Preheader->getTerminator()->replaceUsesOfWith(MainLoopStructure.Header,
1504a1837a34SSanjoy Das PreLoop.Structure.Header);
1505a1837a34SSanjoy Das
1506a1837a34SSanjoy Das MainLoopPreheader =
1507a1837a34SSanjoy Das createPreheader(MainLoopStructure, Preheader, "mainloop");
1508e75ed926SSanjoy Das PreLoopRRI = changeIterationSpaceEnd(PreLoop.Structure, Preheader,
1509e75ed926SSanjoy Das ExitPreLoopAt, MainLoopPreheader);
1510a1837a34SSanjoy Das rewriteIncomingValuesForPHIs(MainLoopStructure, MainLoopPreheader,
1511a1837a34SSanjoy Das PreLoopRRI);
1512a1837a34SSanjoy Das }
1513a1837a34SSanjoy Das
1514a1837a34SSanjoy Das BasicBlock *PostLoopPreheader = nullptr;
1515a1837a34SSanjoy Das RewrittenRangeInfo PostLoopRRI;
1516a1837a34SSanjoy Das
1517a1837a34SSanjoy Das if (NeedsPostLoop) {
1518a1837a34SSanjoy Das PostLoopPreheader =
1519a1837a34SSanjoy Das createPreheader(PostLoop.Structure, Preheader, "postloop");
1520a1837a34SSanjoy Das PostLoopRRI = changeIterationSpaceEnd(MainLoopStructure, MainLoopPreheader,
1521e75ed926SSanjoy Das ExitMainLoopAt, PostLoopPreheader);
1522a1837a34SSanjoy Das rewriteIncomingValuesForPHIs(PostLoop.Structure, PostLoopPreheader,
1523a1837a34SSanjoy Das PostLoopRRI);
1524a1837a34SSanjoy Das }
1525a1837a34SSanjoy Das
152639f76acbSBenjamin Kramer BasicBlock *NewMainLoopPreheader =
152739f76acbSBenjamin Kramer MainLoopPreheader != Preheader ? MainLoopPreheader : nullptr;
152839f76acbSBenjamin Kramer BasicBlock *NewBlocks[] = {PostLoopPreheader, PreLoopRRI.PseudoExit,
152939f76acbSBenjamin Kramer PreLoopRRI.ExitSelector, PostLoopRRI.PseudoExit,
153039f76acbSBenjamin Kramer PostLoopRRI.ExitSelector, NewMainLoopPreheader};
1531a1837a34SSanjoy Das
1532a1837a34SSanjoy Das // Some of the above may be nullptr, filter them out before passing to
1533a1837a34SSanjoy Das // addToParentLoopIfNeeded.
153439f76acbSBenjamin Kramer auto NewBlocksEnd =
153539f76acbSBenjamin Kramer std::remove(std::begin(NewBlocks), std::end(NewBlocks), nullptr);
1536a1837a34SSanjoy Das
153739f76acbSBenjamin Kramer addToParentLoopIfNeeded(makeArrayRef(std::begin(NewBlocks), NewBlocksEnd));
1538a1837a34SSanjoy Das
1539f45e03e2SSanjoy Das DT.recalculate(F);
15402143447cSSanjoy Das
154172180320SAnna Thomas // We need to first add all the pre and post loop blocks into the loop
154272180320SAnna Thomas // structures (as part of createClonedLoopStructure), and then update the
154372180320SAnna Thomas // LCSSA form and LoopSimplifyForm. This is necessary for correctly updating
154472180320SAnna Thomas // LI when LoopSimplifyForm is generated.
154572180320SAnna Thomas Loop *PreL = nullptr, *PostL = nullptr;
15462143447cSSanjoy Das if (!PreLoop.Blocks.empty()) {
1547194a407bSFedor Sergeev PreL = createClonedLoopStructure(&OriginalLoop,
1548194a407bSFedor Sergeev OriginalLoop.getParentLoop(), PreLoop.Map,
1549194a407bSFedor Sergeev /* IsSubLoop */ false);
15502143447cSSanjoy Das }
15512143447cSSanjoy Das
15522143447cSSanjoy Das if (!PostLoop.Blocks.empty()) {
1553194a407bSFedor Sergeev PostL =
1554194a407bSFedor Sergeev createClonedLoopStructure(&OriginalLoop, OriginalLoop.getParentLoop(),
1555194a407bSFedor Sergeev PostLoop.Map, /* IsSubLoop */ false);
15562143447cSSanjoy Das }
15572143447cSSanjoy Das
155872180320SAnna Thomas // This function canonicalizes the loop into Loop-Simplify and LCSSA forms.
155972180320SAnna Thomas auto CanonicalizeLoop = [&] (Loop *L, bool IsOriginalLoop) {
156072180320SAnna Thomas formLCSSARecursively(*L, DT, &LI, &SE);
1561f31eba64SAlina Sbirlea simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr, true);
156272180320SAnna Thomas // Pre/post loops are slow paths, we do not need to perform any loop
156372180320SAnna Thomas // optimizations on them.
156472180320SAnna Thomas if (!IsOriginalLoop)
156572180320SAnna Thomas DisableAllLoopOptsOnLoop(*L);
156672180320SAnna Thomas };
156772180320SAnna Thomas if (PreL)
156872180320SAnna Thomas CanonicalizeLoop(PreL, false);
156972180320SAnna Thomas if (PostL)
157072180320SAnna Thomas CanonicalizeLoop(PostL, false);
157172180320SAnna Thomas CanonicalizeLoop(&OriginalLoop, true);
1572f45e03e2SSanjoy Das
1573a1837a34SSanjoy Das return true;
1574a1837a34SSanjoy Das }
1575a1837a34SSanjoy Das
157695c476dbSSanjoy Das /// Computes and returns a range of values for the induction variable (IndVar)
157795c476dbSSanjoy Das /// in which the range check can be safely elided. If it cannot compute such a
157895c476dbSSanjoy Das /// range, returns None.
1579a1837a34SSanjoy Das Optional<InductiveRangeCheck::Range>
computeSafeIterationSpace(ScalarEvolution & SE,const SCEVAddRecExpr * IndVar,bool IsLatchSigned) const158059776734SSanjoy Das InductiveRangeCheck::computeSafeIterationSpace(
158126846786SMax Kazantsev ScalarEvolution &SE, const SCEVAddRecExpr *IndVar,
158226846786SMax Kazantsev bool IsLatchSigned) const {
1583d9aee3c0SMax Kazantsev // We can deal when types of latch check and range checks don't match in case
1584d9aee3c0SMax Kazantsev // if latch check is more narrow.
1585d9aee3c0SMax Kazantsev auto *IVType = cast<IntegerType>(IndVar->getType());
1586d9aee3c0SMax Kazantsev auto *RCType = cast<IntegerType>(getBegin()->getType());
1587d9aee3c0SMax Kazantsev if (IVType->getBitWidth() > RCType->getBitWidth())
1588d9aee3c0SMax Kazantsev return None;
158995c476dbSSanjoy Das // IndVar is of the form "A + B * I" (where "I" is the canonical induction
159095c476dbSSanjoy Das // variable, that may or may not exist as a real llvm::Value in the loop) and
159195c476dbSSanjoy Das // this inductive range check is a range check on the "C + D * I" ("C" is
159284286ce5SMax Kazantsev // getBegin() and "D" is getStep()). We rewrite the value being range
159395c476dbSSanjoy Das // checked to "M + N * IndVar" where "N" = "D * B^(-1)" and "M" = "C - NA".
1594a1837a34SSanjoy Das //
159595c476dbSSanjoy Das // The actual inequalities we solve are of the form
1596a1837a34SSanjoy Das //
159795c476dbSSanjoy Das // 0 <= M + 1 * IndVar < L given L >= 0 (i.e. N == 1)
159895c476dbSSanjoy Das //
159926846786SMax Kazantsev // Here L stands for upper limit of the safe iteration space.
160026846786SMax Kazantsev // The inequality is satisfied by (0 - M) <= IndVar < (L - M). To avoid
160126846786SMax Kazantsev // overflows when calculating (0 - M) and (L - M) we, depending on type of
160226846786SMax Kazantsev // IV's iteration space, limit the calculations by borders of the iteration
160326846786SMax Kazantsev // space. For example, if IndVar is unsigned, (0 - M) overflows for any M > 0.
160426846786SMax Kazantsev // If we figured out that "anything greater than (-M) is safe", we strengthen
160526846786SMax Kazantsev // this to "everything greater than 0 is safe", assuming that values between
160626846786SMax Kazantsev // -M and 0 just do not exist in unsigned iteration space, and we don't want
160726846786SMax Kazantsev // to deal with overflown values.
1608a1837a34SSanjoy Das
160995c476dbSSanjoy Das if (!IndVar->isAffine())
1610a1837a34SSanjoy Das return None;
1611a1837a34SSanjoy Das
1612d9aee3c0SMax Kazantsev const SCEV *A = NoopOrExtend(IndVar->getStart(), RCType, SE, IsLatchSigned);
1613d9aee3c0SMax Kazantsev const SCEVConstant *B = dyn_cast<SCEVConstant>(
1614d9aee3c0SMax Kazantsev NoopOrExtend(IndVar->getStepRecurrence(SE), RCType, SE, IsLatchSigned));
161595c476dbSSanjoy Das if (!B)
161695c476dbSSanjoy Das return None;
1617e4c220e8SMax Kazantsev assert(!B->isZero() && "Recurrence with zero step?");
161895c476dbSSanjoy Das
161984286ce5SMax Kazantsev const SCEV *C = getBegin();
162084286ce5SMax Kazantsev const SCEVConstant *D = dyn_cast<SCEVConstant>(getStep());
162195c476dbSSanjoy Das if (D != B)
162295c476dbSSanjoy Das return None;
162395c476dbSSanjoy Das
162495054700SMax Kazantsev assert(!D->getValue()->isZero() && "Recurrence with zero step?");
1625d9aee3c0SMax Kazantsev unsigned BitWidth = RCType->getBitWidth();
162626846786SMax Kazantsev const SCEV *SIntMax = SE.getConstant(APInt::getSignedMaxValue(BitWidth));
162795c476dbSSanjoy Das
1628b57ca09eSMax Kazantsev // Subtract Y from X so that it does not go through border of the IV
162926846786SMax Kazantsev // iteration space. Mathematically, it is equivalent to:
163026846786SMax Kazantsev //
1631b57ca09eSMax Kazantsev // ClampedSubtract(X, Y) = min(max(X - Y, INT_MIN), INT_MAX). [1]
163226846786SMax Kazantsev //
1633b57ca09eSMax Kazantsev // In [1], 'X - Y' is a mathematical subtraction (result is not bounded to
163426846786SMax Kazantsev // any width of bit grid). But after we take min/max, the result is
163526846786SMax Kazantsev // guaranteed to be within [INT_MIN, INT_MAX].
163626846786SMax Kazantsev //
163726846786SMax Kazantsev // In [1], INT_MAX and INT_MIN are respectively signed and unsigned max/min
163826846786SMax Kazantsev // values, depending on type of latch condition that defines IV iteration
163926846786SMax Kazantsev // space.
1640b57ca09eSMax Kazantsev auto ClampedSubtract = [&](const SCEV *X, const SCEV *Y) {
1641c0b268f9SMax Kazantsev // FIXME: The current implementation assumes that X is in [0, SINT_MAX].
1642c0b268f9SMax Kazantsev // This is required to ensure that SINT_MAX - X does not overflow signed and
1643c0b268f9SMax Kazantsev // that X - Y does not overflow unsigned if Y is negative. Can we lift this
1644c0b268f9SMax Kazantsev // restriction and make it work for negative X either?
164526846786SMax Kazantsev if (IsLatchSigned) {
164626846786SMax Kazantsev // X is a number from signed range, Y is interpreted as signed.
164726846786SMax Kazantsev // Even if Y is SINT_MAX, (X - Y) does not reach SINT_MIN. So the only
164826846786SMax Kazantsev // thing we should care about is that we didn't cross SINT_MAX.
1649b57ca09eSMax Kazantsev // So, if Y is positive, we subtract Y safely.
165026846786SMax Kazantsev // Rule 1: Y > 0 ---> Y.
1651b57ca09eSMax Kazantsev // If 0 <= -Y <= (SINT_MAX - X), we subtract Y safely.
165226846786SMax Kazantsev // Rule 2: Y >=s (X - SINT_MAX) ---> Y.
1653b57ca09eSMax Kazantsev // If 0 <= (SINT_MAX - X) < -Y, we can only subtract (X - SINT_MAX).
165426846786SMax Kazantsev // Rule 3: Y <s (X - SINT_MAX) ---> (X - SINT_MAX).
1655b57ca09eSMax Kazantsev // It gives us smax(Y, X - SINT_MAX) to subtract in all cases.
165626846786SMax Kazantsev const SCEV *XMinusSIntMax = SE.getMinusSCEV(X, SIntMax);
1657716e647dSMax Kazantsev return SE.getMinusSCEV(X, SE.getSMaxExpr(Y, XMinusSIntMax),
1658716e647dSMax Kazantsev SCEV::FlagNSW);
165926846786SMax Kazantsev } else
166026846786SMax Kazantsev // X is a number from unsigned range, Y is interpreted as signed.
166126846786SMax Kazantsev // Even if Y is SINT_MIN, (X - Y) does not reach UINT_MAX. So the only
166226846786SMax Kazantsev // thing we should care about is that we didn't cross zero.
1663b57ca09eSMax Kazantsev // So, if Y is negative, we subtract Y safely.
166426846786SMax Kazantsev // Rule 1: Y <s 0 ---> Y.
1665b57ca09eSMax Kazantsev // If 0 <= Y <= X, we subtract Y safely.
166626846786SMax Kazantsev // Rule 2: Y <=s X ---> Y.
1667b57ca09eSMax Kazantsev // If 0 <= X < Y, we should stop at 0 and can only subtract X.
166826846786SMax Kazantsev // Rule 3: Y >s X ---> X.
1669b57ca09eSMax Kazantsev // It gives us smin(X, Y) to subtract in all cases.
1670716e647dSMax Kazantsev return SE.getMinusSCEV(X, SE.getSMinExpr(X, Y), SCEV::FlagNUW);
167126846786SMax Kazantsev };
167295c476dbSSanjoy Das const SCEV *M = SE.getMinusSCEV(C, A);
167326846786SMax Kazantsev const SCEV *Zero = SE.getZero(M->getType());
1674c0b268f9SMax Kazantsev
1675c0b268f9SMax Kazantsev // This function returns SCEV equal to 1 if X is non-negative 0 otherwise.
1676c0b268f9SMax Kazantsev auto SCEVCheckNonNegative = [&](const SCEV *X) {
1677c0b268f9SMax Kazantsev const Loop *L = IndVar->getLoop();
1678c0b268f9SMax Kazantsev const SCEV *One = SE.getOne(X->getType());
1679c0b268f9SMax Kazantsev // Can we trivially prove that X is a non-negative or negative value?
1680c0b268f9SMax Kazantsev if (isKnownNonNegativeInLoop(X, L, SE))
1681c0b268f9SMax Kazantsev return One;
1682c0b268f9SMax Kazantsev else if (isKnownNegativeInLoop(X, L, SE))
1683c0b268f9SMax Kazantsev return Zero;
1684c0b268f9SMax Kazantsev // If not, we will have to figure it out during the execution.
1685c0b268f9SMax Kazantsev // Function smax(smin(X, 0), -1) + 1 equals to 1 if X >= 0 and 0 if X < 0.
1686c0b268f9SMax Kazantsev const SCEV *NegOne = SE.getNegativeSCEV(One);
1687c0b268f9SMax Kazantsev return SE.getAddExpr(SE.getSMaxExpr(SE.getSMinExpr(X, Zero), NegOne), One);
1688c0b268f9SMax Kazantsev };
1689c0b268f9SMax Kazantsev // FIXME: Current implementation of ClampedSubtract implicitly assumes that
1690c0b268f9SMax Kazantsev // X is non-negative (in sense of a signed value). We need to re-implement
1691c0b268f9SMax Kazantsev // this function in a way that it will correctly handle negative X as well.
1692c0b268f9SMax Kazantsev // We use it twice: for X = 0 everything is fine, but for X = getEnd() we can
1693c0b268f9SMax Kazantsev // end up with a negative X and produce wrong results. So currently we ensure
1694c0b268f9SMax Kazantsev // that if getEnd() is negative then both ends of the safe range are zero.
1695c0b268f9SMax Kazantsev // Note that this may pessimize elimination of unsigned range checks against
1696c0b268f9SMax Kazantsev // negative values.
1697c0b268f9SMax Kazantsev const SCEV *REnd = getEnd();
1698c0b268f9SMax Kazantsev const SCEV *EndIsNonNegative = SCEVCheckNonNegative(REnd);
1699c0b268f9SMax Kazantsev
1700c0b268f9SMax Kazantsev const SCEV *Begin = SE.getMulExpr(ClampedSubtract(Zero, M), EndIsNonNegative);
1701c0b268f9SMax Kazantsev const SCEV *End = SE.getMulExpr(ClampedSubtract(REnd, M), EndIsNonNegative);
1702351db053SSanjoy Das return InductiveRangeCheck::Range(Begin, End);
1703a1837a34SSanjoy Das }
1704a1837a34SSanjoy Das
1705d1fb13ceSSanjoy Das static Optional<InductiveRangeCheck::Range>
IntersectSignedRange(ScalarEvolution & SE,const Optional<InductiveRangeCheck::Range> & R1,const InductiveRangeCheck::Range & R2)17069ac7021aSMax Kazantsev IntersectSignedRange(ScalarEvolution &SE,
17077fc60da2SSanjoy Das const Optional<InductiveRangeCheck::Range> &R1,
170859776734SSanjoy Das const InductiveRangeCheck::Range &R2) {
17094332a943SMax Kazantsev if (R2.isEmpty(SE, /* IsSigned */ true))
171025d8655dSMax Kazantsev return None;
1711a7938c74SKazu Hirata if (!R1)
17123612d4b4SMax Kazantsev return R2;
1713611ffcf4SKazu Hirata auto &R1Value = R1.value();
17143612d4b4SMax Kazantsev // We never return empty ranges from this function, and R1 is supposed to be
17153612d4b4SMax Kazantsev // a result of intersection. Thus, R1 is never empty.
17164332a943SMax Kazantsev assert(!R1Value.isEmpty(SE, /* IsSigned */ true) &&
17174332a943SMax Kazantsev "We should never have empty R1!");
1718a1837a34SSanjoy Das
1719d1fb13ceSSanjoy Das // TODO: we could widen the smaller range and have this work; but for now we
1720d1fb13ceSSanjoy Das // bail out to keep things simple.
1721351db053SSanjoy Das if (R1Value.getType() != R2.getType())
1722d1fb13ceSSanjoy Das return None;
1723d1fb13ceSSanjoy Das
17247fc60da2SSanjoy Das const SCEV *NewBegin = SE.getSMaxExpr(R1Value.getBegin(), R2.getBegin());
17257fc60da2SSanjoy Das const SCEV *NewEnd = SE.getSMinExpr(R1Value.getEnd(), R2.getEnd());
17267fc60da2SSanjoy Das
172725d8655dSMax Kazantsev // If the resulting range is empty, just return None.
172825d8655dSMax Kazantsev auto Ret = InductiveRangeCheck::Range(NewBegin, NewEnd);
17294332a943SMax Kazantsev if (Ret.isEmpty(SE, /* IsSigned */ true))
173025d8655dSMax Kazantsev return None;
173125d8655dSMax Kazantsev return Ret;
1732a1837a34SSanjoy Das }
1733a1837a34SSanjoy Das
17349ac7021aSMax Kazantsev static Optional<InductiveRangeCheck::Range>
IntersectUnsignedRange(ScalarEvolution & SE,const Optional<InductiveRangeCheck::Range> & R1,const InductiveRangeCheck::Range & R2)17359ac7021aSMax Kazantsev IntersectUnsignedRange(ScalarEvolution &SE,
17369ac7021aSMax Kazantsev const Optional<InductiveRangeCheck::Range> &R1,
17379ac7021aSMax Kazantsev const InductiveRangeCheck::Range &R2) {
17389ac7021aSMax Kazantsev if (R2.isEmpty(SE, /* IsSigned */ false))
17399ac7021aSMax Kazantsev return None;
1740a7938c74SKazu Hirata if (!R1)
17419ac7021aSMax Kazantsev return R2;
1742611ffcf4SKazu Hirata auto &R1Value = R1.value();
17439ac7021aSMax Kazantsev // We never return empty ranges from this function, and R1 is supposed to be
17449ac7021aSMax Kazantsev // a result of intersection. Thus, R1 is never empty.
17459ac7021aSMax Kazantsev assert(!R1Value.isEmpty(SE, /* IsSigned */ false) &&
17469ac7021aSMax Kazantsev "We should never have empty R1!");
17479ac7021aSMax Kazantsev
17489ac7021aSMax Kazantsev // TODO: we could widen the smaller range and have this work; but for now we
17499ac7021aSMax Kazantsev // bail out to keep things simple.
17509ac7021aSMax Kazantsev if (R1Value.getType() != R2.getType())
17519ac7021aSMax Kazantsev return None;
17529ac7021aSMax Kazantsev
17539ac7021aSMax Kazantsev const SCEV *NewBegin = SE.getUMaxExpr(R1Value.getBegin(), R2.getBegin());
17549ac7021aSMax Kazantsev const SCEV *NewEnd = SE.getUMinExpr(R1Value.getEnd(), R2.getEnd());
17559ac7021aSMax Kazantsev
17569ac7021aSMax Kazantsev // If the resulting range is empty, just return None.
17579ac7021aSMax Kazantsev auto Ret = InductiveRangeCheck::Range(NewBegin, NewEnd);
17589ac7021aSMax Kazantsev if (Ret.isEmpty(SE, /* IsSigned */ false))
17599ac7021aSMax Kazantsev return None;
17609ac7021aSMax Kazantsev return Ret;
17619ac7021aSMax Kazantsev }
17629ac7021aSMax Kazantsev
run(Function & F,FunctionAnalysisManager & AM)176367904db2SAlina Sbirlea PreservedAnalyses IRCEPass::run(Function &F, FunctionAnalysisManager &AM) {
176467904db2SAlina Sbirlea auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
176567904db2SAlina Sbirlea LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
1766c515b2f3SAnna Thomas // There are no loops in the function. Return before computing other expensive
1767c515b2f3SAnna Thomas // analyses.
1768c515b2f3SAnna Thomas if (LI.empty())
1769c515b2f3SAnna Thomas return PreservedAnalyses::all();
1770c515b2f3SAnna Thomas auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
1771c515b2f3SAnna Thomas auto &BPI = AM.getResult<BranchProbabilityAnalysis>(F);
177267904db2SAlina Sbirlea
177338799975SSerguei Katkov // Get BFI analysis result on demand. Please note that modification of
177438799975SSerguei Katkov // CFG invalidates this analysis and we should handle it.
177538799975SSerguei Katkov auto getBFI = [&F, &AM ]()->BlockFrequencyInfo & {
177638799975SSerguei Katkov return AM.getResult<BlockFrequencyAnalysis>(F);
177738799975SSerguei Katkov };
177838799975SSerguei Katkov InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI, { getBFI });
177967904db2SAlina Sbirlea
178067904db2SAlina Sbirlea bool Changed = false;
178138799975SSerguei Katkov {
178238799975SSerguei Katkov bool CFGChanged = false;
178367904db2SAlina Sbirlea for (const auto &L : LI) {
178438799975SSerguei Katkov CFGChanged |= simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr,
178567904db2SAlina Sbirlea /*PreserveLCSSA=*/false);
178667904db2SAlina Sbirlea Changed |= formLCSSARecursively(*L, DT, &LI, &SE);
178767904db2SAlina Sbirlea }
178838799975SSerguei Katkov Changed |= CFGChanged;
178938799975SSerguei Katkov
17909c776c2fSArthur Eubanks if (CFGChanged && !SkipProfitabilityChecks) {
17919c776c2fSArthur Eubanks PreservedAnalyses PA = PreservedAnalyses::all();
17929c776c2fSArthur Eubanks PA.abandon<BlockFrequencyAnalysis>();
17939c776c2fSArthur Eubanks AM.invalidate(F, PA);
17949c776c2fSArthur Eubanks }
179538799975SSerguei Katkov }
179667904db2SAlina Sbirlea
179767904db2SAlina Sbirlea SmallPriorityWorklist<Loop *, 4> Worklist;
179867904db2SAlina Sbirlea appendLoopsToWorklist(LI, Worklist);
179967904db2SAlina Sbirlea auto LPMAddNewLoop = [&Worklist](Loop *NL, bool IsSubloop) {
1800194a407bSFedor Sergeev if (!IsSubloop)
180167904db2SAlina Sbirlea appendLoopsToWorklist(*NL, Worklist);
1802194a407bSFedor Sergeev };
180367904db2SAlina Sbirlea
180467904db2SAlina Sbirlea while (!Worklist.empty()) {
180567904db2SAlina Sbirlea Loop *L = Worklist.pop_back_val();
180638799975SSerguei Katkov if (IRCE.run(L, LPMAddNewLoop)) {
180738799975SSerguei Katkov Changed = true;
18089c776c2fSArthur Eubanks if (!SkipProfitabilityChecks) {
18099c776c2fSArthur Eubanks PreservedAnalyses PA = PreservedAnalyses::all();
18109c776c2fSArthur Eubanks PA.abandon<BlockFrequencyAnalysis>();
18119c776c2fSArthur Eubanks AM.invalidate(F, PA);
18129c776c2fSArthur Eubanks }
181338799975SSerguei Katkov }
181467904db2SAlina Sbirlea }
181567904db2SAlina Sbirlea
1816194a407bSFedor Sergeev if (!Changed)
1817194a407bSFedor Sergeev return PreservedAnalyses::all();
1818194a407bSFedor Sergeev return getLoopPassPreservedAnalyses();
1819194a407bSFedor Sergeev }
1820194a407bSFedor Sergeev
runOnFunction(Function & F)182167904db2SAlina Sbirlea bool IRCELegacyPass::runOnFunction(Function &F) {
182267904db2SAlina Sbirlea if (skipFunction(F))
182350271f78SAndrew Kaylor return false;
182450271f78SAndrew Kaylor
1825194a407bSFedor Sergeev ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1826194a407bSFedor Sergeev BranchProbabilityInfo &BPI =
1827194a407bSFedor Sergeev getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
1828194a407bSFedor Sergeev auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1829194a407bSFedor Sergeev auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1830194a407bSFedor Sergeev InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI);
183167904db2SAlina Sbirlea
183267904db2SAlina Sbirlea bool Changed = false;
183367904db2SAlina Sbirlea
183467904db2SAlina Sbirlea for (const auto &L : LI) {
183567904db2SAlina Sbirlea Changed |= simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr,
183667904db2SAlina Sbirlea /*PreserveLCSSA=*/false);
183767904db2SAlina Sbirlea Changed |= formLCSSARecursively(*L, DT, &LI, &SE);
183867904db2SAlina Sbirlea }
183967904db2SAlina Sbirlea
184067904db2SAlina Sbirlea SmallPriorityWorklist<Loop *, 4> Worklist;
184167904db2SAlina Sbirlea appendLoopsToWorklist(LI, Worklist);
184267904db2SAlina Sbirlea auto LPMAddNewLoop = [&](Loop *NL, bool IsSubloop) {
184367904db2SAlina Sbirlea if (!IsSubloop)
184467904db2SAlina Sbirlea appendLoopsToWorklist(*NL, Worklist);
1845194a407bSFedor Sergeev };
184667904db2SAlina Sbirlea
184767904db2SAlina Sbirlea while (!Worklist.empty()) {
184867904db2SAlina Sbirlea Loop *L = Worklist.pop_back_val();
184967904db2SAlina Sbirlea Changed |= IRCE.run(L, LPMAddNewLoop);
185067904db2SAlina Sbirlea }
185167904db2SAlina Sbirlea return Changed;
1852194a407bSFedor Sergeev }
1853194a407bSFedor Sergeev
185475d0e0cdSSerguei Katkov bool
isProfitableToTransform(const Loop & L,LoopStructure & LS)185575d0e0cdSSerguei Katkov InductiveRangeCheckElimination::isProfitableToTransform(const Loop &L,
185675d0e0cdSSerguei Katkov LoopStructure &LS) {
185775d0e0cdSSerguei Katkov if (SkipProfitabilityChecks)
185875d0e0cdSSerguei Katkov return true;
1859e0e687a6SKazu Hirata if (GetBFI) {
186075d0e0cdSSerguei Katkov BlockFrequencyInfo &BFI = (*GetBFI)();
186175d0e0cdSSerguei Katkov uint64_t hFreq = BFI.getBlockFreq(LS.Header).getFrequency();
186275d0e0cdSSerguei Katkov uint64_t phFreq = BFI.getBlockFreq(L.getLoopPreheader()).getFrequency();
186375d0e0cdSSerguei Katkov if (phFreq != 0 && hFreq != 0 && (hFreq / phFreq < MinRuntimeIterations)) {
186475d0e0cdSSerguei Katkov LLVM_DEBUG(dbgs() << "irce: could not prove profitability: "
186575d0e0cdSSerguei Katkov << "the estimated number of iterations basing on "
186675d0e0cdSSerguei Katkov "frequency info is " << (hFreq / phFreq) << "\n";);
186775d0e0cdSSerguei Katkov return false;
186875d0e0cdSSerguei Katkov }
186975d0e0cdSSerguei Katkov return true;
187075d0e0cdSSerguei Katkov }
187175d0e0cdSSerguei Katkov
187275d0e0cdSSerguei Katkov if (!BPI)
187375d0e0cdSSerguei Katkov return true;
187475d0e0cdSSerguei Katkov BranchProbability ExitProbability =
187575d0e0cdSSerguei Katkov BPI->getEdgeProbability(LS.Latch, LS.LatchBrExitIdx);
1876400f6edcSSerguei Katkov if (ExitProbability > BranchProbability(1, MinRuntimeIterations)) {
187775d0e0cdSSerguei Katkov LLVM_DEBUG(dbgs() << "irce: could not prove profitability: "
187875d0e0cdSSerguei Katkov << "the exit probability is too big " << ExitProbability
187975d0e0cdSSerguei Katkov << "\n";);
188075d0e0cdSSerguei Katkov return false;
188175d0e0cdSSerguei Katkov }
188275d0e0cdSSerguei Katkov return true;
188375d0e0cdSSerguei Katkov }
188475d0e0cdSSerguei Katkov
run(Loop * L,function_ref<void (Loop *,bool)> LPMAddNewLoop)1885194a407bSFedor Sergeev bool InductiveRangeCheckElimination::run(
1886194a407bSFedor Sergeev Loop *L, function_ref<void(Loop *, bool)> LPMAddNewLoop) {
1887a1837a34SSanjoy Das if (L->getBlocks().size() >= LoopSizeCutoff) {
1888d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: giving up constraining loop, too large\n");
1889a1837a34SSanjoy Das return false;
1890a1837a34SSanjoy Das }
1891a1837a34SSanjoy Das
1892a1837a34SSanjoy Das BasicBlock *Preheader = L->getLoopPreheader();
1893a1837a34SSanjoy Das if (!Preheader) {
1894d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: loop has no preheader, leaving\n");
1895a1837a34SSanjoy Das return false;
1896a1837a34SSanjoy Das }
1897a1837a34SSanjoy Das
1898a1837a34SSanjoy Das LLVMContext &Context = Preheader->getContext();
1899c5b1169dSSanjoy Das SmallVector<InductiveRangeCheck, 16> RangeChecks;
1900a1837a34SSanjoy Das
1901a1837a34SSanjoy Das for (auto BBI : L->getBlocks())
1902a1837a34SSanjoy Das if (BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator()))
1903a099268eSSanjoy Das InductiveRangeCheck::extractRangeChecksFromBranch(TBI, L, SE, BPI,
1904a099268eSSanjoy Das RangeChecks);
1905a1837a34SSanjoy Das
1906a1837a34SSanjoy Das if (RangeChecks.empty())
1907a1837a34SSanjoy Das return false;
1908a1837a34SSanjoy Das
19099c1bfae6SSanjoy Das auto PrintRecognizedRangeChecks = [&](raw_ostream &OS) {
19109c1bfae6SSanjoy Das OS << "irce: looking at loop "; L->print(OS);
19119c1bfae6SSanjoy Das OS << "irce: loop has " << RangeChecks.size()
1912a1837a34SSanjoy Das << " inductive range checks: \n";
1913c5b1169dSSanjoy Das for (InductiveRangeCheck &IRC : RangeChecks)
1914c5b1169dSSanjoy Das IRC.print(OS);
19159c1bfae6SSanjoy Das };
19169c1bfae6SSanjoy Das
1917d34e60caSNicola Zaghen LLVM_DEBUG(PrintRecognizedRangeChecks(dbgs()));
19189c1bfae6SSanjoy Das
19199c1bfae6SSanjoy Das if (PrintRangeChecks)
19209c1bfae6SSanjoy Das PrintRecognizedRangeChecks(errs());
1921a1837a34SSanjoy Das
1922e75ed926SSanjoy Das const char *FailureReason = nullptr;
1923e75ed926SSanjoy Das Optional<LoopStructure> MaybeLoopStructure =
192475d0e0cdSSerguei Katkov LoopStructure::parseLoopStructure(SE, *L, FailureReason);
1925e0e687a6SKazu Hirata if (!MaybeLoopStructure) {
1926d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "irce: could not parse loop structure: "
1927d34e60caSNicola Zaghen << FailureReason << "\n";);
1928e75ed926SSanjoy Das return false;
1929e75ed926SSanjoy Das }
19307a47ee51SKazu Hirata LoopStructure LS = *MaybeLoopStructure;
193175d0e0cdSSerguei Katkov if (!isProfitableToTransform(*L, LS))
193238799975SSerguei Katkov return false;
1933e75ed926SSanjoy Das const SCEVAddRecExpr *IndVar =
1934675e304eSSerguei Katkov cast<SCEVAddRecExpr>(SE.getMinusSCEV(SE.getSCEV(LS.IndVarBase), SE.getSCEV(LS.IndVarStep)));
1935e75ed926SSanjoy Das
1936a1837a34SSanjoy Das Optional<InductiveRangeCheck::Range> SafeIterRange;
1937a1837a34SSanjoy Das Instruction *ExprInsertPt = Preheader->getTerminator();
1938a1837a34SSanjoy Das
1939c5b1169dSSanjoy Das SmallVector<InductiveRangeCheck, 4> RangeChecksToEliminate;
19409ac7021aSMax Kazantsev // Basing on the type of latch predicate, we interpret the IV iteration range
19419ac7021aSMax Kazantsev // as signed or unsigned range. We use different min/max functions (signed or
19429ac7021aSMax Kazantsev // unsigned) when intersecting this range with safe iteration ranges implied
19439ac7021aSMax Kazantsev // by range checks.
19449ac7021aSMax Kazantsev auto IntersectRange =
19459ac7021aSMax Kazantsev LS.IsSignedPredicate ? IntersectSignedRange : IntersectUnsignedRange;
1946a1837a34SSanjoy Das
1947a1837a34SSanjoy Das IRBuilder<> B(ExprInsertPt);
1948c5b1169dSSanjoy Das for (InductiveRangeCheck &IRC : RangeChecks) {
194926846786SMax Kazantsev auto Result = IRC.computeSafeIterationSpace(SE, IndVar,
195026846786SMax Kazantsev LS.IsSignedPredicate);
1951a7938c74SKazu Hirata if (Result) {
19523b7c3a65SKazu Hirata auto MaybeSafeIterRange =
1953611ffcf4SKazu Hirata IntersectRange(SE, SafeIterRange, Result.value());
1954a7938c74SKazu Hirata if (MaybeSafeIterRange) {
1955611ffcf4SKazu Hirata assert(!MaybeSafeIterRange.value().isEmpty(SE, LS.IsSignedPredicate) &&
195625d8655dSMax Kazantsev "We should never return empty ranges!");
1957a1837a34SSanjoy Das RangeChecksToEliminate.push_back(IRC);
1958611ffcf4SKazu Hirata SafeIterRange = MaybeSafeIterRange.value();
1959d1fb13ceSSanjoy Das }
1960a1837a34SSanjoy Das }
1961a1837a34SSanjoy Das }
1962a1837a34SSanjoy Das
1963a7938c74SKazu Hirata if (!SafeIterRange)
1964a1837a34SSanjoy Das return false;
1965a1837a34SSanjoy Das
1966611ffcf4SKazu Hirata LoopConstrainer LC(*L, LI, LPMAddNewLoop, LS, SE, DT, SafeIterRange.value());
1967a1837a34SSanjoy Das bool Changed = LC.run();
1968a1837a34SSanjoy Das
1969a1837a34SSanjoy Das if (Changed) {
1970a1837a34SSanjoy Das auto PrintConstrainedLoopInfo = [L]() {
1971a1837a34SSanjoy Das dbgs() << "irce: in function ";
1972a1837a34SSanjoy Das dbgs() << L->getHeader()->getParent()->getName() << ": ";
1973a1837a34SSanjoy Das dbgs() << "constrained ";
1974a1837a34SSanjoy Das L->print(dbgs());
1975a1837a34SSanjoy Das };
1976a1837a34SSanjoy Das
1977d34e60caSNicola Zaghen LLVM_DEBUG(PrintConstrainedLoopInfo());
1978a1837a34SSanjoy Das
1979a1837a34SSanjoy Das if (PrintChangedLoops)
1980a1837a34SSanjoy Das PrintConstrainedLoopInfo();
1981a1837a34SSanjoy Das
1982a1837a34SSanjoy Das // Optimize away the now-redundant range checks.
1983a1837a34SSanjoy Das
1984c5b1169dSSanjoy Das for (InductiveRangeCheck &IRC : RangeChecksToEliminate) {
1985c5b1169dSSanjoy Das ConstantInt *FoldedRangeCheck = IRC.getPassingDirection()
1986a1837a34SSanjoy Das ? ConstantInt::getTrue(Context)
1987a1837a34SSanjoy Das : ConstantInt::getFalse(Context);
1988aa83c47bSSanjoy Das IRC.getCheckUse()->set(FoldedRangeCheck);
1989a1837a34SSanjoy Das }
1990a1837a34SSanjoy Das }
1991a1837a34SSanjoy Das
1992a1837a34SSanjoy Das return Changed;
1993a1837a34SSanjoy Das }
1994a1837a34SSanjoy Das
createInductiveRangeCheckEliminationPass()1995a1837a34SSanjoy Das Pass *llvm::createInductiveRangeCheckEliminationPass() {
1996194a407bSFedor Sergeev return new IRCELegacyPass();
1997a1837a34SSanjoy Das }
1998