1*9880d681SAndroid Build Coastguard Worker //===-- LoopReroll.cpp - Loop rerolling pass ------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This pass implements a simple loop reroller.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Scalar.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/MapVector.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasAnalysis.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasSetTracker.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopPass.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolution.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpander.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpressions.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/TargetLibraryInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Local.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/LoopUtils.h"
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker using namespace llvm;
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "loop-reroll"
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker STATISTIC(NumRerolledLoops, "Number of rerolled loops");
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned>
45*9880d681SAndroid Build Coastguard Worker MaxInc("max-reroll-increment", cl::init(2048), cl::Hidden,
46*9880d681SAndroid Build Coastguard Worker cl::desc("The maximum increment for loop rerolling"));
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned>
49*9880d681SAndroid Build Coastguard Worker NumToleratedFailedMatches("reroll-num-tolerated-failed-matches", cl::init(400),
50*9880d681SAndroid Build Coastguard Worker cl::Hidden,
51*9880d681SAndroid Build Coastguard Worker cl::desc("The maximum number of failures to tolerate"
52*9880d681SAndroid Build Coastguard Worker " during fuzzy matching. (default: 400)"));
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker // This loop re-rolling transformation aims to transform loops like this:
55*9880d681SAndroid Build Coastguard Worker //
56*9880d681SAndroid Build Coastguard Worker // int foo(int a);
57*9880d681SAndroid Build Coastguard Worker // void bar(int *x) {
58*9880d681SAndroid Build Coastguard Worker // for (int i = 0; i < 500; i += 3) {
59*9880d681SAndroid Build Coastguard Worker // foo(i);
60*9880d681SAndroid Build Coastguard Worker // foo(i+1);
61*9880d681SAndroid Build Coastguard Worker // foo(i+2);
62*9880d681SAndroid Build Coastguard Worker // }
63*9880d681SAndroid Build Coastguard Worker // }
64*9880d681SAndroid Build Coastguard Worker //
65*9880d681SAndroid Build Coastguard Worker // into a loop like this:
66*9880d681SAndroid Build Coastguard Worker //
67*9880d681SAndroid Build Coastguard Worker // void bar(int *x) {
68*9880d681SAndroid Build Coastguard Worker // for (int i = 0; i < 500; ++i)
69*9880d681SAndroid Build Coastguard Worker // foo(i);
70*9880d681SAndroid Build Coastguard Worker // }
71*9880d681SAndroid Build Coastguard Worker //
72*9880d681SAndroid Build Coastguard Worker // It does this by looking for loops that, besides the latch code, are composed
73*9880d681SAndroid Build Coastguard Worker // of isomorphic DAGs of instructions, with each DAG rooted at some increment
74*9880d681SAndroid Build Coastguard Worker // to the induction variable, and where each DAG is isomorphic to the DAG
75*9880d681SAndroid Build Coastguard Worker // rooted at the induction variable (excepting the sub-DAGs which root the
76*9880d681SAndroid Build Coastguard Worker // other induction-variable increments). In other words, we're looking for loop
77*9880d681SAndroid Build Coastguard Worker // bodies of the form:
78*9880d681SAndroid Build Coastguard Worker //
79*9880d681SAndroid Build Coastguard Worker // %iv = phi [ (preheader, ...), (body, %iv.next) ]
80*9880d681SAndroid Build Coastguard Worker // f(%iv)
81*9880d681SAndroid Build Coastguard Worker // %iv.1 = add %iv, 1 <-- a root increment
82*9880d681SAndroid Build Coastguard Worker // f(%iv.1)
83*9880d681SAndroid Build Coastguard Worker // %iv.2 = add %iv, 2 <-- a root increment
84*9880d681SAndroid Build Coastguard Worker // f(%iv.2)
85*9880d681SAndroid Build Coastguard Worker // %iv.scale_m_1 = add %iv, scale-1 <-- a root increment
86*9880d681SAndroid Build Coastguard Worker // f(%iv.scale_m_1)
87*9880d681SAndroid Build Coastguard Worker // ...
88*9880d681SAndroid Build Coastguard Worker // %iv.next = add %iv, scale
89*9880d681SAndroid Build Coastguard Worker // %cmp = icmp(%iv, ...)
90*9880d681SAndroid Build Coastguard Worker // br %cmp, header, exit
91*9880d681SAndroid Build Coastguard Worker //
92*9880d681SAndroid Build Coastguard Worker // where each f(i) is a set of instructions that, collectively, are a function
93*9880d681SAndroid Build Coastguard Worker // only of i (and other loop-invariant values).
94*9880d681SAndroid Build Coastguard Worker //
95*9880d681SAndroid Build Coastguard Worker // As a special case, we can also reroll loops like this:
96*9880d681SAndroid Build Coastguard Worker //
97*9880d681SAndroid Build Coastguard Worker // int foo(int);
98*9880d681SAndroid Build Coastguard Worker // void bar(int *x) {
99*9880d681SAndroid Build Coastguard Worker // for (int i = 0; i < 500; ++i) {
100*9880d681SAndroid Build Coastguard Worker // x[3*i] = foo(0);
101*9880d681SAndroid Build Coastguard Worker // x[3*i+1] = foo(0);
102*9880d681SAndroid Build Coastguard Worker // x[3*i+2] = foo(0);
103*9880d681SAndroid Build Coastguard Worker // }
104*9880d681SAndroid Build Coastguard Worker // }
105*9880d681SAndroid Build Coastguard Worker //
106*9880d681SAndroid Build Coastguard Worker // into this:
107*9880d681SAndroid Build Coastguard Worker //
108*9880d681SAndroid Build Coastguard Worker // void bar(int *x) {
109*9880d681SAndroid Build Coastguard Worker // for (int i = 0; i < 1500; ++i)
110*9880d681SAndroid Build Coastguard Worker // x[i] = foo(0);
111*9880d681SAndroid Build Coastguard Worker // }
112*9880d681SAndroid Build Coastguard Worker //
113*9880d681SAndroid Build Coastguard Worker // in which case, we're looking for inputs like this:
114*9880d681SAndroid Build Coastguard Worker //
115*9880d681SAndroid Build Coastguard Worker // %iv = phi [ (preheader, ...), (body, %iv.next) ]
116*9880d681SAndroid Build Coastguard Worker // %scaled.iv = mul %iv, scale
117*9880d681SAndroid Build Coastguard Worker // f(%scaled.iv)
118*9880d681SAndroid Build Coastguard Worker // %scaled.iv.1 = add %scaled.iv, 1
119*9880d681SAndroid Build Coastguard Worker // f(%scaled.iv.1)
120*9880d681SAndroid Build Coastguard Worker // %scaled.iv.2 = add %scaled.iv, 2
121*9880d681SAndroid Build Coastguard Worker // f(%scaled.iv.2)
122*9880d681SAndroid Build Coastguard Worker // %scaled.iv.scale_m_1 = add %scaled.iv, scale-1
123*9880d681SAndroid Build Coastguard Worker // f(%scaled.iv.scale_m_1)
124*9880d681SAndroid Build Coastguard Worker // ...
125*9880d681SAndroid Build Coastguard Worker // %iv.next = add %iv, 1
126*9880d681SAndroid Build Coastguard Worker // %cmp = icmp(%iv, ...)
127*9880d681SAndroid Build Coastguard Worker // br %cmp, header, exit
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker namespace {
130*9880d681SAndroid Build Coastguard Worker enum IterationLimits {
131*9880d681SAndroid Build Coastguard Worker /// The maximum number of iterations that we'll try and reroll.
132*9880d681SAndroid Build Coastguard Worker IL_MaxRerollIterations = 32,
133*9880d681SAndroid Build Coastguard Worker /// The bitvector index used by loop induction variables and other
134*9880d681SAndroid Build Coastguard Worker /// instructions that belong to all iterations.
135*9880d681SAndroid Build Coastguard Worker IL_All,
136*9880d681SAndroid Build Coastguard Worker IL_End
137*9880d681SAndroid Build Coastguard Worker };
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker class LoopReroll : public LoopPass {
140*9880d681SAndroid Build Coastguard Worker public:
141*9880d681SAndroid Build Coastguard Worker static char ID; // Pass ID, replacement for typeid
LoopReroll()142*9880d681SAndroid Build Coastguard Worker LoopReroll() : LoopPass(ID) {
143*9880d681SAndroid Build Coastguard Worker initializeLoopRerollPass(*PassRegistry::getPassRegistry());
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker bool runOnLoop(Loop *L, LPPassManager &LPM) override;
147*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const148*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
149*9880d681SAndroid Build Coastguard Worker AU.addRequired<TargetLibraryInfoWrapperPass>();
150*9880d681SAndroid Build Coastguard Worker getLoopAnalysisUsage(AU);
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker protected:
154*9880d681SAndroid Build Coastguard Worker AliasAnalysis *AA;
155*9880d681SAndroid Build Coastguard Worker LoopInfo *LI;
156*9880d681SAndroid Build Coastguard Worker ScalarEvolution *SE;
157*9880d681SAndroid Build Coastguard Worker TargetLibraryInfo *TLI;
158*9880d681SAndroid Build Coastguard Worker DominatorTree *DT;
159*9880d681SAndroid Build Coastguard Worker bool PreserveLCSSA;
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker typedef SmallVector<Instruction *, 16> SmallInstructionVector;
162*9880d681SAndroid Build Coastguard Worker typedef SmallSet<Instruction *, 16> SmallInstructionSet;
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker // Map between induction variable and its increment
165*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int64_t> IVToIncMap;
166*9880d681SAndroid Build Coastguard Worker // For loop with multiple induction variable, remember the one used only to
167*9880d681SAndroid Build Coastguard Worker // control the loop.
168*9880d681SAndroid Build Coastguard Worker Instruction *LoopControlIV;
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker // A chain of isomorphic instructions, identified by a single-use PHI
171*9880d681SAndroid Build Coastguard Worker // representing a reduction. Only the last value may be used outside the
172*9880d681SAndroid Build Coastguard Worker // loop.
173*9880d681SAndroid Build Coastguard Worker struct SimpleLoopReduction {
SimpleLoopReduction__anonda39918c0111::LoopReroll::SimpleLoopReduction174*9880d681SAndroid Build Coastguard Worker SimpleLoopReduction(Instruction *P, Loop *L)
175*9880d681SAndroid Build Coastguard Worker : Valid(false), Instructions(1, P) {
176*9880d681SAndroid Build Coastguard Worker assert(isa<PHINode>(P) && "First reduction instruction must be a PHI");
177*9880d681SAndroid Build Coastguard Worker add(L);
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
valid__anonda39918c0111::LoopReroll::SimpleLoopReduction180*9880d681SAndroid Build Coastguard Worker bool valid() const {
181*9880d681SAndroid Build Coastguard Worker return Valid;
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker
getPHI__anonda39918c0111::LoopReroll::SimpleLoopReduction184*9880d681SAndroid Build Coastguard Worker Instruction *getPHI() const {
185*9880d681SAndroid Build Coastguard Worker assert(Valid && "Using invalid reduction");
186*9880d681SAndroid Build Coastguard Worker return Instructions.front();
187*9880d681SAndroid Build Coastguard Worker }
188*9880d681SAndroid Build Coastguard Worker
getReducedValue__anonda39918c0111::LoopReroll::SimpleLoopReduction189*9880d681SAndroid Build Coastguard Worker Instruction *getReducedValue() const {
190*9880d681SAndroid Build Coastguard Worker assert(Valid && "Using invalid reduction");
191*9880d681SAndroid Build Coastguard Worker return Instructions.back();
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker
get__anonda39918c0111::LoopReroll::SimpleLoopReduction194*9880d681SAndroid Build Coastguard Worker Instruction *get(size_t i) const {
195*9880d681SAndroid Build Coastguard Worker assert(Valid && "Using invalid reduction");
196*9880d681SAndroid Build Coastguard Worker return Instructions[i+1];
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker
operator []__anonda39918c0111::LoopReroll::SimpleLoopReduction199*9880d681SAndroid Build Coastguard Worker Instruction *operator [] (size_t i) const { return get(i); }
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker // The size, ignoring the initial PHI.
size__anonda39918c0111::LoopReroll::SimpleLoopReduction202*9880d681SAndroid Build Coastguard Worker size_t size() const {
203*9880d681SAndroid Build Coastguard Worker assert(Valid && "Using invalid reduction");
204*9880d681SAndroid Build Coastguard Worker return Instructions.size()-1;
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker typedef SmallInstructionVector::iterator iterator;
208*9880d681SAndroid Build Coastguard Worker typedef SmallInstructionVector::const_iterator const_iterator;
209*9880d681SAndroid Build Coastguard Worker
begin__anonda39918c0111::LoopReroll::SimpleLoopReduction210*9880d681SAndroid Build Coastguard Worker iterator begin() {
211*9880d681SAndroid Build Coastguard Worker assert(Valid && "Using invalid reduction");
212*9880d681SAndroid Build Coastguard Worker return std::next(Instructions.begin());
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker
begin__anonda39918c0111::LoopReroll::SimpleLoopReduction215*9880d681SAndroid Build Coastguard Worker const_iterator begin() const {
216*9880d681SAndroid Build Coastguard Worker assert(Valid && "Using invalid reduction");
217*9880d681SAndroid Build Coastguard Worker return std::next(Instructions.begin());
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker
end__anonda39918c0111::LoopReroll::SimpleLoopReduction220*9880d681SAndroid Build Coastguard Worker iterator end() { return Instructions.end(); }
end__anonda39918c0111::LoopReroll::SimpleLoopReduction221*9880d681SAndroid Build Coastguard Worker const_iterator end() const { return Instructions.end(); }
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker protected:
224*9880d681SAndroid Build Coastguard Worker bool Valid;
225*9880d681SAndroid Build Coastguard Worker SmallInstructionVector Instructions;
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker void add(Loop *L);
228*9880d681SAndroid Build Coastguard Worker };
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker // The set of all reductions, and state tracking of possible reductions
231*9880d681SAndroid Build Coastguard Worker // during loop instruction processing.
232*9880d681SAndroid Build Coastguard Worker struct ReductionTracker {
233*9880d681SAndroid Build Coastguard Worker typedef SmallVector<SimpleLoopReduction, 16> SmallReductionVector;
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker // Add a new possible reduction.
addSLR__anonda39918c0111::LoopReroll::ReductionTracker236*9880d681SAndroid Build Coastguard Worker void addSLR(SimpleLoopReduction &SLR) { PossibleReds.push_back(SLR); }
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker // Setup to track possible reductions corresponding to the provided
239*9880d681SAndroid Build Coastguard Worker // rerolling scale. Only reductions with a number of non-PHI instructions
240*9880d681SAndroid Build Coastguard Worker // that is divisible by the scale are considered. Three instructions sets
241*9880d681SAndroid Build Coastguard Worker // are filled in:
242*9880d681SAndroid Build Coastguard Worker // - A set of all possible instructions in eligible reductions.
243*9880d681SAndroid Build Coastguard Worker // - A set of all PHIs in eligible reductions
244*9880d681SAndroid Build Coastguard Worker // - A set of all reduced values (last instructions) in eligible
245*9880d681SAndroid Build Coastguard Worker // reductions.
restrictToScale__anonda39918c0111::LoopReroll::ReductionTracker246*9880d681SAndroid Build Coastguard Worker void restrictToScale(uint64_t Scale,
247*9880d681SAndroid Build Coastguard Worker SmallInstructionSet &PossibleRedSet,
248*9880d681SAndroid Build Coastguard Worker SmallInstructionSet &PossibleRedPHISet,
249*9880d681SAndroid Build Coastguard Worker SmallInstructionSet &PossibleRedLastSet) {
250*9880d681SAndroid Build Coastguard Worker PossibleRedIdx.clear();
251*9880d681SAndroid Build Coastguard Worker PossibleRedIter.clear();
252*9880d681SAndroid Build Coastguard Worker Reds.clear();
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = PossibleReds.size(); i != e; ++i)
255*9880d681SAndroid Build Coastguard Worker if (PossibleReds[i].size() % Scale == 0) {
256*9880d681SAndroid Build Coastguard Worker PossibleRedLastSet.insert(PossibleReds[i].getReducedValue());
257*9880d681SAndroid Build Coastguard Worker PossibleRedPHISet.insert(PossibleReds[i].getPHI());
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker PossibleRedSet.insert(PossibleReds[i].getPHI());
260*9880d681SAndroid Build Coastguard Worker PossibleRedIdx[PossibleReds[i].getPHI()] = i;
261*9880d681SAndroid Build Coastguard Worker for (Instruction *J : PossibleReds[i]) {
262*9880d681SAndroid Build Coastguard Worker PossibleRedSet.insert(J);
263*9880d681SAndroid Build Coastguard Worker PossibleRedIdx[J] = i;
264*9880d681SAndroid Build Coastguard Worker }
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker // The functions below are used while processing the loop instructions.
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker // Are the two instructions both from reductions, and furthermore, from
271*9880d681SAndroid Build Coastguard Worker // the same reduction?
isPairInSame__anonda39918c0111::LoopReroll::ReductionTracker272*9880d681SAndroid Build Coastguard Worker bool isPairInSame(Instruction *J1, Instruction *J2) {
273*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int>::iterator J1I = PossibleRedIdx.find(J1);
274*9880d681SAndroid Build Coastguard Worker if (J1I != PossibleRedIdx.end()) {
275*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int>::iterator J2I = PossibleRedIdx.find(J2);
276*9880d681SAndroid Build Coastguard Worker if (J2I != PossibleRedIdx.end() && J1I->second == J2I->second)
277*9880d681SAndroid Build Coastguard Worker return true;
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker return false;
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker // The two provided instructions, the first from the base iteration, and
284*9880d681SAndroid Build Coastguard Worker // the second from iteration i, form a matched pair. If these are part of
285*9880d681SAndroid Build Coastguard Worker // a reduction, record that fact.
recordPair__anonda39918c0111::LoopReroll::ReductionTracker286*9880d681SAndroid Build Coastguard Worker void recordPair(Instruction *J1, Instruction *J2, unsigned i) {
287*9880d681SAndroid Build Coastguard Worker if (PossibleRedIdx.count(J1)) {
288*9880d681SAndroid Build Coastguard Worker assert(PossibleRedIdx.count(J2) &&
289*9880d681SAndroid Build Coastguard Worker "Recording reduction vs. non-reduction instruction?");
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker PossibleRedIter[J1] = 0;
292*9880d681SAndroid Build Coastguard Worker PossibleRedIter[J2] = i;
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker int Idx = PossibleRedIdx[J1];
295*9880d681SAndroid Build Coastguard Worker assert(Idx == PossibleRedIdx[J2] &&
296*9880d681SAndroid Build Coastguard Worker "Recording pair from different reductions?");
297*9880d681SAndroid Build Coastguard Worker Reds.insert(Idx);
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker // The functions below can be called after we've finished processing all
302*9880d681SAndroid Build Coastguard Worker // instructions in the loop, and we know which reductions were selected.
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker bool validateSelected();
305*9880d681SAndroid Build Coastguard Worker void replaceSelected();
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker protected:
308*9880d681SAndroid Build Coastguard Worker // The vector of all possible reductions (for any scale).
309*9880d681SAndroid Build Coastguard Worker SmallReductionVector PossibleReds;
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int> PossibleRedIdx;
312*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int> PossibleRedIter;
313*9880d681SAndroid Build Coastguard Worker DenseSet<int> Reds;
314*9880d681SAndroid Build Coastguard Worker };
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker // A DAGRootSet models an induction variable being used in a rerollable
317*9880d681SAndroid Build Coastguard Worker // loop. For example,
318*9880d681SAndroid Build Coastguard Worker //
319*9880d681SAndroid Build Coastguard Worker // x[i*3+0] = y1
320*9880d681SAndroid Build Coastguard Worker // x[i*3+1] = y2
321*9880d681SAndroid Build Coastguard Worker // x[i*3+2] = y3
322*9880d681SAndroid Build Coastguard Worker //
323*9880d681SAndroid Build Coastguard Worker // Base instruction -> i*3
324*9880d681SAndroid Build Coastguard Worker // +---+----+
325*9880d681SAndroid Build Coastguard Worker // / | \
326*9880d681SAndroid Build Coastguard Worker // ST[y1] +1 +2 <-- Roots
327*9880d681SAndroid Build Coastguard Worker // | |
328*9880d681SAndroid Build Coastguard Worker // ST[y2] ST[y3]
329*9880d681SAndroid Build Coastguard Worker //
330*9880d681SAndroid Build Coastguard Worker // There may be multiple DAGRoots, for example:
331*9880d681SAndroid Build Coastguard Worker //
332*9880d681SAndroid Build Coastguard Worker // x[i*2+0] = ... (1)
333*9880d681SAndroid Build Coastguard Worker // x[i*2+1] = ... (1)
334*9880d681SAndroid Build Coastguard Worker // x[i*2+4] = ... (2)
335*9880d681SAndroid Build Coastguard Worker // x[i*2+5] = ... (2)
336*9880d681SAndroid Build Coastguard Worker // x[(i+1234)*2+5678] = ... (3)
337*9880d681SAndroid Build Coastguard Worker // x[(i+1234)*2+5679] = ... (3)
338*9880d681SAndroid Build Coastguard Worker //
339*9880d681SAndroid Build Coastguard Worker // The loop will be rerolled by adding a new loop induction variable,
340*9880d681SAndroid Build Coastguard Worker // one for the Base instruction in each DAGRootSet.
341*9880d681SAndroid Build Coastguard Worker //
342*9880d681SAndroid Build Coastguard Worker struct DAGRootSet {
343*9880d681SAndroid Build Coastguard Worker Instruction *BaseInst;
344*9880d681SAndroid Build Coastguard Worker SmallInstructionVector Roots;
345*9880d681SAndroid Build Coastguard Worker // The instructions between IV and BaseInst (but not including BaseInst).
346*9880d681SAndroid Build Coastguard Worker SmallInstructionSet SubsumedInsts;
347*9880d681SAndroid Build Coastguard Worker };
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker // The set of all DAG roots, and state tracking of all roots
350*9880d681SAndroid Build Coastguard Worker // for a particular induction variable.
351*9880d681SAndroid Build Coastguard Worker struct DAGRootTracker {
DAGRootTracker__anonda39918c0111::LoopReroll::DAGRootTracker352*9880d681SAndroid Build Coastguard Worker DAGRootTracker(LoopReroll *Parent, Loop *L, Instruction *IV,
353*9880d681SAndroid Build Coastguard Worker ScalarEvolution *SE, AliasAnalysis *AA,
354*9880d681SAndroid Build Coastguard Worker TargetLibraryInfo *TLI, DominatorTree *DT, LoopInfo *LI,
355*9880d681SAndroid Build Coastguard Worker bool PreserveLCSSA,
356*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int64_t> &IncrMap,
357*9880d681SAndroid Build Coastguard Worker Instruction *LoopCtrlIV)
358*9880d681SAndroid Build Coastguard Worker : Parent(Parent), L(L), SE(SE), AA(AA), TLI(TLI), DT(DT), LI(LI),
359*9880d681SAndroid Build Coastguard Worker PreserveLCSSA(PreserveLCSSA), IV(IV), IVToIncMap(IncrMap),
360*9880d681SAndroid Build Coastguard Worker LoopControlIV(LoopCtrlIV) {}
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker /// Stage 1: Find all the DAG roots for the induction variable.
363*9880d681SAndroid Build Coastguard Worker bool findRoots();
364*9880d681SAndroid Build Coastguard Worker /// Stage 2: Validate if the found roots are valid.
365*9880d681SAndroid Build Coastguard Worker bool validate(ReductionTracker &Reductions);
366*9880d681SAndroid Build Coastguard Worker /// Stage 3: Assuming validate() returned true, perform the
367*9880d681SAndroid Build Coastguard Worker /// replacement.
368*9880d681SAndroid Build Coastguard Worker /// @param IterCount The maximum iteration count of L.
369*9880d681SAndroid Build Coastguard Worker void replace(const SCEV *IterCount);
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker protected:
372*9880d681SAndroid Build Coastguard Worker typedef MapVector<Instruction*, BitVector> UsesTy;
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker bool findRootsRecursive(Instruction *IVU,
375*9880d681SAndroid Build Coastguard Worker SmallInstructionSet SubsumedInsts);
376*9880d681SAndroid Build Coastguard Worker bool findRootsBase(Instruction *IVU, SmallInstructionSet SubsumedInsts);
377*9880d681SAndroid Build Coastguard Worker bool collectPossibleRoots(Instruction *Base,
378*9880d681SAndroid Build Coastguard Worker std::map<int64_t,Instruction*> &Roots);
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker bool collectUsedInstructions(SmallInstructionSet &PossibleRedSet);
381*9880d681SAndroid Build Coastguard Worker void collectInLoopUserSet(const SmallInstructionVector &Roots,
382*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Exclude,
383*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Final,
384*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction *> &Users);
385*9880d681SAndroid Build Coastguard Worker void collectInLoopUserSet(Instruction *Root,
386*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Exclude,
387*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Final,
388*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction *> &Users);
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker UsesTy::iterator nextInstr(int Val, UsesTy &In,
391*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Exclude,
392*9880d681SAndroid Build Coastguard Worker UsesTy::iterator *StartI=nullptr);
393*9880d681SAndroid Build Coastguard Worker bool isBaseInst(Instruction *I);
394*9880d681SAndroid Build Coastguard Worker bool isRootInst(Instruction *I);
395*9880d681SAndroid Build Coastguard Worker bool instrDependsOn(Instruction *I,
396*9880d681SAndroid Build Coastguard Worker UsesTy::iterator Start,
397*9880d681SAndroid Build Coastguard Worker UsesTy::iterator End);
398*9880d681SAndroid Build Coastguard Worker void replaceIV(Instruction *Inst, Instruction *IV, const SCEV *IterCount);
399*9880d681SAndroid Build Coastguard Worker void updateNonLoopCtrlIncr();
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker LoopReroll *Parent;
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Worker // Members of Parent, replicated here for brevity.
404*9880d681SAndroid Build Coastguard Worker Loop *L;
405*9880d681SAndroid Build Coastguard Worker ScalarEvolution *SE;
406*9880d681SAndroid Build Coastguard Worker AliasAnalysis *AA;
407*9880d681SAndroid Build Coastguard Worker TargetLibraryInfo *TLI;
408*9880d681SAndroid Build Coastguard Worker DominatorTree *DT;
409*9880d681SAndroid Build Coastguard Worker LoopInfo *LI;
410*9880d681SAndroid Build Coastguard Worker bool PreserveLCSSA;
411*9880d681SAndroid Build Coastguard Worker
412*9880d681SAndroid Build Coastguard Worker // The loop induction variable.
413*9880d681SAndroid Build Coastguard Worker Instruction *IV;
414*9880d681SAndroid Build Coastguard Worker // Loop step amount.
415*9880d681SAndroid Build Coastguard Worker int64_t Inc;
416*9880d681SAndroid Build Coastguard Worker // Loop reroll count; if Inc == 1, this records the scaling applied
417*9880d681SAndroid Build Coastguard Worker // to the indvar: a[i*2+0] = ...; a[i*2+1] = ... ;
418*9880d681SAndroid Build Coastguard Worker // If Inc is not 1, Scale = Inc.
419*9880d681SAndroid Build Coastguard Worker uint64_t Scale;
420*9880d681SAndroid Build Coastguard Worker // The roots themselves.
421*9880d681SAndroid Build Coastguard Worker SmallVector<DAGRootSet,16> RootSets;
422*9880d681SAndroid Build Coastguard Worker // All increment instructions for IV.
423*9880d681SAndroid Build Coastguard Worker SmallInstructionVector LoopIncs;
424*9880d681SAndroid Build Coastguard Worker // Map of all instructions in the loop (in order) to the iterations
425*9880d681SAndroid Build Coastguard Worker // they are used in (or specially, IL_All for instructions
426*9880d681SAndroid Build Coastguard Worker // used in the loop increment mechanism).
427*9880d681SAndroid Build Coastguard Worker UsesTy Uses;
428*9880d681SAndroid Build Coastguard Worker // Map between induction variable and its increment
429*9880d681SAndroid Build Coastguard Worker DenseMap<Instruction *, int64_t> &IVToIncMap;
430*9880d681SAndroid Build Coastguard Worker Instruction *LoopControlIV;
431*9880d681SAndroid Build Coastguard Worker };
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker // Check if it is a compare-like instruction whose user is a branch
isCompareUsedByBranch(Instruction * I)434*9880d681SAndroid Build Coastguard Worker bool isCompareUsedByBranch(Instruction *I) {
435*9880d681SAndroid Build Coastguard Worker auto *TI = I->getParent()->getTerminator();
436*9880d681SAndroid Build Coastguard Worker if (!isa<BranchInst>(TI) || !isa<CmpInst>(I))
437*9880d681SAndroid Build Coastguard Worker return false;
438*9880d681SAndroid Build Coastguard Worker return I->hasOneUse() && TI->getOperand(0) == I;
439*9880d681SAndroid Build Coastguard Worker };
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker bool isLoopControlIV(Loop *L, Instruction *IV);
442*9880d681SAndroid Build Coastguard Worker void collectPossibleIVs(Loop *L, SmallInstructionVector &PossibleIVs);
443*9880d681SAndroid Build Coastguard Worker void collectPossibleReductions(Loop *L,
444*9880d681SAndroid Build Coastguard Worker ReductionTracker &Reductions);
445*9880d681SAndroid Build Coastguard Worker bool reroll(Instruction *IV, Loop *L, BasicBlock *Header, const SCEV *IterCount,
446*9880d681SAndroid Build Coastguard Worker ReductionTracker &Reductions);
447*9880d681SAndroid Build Coastguard Worker };
448*9880d681SAndroid Build Coastguard Worker }
449*9880d681SAndroid Build Coastguard Worker
450*9880d681SAndroid Build Coastguard Worker char LoopReroll::ID = 0;
451*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(LoopReroll, "loop-reroll", "Reroll loops", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)452*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LoopPass)
453*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
454*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(LoopReroll, "loop-reroll", "Reroll loops", false, false)
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker Pass *llvm::createLoopRerollPass() {
457*9880d681SAndroid Build Coastguard Worker return new LoopReroll;
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker // Returns true if the provided instruction is used outside the given loop.
461*9880d681SAndroid Build Coastguard Worker // This operates like Instruction::isUsedOutsideOfBlock, but considers PHIs in
462*9880d681SAndroid Build Coastguard Worker // non-loop blocks to be outside the loop.
hasUsesOutsideLoop(Instruction * I,Loop * L)463*9880d681SAndroid Build Coastguard Worker static bool hasUsesOutsideLoop(Instruction *I, Loop *L) {
464*9880d681SAndroid Build Coastguard Worker for (User *U : I->users()) {
465*9880d681SAndroid Build Coastguard Worker if (!L->contains(cast<Instruction>(U)))
466*9880d681SAndroid Build Coastguard Worker return true;
467*9880d681SAndroid Build Coastguard Worker }
468*9880d681SAndroid Build Coastguard Worker return false;
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker
getIncrmentFactorSCEV(ScalarEvolution * SE,const SCEV * SCEVExpr,Instruction & IV)471*9880d681SAndroid Build Coastguard Worker static const SCEVConstant *getIncrmentFactorSCEV(ScalarEvolution *SE,
472*9880d681SAndroid Build Coastguard Worker const SCEV *SCEVExpr,
473*9880d681SAndroid Build Coastguard Worker Instruction &IV) {
474*9880d681SAndroid Build Coastguard Worker const SCEVMulExpr *MulSCEV = dyn_cast<SCEVMulExpr>(SCEVExpr);
475*9880d681SAndroid Build Coastguard Worker
476*9880d681SAndroid Build Coastguard Worker // If StepRecurrence of a SCEVExpr is a constant (c1 * c2, c2 = sizeof(ptr)),
477*9880d681SAndroid Build Coastguard Worker // Return c1.
478*9880d681SAndroid Build Coastguard Worker if (!MulSCEV && IV.getType()->isPointerTy())
479*9880d681SAndroid Build Coastguard Worker if (const SCEVConstant *IncSCEV = dyn_cast<SCEVConstant>(SCEVExpr)) {
480*9880d681SAndroid Build Coastguard Worker const PointerType *PTy = cast<PointerType>(IV.getType());
481*9880d681SAndroid Build Coastguard Worker Type *ElTy = PTy->getElementType();
482*9880d681SAndroid Build Coastguard Worker const SCEV *SizeOfExpr =
483*9880d681SAndroid Build Coastguard Worker SE->getSizeOfExpr(SE->getEffectiveSCEVType(IV.getType()), ElTy);
484*9880d681SAndroid Build Coastguard Worker if (IncSCEV->getValue()->getValue().isNegative()) {
485*9880d681SAndroid Build Coastguard Worker const SCEV *NewSCEV =
486*9880d681SAndroid Build Coastguard Worker SE->getUDivExpr(SE->getNegativeSCEV(SCEVExpr), SizeOfExpr);
487*9880d681SAndroid Build Coastguard Worker return dyn_cast<SCEVConstant>(SE->getNegativeSCEV(NewSCEV));
488*9880d681SAndroid Build Coastguard Worker } else {
489*9880d681SAndroid Build Coastguard Worker return dyn_cast<SCEVConstant>(SE->getUDivExpr(SCEVExpr, SizeOfExpr));
490*9880d681SAndroid Build Coastguard Worker }
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Worker if (!MulSCEV)
494*9880d681SAndroid Build Coastguard Worker return nullptr;
495*9880d681SAndroid Build Coastguard Worker
496*9880d681SAndroid Build Coastguard Worker // If StepRecurrence of a SCEVExpr is a c * sizeof(x), where c is constant,
497*9880d681SAndroid Build Coastguard Worker // Return c.
498*9880d681SAndroid Build Coastguard Worker const SCEVConstant *CIncSCEV = nullptr;
499*9880d681SAndroid Build Coastguard Worker for (const SCEV *Operand : MulSCEV->operands()) {
500*9880d681SAndroid Build Coastguard Worker if (const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Operand)) {
501*9880d681SAndroid Build Coastguard Worker CIncSCEV = Constant;
502*9880d681SAndroid Build Coastguard Worker } else if (const SCEVUnknown *Unknown = dyn_cast<SCEVUnknown>(Operand)) {
503*9880d681SAndroid Build Coastguard Worker Type *AllocTy;
504*9880d681SAndroid Build Coastguard Worker if (!Unknown->isSizeOf(AllocTy))
505*9880d681SAndroid Build Coastguard Worker break;
506*9880d681SAndroid Build Coastguard Worker } else {
507*9880d681SAndroid Build Coastguard Worker return nullptr;
508*9880d681SAndroid Build Coastguard Worker }
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker return CIncSCEV;
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker // Check if an IV is only used to control the loop. There are two cases:
514*9880d681SAndroid Build Coastguard Worker // 1. It only has one use which is loop increment, and the increment is only
515*9880d681SAndroid Build Coastguard Worker // used by comparison and the PHI (could has sext with nsw in between), and the
516*9880d681SAndroid Build Coastguard Worker // comparison is only used by branch.
517*9880d681SAndroid Build Coastguard Worker // 2. It is used by loop increment and the comparison, the loop increment is
518*9880d681SAndroid Build Coastguard Worker // only used by the PHI, and the comparison is used only by the branch.
isLoopControlIV(Loop * L,Instruction * IV)519*9880d681SAndroid Build Coastguard Worker bool LoopReroll::isLoopControlIV(Loop *L, Instruction *IV) {
520*9880d681SAndroid Build Coastguard Worker unsigned IVUses = IV->getNumUses();
521*9880d681SAndroid Build Coastguard Worker if (IVUses != 2 && IVUses != 1)
522*9880d681SAndroid Build Coastguard Worker return false;
523*9880d681SAndroid Build Coastguard Worker
524*9880d681SAndroid Build Coastguard Worker for (auto *User : IV->users()) {
525*9880d681SAndroid Build Coastguard Worker int32_t IncOrCmpUses = User->getNumUses();
526*9880d681SAndroid Build Coastguard Worker bool IsCompInst = isCompareUsedByBranch(cast<Instruction>(User));
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker // User can only have one or two uses.
529*9880d681SAndroid Build Coastguard Worker if (IncOrCmpUses != 2 && IncOrCmpUses != 1)
530*9880d681SAndroid Build Coastguard Worker return false;
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker // Case 1
533*9880d681SAndroid Build Coastguard Worker if (IVUses == 1) {
534*9880d681SAndroid Build Coastguard Worker // The only user must be the loop increment.
535*9880d681SAndroid Build Coastguard Worker // The loop increment must have two uses.
536*9880d681SAndroid Build Coastguard Worker if (IsCompInst || IncOrCmpUses != 2)
537*9880d681SAndroid Build Coastguard Worker return false;
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker // Case 2
541*9880d681SAndroid Build Coastguard Worker if (IVUses == 2 && IncOrCmpUses != 1)
542*9880d681SAndroid Build Coastguard Worker return false;
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker // The users of the IV must be a binary operation or a comparison
545*9880d681SAndroid Build Coastguard Worker if (auto *BO = dyn_cast<BinaryOperator>(User)) {
546*9880d681SAndroid Build Coastguard Worker if (BO->getOpcode() == Instruction::Add) {
547*9880d681SAndroid Build Coastguard Worker // Loop Increment
548*9880d681SAndroid Build Coastguard Worker // User of Loop Increment should be either PHI or CMP
549*9880d681SAndroid Build Coastguard Worker for (auto *UU : User->users()) {
550*9880d681SAndroid Build Coastguard Worker if (PHINode *PN = dyn_cast<PHINode>(UU)) {
551*9880d681SAndroid Build Coastguard Worker if (PN != IV)
552*9880d681SAndroid Build Coastguard Worker return false;
553*9880d681SAndroid Build Coastguard Worker }
554*9880d681SAndroid Build Coastguard Worker // Must be a CMP or an ext (of a value with nsw) then CMP
555*9880d681SAndroid Build Coastguard Worker else {
556*9880d681SAndroid Build Coastguard Worker Instruction *UUser = dyn_cast<Instruction>(UU);
557*9880d681SAndroid Build Coastguard Worker // Skip SExt if we are extending an nsw value
558*9880d681SAndroid Build Coastguard Worker // TODO: Allow ZExt too
559*9880d681SAndroid Build Coastguard Worker if (BO->hasNoSignedWrap() && UUser && UUser->getNumUses() == 1 &&
560*9880d681SAndroid Build Coastguard Worker isa<SExtInst>(UUser))
561*9880d681SAndroid Build Coastguard Worker UUser = dyn_cast<Instruction>(*(UUser->user_begin()));
562*9880d681SAndroid Build Coastguard Worker if (!isCompareUsedByBranch(UUser))
563*9880d681SAndroid Build Coastguard Worker return false;
564*9880d681SAndroid Build Coastguard Worker }
565*9880d681SAndroid Build Coastguard Worker }
566*9880d681SAndroid Build Coastguard Worker } else
567*9880d681SAndroid Build Coastguard Worker return false;
568*9880d681SAndroid Build Coastguard Worker // Compare : can only have one use, and must be branch
569*9880d681SAndroid Build Coastguard Worker } else if (!IsCompInst)
570*9880d681SAndroid Build Coastguard Worker return false;
571*9880d681SAndroid Build Coastguard Worker }
572*9880d681SAndroid Build Coastguard Worker return true;
573*9880d681SAndroid Build Coastguard Worker }
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker // Collect the list of loop induction variables with respect to which it might
576*9880d681SAndroid Build Coastguard Worker // be possible to reroll the loop.
collectPossibleIVs(Loop * L,SmallInstructionVector & PossibleIVs)577*9880d681SAndroid Build Coastguard Worker void LoopReroll::collectPossibleIVs(Loop *L,
578*9880d681SAndroid Build Coastguard Worker SmallInstructionVector &PossibleIVs) {
579*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = L->getHeader();
580*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator I = Header->begin(),
581*9880d681SAndroid Build Coastguard Worker IE = Header->getFirstInsertionPt(); I != IE; ++I) {
582*9880d681SAndroid Build Coastguard Worker if (!isa<PHINode>(I))
583*9880d681SAndroid Build Coastguard Worker continue;
584*9880d681SAndroid Build Coastguard Worker if (!I->getType()->isIntegerTy() && !I->getType()->isPointerTy())
585*9880d681SAndroid Build Coastguard Worker continue;
586*9880d681SAndroid Build Coastguard Worker
587*9880d681SAndroid Build Coastguard Worker if (const SCEVAddRecExpr *PHISCEV =
588*9880d681SAndroid Build Coastguard Worker dyn_cast<SCEVAddRecExpr>(SE->getSCEV(&*I))) {
589*9880d681SAndroid Build Coastguard Worker if (PHISCEV->getLoop() != L)
590*9880d681SAndroid Build Coastguard Worker continue;
591*9880d681SAndroid Build Coastguard Worker if (!PHISCEV->isAffine())
592*9880d681SAndroid Build Coastguard Worker continue;
593*9880d681SAndroid Build Coastguard Worker const SCEVConstant *IncSCEV = nullptr;
594*9880d681SAndroid Build Coastguard Worker if (I->getType()->isPointerTy())
595*9880d681SAndroid Build Coastguard Worker IncSCEV =
596*9880d681SAndroid Build Coastguard Worker getIncrmentFactorSCEV(SE, PHISCEV->getStepRecurrence(*SE), *I);
597*9880d681SAndroid Build Coastguard Worker else
598*9880d681SAndroid Build Coastguard Worker IncSCEV = dyn_cast<SCEVConstant>(PHISCEV->getStepRecurrence(*SE));
599*9880d681SAndroid Build Coastguard Worker if (IncSCEV) {
600*9880d681SAndroid Build Coastguard Worker const APInt &AInt = IncSCEV->getValue()->getValue().abs();
601*9880d681SAndroid Build Coastguard Worker if (IncSCEV->getValue()->isZero() || AInt.uge(MaxInc))
602*9880d681SAndroid Build Coastguard Worker continue;
603*9880d681SAndroid Build Coastguard Worker IVToIncMap[&*I] = IncSCEV->getValue()->getSExtValue();
604*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Possible IV: " << *I << " = " << *PHISCEV
605*9880d681SAndroid Build Coastguard Worker << "\n");
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker if (isLoopControlIV(L, &*I)) {
608*9880d681SAndroid Build Coastguard Worker assert(!LoopControlIV && "Found two loop control only IV");
609*9880d681SAndroid Build Coastguard Worker LoopControlIV = &(*I);
610*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Possible loop control only IV: " << *I << " = "
611*9880d681SAndroid Build Coastguard Worker << *PHISCEV << "\n");
612*9880d681SAndroid Build Coastguard Worker } else
613*9880d681SAndroid Build Coastguard Worker PossibleIVs.push_back(&*I);
614*9880d681SAndroid Build Coastguard Worker }
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker }
617*9880d681SAndroid Build Coastguard Worker }
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker // Add the remainder of the reduction-variable chain to the instruction vector
620*9880d681SAndroid Build Coastguard Worker // (the initial PHINode has already been added). If successful, the object is
621*9880d681SAndroid Build Coastguard Worker // marked as valid.
add(Loop * L)622*9880d681SAndroid Build Coastguard Worker void LoopReroll::SimpleLoopReduction::add(Loop *L) {
623*9880d681SAndroid Build Coastguard Worker assert(!Valid && "Cannot add to an already-valid chain");
624*9880d681SAndroid Build Coastguard Worker
625*9880d681SAndroid Build Coastguard Worker // The reduction variable must be a chain of single-use instructions
626*9880d681SAndroid Build Coastguard Worker // (including the PHI), except for the last value (which is used by the PHI
627*9880d681SAndroid Build Coastguard Worker // and also outside the loop).
628*9880d681SAndroid Build Coastguard Worker Instruction *C = Instructions.front();
629*9880d681SAndroid Build Coastguard Worker if (C->user_empty())
630*9880d681SAndroid Build Coastguard Worker return;
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Worker do {
633*9880d681SAndroid Build Coastguard Worker C = cast<Instruction>(*C->user_begin());
634*9880d681SAndroid Build Coastguard Worker if (C->hasOneUse()) {
635*9880d681SAndroid Build Coastguard Worker if (!C->isBinaryOp())
636*9880d681SAndroid Build Coastguard Worker return;
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker if (!(isa<PHINode>(Instructions.back()) ||
639*9880d681SAndroid Build Coastguard Worker C->isSameOperationAs(Instructions.back())))
640*9880d681SAndroid Build Coastguard Worker return;
641*9880d681SAndroid Build Coastguard Worker
642*9880d681SAndroid Build Coastguard Worker Instructions.push_back(C);
643*9880d681SAndroid Build Coastguard Worker }
644*9880d681SAndroid Build Coastguard Worker } while (C->hasOneUse());
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker if (Instructions.size() < 2 ||
647*9880d681SAndroid Build Coastguard Worker !C->isSameOperationAs(Instructions.back()) ||
648*9880d681SAndroid Build Coastguard Worker C->use_empty())
649*9880d681SAndroid Build Coastguard Worker return;
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Worker // C is now the (potential) last instruction in the reduction chain.
652*9880d681SAndroid Build Coastguard Worker for (User *U : C->users()) {
653*9880d681SAndroid Build Coastguard Worker // The only in-loop user can be the initial PHI.
654*9880d681SAndroid Build Coastguard Worker if (L->contains(cast<Instruction>(U)))
655*9880d681SAndroid Build Coastguard Worker if (cast<Instruction>(U) != Instructions.front())
656*9880d681SAndroid Build Coastguard Worker return;
657*9880d681SAndroid Build Coastguard Worker }
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker Instructions.push_back(C);
660*9880d681SAndroid Build Coastguard Worker Valid = true;
661*9880d681SAndroid Build Coastguard Worker }
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker // Collect the vector of possible reduction variables.
collectPossibleReductions(Loop * L,ReductionTracker & Reductions)664*9880d681SAndroid Build Coastguard Worker void LoopReroll::collectPossibleReductions(Loop *L,
665*9880d681SAndroid Build Coastguard Worker ReductionTracker &Reductions) {
666*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = L->getHeader();
667*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator I = Header->begin(),
668*9880d681SAndroid Build Coastguard Worker IE = Header->getFirstInsertionPt(); I != IE; ++I) {
669*9880d681SAndroid Build Coastguard Worker if (!isa<PHINode>(I))
670*9880d681SAndroid Build Coastguard Worker continue;
671*9880d681SAndroid Build Coastguard Worker if (!I->getType()->isSingleValueType())
672*9880d681SAndroid Build Coastguard Worker continue;
673*9880d681SAndroid Build Coastguard Worker
674*9880d681SAndroid Build Coastguard Worker SimpleLoopReduction SLR(&*I, L);
675*9880d681SAndroid Build Coastguard Worker if (!SLR.valid())
676*9880d681SAndroid Build Coastguard Worker continue;
677*9880d681SAndroid Build Coastguard Worker
678*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Possible reduction: " << *I << " (with " <<
679*9880d681SAndroid Build Coastguard Worker SLR.size() << " chained instructions)\n");
680*9880d681SAndroid Build Coastguard Worker Reductions.addSLR(SLR);
681*9880d681SAndroid Build Coastguard Worker }
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker // Collect the set of all users of the provided root instruction. This set of
685*9880d681SAndroid Build Coastguard Worker // users contains not only the direct users of the root instruction, but also
686*9880d681SAndroid Build Coastguard Worker // all users of those users, and so on. There are two exceptions:
687*9880d681SAndroid Build Coastguard Worker //
688*9880d681SAndroid Build Coastguard Worker // 1. Instructions in the set of excluded instructions are never added to the
689*9880d681SAndroid Build Coastguard Worker // use set (even if they are users). This is used, for example, to exclude
690*9880d681SAndroid Build Coastguard Worker // including root increments in the use set of the primary IV.
691*9880d681SAndroid Build Coastguard Worker //
692*9880d681SAndroid Build Coastguard Worker // 2. Instructions in the set of final instructions are added to the use set
693*9880d681SAndroid Build Coastguard Worker // if they are users, but their users are not added. This is used, for
694*9880d681SAndroid Build Coastguard Worker // example, to prevent a reduction update from forcing all later reduction
695*9880d681SAndroid Build Coastguard Worker // updates into the use set.
collectInLoopUserSet(Instruction * Root,const SmallInstructionSet & Exclude,const SmallInstructionSet & Final,DenseSet<Instruction * > & Users)696*9880d681SAndroid Build Coastguard Worker void LoopReroll::DAGRootTracker::collectInLoopUserSet(
697*9880d681SAndroid Build Coastguard Worker Instruction *Root, const SmallInstructionSet &Exclude,
698*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Final,
699*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction *> &Users) {
700*9880d681SAndroid Build Coastguard Worker SmallInstructionVector Queue(1, Root);
701*9880d681SAndroid Build Coastguard Worker while (!Queue.empty()) {
702*9880d681SAndroid Build Coastguard Worker Instruction *I = Queue.pop_back_val();
703*9880d681SAndroid Build Coastguard Worker if (!Users.insert(I).second)
704*9880d681SAndroid Build Coastguard Worker continue;
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker if (!Final.count(I))
707*9880d681SAndroid Build Coastguard Worker for (Use &U : I->uses()) {
708*9880d681SAndroid Build Coastguard Worker Instruction *User = cast<Instruction>(U.getUser());
709*9880d681SAndroid Build Coastguard Worker if (PHINode *PN = dyn_cast<PHINode>(User)) {
710*9880d681SAndroid Build Coastguard Worker // Ignore "wrap-around" uses to PHIs of this loop's header.
711*9880d681SAndroid Build Coastguard Worker if (PN->getIncomingBlock(U) == L->getHeader())
712*9880d681SAndroid Build Coastguard Worker continue;
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker
715*9880d681SAndroid Build Coastguard Worker if (L->contains(User) && !Exclude.count(User)) {
716*9880d681SAndroid Build Coastguard Worker Queue.push_back(User);
717*9880d681SAndroid Build Coastguard Worker }
718*9880d681SAndroid Build Coastguard Worker }
719*9880d681SAndroid Build Coastguard Worker
720*9880d681SAndroid Build Coastguard Worker // We also want to collect single-user "feeder" values.
721*9880d681SAndroid Build Coastguard Worker for (User::op_iterator OI = I->op_begin(),
722*9880d681SAndroid Build Coastguard Worker OIE = I->op_end(); OI != OIE; ++OI) {
723*9880d681SAndroid Build Coastguard Worker if (Instruction *Op = dyn_cast<Instruction>(*OI))
724*9880d681SAndroid Build Coastguard Worker if (Op->hasOneUse() && L->contains(Op) && !Exclude.count(Op) &&
725*9880d681SAndroid Build Coastguard Worker !Final.count(Op))
726*9880d681SAndroid Build Coastguard Worker Queue.push_back(Op);
727*9880d681SAndroid Build Coastguard Worker }
728*9880d681SAndroid Build Coastguard Worker }
729*9880d681SAndroid Build Coastguard Worker }
730*9880d681SAndroid Build Coastguard Worker
731*9880d681SAndroid Build Coastguard Worker // Collect all of the users of all of the provided root instructions (combined
732*9880d681SAndroid Build Coastguard Worker // into a single set).
collectInLoopUserSet(const SmallInstructionVector & Roots,const SmallInstructionSet & Exclude,const SmallInstructionSet & Final,DenseSet<Instruction * > & Users)733*9880d681SAndroid Build Coastguard Worker void LoopReroll::DAGRootTracker::collectInLoopUserSet(
734*9880d681SAndroid Build Coastguard Worker const SmallInstructionVector &Roots,
735*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Exclude,
736*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Final,
737*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction *> &Users) {
738*9880d681SAndroid Build Coastguard Worker for (Instruction *Root : Roots)
739*9880d681SAndroid Build Coastguard Worker collectInLoopUserSet(Root, Exclude, Final, Users);
740*9880d681SAndroid Build Coastguard Worker }
741*9880d681SAndroid Build Coastguard Worker
isSimpleLoadStore(Instruction * I)742*9880d681SAndroid Build Coastguard Worker static bool isSimpleLoadStore(Instruction *I) {
743*9880d681SAndroid Build Coastguard Worker if (LoadInst *LI = dyn_cast<LoadInst>(I))
744*9880d681SAndroid Build Coastguard Worker return LI->isSimple();
745*9880d681SAndroid Build Coastguard Worker if (StoreInst *SI = dyn_cast<StoreInst>(I))
746*9880d681SAndroid Build Coastguard Worker return SI->isSimple();
747*9880d681SAndroid Build Coastguard Worker if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I))
748*9880d681SAndroid Build Coastguard Worker return !MI->isVolatile();
749*9880d681SAndroid Build Coastguard Worker return false;
750*9880d681SAndroid Build Coastguard Worker }
751*9880d681SAndroid Build Coastguard Worker
752*9880d681SAndroid Build Coastguard Worker /// Return true if IVU is a "simple" arithmetic operation.
753*9880d681SAndroid Build Coastguard Worker /// This is used for narrowing the search space for DAGRoots; only arithmetic
754*9880d681SAndroid Build Coastguard Worker /// and GEPs can be part of a DAGRoot.
isSimpleArithmeticOp(User * IVU)755*9880d681SAndroid Build Coastguard Worker static bool isSimpleArithmeticOp(User *IVU) {
756*9880d681SAndroid Build Coastguard Worker if (Instruction *I = dyn_cast<Instruction>(IVU)) {
757*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
758*9880d681SAndroid Build Coastguard Worker default: return false;
759*9880d681SAndroid Build Coastguard Worker case Instruction::Add:
760*9880d681SAndroid Build Coastguard Worker case Instruction::Sub:
761*9880d681SAndroid Build Coastguard Worker case Instruction::Mul:
762*9880d681SAndroid Build Coastguard Worker case Instruction::Shl:
763*9880d681SAndroid Build Coastguard Worker case Instruction::AShr:
764*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
765*9880d681SAndroid Build Coastguard Worker case Instruction::GetElementPtr:
766*9880d681SAndroid Build Coastguard Worker case Instruction::Trunc:
767*9880d681SAndroid Build Coastguard Worker case Instruction::ZExt:
768*9880d681SAndroid Build Coastguard Worker case Instruction::SExt:
769*9880d681SAndroid Build Coastguard Worker return true;
770*9880d681SAndroid Build Coastguard Worker }
771*9880d681SAndroid Build Coastguard Worker }
772*9880d681SAndroid Build Coastguard Worker return false;
773*9880d681SAndroid Build Coastguard Worker }
774*9880d681SAndroid Build Coastguard Worker
isLoopIncrement(User * U,Instruction * IV)775*9880d681SAndroid Build Coastguard Worker static bool isLoopIncrement(User *U, Instruction *IV) {
776*9880d681SAndroid Build Coastguard Worker BinaryOperator *BO = dyn_cast<BinaryOperator>(U);
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Worker if ((BO && BO->getOpcode() != Instruction::Add) ||
779*9880d681SAndroid Build Coastguard Worker (!BO && !isa<GetElementPtrInst>(U)))
780*9880d681SAndroid Build Coastguard Worker return false;
781*9880d681SAndroid Build Coastguard Worker
782*9880d681SAndroid Build Coastguard Worker for (auto *UU : U->users()) {
783*9880d681SAndroid Build Coastguard Worker PHINode *PN = dyn_cast<PHINode>(UU);
784*9880d681SAndroid Build Coastguard Worker if (PN && PN == IV)
785*9880d681SAndroid Build Coastguard Worker return true;
786*9880d681SAndroid Build Coastguard Worker }
787*9880d681SAndroid Build Coastguard Worker return false;
788*9880d681SAndroid Build Coastguard Worker }
789*9880d681SAndroid Build Coastguard Worker
790*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::
collectPossibleRoots(Instruction * Base,std::map<int64_t,Instruction * > & Roots)791*9880d681SAndroid Build Coastguard Worker collectPossibleRoots(Instruction *Base, std::map<int64_t,Instruction*> &Roots) {
792*9880d681SAndroid Build Coastguard Worker SmallInstructionVector BaseUsers;
793*9880d681SAndroid Build Coastguard Worker
794*9880d681SAndroid Build Coastguard Worker for (auto *I : Base->users()) {
795*9880d681SAndroid Build Coastguard Worker ConstantInt *CI = nullptr;
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Worker if (isLoopIncrement(I, IV)) {
798*9880d681SAndroid Build Coastguard Worker LoopIncs.push_back(cast<Instruction>(I));
799*9880d681SAndroid Build Coastguard Worker continue;
800*9880d681SAndroid Build Coastguard Worker }
801*9880d681SAndroid Build Coastguard Worker
802*9880d681SAndroid Build Coastguard Worker // The root nodes must be either GEPs, ORs or ADDs.
803*9880d681SAndroid Build Coastguard Worker if (auto *BO = dyn_cast<BinaryOperator>(I)) {
804*9880d681SAndroid Build Coastguard Worker if (BO->getOpcode() == Instruction::Add ||
805*9880d681SAndroid Build Coastguard Worker BO->getOpcode() == Instruction::Or)
806*9880d681SAndroid Build Coastguard Worker CI = dyn_cast<ConstantInt>(BO->getOperand(1));
807*9880d681SAndroid Build Coastguard Worker } else if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
808*9880d681SAndroid Build Coastguard Worker Value *LastOperand = GEP->getOperand(GEP->getNumOperands()-1);
809*9880d681SAndroid Build Coastguard Worker CI = dyn_cast<ConstantInt>(LastOperand);
810*9880d681SAndroid Build Coastguard Worker }
811*9880d681SAndroid Build Coastguard Worker
812*9880d681SAndroid Build Coastguard Worker if (!CI) {
813*9880d681SAndroid Build Coastguard Worker if (Instruction *II = dyn_cast<Instruction>(I)) {
814*9880d681SAndroid Build Coastguard Worker BaseUsers.push_back(II);
815*9880d681SAndroid Build Coastguard Worker continue;
816*9880d681SAndroid Build Coastguard Worker } else {
817*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting due to non-instruction: " << *I << "\n");
818*9880d681SAndroid Build Coastguard Worker return false;
819*9880d681SAndroid Build Coastguard Worker }
820*9880d681SAndroid Build Coastguard Worker }
821*9880d681SAndroid Build Coastguard Worker
822*9880d681SAndroid Build Coastguard Worker int64_t V = std::abs(CI->getValue().getSExtValue());
823*9880d681SAndroid Build Coastguard Worker if (Roots.find(V) != Roots.end())
824*9880d681SAndroid Build Coastguard Worker // No duplicates, please.
825*9880d681SAndroid Build Coastguard Worker return false;
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Worker Roots[V] = cast<Instruction>(I);
828*9880d681SAndroid Build Coastguard Worker }
829*9880d681SAndroid Build Coastguard Worker
830*9880d681SAndroid Build Coastguard Worker if (Roots.empty())
831*9880d681SAndroid Build Coastguard Worker return false;
832*9880d681SAndroid Build Coastguard Worker
833*9880d681SAndroid Build Coastguard Worker // If we found non-loop-inc, non-root users of Base, assume they are
834*9880d681SAndroid Build Coastguard Worker // for the zeroth root index. This is because "add %a, 0" gets optimized
835*9880d681SAndroid Build Coastguard Worker // away.
836*9880d681SAndroid Build Coastguard Worker if (BaseUsers.size()) {
837*9880d681SAndroid Build Coastguard Worker if (Roots.find(0) != Roots.end()) {
838*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Multiple roots found for base - aborting!\n");
839*9880d681SAndroid Build Coastguard Worker return false;
840*9880d681SAndroid Build Coastguard Worker }
841*9880d681SAndroid Build Coastguard Worker Roots[0] = Base;
842*9880d681SAndroid Build Coastguard Worker }
843*9880d681SAndroid Build Coastguard Worker
844*9880d681SAndroid Build Coastguard Worker // Calculate the number of users of the base, or lowest indexed, iteration.
845*9880d681SAndroid Build Coastguard Worker unsigned NumBaseUses = BaseUsers.size();
846*9880d681SAndroid Build Coastguard Worker if (NumBaseUses == 0)
847*9880d681SAndroid Build Coastguard Worker NumBaseUses = Roots.begin()->second->getNumUses();
848*9880d681SAndroid Build Coastguard Worker
849*9880d681SAndroid Build Coastguard Worker // Check that every node has the same number of users.
850*9880d681SAndroid Build Coastguard Worker for (auto &KV : Roots) {
851*9880d681SAndroid Build Coastguard Worker if (KV.first == 0)
852*9880d681SAndroid Build Coastguard Worker continue;
853*9880d681SAndroid Build Coastguard Worker if (KV.second->getNumUses() != NumBaseUses) {
854*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting - Root and Base #users not the same: "
855*9880d681SAndroid Build Coastguard Worker << "#Base=" << NumBaseUses << ", #Root=" <<
856*9880d681SAndroid Build Coastguard Worker KV.second->getNumUses() << "\n");
857*9880d681SAndroid Build Coastguard Worker return false;
858*9880d681SAndroid Build Coastguard Worker }
859*9880d681SAndroid Build Coastguard Worker }
860*9880d681SAndroid Build Coastguard Worker
861*9880d681SAndroid Build Coastguard Worker return true;
862*9880d681SAndroid Build Coastguard Worker }
863*9880d681SAndroid Build Coastguard Worker
864*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::
findRootsRecursive(Instruction * I,SmallInstructionSet SubsumedInsts)865*9880d681SAndroid Build Coastguard Worker findRootsRecursive(Instruction *I, SmallInstructionSet SubsumedInsts) {
866*9880d681SAndroid Build Coastguard Worker // Does the user look like it could be part of a root set?
867*9880d681SAndroid Build Coastguard Worker // All its users must be simple arithmetic ops.
868*9880d681SAndroid Build Coastguard Worker if (I->getNumUses() > IL_MaxRerollIterations)
869*9880d681SAndroid Build Coastguard Worker return false;
870*9880d681SAndroid Build Coastguard Worker
871*9880d681SAndroid Build Coastguard Worker if ((I->getOpcode() == Instruction::Mul ||
872*9880d681SAndroid Build Coastguard Worker I->getOpcode() == Instruction::PHI) &&
873*9880d681SAndroid Build Coastguard Worker I != IV &&
874*9880d681SAndroid Build Coastguard Worker findRootsBase(I, SubsumedInsts))
875*9880d681SAndroid Build Coastguard Worker return true;
876*9880d681SAndroid Build Coastguard Worker
877*9880d681SAndroid Build Coastguard Worker SubsumedInsts.insert(I);
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Worker for (User *V : I->users()) {
880*9880d681SAndroid Build Coastguard Worker Instruction *I = dyn_cast<Instruction>(V);
881*9880d681SAndroid Build Coastguard Worker if (std::find(LoopIncs.begin(), LoopIncs.end(), I) != LoopIncs.end())
882*9880d681SAndroid Build Coastguard Worker continue;
883*9880d681SAndroid Build Coastguard Worker
884*9880d681SAndroid Build Coastguard Worker if (!I || !isSimpleArithmeticOp(I) ||
885*9880d681SAndroid Build Coastguard Worker !findRootsRecursive(I, SubsumedInsts))
886*9880d681SAndroid Build Coastguard Worker return false;
887*9880d681SAndroid Build Coastguard Worker }
888*9880d681SAndroid Build Coastguard Worker return true;
889*9880d681SAndroid Build Coastguard Worker }
890*9880d681SAndroid Build Coastguard Worker
891*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::
findRootsBase(Instruction * IVU,SmallInstructionSet SubsumedInsts)892*9880d681SAndroid Build Coastguard Worker findRootsBase(Instruction *IVU, SmallInstructionSet SubsumedInsts) {
893*9880d681SAndroid Build Coastguard Worker
894*9880d681SAndroid Build Coastguard Worker // The base instruction needs to be a multiply so
895*9880d681SAndroid Build Coastguard Worker // that we can erase it.
896*9880d681SAndroid Build Coastguard Worker if (IVU->getOpcode() != Instruction::Mul &&
897*9880d681SAndroid Build Coastguard Worker IVU->getOpcode() != Instruction::PHI)
898*9880d681SAndroid Build Coastguard Worker return false;
899*9880d681SAndroid Build Coastguard Worker
900*9880d681SAndroid Build Coastguard Worker std::map<int64_t, Instruction*> V;
901*9880d681SAndroid Build Coastguard Worker if (!collectPossibleRoots(IVU, V))
902*9880d681SAndroid Build Coastguard Worker return false;
903*9880d681SAndroid Build Coastguard Worker
904*9880d681SAndroid Build Coastguard Worker // If we didn't get a root for index zero, then IVU must be
905*9880d681SAndroid Build Coastguard Worker // subsumed.
906*9880d681SAndroid Build Coastguard Worker if (V.find(0) == V.end())
907*9880d681SAndroid Build Coastguard Worker SubsumedInsts.insert(IVU);
908*9880d681SAndroid Build Coastguard Worker
909*9880d681SAndroid Build Coastguard Worker // Partition the vector into monotonically increasing indexes.
910*9880d681SAndroid Build Coastguard Worker DAGRootSet DRS;
911*9880d681SAndroid Build Coastguard Worker DRS.BaseInst = nullptr;
912*9880d681SAndroid Build Coastguard Worker
913*9880d681SAndroid Build Coastguard Worker for (auto &KV : V) {
914*9880d681SAndroid Build Coastguard Worker if (!DRS.BaseInst) {
915*9880d681SAndroid Build Coastguard Worker DRS.BaseInst = KV.second;
916*9880d681SAndroid Build Coastguard Worker DRS.SubsumedInsts = SubsumedInsts;
917*9880d681SAndroid Build Coastguard Worker } else if (DRS.Roots.empty()) {
918*9880d681SAndroid Build Coastguard Worker DRS.Roots.push_back(KV.second);
919*9880d681SAndroid Build Coastguard Worker } else if (V.find(KV.first - 1) != V.end()) {
920*9880d681SAndroid Build Coastguard Worker DRS.Roots.push_back(KV.second);
921*9880d681SAndroid Build Coastguard Worker } else {
922*9880d681SAndroid Build Coastguard Worker // Linear sequence terminated.
923*9880d681SAndroid Build Coastguard Worker RootSets.push_back(DRS);
924*9880d681SAndroid Build Coastguard Worker DRS.BaseInst = KV.second;
925*9880d681SAndroid Build Coastguard Worker DRS.SubsumedInsts = SubsumedInsts;
926*9880d681SAndroid Build Coastguard Worker DRS.Roots.clear();
927*9880d681SAndroid Build Coastguard Worker }
928*9880d681SAndroid Build Coastguard Worker }
929*9880d681SAndroid Build Coastguard Worker RootSets.push_back(DRS);
930*9880d681SAndroid Build Coastguard Worker
931*9880d681SAndroid Build Coastguard Worker return true;
932*9880d681SAndroid Build Coastguard Worker }
933*9880d681SAndroid Build Coastguard Worker
findRoots()934*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::findRoots() {
935*9880d681SAndroid Build Coastguard Worker Inc = IVToIncMap[IV];
936*9880d681SAndroid Build Coastguard Worker
937*9880d681SAndroid Build Coastguard Worker assert(RootSets.empty() && "Unclean state!");
938*9880d681SAndroid Build Coastguard Worker if (std::abs(Inc) == 1) {
939*9880d681SAndroid Build Coastguard Worker for (auto *IVU : IV->users()) {
940*9880d681SAndroid Build Coastguard Worker if (isLoopIncrement(IVU, IV))
941*9880d681SAndroid Build Coastguard Worker LoopIncs.push_back(cast<Instruction>(IVU));
942*9880d681SAndroid Build Coastguard Worker }
943*9880d681SAndroid Build Coastguard Worker if (!findRootsRecursive(IV, SmallInstructionSet()))
944*9880d681SAndroid Build Coastguard Worker return false;
945*9880d681SAndroid Build Coastguard Worker LoopIncs.push_back(IV);
946*9880d681SAndroid Build Coastguard Worker } else {
947*9880d681SAndroid Build Coastguard Worker if (!findRootsBase(IV, SmallInstructionSet()))
948*9880d681SAndroid Build Coastguard Worker return false;
949*9880d681SAndroid Build Coastguard Worker }
950*9880d681SAndroid Build Coastguard Worker
951*9880d681SAndroid Build Coastguard Worker // Ensure all sets have the same size.
952*9880d681SAndroid Build Coastguard Worker if (RootSets.empty()) {
953*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting because no root sets found!\n");
954*9880d681SAndroid Build Coastguard Worker return false;
955*9880d681SAndroid Build Coastguard Worker }
956*9880d681SAndroid Build Coastguard Worker for (auto &V : RootSets) {
957*9880d681SAndroid Build Coastguard Worker if (V.Roots.empty() || V.Roots.size() != RootSets[0].Roots.size()) {
958*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs()
959*9880d681SAndroid Build Coastguard Worker << "LRR: Aborting because not all root sets have the same size\n");
960*9880d681SAndroid Build Coastguard Worker return false;
961*9880d681SAndroid Build Coastguard Worker }
962*9880d681SAndroid Build Coastguard Worker }
963*9880d681SAndroid Build Coastguard Worker
964*9880d681SAndroid Build Coastguard Worker // And ensure all loop iterations are consecutive. We rely on std::map
965*9880d681SAndroid Build Coastguard Worker // providing ordered traversal.
966*9880d681SAndroid Build Coastguard Worker for (auto &V : RootSets) {
967*9880d681SAndroid Build Coastguard Worker const auto *ADR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(V.BaseInst));
968*9880d681SAndroid Build Coastguard Worker if (!ADR)
969*9880d681SAndroid Build Coastguard Worker return false;
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Worker // Consider a DAGRootSet with N-1 roots (so N different values including
972*9880d681SAndroid Build Coastguard Worker // BaseInst).
973*9880d681SAndroid Build Coastguard Worker // Define d = Roots[0] - BaseInst, which should be the same as
974*9880d681SAndroid Build Coastguard Worker // Roots[I] - Roots[I-1] for all I in [1..N).
975*9880d681SAndroid Build Coastguard Worker // Define D = BaseInst@J - BaseInst@J-1, where "@J" means the value at the
976*9880d681SAndroid Build Coastguard Worker // loop iteration J.
977*9880d681SAndroid Build Coastguard Worker //
978*9880d681SAndroid Build Coastguard Worker // Now, For the loop iterations to be consecutive:
979*9880d681SAndroid Build Coastguard Worker // D = d * N
980*9880d681SAndroid Build Coastguard Worker
981*9880d681SAndroid Build Coastguard Worker unsigned N = V.Roots.size() + 1;
982*9880d681SAndroid Build Coastguard Worker const SCEV *StepSCEV = SE->getMinusSCEV(SE->getSCEV(V.Roots[0]), ADR);
983*9880d681SAndroid Build Coastguard Worker const SCEV *ScaleSCEV = SE->getConstant(StepSCEV->getType(), N);
984*9880d681SAndroid Build Coastguard Worker if (ADR->getStepRecurrence(*SE) != SE->getMulExpr(StepSCEV, ScaleSCEV)) {
985*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting because iterations are not consecutive\n");
986*9880d681SAndroid Build Coastguard Worker return false;
987*9880d681SAndroid Build Coastguard Worker }
988*9880d681SAndroid Build Coastguard Worker }
989*9880d681SAndroid Build Coastguard Worker Scale = RootSets[0].Roots.size() + 1;
990*9880d681SAndroid Build Coastguard Worker
991*9880d681SAndroid Build Coastguard Worker if (Scale > IL_MaxRerollIterations) {
992*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting - too many iterations found. "
993*9880d681SAndroid Build Coastguard Worker << "#Found=" << Scale << ", #Max=" << IL_MaxRerollIterations
994*9880d681SAndroid Build Coastguard Worker << "\n");
995*9880d681SAndroid Build Coastguard Worker return false;
996*9880d681SAndroid Build Coastguard Worker }
997*9880d681SAndroid Build Coastguard Worker
998*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Successfully found roots: Scale=" << Scale << "\n");
999*9880d681SAndroid Build Coastguard Worker
1000*9880d681SAndroid Build Coastguard Worker return true;
1001*9880d681SAndroid Build Coastguard Worker }
1002*9880d681SAndroid Build Coastguard Worker
collectUsedInstructions(SmallInstructionSet & PossibleRedSet)1003*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::collectUsedInstructions(SmallInstructionSet &PossibleRedSet) {
1004*9880d681SAndroid Build Coastguard Worker // Populate the MapVector with all instructions in the block, in order first,
1005*9880d681SAndroid Build Coastguard Worker // so we can iterate over the contents later in perfect order.
1006*9880d681SAndroid Build Coastguard Worker for (auto &I : *L->getHeader()) {
1007*9880d681SAndroid Build Coastguard Worker Uses[&I].resize(IL_End);
1008*9880d681SAndroid Build Coastguard Worker }
1009*9880d681SAndroid Build Coastguard Worker
1010*9880d681SAndroid Build Coastguard Worker SmallInstructionSet Exclude;
1011*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets) {
1012*9880d681SAndroid Build Coastguard Worker Exclude.insert(DRS.Roots.begin(), DRS.Roots.end());
1013*9880d681SAndroid Build Coastguard Worker Exclude.insert(DRS.SubsumedInsts.begin(), DRS.SubsumedInsts.end());
1014*9880d681SAndroid Build Coastguard Worker Exclude.insert(DRS.BaseInst);
1015*9880d681SAndroid Build Coastguard Worker }
1016*9880d681SAndroid Build Coastguard Worker Exclude.insert(LoopIncs.begin(), LoopIncs.end());
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets) {
1019*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction*> VBase;
1020*9880d681SAndroid Build Coastguard Worker collectInLoopUserSet(DRS.BaseInst, Exclude, PossibleRedSet, VBase);
1021*9880d681SAndroid Build Coastguard Worker for (auto *I : VBase) {
1022*9880d681SAndroid Build Coastguard Worker Uses[I].set(0);
1023*9880d681SAndroid Build Coastguard Worker }
1024*9880d681SAndroid Build Coastguard Worker
1025*9880d681SAndroid Build Coastguard Worker unsigned Idx = 1;
1026*9880d681SAndroid Build Coastguard Worker for (auto *Root : DRS.Roots) {
1027*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction*> V;
1028*9880d681SAndroid Build Coastguard Worker collectInLoopUserSet(Root, Exclude, PossibleRedSet, V);
1029*9880d681SAndroid Build Coastguard Worker
1030*9880d681SAndroid Build Coastguard Worker // While we're here, check the use sets are the same size.
1031*9880d681SAndroid Build Coastguard Worker if (V.size() != VBase.size()) {
1032*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting - use sets are different sizes\n");
1033*9880d681SAndroid Build Coastguard Worker return false;
1034*9880d681SAndroid Build Coastguard Worker }
1035*9880d681SAndroid Build Coastguard Worker
1036*9880d681SAndroid Build Coastguard Worker for (auto *I : V) {
1037*9880d681SAndroid Build Coastguard Worker Uses[I].set(Idx);
1038*9880d681SAndroid Build Coastguard Worker }
1039*9880d681SAndroid Build Coastguard Worker ++Idx;
1040*9880d681SAndroid Build Coastguard Worker }
1041*9880d681SAndroid Build Coastguard Worker
1042*9880d681SAndroid Build Coastguard Worker // Make sure our subsumed instructions are remembered too.
1043*9880d681SAndroid Build Coastguard Worker for (auto *I : DRS.SubsumedInsts) {
1044*9880d681SAndroid Build Coastguard Worker Uses[I].set(IL_All);
1045*9880d681SAndroid Build Coastguard Worker }
1046*9880d681SAndroid Build Coastguard Worker }
1047*9880d681SAndroid Build Coastguard Worker
1048*9880d681SAndroid Build Coastguard Worker // Make sure the loop increments are also accounted for.
1049*9880d681SAndroid Build Coastguard Worker
1050*9880d681SAndroid Build Coastguard Worker Exclude.clear();
1051*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets) {
1052*9880d681SAndroid Build Coastguard Worker Exclude.insert(DRS.Roots.begin(), DRS.Roots.end());
1053*9880d681SAndroid Build Coastguard Worker Exclude.insert(DRS.SubsumedInsts.begin(), DRS.SubsumedInsts.end());
1054*9880d681SAndroid Build Coastguard Worker Exclude.insert(DRS.BaseInst);
1055*9880d681SAndroid Build Coastguard Worker }
1056*9880d681SAndroid Build Coastguard Worker
1057*9880d681SAndroid Build Coastguard Worker DenseSet<Instruction*> V;
1058*9880d681SAndroid Build Coastguard Worker collectInLoopUserSet(LoopIncs, Exclude, PossibleRedSet, V);
1059*9880d681SAndroid Build Coastguard Worker for (auto *I : V) {
1060*9880d681SAndroid Build Coastguard Worker Uses[I].set(IL_All);
1061*9880d681SAndroid Build Coastguard Worker }
1062*9880d681SAndroid Build Coastguard Worker
1063*9880d681SAndroid Build Coastguard Worker return true;
1064*9880d681SAndroid Build Coastguard Worker
1065*9880d681SAndroid Build Coastguard Worker }
1066*9880d681SAndroid Build Coastguard Worker
1067*9880d681SAndroid Build Coastguard Worker /// Get the next instruction in "In" that is a member of set Val.
1068*9880d681SAndroid Build Coastguard Worker /// Start searching from StartI, and do not return anything in Exclude.
1069*9880d681SAndroid Build Coastguard Worker /// If StartI is not given, start from In.begin().
1070*9880d681SAndroid Build Coastguard Worker LoopReroll::DAGRootTracker::UsesTy::iterator
nextInstr(int Val,UsesTy & In,const SmallInstructionSet & Exclude,UsesTy::iterator * StartI)1071*9880d681SAndroid Build Coastguard Worker LoopReroll::DAGRootTracker::nextInstr(int Val, UsesTy &In,
1072*9880d681SAndroid Build Coastguard Worker const SmallInstructionSet &Exclude,
1073*9880d681SAndroid Build Coastguard Worker UsesTy::iterator *StartI) {
1074*9880d681SAndroid Build Coastguard Worker UsesTy::iterator I = StartI ? *StartI : In.begin();
1075*9880d681SAndroid Build Coastguard Worker while (I != In.end() && (I->second.test(Val) == 0 ||
1076*9880d681SAndroid Build Coastguard Worker Exclude.count(I->first) != 0))
1077*9880d681SAndroid Build Coastguard Worker ++I;
1078*9880d681SAndroid Build Coastguard Worker return I;
1079*9880d681SAndroid Build Coastguard Worker }
1080*9880d681SAndroid Build Coastguard Worker
isBaseInst(Instruction * I)1081*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::isBaseInst(Instruction *I) {
1082*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets) {
1083*9880d681SAndroid Build Coastguard Worker if (DRS.BaseInst == I)
1084*9880d681SAndroid Build Coastguard Worker return true;
1085*9880d681SAndroid Build Coastguard Worker }
1086*9880d681SAndroid Build Coastguard Worker return false;
1087*9880d681SAndroid Build Coastguard Worker }
1088*9880d681SAndroid Build Coastguard Worker
isRootInst(Instruction * I)1089*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::isRootInst(Instruction *I) {
1090*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets) {
1091*9880d681SAndroid Build Coastguard Worker if (std::find(DRS.Roots.begin(), DRS.Roots.end(), I) != DRS.Roots.end())
1092*9880d681SAndroid Build Coastguard Worker return true;
1093*9880d681SAndroid Build Coastguard Worker }
1094*9880d681SAndroid Build Coastguard Worker return false;
1095*9880d681SAndroid Build Coastguard Worker }
1096*9880d681SAndroid Build Coastguard Worker
1097*9880d681SAndroid Build Coastguard Worker /// Return true if instruction I depends on any instruction between
1098*9880d681SAndroid Build Coastguard Worker /// Start and End.
instrDependsOn(Instruction * I,UsesTy::iterator Start,UsesTy::iterator End)1099*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::instrDependsOn(Instruction *I,
1100*9880d681SAndroid Build Coastguard Worker UsesTy::iterator Start,
1101*9880d681SAndroid Build Coastguard Worker UsesTy::iterator End) {
1102*9880d681SAndroid Build Coastguard Worker for (auto *U : I->users()) {
1103*9880d681SAndroid Build Coastguard Worker for (auto It = Start; It != End; ++It)
1104*9880d681SAndroid Build Coastguard Worker if (U == It->first)
1105*9880d681SAndroid Build Coastguard Worker return true;
1106*9880d681SAndroid Build Coastguard Worker }
1107*9880d681SAndroid Build Coastguard Worker return false;
1108*9880d681SAndroid Build Coastguard Worker }
1109*9880d681SAndroid Build Coastguard Worker
isIgnorableInst(const Instruction * I)1110*9880d681SAndroid Build Coastguard Worker static bool isIgnorableInst(const Instruction *I) {
1111*9880d681SAndroid Build Coastguard Worker if (isa<DbgInfoIntrinsic>(I))
1112*9880d681SAndroid Build Coastguard Worker return true;
1113*9880d681SAndroid Build Coastguard Worker const IntrinsicInst* II = dyn_cast<IntrinsicInst>(I);
1114*9880d681SAndroid Build Coastguard Worker if (!II)
1115*9880d681SAndroid Build Coastguard Worker return false;
1116*9880d681SAndroid Build Coastguard Worker switch (II->getIntrinsicID()) {
1117*9880d681SAndroid Build Coastguard Worker default:
1118*9880d681SAndroid Build Coastguard Worker return false;
1119*9880d681SAndroid Build Coastguard Worker case llvm::Intrinsic::annotation:
1120*9880d681SAndroid Build Coastguard Worker case Intrinsic::ptr_annotation:
1121*9880d681SAndroid Build Coastguard Worker case Intrinsic::var_annotation:
1122*9880d681SAndroid Build Coastguard Worker // TODO: the following intrinsics may also be whitelisted:
1123*9880d681SAndroid Build Coastguard Worker // lifetime_start, lifetime_end, invariant_start, invariant_end
1124*9880d681SAndroid Build Coastguard Worker return true;
1125*9880d681SAndroid Build Coastguard Worker }
1126*9880d681SAndroid Build Coastguard Worker return false;
1127*9880d681SAndroid Build Coastguard Worker }
1128*9880d681SAndroid Build Coastguard Worker
validate(ReductionTracker & Reductions)1129*9880d681SAndroid Build Coastguard Worker bool LoopReroll::DAGRootTracker::validate(ReductionTracker &Reductions) {
1130*9880d681SAndroid Build Coastguard Worker // We now need to check for equivalence of the use graph of each root with
1131*9880d681SAndroid Build Coastguard Worker // that of the primary induction variable (excluding the roots). Our goal
1132*9880d681SAndroid Build Coastguard Worker // here is not to solve the full graph isomorphism problem, but rather to
1133*9880d681SAndroid Build Coastguard Worker // catch common cases without a lot of work. As a result, we will assume
1134*9880d681SAndroid Build Coastguard Worker // that the relative order of the instructions in each unrolled iteration
1135*9880d681SAndroid Build Coastguard Worker // is the same (although we will not make an assumption about how the
1136*9880d681SAndroid Build Coastguard Worker // different iterations are intermixed). Note that while the order must be
1137*9880d681SAndroid Build Coastguard Worker // the same, the instructions may not be in the same basic block.
1138*9880d681SAndroid Build Coastguard Worker
1139*9880d681SAndroid Build Coastguard Worker // An array of just the possible reductions for this scale factor. When we
1140*9880d681SAndroid Build Coastguard Worker // collect the set of all users of some root instructions, these reduction
1141*9880d681SAndroid Build Coastguard Worker // instructions are treated as 'final' (their uses are not considered).
1142*9880d681SAndroid Build Coastguard Worker // This is important because we don't want the root use set to search down
1143*9880d681SAndroid Build Coastguard Worker // the reduction chain.
1144*9880d681SAndroid Build Coastguard Worker SmallInstructionSet PossibleRedSet;
1145*9880d681SAndroid Build Coastguard Worker SmallInstructionSet PossibleRedLastSet;
1146*9880d681SAndroid Build Coastguard Worker SmallInstructionSet PossibleRedPHISet;
1147*9880d681SAndroid Build Coastguard Worker Reductions.restrictToScale(Scale, PossibleRedSet,
1148*9880d681SAndroid Build Coastguard Worker PossibleRedPHISet, PossibleRedLastSet);
1149*9880d681SAndroid Build Coastguard Worker
1150*9880d681SAndroid Build Coastguard Worker // Populate "Uses" with where each instruction is used.
1151*9880d681SAndroid Build Coastguard Worker if (!collectUsedInstructions(PossibleRedSet))
1152*9880d681SAndroid Build Coastguard Worker return false;
1153*9880d681SAndroid Build Coastguard Worker
1154*9880d681SAndroid Build Coastguard Worker // Make sure we mark the reduction PHIs as used in all iterations.
1155*9880d681SAndroid Build Coastguard Worker for (auto *I : PossibleRedPHISet) {
1156*9880d681SAndroid Build Coastguard Worker Uses[I].set(IL_All);
1157*9880d681SAndroid Build Coastguard Worker }
1158*9880d681SAndroid Build Coastguard Worker
1159*9880d681SAndroid Build Coastguard Worker // Make sure we mark loop-control-only PHIs as used in all iterations. See
1160*9880d681SAndroid Build Coastguard Worker // comment above LoopReroll::isLoopControlIV for more information.
1161*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = L->getHeader();
1162*9880d681SAndroid Build Coastguard Worker if (LoopControlIV && LoopControlIV != IV) {
1163*9880d681SAndroid Build Coastguard Worker for (auto *U : LoopControlIV->users()) {
1164*9880d681SAndroid Build Coastguard Worker Instruction *IVUser = dyn_cast<Instruction>(U);
1165*9880d681SAndroid Build Coastguard Worker // IVUser could be loop increment or compare
1166*9880d681SAndroid Build Coastguard Worker Uses[IVUser].set(IL_All);
1167*9880d681SAndroid Build Coastguard Worker for (auto *UU : IVUser->users()) {
1168*9880d681SAndroid Build Coastguard Worker Instruction *UUser = dyn_cast<Instruction>(UU);
1169*9880d681SAndroid Build Coastguard Worker // UUser could be compare, PHI or branch
1170*9880d681SAndroid Build Coastguard Worker Uses[UUser].set(IL_All);
1171*9880d681SAndroid Build Coastguard Worker // Skip SExt
1172*9880d681SAndroid Build Coastguard Worker if (isa<SExtInst>(UUser)) {
1173*9880d681SAndroid Build Coastguard Worker UUser = dyn_cast<Instruction>(*(UUser->user_begin()));
1174*9880d681SAndroid Build Coastguard Worker Uses[UUser].set(IL_All);
1175*9880d681SAndroid Build Coastguard Worker }
1176*9880d681SAndroid Build Coastguard Worker // Is UUser a compare instruction?
1177*9880d681SAndroid Build Coastguard Worker if (UU->hasOneUse()) {
1178*9880d681SAndroid Build Coastguard Worker Instruction *BI = dyn_cast<BranchInst>(*UUser->user_begin());
1179*9880d681SAndroid Build Coastguard Worker if (BI == cast<BranchInst>(Header->getTerminator()))
1180*9880d681SAndroid Build Coastguard Worker Uses[BI].set(IL_All);
1181*9880d681SAndroid Build Coastguard Worker }
1182*9880d681SAndroid Build Coastguard Worker }
1183*9880d681SAndroid Build Coastguard Worker }
1184*9880d681SAndroid Build Coastguard Worker }
1185*9880d681SAndroid Build Coastguard Worker
1186*9880d681SAndroid Build Coastguard Worker // Make sure all instructions in the loop are in one and only one
1187*9880d681SAndroid Build Coastguard Worker // set.
1188*9880d681SAndroid Build Coastguard Worker for (auto &KV : Uses) {
1189*9880d681SAndroid Build Coastguard Worker if (KV.second.count() != 1 && !isIgnorableInst(KV.first)) {
1190*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Aborting - instruction is not used in 1 iteration: "
1191*9880d681SAndroid Build Coastguard Worker << *KV.first << " (#uses=" << KV.second.count() << ")\n");
1192*9880d681SAndroid Build Coastguard Worker return false;
1193*9880d681SAndroid Build Coastguard Worker }
1194*9880d681SAndroid Build Coastguard Worker }
1195*9880d681SAndroid Build Coastguard Worker
1196*9880d681SAndroid Build Coastguard Worker DEBUG(
1197*9880d681SAndroid Build Coastguard Worker for (auto &KV : Uses) {
1198*9880d681SAndroid Build Coastguard Worker dbgs() << "LRR: " << KV.second.find_first() << "\t" << *KV.first << "\n";
1199*9880d681SAndroid Build Coastguard Worker }
1200*9880d681SAndroid Build Coastguard Worker );
1201*9880d681SAndroid Build Coastguard Worker
1202*9880d681SAndroid Build Coastguard Worker for (unsigned Iter = 1; Iter < Scale; ++Iter) {
1203*9880d681SAndroid Build Coastguard Worker // In addition to regular aliasing information, we need to look for
1204*9880d681SAndroid Build Coastguard Worker // instructions from later (future) iterations that have side effects
1205*9880d681SAndroid Build Coastguard Worker // preventing us from reordering them past other instructions with side
1206*9880d681SAndroid Build Coastguard Worker // effects.
1207*9880d681SAndroid Build Coastguard Worker bool FutureSideEffects = false;
1208*9880d681SAndroid Build Coastguard Worker AliasSetTracker AST(*AA);
1209*9880d681SAndroid Build Coastguard Worker // The map between instructions in f(%iv.(i+1)) and f(%iv).
1210*9880d681SAndroid Build Coastguard Worker DenseMap<Value *, Value *> BaseMap;
1211*9880d681SAndroid Build Coastguard Worker
1212*9880d681SAndroid Build Coastguard Worker // Compare iteration Iter to the base.
1213*9880d681SAndroid Build Coastguard Worker SmallInstructionSet Visited;
1214*9880d681SAndroid Build Coastguard Worker auto BaseIt = nextInstr(0, Uses, Visited);
1215*9880d681SAndroid Build Coastguard Worker auto RootIt = nextInstr(Iter, Uses, Visited);
1216*9880d681SAndroid Build Coastguard Worker auto LastRootIt = Uses.begin();
1217*9880d681SAndroid Build Coastguard Worker
1218*9880d681SAndroid Build Coastguard Worker while (BaseIt != Uses.end() && RootIt != Uses.end()) {
1219*9880d681SAndroid Build Coastguard Worker Instruction *BaseInst = BaseIt->first;
1220*9880d681SAndroid Build Coastguard Worker Instruction *RootInst = RootIt->first;
1221*9880d681SAndroid Build Coastguard Worker
1222*9880d681SAndroid Build Coastguard Worker // Skip over the IV or root instructions; only match their users.
1223*9880d681SAndroid Build Coastguard Worker bool Continue = false;
1224*9880d681SAndroid Build Coastguard Worker if (isBaseInst(BaseInst)) {
1225*9880d681SAndroid Build Coastguard Worker Visited.insert(BaseInst);
1226*9880d681SAndroid Build Coastguard Worker BaseIt = nextInstr(0, Uses, Visited);
1227*9880d681SAndroid Build Coastguard Worker Continue = true;
1228*9880d681SAndroid Build Coastguard Worker }
1229*9880d681SAndroid Build Coastguard Worker if (isRootInst(RootInst)) {
1230*9880d681SAndroid Build Coastguard Worker LastRootIt = RootIt;
1231*9880d681SAndroid Build Coastguard Worker Visited.insert(RootInst);
1232*9880d681SAndroid Build Coastguard Worker RootIt = nextInstr(Iter, Uses, Visited);
1233*9880d681SAndroid Build Coastguard Worker Continue = true;
1234*9880d681SAndroid Build Coastguard Worker }
1235*9880d681SAndroid Build Coastguard Worker if (Continue) continue;
1236*9880d681SAndroid Build Coastguard Worker
1237*9880d681SAndroid Build Coastguard Worker if (!BaseInst->isSameOperationAs(RootInst)) {
1238*9880d681SAndroid Build Coastguard Worker // Last chance saloon. We don't try and solve the full isomorphism
1239*9880d681SAndroid Build Coastguard Worker // problem, but try and at least catch the case where two instructions
1240*9880d681SAndroid Build Coastguard Worker // *of different types* are round the wrong way. We won't be able to
1241*9880d681SAndroid Build Coastguard Worker // efficiently tell, given two ADD instructions, which way around we
1242*9880d681SAndroid Build Coastguard Worker // should match them, but given an ADD and a SUB, we can at least infer
1243*9880d681SAndroid Build Coastguard Worker // which one is which.
1244*9880d681SAndroid Build Coastguard Worker //
1245*9880d681SAndroid Build Coastguard Worker // This should allow us to deal with a greater subset of the isomorphism
1246*9880d681SAndroid Build Coastguard Worker // problem. It does however change a linear algorithm into a quadratic
1247*9880d681SAndroid Build Coastguard Worker // one, so limit the number of probes we do.
1248*9880d681SAndroid Build Coastguard Worker auto TryIt = RootIt;
1249*9880d681SAndroid Build Coastguard Worker unsigned N = NumToleratedFailedMatches;
1250*9880d681SAndroid Build Coastguard Worker while (TryIt != Uses.end() &&
1251*9880d681SAndroid Build Coastguard Worker !BaseInst->isSameOperationAs(TryIt->first) &&
1252*9880d681SAndroid Build Coastguard Worker N--) {
1253*9880d681SAndroid Build Coastguard Worker ++TryIt;
1254*9880d681SAndroid Build Coastguard Worker TryIt = nextInstr(Iter, Uses, Visited, &TryIt);
1255*9880d681SAndroid Build Coastguard Worker }
1256*9880d681SAndroid Build Coastguard Worker
1257*9880d681SAndroid Build Coastguard Worker if (TryIt == Uses.end() || TryIt == RootIt ||
1258*9880d681SAndroid Build Coastguard Worker instrDependsOn(TryIt->first, RootIt, TryIt)) {
1259*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration root match failed at " << *BaseInst <<
1260*9880d681SAndroid Build Coastguard Worker " vs. " << *RootInst << "\n");
1261*9880d681SAndroid Build Coastguard Worker return false;
1262*9880d681SAndroid Build Coastguard Worker }
1263*9880d681SAndroid Build Coastguard Worker
1264*9880d681SAndroid Build Coastguard Worker RootIt = TryIt;
1265*9880d681SAndroid Build Coastguard Worker RootInst = TryIt->first;
1266*9880d681SAndroid Build Coastguard Worker }
1267*9880d681SAndroid Build Coastguard Worker
1268*9880d681SAndroid Build Coastguard Worker // All instructions between the last root and this root
1269*9880d681SAndroid Build Coastguard Worker // may belong to some other iteration. If they belong to a
1270*9880d681SAndroid Build Coastguard Worker // future iteration, then they're dangerous to alias with.
1271*9880d681SAndroid Build Coastguard Worker //
1272*9880d681SAndroid Build Coastguard Worker // Note that because we allow a limited amount of flexibility in the order
1273*9880d681SAndroid Build Coastguard Worker // that we visit nodes, LastRootIt might be *before* RootIt, in which
1274*9880d681SAndroid Build Coastguard Worker // case we've already checked this set of instructions so we shouldn't
1275*9880d681SAndroid Build Coastguard Worker // do anything.
1276*9880d681SAndroid Build Coastguard Worker for (; LastRootIt < RootIt; ++LastRootIt) {
1277*9880d681SAndroid Build Coastguard Worker Instruction *I = LastRootIt->first;
1278*9880d681SAndroid Build Coastguard Worker if (LastRootIt->second.find_first() < (int)Iter)
1279*9880d681SAndroid Build Coastguard Worker continue;
1280*9880d681SAndroid Build Coastguard Worker if (I->mayWriteToMemory())
1281*9880d681SAndroid Build Coastguard Worker AST.add(I);
1282*9880d681SAndroid Build Coastguard Worker // Note: This is specifically guarded by a check on isa<PHINode>,
1283*9880d681SAndroid Build Coastguard Worker // which while a valid (somewhat arbitrary) micro-optimization, is
1284*9880d681SAndroid Build Coastguard Worker // needed because otherwise isSafeToSpeculativelyExecute returns
1285*9880d681SAndroid Build Coastguard Worker // false on PHI nodes.
1286*9880d681SAndroid Build Coastguard Worker if (!isa<PHINode>(I) && !isSimpleLoadStore(I) &&
1287*9880d681SAndroid Build Coastguard Worker !isSafeToSpeculativelyExecute(I))
1288*9880d681SAndroid Build Coastguard Worker // Intervening instructions cause side effects.
1289*9880d681SAndroid Build Coastguard Worker FutureSideEffects = true;
1290*9880d681SAndroid Build Coastguard Worker }
1291*9880d681SAndroid Build Coastguard Worker
1292*9880d681SAndroid Build Coastguard Worker // Make sure that this instruction, which is in the use set of this
1293*9880d681SAndroid Build Coastguard Worker // root instruction, does not also belong to the base set or the set of
1294*9880d681SAndroid Build Coastguard Worker // some other root instruction.
1295*9880d681SAndroid Build Coastguard Worker if (RootIt->second.count() > 1) {
1296*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration root match failed at " << *BaseInst <<
1297*9880d681SAndroid Build Coastguard Worker " vs. " << *RootInst << " (prev. case overlap)\n");
1298*9880d681SAndroid Build Coastguard Worker return false;
1299*9880d681SAndroid Build Coastguard Worker }
1300*9880d681SAndroid Build Coastguard Worker
1301*9880d681SAndroid Build Coastguard Worker // Make sure that we don't alias with any instruction in the alias set
1302*9880d681SAndroid Build Coastguard Worker // tracker. If we do, then we depend on a future iteration, and we
1303*9880d681SAndroid Build Coastguard Worker // can't reroll.
1304*9880d681SAndroid Build Coastguard Worker if (RootInst->mayReadFromMemory())
1305*9880d681SAndroid Build Coastguard Worker for (auto &K : AST) {
1306*9880d681SAndroid Build Coastguard Worker if (K.aliasesUnknownInst(RootInst, *AA)) {
1307*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration root match failed at " << *BaseInst <<
1308*9880d681SAndroid Build Coastguard Worker " vs. " << *RootInst << " (depends on future store)\n");
1309*9880d681SAndroid Build Coastguard Worker return false;
1310*9880d681SAndroid Build Coastguard Worker }
1311*9880d681SAndroid Build Coastguard Worker }
1312*9880d681SAndroid Build Coastguard Worker
1313*9880d681SAndroid Build Coastguard Worker // If we've past an instruction from a future iteration that may have
1314*9880d681SAndroid Build Coastguard Worker // side effects, and this instruction might also, then we can't reorder
1315*9880d681SAndroid Build Coastguard Worker // them, and this matching fails. As an exception, we allow the alias
1316*9880d681SAndroid Build Coastguard Worker // set tracker to handle regular (simple) load/store dependencies.
1317*9880d681SAndroid Build Coastguard Worker if (FutureSideEffects && ((!isSimpleLoadStore(BaseInst) &&
1318*9880d681SAndroid Build Coastguard Worker !isSafeToSpeculativelyExecute(BaseInst)) ||
1319*9880d681SAndroid Build Coastguard Worker (!isSimpleLoadStore(RootInst) &&
1320*9880d681SAndroid Build Coastguard Worker !isSafeToSpeculativelyExecute(RootInst)))) {
1321*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration root match failed at " << *BaseInst <<
1322*9880d681SAndroid Build Coastguard Worker " vs. " << *RootInst <<
1323*9880d681SAndroid Build Coastguard Worker " (side effects prevent reordering)\n");
1324*9880d681SAndroid Build Coastguard Worker return false;
1325*9880d681SAndroid Build Coastguard Worker }
1326*9880d681SAndroid Build Coastguard Worker
1327*9880d681SAndroid Build Coastguard Worker // For instructions that are part of a reduction, if the operation is
1328*9880d681SAndroid Build Coastguard Worker // associative, then don't bother matching the operands (because we
1329*9880d681SAndroid Build Coastguard Worker // already know that the instructions are isomorphic, and the order
1330*9880d681SAndroid Build Coastguard Worker // within the iteration does not matter). For non-associative reductions,
1331*9880d681SAndroid Build Coastguard Worker // we do need to match the operands, because we need to reject
1332*9880d681SAndroid Build Coastguard Worker // out-of-order instructions within an iteration!
1333*9880d681SAndroid Build Coastguard Worker // For example (assume floating-point addition), we need to reject this:
1334*9880d681SAndroid Build Coastguard Worker // x += a[i]; x += b[i];
1335*9880d681SAndroid Build Coastguard Worker // x += a[i+1]; x += b[i+1];
1336*9880d681SAndroid Build Coastguard Worker // x += b[i+2]; x += a[i+2];
1337*9880d681SAndroid Build Coastguard Worker bool InReduction = Reductions.isPairInSame(BaseInst, RootInst);
1338*9880d681SAndroid Build Coastguard Worker
1339*9880d681SAndroid Build Coastguard Worker if (!(InReduction && BaseInst->isAssociative())) {
1340*9880d681SAndroid Build Coastguard Worker bool Swapped = false, SomeOpMatched = false;
1341*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0; j < BaseInst->getNumOperands(); ++j) {
1342*9880d681SAndroid Build Coastguard Worker Value *Op2 = RootInst->getOperand(j);
1343*9880d681SAndroid Build Coastguard Worker
1344*9880d681SAndroid Build Coastguard Worker // If this is part of a reduction (and the operation is not
1345*9880d681SAndroid Build Coastguard Worker // associatve), then we match all operands, but not those that are
1346*9880d681SAndroid Build Coastguard Worker // part of the reduction.
1347*9880d681SAndroid Build Coastguard Worker if (InReduction)
1348*9880d681SAndroid Build Coastguard Worker if (Instruction *Op2I = dyn_cast<Instruction>(Op2))
1349*9880d681SAndroid Build Coastguard Worker if (Reductions.isPairInSame(RootInst, Op2I))
1350*9880d681SAndroid Build Coastguard Worker continue;
1351*9880d681SAndroid Build Coastguard Worker
1352*9880d681SAndroid Build Coastguard Worker DenseMap<Value *, Value *>::iterator BMI = BaseMap.find(Op2);
1353*9880d681SAndroid Build Coastguard Worker if (BMI != BaseMap.end()) {
1354*9880d681SAndroid Build Coastguard Worker Op2 = BMI->second;
1355*9880d681SAndroid Build Coastguard Worker } else {
1356*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets) {
1357*9880d681SAndroid Build Coastguard Worker if (DRS.Roots[Iter-1] == (Instruction*) Op2) {
1358*9880d681SAndroid Build Coastguard Worker Op2 = DRS.BaseInst;
1359*9880d681SAndroid Build Coastguard Worker break;
1360*9880d681SAndroid Build Coastguard Worker }
1361*9880d681SAndroid Build Coastguard Worker }
1362*9880d681SAndroid Build Coastguard Worker }
1363*9880d681SAndroid Build Coastguard Worker
1364*9880d681SAndroid Build Coastguard Worker if (BaseInst->getOperand(Swapped ? unsigned(!j) : j) != Op2) {
1365*9880d681SAndroid Build Coastguard Worker // If we've not already decided to swap the matched operands, and
1366*9880d681SAndroid Build Coastguard Worker // we've not already matched our first operand (note that we could
1367*9880d681SAndroid Build Coastguard Worker // have skipped matching the first operand because it is part of a
1368*9880d681SAndroid Build Coastguard Worker // reduction above), and the instruction is commutative, then try
1369*9880d681SAndroid Build Coastguard Worker // the swapped match.
1370*9880d681SAndroid Build Coastguard Worker if (!Swapped && BaseInst->isCommutative() && !SomeOpMatched &&
1371*9880d681SAndroid Build Coastguard Worker BaseInst->getOperand(!j) == Op2) {
1372*9880d681SAndroid Build Coastguard Worker Swapped = true;
1373*9880d681SAndroid Build Coastguard Worker } else {
1374*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration root match failed at " << *BaseInst
1375*9880d681SAndroid Build Coastguard Worker << " vs. " << *RootInst << " (operand " << j << ")\n");
1376*9880d681SAndroid Build Coastguard Worker return false;
1377*9880d681SAndroid Build Coastguard Worker }
1378*9880d681SAndroid Build Coastguard Worker }
1379*9880d681SAndroid Build Coastguard Worker
1380*9880d681SAndroid Build Coastguard Worker SomeOpMatched = true;
1381*9880d681SAndroid Build Coastguard Worker }
1382*9880d681SAndroid Build Coastguard Worker }
1383*9880d681SAndroid Build Coastguard Worker
1384*9880d681SAndroid Build Coastguard Worker if ((!PossibleRedLastSet.count(BaseInst) &&
1385*9880d681SAndroid Build Coastguard Worker hasUsesOutsideLoop(BaseInst, L)) ||
1386*9880d681SAndroid Build Coastguard Worker (!PossibleRedLastSet.count(RootInst) &&
1387*9880d681SAndroid Build Coastguard Worker hasUsesOutsideLoop(RootInst, L))) {
1388*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration root match failed at " << *BaseInst <<
1389*9880d681SAndroid Build Coastguard Worker " vs. " << *RootInst << " (uses outside loop)\n");
1390*9880d681SAndroid Build Coastguard Worker return false;
1391*9880d681SAndroid Build Coastguard Worker }
1392*9880d681SAndroid Build Coastguard Worker
1393*9880d681SAndroid Build Coastguard Worker Reductions.recordPair(BaseInst, RootInst, Iter);
1394*9880d681SAndroid Build Coastguard Worker BaseMap.insert(std::make_pair(RootInst, BaseInst));
1395*9880d681SAndroid Build Coastguard Worker
1396*9880d681SAndroid Build Coastguard Worker LastRootIt = RootIt;
1397*9880d681SAndroid Build Coastguard Worker Visited.insert(BaseInst);
1398*9880d681SAndroid Build Coastguard Worker Visited.insert(RootInst);
1399*9880d681SAndroid Build Coastguard Worker BaseIt = nextInstr(0, Uses, Visited);
1400*9880d681SAndroid Build Coastguard Worker RootIt = nextInstr(Iter, Uses, Visited);
1401*9880d681SAndroid Build Coastguard Worker }
1402*9880d681SAndroid Build Coastguard Worker assert (BaseIt == Uses.end() && RootIt == Uses.end() &&
1403*9880d681SAndroid Build Coastguard Worker "Mismatched set sizes!");
1404*9880d681SAndroid Build Coastguard Worker }
1405*9880d681SAndroid Build Coastguard Worker
1406*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Matched all iteration increments for " <<
1407*9880d681SAndroid Build Coastguard Worker *IV << "\n");
1408*9880d681SAndroid Build Coastguard Worker
1409*9880d681SAndroid Build Coastguard Worker return true;
1410*9880d681SAndroid Build Coastguard Worker }
1411*9880d681SAndroid Build Coastguard Worker
replace(const SCEV * IterCount)1412*9880d681SAndroid Build Coastguard Worker void LoopReroll::DAGRootTracker::replace(const SCEV *IterCount) {
1413*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = L->getHeader();
1414*9880d681SAndroid Build Coastguard Worker // Remove instructions associated with non-base iterations.
1415*9880d681SAndroid Build Coastguard Worker for (BasicBlock::reverse_iterator J = Header->rbegin();
1416*9880d681SAndroid Build Coastguard Worker J != Header->rend();) {
1417*9880d681SAndroid Build Coastguard Worker unsigned I = Uses[&*J].find_first();
1418*9880d681SAndroid Build Coastguard Worker if (I > 0 && I < IL_All) {
1419*9880d681SAndroid Build Coastguard Worker Instruction *D = &*J;
1420*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: removing: " << *D << "\n");
1421*9880d681SAndroid Build Coastguard Worker D->eraseFromParent();
1422*9880d681SAndroid Build Coastguard Worker continue;
1423*9880d681SAndroid Build Coastguard Worker }
1424*9880d681SAndroid Build Coastguard Worker
1425*9880d681SAndroid Build Coastguard Worker ++J;
1426*9880d681SAndroid Build Coastguard Worker }
1427*9880d681SAndroid Build Coastguard Worker
1428*9880d681SAndroid Build Coastguard Worker bool HasTwoIVs = LoopControlIV && LoopControlIV != IV;
1429*9880d681SAndroid Build Coastguard Worker
1430*9880d681SAndroid Build Coastguard Worker if (HasTwoIVs) {
1431*9880d681SAndroid Build Coastguard Worker updateNonLoopCtrlIncr();
1432*9880d681SAndroid Build Coastguard Worker replaceIV(LoopControlIV, LoopControlIV, IterCount);
1433*9880d681SAndroid Build Coastguard Worker } else
1434*9880d681SAndroid Build Coastguard Worker // We need to create a new induction variable for each different BaseInst.
1435*9880d681SAndroid Build Coastguard Worker for (auto &DRS : RootSets)
1436*9880d681SAndroid Build Coastguard Worker // Insert the new induction variable.
1437*9880d681SAndroid Build Coastguard Worker replaceIV(DRS.BaseInst, IV, IterCount);
1438*9880d681SAndroid Build Coastguard Worker
1439*9880d681SAndroid Build Coastguard Worker SimplifyInstructionsInBlock(Header, TLI);
1440*9880d681SAndroid Build Coastguard Worker DeleteDeadPHIs(Header, TLI);
1441*9880d681SAndroid Build Coastguard Worker }
1442*9880d681SAndroid Build Coastguard Worker
1443*9880d681SAndroid Build Coastguard Worker // For non-loop-control IVs, we only need to update the last increment
1444*9880d681SAndroid Build Coastguard Worker // with right amount, then we are done.
updateNonLoopCtrlIncr()1445*9880d681SAndroid Build Coastguard Worker void LoopReroll::DAGRootTracker::updateNonLoopCtrlIncr() {
1446*9880d681SAndroid Build Coastguard Worker const SCEV *NewInc = nullptr;
1447*9880d681SAndroid Build Coastguard Worker for (auto *LoopInc : LoopIncs) {
1448*9880d681SAndroid Build Coastguard Worker GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LoopInc);
1449*9880d681SAndroid Build Coastguard Worker const SCEVConstant *COp = nullptr;
1450*9880d681SAndroid Build Coastguard Worker if (GEP && LoopInc->getOperand(0)->getType()->isPointerTy()) {
1451*9880d681SAndroid Build Coastguard Worker COp = dyn_cast<SCEVConstant>(SE->getSCEV(LoopInc->getOperand(1)));
1452*9880d681SAndroid Build Coastguard Worker } else {
1453*9880d681SAndroid Build Coastguard Worker COp = dyn_cast<SCEVConstant>(SE->getSCEV(LoopInc->getOperand(0)));
1454*9880d681SAndroid Build Coastguard Worker if (!COp)
1455*9880d681SAndroid Build Coastguard Worker COp = dyn_cast<SCEVConstant>(SE->getSCEV(LoopInc->getOperand(1)));
1456*9880d681SAndroid Build Coastguard Worker }
1457*9880d681SAndroid Build Coastguard Worker
1458*9880d681SAndroid Build Coastguard Worker assert(COp && "Didn't find constant operand of LoopInc!\n");
1459*9880d681SAndroid Build Coastguard Worker
1460*9880d681SAndroid Build Coastguard Worker const APInt &AInt = COp->getValue()->getValue();
1461*9880d681SAndroid Build Coastguard Worker const SCEV *ScaleSCEV = SE->getConstant(COp->getType(), Scale);
1462*9880d681SAndroid Build Coastguard Worker if (AInt.isNegative()) {
1463*9880d681SAndroid Build Coastguard Worker NewInc = SE->getNegativeSCEV(COp);
1464*9880d681SAndroid Build Coastguard Worker NewInc = SE->getUDivExpr(NewInc, ScaleSCEV);
1465*9880d681SAndroid Build Coastguard Worker NewInc = SE->getNegativeSCEV(NewInc);
1466*9880d681SAndroid Build Coastguard Worker } else
1467*9880d681SAndroid Build Coastguard Worker NewInc = SE->getUDivExpr(COp, ScaleSCEV);
1468*9880d681SAndroid Build Coastguard Worker
1469*9880d681SAndroid Build Coastguard Worker LoopInc->setOperand(1, dyn_cast<SCEVConstant>(NewInc)->getValue());
1470*9880d681SAndroid Build Coastguard Worker }
1471*9880d681SAndroid Build Coastguard Worker }
1472*9880d681SAndroid Build Coastguard Worker
replaceIV(Instruction * Inst,Instruction * InstIV,const SCEV * IterCount)1473*9880d681SAndroid Build Coastguard Worker void LoopReroll::DAGRootTracker::replaceIV(Instruction *Inst,
1474*9880d681SAndroid Build Coastguard Worker Instruction *InstIV,
1475*9880d681SAndroid Build Coastguard Worker const SCEV *IterCount) {
1476*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = L->getHeader();
1477*9880d681SAndroid Build Coastguard Worker int64_t Inc = IVToIncMap[InstIV];
1478*9880d681SAndroid Build Coastguard Worker bool NeedNewIV = InstIV == LoopControlIV;
1479*9880d681SAndroid Build Coastguard Worker bool Negative = !NeedNewIV && Inc < 0;
1480*9880d681SAndroid Build Coastguard Worker
1481*9880d681SAndroid Build Coastguard Worker const SCEVAddRecExpr *RealIVSCEV = cast<SCEVAddRecExpr>(SE->getSCEV(Inst));
1482*9880d681SAndroid Build Coastguard Worker const SCEV *Start = RealIVSCEV->getStart();
1483*9880d681SAndroid Build Coastguard Worker
1484*9880d681SAndroid Build Coastguard Worker if (NeedNewIV)
1485*9880d681SAndroid Build Coastguard Worker Start = SE->getConstant(Start->getType(), 0);
1486*9880d681SAndroid Build Coastguard Worker
1487*9880d681SAndroid Build Coastguard Worker const SCEV *SizeOfExpr = nullptr;
1488*9880d681SAndroid Build Coastguard Worker const SCEV *IncrExpr =
1489*9880d681SAndroid Build Coastguard Worker SE->getConstant(RealIVSCEV->getType(), Negative ? -1 : 1);
1490*9880d681SAndroid Build Coastguard Worker if (auto *PTy = dyn_cast<PointerType>(Inst->getType())) {
1491*9880d681SAndroid Build Coastguard Worker Type *ElTy = PTy->getElementType();
1492*9880d681SAndroid Build Coastguard Worker SizeOfExpr =
1493*9880d681SAndroid Build Coastguard Worker SE->getSizeOfExpr(SE->getEffectiveSCEVType(Inst->getType()), ElTy);
1494*9880d681SAndroid Build Coastguard Worker IncrExpr = SE->getMulExpr(IncrExpr, SizeOfExpr);
1495*9880d681SAndroid Build Coastguard Worker }
1496*9880d681SAndroid Build Coastguard Worker const SCEV *NewIVSCEV =
1497*9880d681SAndroid Build Coastguard Worker SE->getAddRecExpr(Start, IncrExpr, L, SCEV::FlagAnyWrap);
1498*9880d681SAndroid Build Coastguard Worker
1499*9880d681SAndroid Build Coastguard Worker { // Limit the lifetime of SCEVExpander.
1500*9880d681SAndroid Build Coastguard Worker const DataLayout &DL = Header->getModule()->getDataLayout();
1501*9880d681SAndroid Build Coastguard Worker SCEVExpander Expander(*SE, DL, "reroll");
1502*9880d681SAndroid Build Coastguard Worker Value *NewIV =
1503*9880d681SAndroid Build Coastguard Worker Expander.expandCodeFor(NewIVSCEV, InstIV->getType(), &Header->front());
1504*9880d681SAndroid Build Coastguard Worker
1505*9880d681SAndroid Build Coastguard Worker for (auto &KV : Uses)
1506*9880d681SAndroid Build Coastguard Worker if (KV.second.find_first() == 0)
1507*9880d681SAndroid Build Coastguard Worker KV.first->replaceUsesOfWith(Inst, NewIV);
1508*9880d681SAndroid Build Coastguard Worker
1509*9880d681SAndroid Build Coastguard Worker if (BranchInst *BI = dyn_cast<BranchInst>(Header->getTerminator())) {
1510*9880d681SAndroid Build Coastguard Worker // FIXME: Why do we need this check?
1511*9880d681SAndroid Build Coastguard Worker if (Uses[BI].find_first() == IL_All) {
1512*9880d681SAndroid Build Coastguard Worker const SCEV *ICSCEV = RealIVSCEV->evaluateAtIteration(IterCount, *SE);
1513*9880d681SAndroid Build Coastguard Worker
1514*9880d681SAndroid Build Coastguard Worker if (NeedNewIV)
1515*9880d681SAndroid Build Coastguard Worker ICSCEV = SE->getMulExpr(IterCount,
1516*9880d681SAndroid Build Coastguard Worker SE->getConstant(IterCount->getType(), Scale));
1517*9880d681SAndroid Build Coastguard Worker
1518*9880d681SAndroid Build Coastguard Worker // Iteration count SCEV minus or plus 1
1519*9880d681SAndroid Build Coastguard Worker const SCEV *MinusPlus1SCEV =
1520*9880d681SAndroid Build Coastguard Worker SE->getConstant(ICSCEV->getType(), Negative ? -1 : 1);
1521*9880d681SAndroid Build Coastguard Worker if (Inst->getType()->isPointerTy()) {
1522*9880d681SAndroid Build Coastguard Worker assert(SizeOfExpr && "SizeOfExpr is not initialized");
1523*9880d681SAndroid Build Coastguard Worker MinusPlus1SCEV = SE->getMulExpr(MinusPlus1SCEV, SizeOfExpr);
1524*9880d681SAndroid Build Coastguard Worker }
1525*9880d681SAndroid Build Coastguard Worker
1526*9880d681SAndroid Build Coastguard Worker const SCEV *ICMinusPlus1SCEV = SE->getMinusSCEV(ICSCEV, MinusPlus1SCEV);
1527*9880d681SAndroid Build Coastguard Worker // Iteration count minus 1
1528*9880d681SAndroid Build Coastguard Worker Instruction *InsertPtr = nullptr;
1529*9880d681SAndroid Build Coastguard Worker if (isa<SCEVConstant>(ICMinusPlus1SCEV)) {
1530*9880d681SAndroid Build Coastguard Worker InsertPtr = BI;
1531*9880d681SAndroid Build Coastguard Worker } else {
1532*9880d681SAndroid Build Coastguard Worker BasicBlock *Preheader = L->getLoopPreheader();
1533*9880d681SAndroid Build Coastguard Worker if (!Preheader)
1534*9880d681SAndroid Build Coastguard Worker Preheader = InsertPreheaderForLoop(L, DT, LI, PreserveLCSSA);
1535*9880d681SAndroid Build Coastguard Worker InsertPtr = Preheader->getTerminator();
1536*9880d681SAndroid Build Coastguard Worker }
1537*9880d681SAndroid Build Coastguard Worker
1538*9880d681SAndroid Build Coastguard Worker if (!isa<PointerType>(NewIV->getType()) && NeedNewIV &&
1539*9880d681SAndroid Build Coastguard Worker (SE->getTypeSizeInBits(NewIV->getType()) <
1540*9880d681SAndroid Build Coastguard Worker SE->getTypeSizeInBits(ICMinusPlus1SCEV->getType()))) {
1541*9880d681SAndroid Build Coastguard Worker IRBuilder<> Builder(BI);
1542*9880d681SAndroid Build Coastguard Worker Builder.SetCurrentDebugLocation(BI->getDebugLoc());
1543*9880d681SAndroid Build Coastguard Worker NewIV = Builder.CreateSExt(NewIV, ICMinusPlus1SCEV->getType());
1544*9880d681SAndroid Build Coastguard Worker }
1545*9880d681SAndroid Build Coastguard Worker Value *ICMinusPlus1 = Expander.expandCodeFor(
1546*9880d681SAndroid Build Coastguard Worker ICMinusPlus1SCEV, NewIV->getType(), InsertPtr);
1547*9880d681SAndroid Build Coastguard Worker
1548*9880d681SAndroid Build Coastguard Worker Value *Cond =
1549*9880d681SAndroid Build Coastguard Worker new ICmpInst(BI, CmpInst::ICMP_EQ, NewIV, ICMinusPlus1, "exitcond");
1550*9880d681SAndroid Build Coastguard Worker BI->setCondition(Cond);
1551*9880d681SAndroid Build Coastguard Worker
1552*9880d681SAndroid Build Coastguard Worker if (BI->getSuccessor(1) != Header)
1553*9880d681SAndroid Build Coastguard Worker BI->swapSuccessors();
1554*9880d681SAndroid Build Coastguard Worker }
1555*9880d681SAndroid Build Coastguard Worker }
1556*9880d681SAndroid Build Coastguard Worker }
1557*9880d681SAndroid Build Coastguard Worker }
1558*9880d681SAndroid Build Coastguard Worker
1559*9880d681SAndroid Build Coastguard Worker // Validate the selected reductions. All iterations must have an isomorphic
1560*9880d681SAndroid Build Coastguard Worker // part of the reduction chain and, for non-associative reductions, the chain
1561*9880d681SAndroid Build Coastguard Worker // entries must appear in order.
validateSelected()1562*9880d681SAndroid Build Coastguard Worker bool LoopReroll::ReductionTracker::validateSelected() {
1563*9880d681SAndroid Build Coastguard Worker // For a non-associative reduction, the chain entries must appear in order.
1564*9880d681SAndroid Build Coastguard Worker for (int i : Reds) {
1565*9880d681SAndroid Build Coastguard Worker int PrevIter = 0, BaseCount = 0, Count = 0;
1566*9880d681SAndroid Build Coastguard Worker for (Instruction *J : PossibleReds[i]) {
1567*9880d681SAndroid Build Coastguard Worker // Note that all instructions in the chain must have been found because
1568*9880d681SAndroid Build Coastguard Worker // all instructions in the function must have been assigned to some
1569*9880d681SAndroid Build Coastguard Worker // iteration.
1570*9880d681SAndroid Build Coastguard Worker int Iter = PossibleRedIter[J];
1571*9880d681SAndroid Build Coastguard Worker if (Iter != PrevIter && Iter != PrevIter + 1 &&
1572*9880d681SAndroid Build Coastguard Worker !PossibleReds[i].getReducedValue()->isAssociative()) {
1573*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Out-of-order non-associative reduction: " <<
1574*9880d681SAndroid Build Coastguard Worker J << "\n");
1575*9880d681SAndroid Build Coastguard Worker return false;
1576*9880d681SAndroid Build Coastguard Worker }
1577*9880d681SAndroid Build Coastguard Worker
1578*9880d681SAndroid Build Coastguard Worker if (Iter != PrevIter) {
1579*9880d681SAndroid Build Coastguard Worker if (Count != BaseCount) {
1580*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Iteration " << PrevIter <<
1581*9880d681SAndroid Build Coastguard Worker " reduction use count " << Count <<
1582*9880d681SAndroid Build Coastguard Worker " is not equal to the base use count " <<
1583*9880d681SAndroid Build Coastguard Worker BaseCount << "\n");
1584*9880d681SAndroid Build Coastguard Worker return false;
1585*9880d681SAndroid Build Coastguard Worker }
1586*9880d681SAndroid Build Coastguard Worker
1587*9880d681SAndroid Build Coastguard Worker Count = 0;
1588*9880d681SAndroid Build Coastguard Worker }
1589*9880d681SAndroid Build Coastguard Worker
1590*9880d681SAndroid Build Coastguard Worker ++Count;
1591*9880d681SAndroid Build Coastguard Worker if (Iter == 0)
1592*9880d681SAndroid Build Coastguard Worker ++BaseCount;
1593*9880d681SAndroid Build Coastguard Worker
1594*9880d681SAndroid Build Coastguard Worker PrevIter = Iter;
1595*9880d681SAndroid Build Coastguard Worker }
1596*9880d681SAndroid Build Coastguard Worker }
1597*9880d681SAndroid Build Coastguard Worker
1598*9880d681SAndroid Build Coastguard Worker return true;
1599*9880d681SAndroid Build Coastguard Worker }
1600*9880d681SAndroid Build Coastguard Worker
1601*9880d681SAndroid Build Coastguard Worker // For all selected reductions, remove all parts except those in the first
1602*9880d681SAndroid Build Coastguard Worker // iteration (and the PHI). Replace outside uses of the reduced value with uses
1603*9880d681SAndroid Build Coastguard Worker // of the first-iteration reduced value (in other words, reroll the selected
1604*9880d681SAndroid Build Coastguard Worker // reductions).
replaceSelected()1605*9880d681SAndroid Build Coastguard Worker void LoopReroll::ReductionTracker::replaceSelected() {
1606*9880d681SAndroid Build Coastguard Worker // Fixup reductions to refer to the last instruction associated with the
1607*9880d681SAndroid Build Coastguard Worker // first iteration (not the last).
1608*9880d681SAndroid Build Coastguard Worker for (int i : Reds) {
1609*9880d681SAndroid Build Coastguard Worker int j = 0;
1610*9880d681SAndroid Build Coastguard Worker for (int e = PossibleReds[i].size(); j != e; ++j)
1611*9880d681SAndroid Build Coastguard Worker if (PossibleRedIter[PossibleReds[i][j]] != 0) {
1612*9880d681SAndroid Build Coastguard Worker --j;
1613*9880d681SAndroid Build Coastguard Worker break;
1614*9880d681SAndroid Build Coastguard Worker }
1615*9880d681SAndroid Build Coastguard Worker
1616*9880d681SAndroid Build Coastguard Worker // Replace users with the new end-of-chain value.
1617*9880d681SAndroid Build Coastguard Worker SmallInstructionVector Users;
1618*9880d681SAndroid Build Coastguard Worker for (User *U : PossibleReds[i].getReducedValue()->users()) {
1619*9880d681SAndroid Build Coastguard Worker Users.push_back(cast<Instruction>(U));
1620*9880d681SAndroid Build Coastguard Worker }
1621*9880d681SAndroid Build Coastguard Worker
1622*9880d681SAndroid Build Coastguard Worker for (Instruction *User : Users)
1623*9880d681SAndroid Build Coastguard Worker User->replaceUsesOfWith(PossibleReds[i].getReducedValue(),
1624*9880d681SAndroid Build Coastguard Worker PossibleReds[i][j]);
1625*9880d681SAndroid Build Coastguard Worker }
1626*9880d681SAndroid Build Coastguard Worker }
1627*9880d681SAndroid Build Coastguard Worker
1628*9880d681SAndroid Build Coastguard Worker // Reroll the provided loop with respect to the provided induction variable.
1629*9880d681SAndroid Build Coastguard Worker // Generally, we're looking for a loop like this:
1630*9880d681SAndroid Build Coastguard Worker //
1631*9880d681SAndroid Build Coastguard Worker // %iv = phi [ (preheader, ...), (body, %iv.next) ]
1632*9880d681SAndroid Build Coastguard Worker // f(%iv)
1633*9880d681SAndroid Build Coastguard Worker // %iv.1 = add %iv, 1 <-- a root increment
1634*9880d681SAndroid Build Coastguard Worker // f(%iv.1)
1635*9880d681SAndroid Build Coastguard Worker // %iv.2 = add %iv, 2 <-- a root increment
1636*9880d681SAndroid Build Coastguard Worker // f(%iv.2)
1637*9880d681SAndroid Build Coastguard Worker // %iv.scale_m_1 = add %iv, scale-1 <-- a root increment
1638*9880d681SAndroid Build Coastguard Worker // f(%iv.scale_m_1)
1639*9880d681SAndroid Build Coastguard Worker // ...
1640*9880d681SAndroid Build Coastguard Worker // %iv.next = add %iv, scale
1641*9880d681SAndroid Build Coastguard Worker // %cmp = icmp(%iv, ...)
1642*9880d681SAndroid Build Coastguard Worker // br %cmp, header, exit
1643*9880d681SAndroid Build Coastguard Worker //
1644*9880d681SAndroid Build Coastguard Worker // Notably, we do not require that f(%iv), f(%iv.1), etc. be isolated groups of
1645*9880d681SAndroid Build Coastguard Worker // instructions. In other words, the instructions in f(%iv), f(%iv.1), etc. can
1646*9880d681SAndroid Build Coastguard Worker // be intermixed with eachother. The restriction imposed by this algorithm is
1647*9880d681SAndroid Build Coastguard Worker // that the relative order of the isomorphic instructions in f(%iv), f(%iv.1),
1648*9880d681SAndroid Build Coastguard Worker // etc. be the same.
1649*9880d681SAndroid Build Coastguard Worker //
1650*9880d681SAndroid Build Coastguard Worker // First, we collect the use set of %iv, excluding the other increment roots.
1651*9880d681SAndroid Build Coastguard Worker // This gives us f(%iv). Then we iterate over the loop instructions (scale-1)
1652*9880d681SAndroid Build Coastguard Worker // times, having collected the use set of f(%iv.(i+1)), during which we:
1653*9880d681SAndroid Build Coastguard Worker // - Ensure that the next unmatched instruction in f(%iv) is isomorphic to
1654*9880d681SAndroid Build Coastguard Worker // the next unmatched instruction in f(%iv.(i+1)).
1655*9880d681SAndroid Build Coastguard Worker // - Ensure that both matched instructions don't have any external users
1656*9880d681SAndroid Build Coastguard Worker // (with the exception of last-in-chain reduction instructions).
1657*9880d681SAndroid Build Coastguard Worker // - Track the (aliasing) write set, and other side effects, of all
1658*9880d681SAndroid Build Coastguard Worker // instructions that belong to future iterations that come before the matched
1659*9880d681SAndroid Build Coastguard Worker // instructions. If the matched instructions read from that write set, then
1660*9880d681SAndroid Build Coastguard Worker // f(%iv) or f(%iv.(i+1)) has some dependency on instructions in
1661*9880d681SAndroid Build Coastguard Worker // f(%iv.(j+1)) for some j > i, and we cannot reroll the loop. Similarly,
1662*9880d681SAndroid Build Coastguard Worker // if any of these future instructions had side effects (could not be
1663*9880d681SAndroid Build Coastguard Worker // speculatively executed), and so do the matched instructions, when we
1664*9880d681SAndroid Build Coastguard Worker // cannot reorder those side-effect-producing instructions, and rerolling
1665*9880d681SAndroid Build Coastguard Worker // fails.
1666*9880d681SAndroid Build Coastguard Worker //
1667*9880d681SAndroid Build Coastguard Worker // Finally, we make sure that all loop instructions are either loop increment
1668*9880d681SAndroid Build Coastguard Worker // roots, belong to simple latch code, parts of validated reductions, part of
1669*9880d681SAndroid Build Coastguard Worker // f(%iv) or part of some f(%iv.i). If all of that is true (and all reductions
1670*9880d681SAndroid Build Coastguard Worker // have been validated), then we reroll the loop.
reroll(Instruction * IV,Loop * L,BasicBlock * Header,const SCEV * IterCount,ReductionTracker & Reductions)1671*9880d681SAndroid Build Coastguard Worker bool LoopReroll::reroll(Instruction *IV, Loop *L, BasicBlock *Header,
1672*9880d681SAndroid Build Coastguard Worker const SCEV *IterCount,
1673*9880d681SAndroid Build Coastguard Worker ReductionTracker &Reductions) {
1674*9880d681SAndroid Build Coastguard Worker DAGRootTracker DAGRoots(this, L, IV, SE, AA, TLI, DT, LI, PreserveLCSSA,
1675*9880d681SAndroid Build Coastguard Worker IVToIncMap, LoopControlIV);
1676*9880d681SAndroid Build Coastguard Worker
1677*9880d681SAndroid Build Coastguard Worker if (!DAGRoots.findRoots())
1678*9880d681SAndroid Build Coastguard Worker return false;
1679*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: Found all root induction increments for: " <<
1680*9880d681SAndroid Build Coastguard Worker *IV << "\n");
1681*9880d681SAndroid Build Coastguard Worker
1682*9880d681SAndroid Build Coastguard Worker if (!DAGRoots.validate(Reductions))
1683*9880d681SAndroid Build Coastguard Worker return false;
1684*9880d681SAndroid Build Coastguard Worker if (!Reductions.validateSelected())
1685*9880d681SAndroid Build Coastguard Worker return false;
1686*9880d681SAndroid Build Coastguard Worker // At this point, we've validated the rerolling, and we're committed to
1687*9880d681SAndroid Build Coastguard Worker // making changes!
1688*9880d681SAndroid Build Coastguard Worker
1689*9880d681SAndroid Build Coastguard Worker Reductions.replaceSelected();
1690*9880d681SAndroid Build Coastguard Worker DAGRoots.replace(IterCount);
1691*9880d681SAndroid Build Coastguard Worker
1692*9880d681SAndroid Build Coastguard Worker ++NumRerolledLoops;
1693*9880d681SAndroid Build Coastguard Worker return true;
1694*9880d681SAndroid Build Coastguard Worker }
1695*9880d681SAndroid Build Coastguard Worker
runOnLoop(Loop * L,LPPassManager & LPM)1696*9880d681SAndroid Build Coastguard Worker bool LoopReroll::runOnLoop(Loop *L, LPPassManager &LPM) {
1697*9880d681SAndroid Build Coastguard Worker if (skipLoop(L))
1698*9880d681SAndroid Build Coastguard Worker return false;
1699*9880d681SAndroid Build Coastguard Worker
1700*9880d681SAndroid Build Coastguard Worker AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
1701*9880d681SAndroid Build Coastguard Worker LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1702*9880d681SAndroid Build Coastguard Worker SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1703*9880d681SAndroid Build Coastguard Worker TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1704*9880d681SAndroid Build Coastguard Worker DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1705*9880d681SAndroid Build Coastguard Worker PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
1706*9880d681SAndroid Build Coastguard Worker
1707*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = L->getHeader();
1708*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: F[" << Header->getParent()->getName() <<
1709*9880d681SAndroid Build Coastguard Worker "] Loop %" << Header->getName() << " (" <<
1710*9880d681SAndroid Build Coastguard Worker L->getNumBlocks() << " block(s))\n");
1711*9880d681SAndroid Build Coastguard Worker
1712*9880d681SAndroid Build Coastguard Worker // For now, we'll handle only single BB loops.
1713*9880d681SAndroid Build Coastguard Worker if (L->getNumBlocks() > 1)
1714*9880d681SAndroid Build Coastguard Worker return false;
1715*9880d681SAndroid Build Coastguard Worker
1716*9880d681SAndroid Build Coastguard Worker if (!SE->hasLoopInvariantBackedgeTakenCount(L))
1717*9880d681SAndroid Build Coastguard Worker return false;
1718*9880d681SAndroid Build Coastguard Worker
1719*9880d681SAndroid Build Coastguard Worker const SCEV *LIBETC = SE->getBackedgeTakenCount(L);
1720*9880d681SAndroid Build Coastguard Worker const SCEV *IterCount = SE->getAddExpr(LIBETC, SE->getOne(LIBETC->getType()));
1721*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\n Before Reroll:\n" << *(L->getHeader()) << "\n");
1722*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: iteration count = " << *IterCount << "\n");
1723*9880d681SAndroid Build Coastguard Worker
1724*9880d681SAndroid Build Coastguard Worker // First, we need to find the induction variable with respect to which we can
1725*9880d681SAndroid Build Coastguard Worker // reroll (there may be several possible options).
1726*9880d681SAndroid Build Coastguard Worker SmallInstructionVector PossibleIVs;
1727*9880d681SAndroid Build Coastguard Worker IVToIncMap.clear();
1728*9880d681SAndroid Build Coastguard Worker LoopControlIV = nullptr;
1729*9880d681SAndroid Build Coastguard Worker collectPossibleIVs(L, PossibleIVs);
1730*9880d681SAndroid Build Coastguard Worker
1731*9880d681SAndroid Build Coastguard Worker if (PossibleIVs.empty()) {
1732*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "LRR: No possible IVs found\n");
1733*9880d681SAndroid Build Coastguard Worker return false;
1734*9880d681SAndroid Build Coastguard Worker }
1735*9880d681SAndroid Build Coastguard Worker
1736*9880d681SAndroid Build Coastguard Worker ReductionTracker Reductions;
1737*9880d681SAndroid Build Coastguard Worker collectPossibleReductions(L, Reductions);
1738*9880d681SAndroid Build Coastguard Worker bool Changed = false;
1739*9880d681SAndroid Build Coastguard Worker
1740*9880d681SAndroid Build Coastguard Worker // For each possible IV, collect the associated possible set of 'root' nodes
1741*9880d681SAndroid Build Coastguard Worker // (i+1, i+2, etc.).
1742*9880d681SAndroid Build Coastguard Worker for (Instruction *PossibleIV : PossibleIVs)
1743*9880d681SAndroid Build Coastguard Worker if (reroll(PossibleIV, L, Header, IterCount, Reductions)) {
1744*9880d681SAndroid Build Coastguard Worker Changed = true;
1745*9880d681SAndroid Build Coastguard Worker break;
1746*9880d681SAndroid Build Coastguard Worker }
1747*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\n After Reroll:\n" << *(L->getHeader()) << "\n");
1748*9880d681SAndroid Build Coastguard Worker
1749*9880d681SAndroid Build Coastguard Worker // Trip count of L has changed so SE must be re-evaluated.
1750*9880d681SAndroid Build Coastguard Worker if (Changed)
1751*9880d681SAndroid Build Coastguard Worker SE->forgetLoop(L);
1752*9880d681SAndroid Build Coastguard Worker
1753*9880d681SAndroid Build Coastguard Worker return Changed;
1754*9880d681SAndroid Build Coastguard Worker }
1755