1f4a2713aSLionel Sambuc //===-- DependenceAnalysis.cpp - DA Implementation --------------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // DependenceAnalysis is an LLVM pass that analyses dependences between memory
11f4a2713aSLionel Sambuc // accesses. Currently, it is an (incomplete) implementation of the approach
12f4a2713aSLionel Sambuc // described in
13f4a2713aSLionel Sambuc //
14f4a2713aSLionel Sambuc //            Practical Dependence Testing
15f4a2713aSLionel Sambuc //            Goff, Kennedy, Tseng
16f4a2713aSLionel Sambuc //            PLDI 1991
17f4a2713aSLionel Sambuc //
18f4a2713aSLionel Sambuc // There's a single entry point that analyzes the dependence between a pair
19f4a2713aSLionel Sambuc // of memory references in a function, returning either NULL, for no dependence,
20f4a2713aSLionel Sambuc // or a more-or-less detailed description of the dependence between them.
21f4a2713aSLionel Sambuc //
22f4a2713aSLionel Sambuc // Currently, the implementation cannot propagate constraints between
23f4a2713aSLionel Sambuc // coupled RDIV subscripts and lacks a multi-subscript MIV test.
24f4a2713aSLionel Sambuc // Both of these are conservative weaknesses;
25f4a2713aSLionel Sambuc // that is, not a source of correctness problems.
26f4a2713aSLionel Sambuc //
27f4a2713aSLionel Sambuc // The implementation depends on the GEP instruction to differentiate
28f4a2713aSLionel Sambuc // subscripts. Since Clang linearizes some array subscripts, the dependence
29f4a2713aSLionel Sambuc // analysis is using SCEV->delinearize to recover the representation of multiple
30f4a2713aSLionel Sambuc // subscripts, and thus avoid the more expensive and less precise MIV tests. The
31f4a2713aSLionel Sambuc // delinearization is controlled by the flag -da-delinearize.
32f4a2713aSLionel Sambuc //
33f4a2713aSLionel Sambuc // We should pay some careful attention to the possibility of integer overflow
34f4a2713aSLionel Sambuc // in the implementation of the various tests. This could happen with Add,
35f4a2713aSLionel Sambuc // Subtract, or Multiply, with both APInt's and SCEV's.
36f4a2713aSLionel Sambuc //
37f4a2713aSLionel Sambuc // Some non-linear subscript pairs can be handled by the GCD test
38f4a2713aSLionel Sambuc // (and perhaps other tests).
39f4a2713aSLionel Sambuc // Should explore how often these things occur.
40f4a2713aSLionel Sambuc //
41f4a2713aSLionel Sambuc // Finally, it seems like certain test cases expose weaknesses in the SCEV
42f4a2713aSLionel Sambuc // simplification, especially in the handling of sign and zero extensions.
43f4a2713aSLionel Sambuc // It could be useful to spend time exploring these.
44f4a2713aSLionel Sambuc //
45f4a2713aSLionel Sambuc // Please note that this is work in progress and the interface is subject to
46f4a2713aSLionel Sambuc // change.
47f4a2713aSLionel Sambuc //
48f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
49f4a2713aSLionel Sambuc //                                                                            //
50f4a2713aSLionel Sambuc //                   In memory of Ken Kennedy, 1945 - 2007                    //
51f4a2713aSLionel Sambuc //                                                                            //
52f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc #include "llvm/Analysis/DependenceAnalysis.h"
55f4a2713aSLionel Sambuc #include "llvm/ADT/Statistic.h"
56f4a2713aSLionel Sambuc #include "llvm/Analysis/AliasAnalysis.h"
57f4a2713aSLionel Sambuc #include "llvm/Analysis/LoopInfo.h"
58f4a2713aSLionel Sambuc #include "llvm/Analysis/ScalarEvolution.h"
59f4a2713aSLionel Sambuc #include "llvm/Analysis/ScalarEvolutionExpressions.h"
60f4a2713aSLionel Sambuc #include "llvm/Analysis/ValueTracking.h"
61*0a6a1f1dSLionel Sambuc #include "llvm/IR/InstIterator.h"
62f4a2713aSLionel Sambuc #include "llvm/IR/Operator.h"
63f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
64f4a2713aSLionel Sambuc #include "llvm/Support/Debug.h"
65f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
66f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc using namespace llvm;
69f4a2713aSLionel Sambuc 
70*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "da"
71*0a6a1f1dSLionel Sambuc 
72f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
73f4a2713aSLionel Sambuc // statistics
74f4a2713aSLionel Sambuc 
75f4a2713aSLionel Sambuc STATISTIC(TotalArrayPairs, "Array pairs tested");
76f4a2713aSLionel Sambuc STATISTIC(SeparableSubscriptPairs, "Separable subscript pairs");
77f4a2713aSLionel Sambuc STATISTIC(CoupledSubscriptPairs, "Coupled subscript pairs");
78f4a2713aSLionel Sambuc STATISTIC(NonlinearSubscriptPairs, "Nonlinear subscript pairs");
79f4a2713aSLionel Sambuc STATISTIC(ZIVapplications, "ZIV applications");
80f4a2713aSLionel Sambuc STATISTIC(ZIVindependence, "ZIV independence");
81f4a2713aSLionel Sambuc STATISTIC(StrongSIVapplications, "Strong SIV applications");
82f4a2713aSLionel Sambuc STATISTIC(StrongSIVsuccesses, "Strong SIV successes");
83f4a2713aSLionel Sambuc STATISTIC(StrongSIVindependence, "Strong SIV independence");
84f4a2713aSLionel Sambuc STATISTIC(WeakCrossingSIVapplications, "Weak-Crossing SIV applications");
85f4a2713aSLionel Sambuc STATISTIC(WeakCrossingSIVsuccesses, "Weak-Crossing SIV successes");
86f4a2713aSLionel Sambuc STATISTIC(WeakCrossingSIVindependence, "Weak-Crossing SIV independence");
87f4a2713aSLionel Sambuc STATISTIC(ExactSIVapplications, "Exact SIV applications");
88f4a2713aSLionel Sambuc STATISTIC(ExactSIVsuccesses, "Exact SIV successes");
89f4a2713aSLionel Sambuc STATISTIC(ExactSIVindependence, "Exact SIV independence");
90f4a2713aSLionel Sambuc STATISTIC(WeakZeroSIVapplications, "Weak-Zero SIV applications");
91f4a2713aSLionel Sambuc STATISTIC(WeakZeroSIVsuccesses, "Weak-Zero SIV successes");
92f4a2713aSLionel Sambuc STATISTIC(WeakZeroSIVindependence, "Weak-Zero SIV independence");
93f4a2713aSLionel Sambuc STATISTIC(ExactRDIVapplications, "Exact RDIV applications");
94f4a2713aSLionel Sambuc STATISTIC(ExactRDIVindependence, "Exact RDIV independence");
95f4a2713aSLionel Sambuc STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
96f4a2713aSLionel Sambuc STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
97f4a2713aSLionel Sambuc STATISTIC(DeltaApplications, "Delta applications");
98f4a2713aSLionel Sambuc STATISTIC(DeltaSuccesses, "Delta successes");
99f4a2713aSLionel Sambuc STATISTIC(DeltaIndependence, "Delta independence");
100f4a2713aSLionel Sambuc STATISTIC(DeltaPropagations, "Delta propagations");
101f4a2713aSLionel Sambuc STATISTIC(GCDapplications, "GCD applications");
102f4a2713aSLionel Sambuc STATISTIC(GCDsuccesses, "GCD successes");
103f4a2713aSLionel Sambuc STATISTIC(GCDindependence, "GCD independence");
104f4a2713aSLionel Sambuc STATISTIC(BanerjeeApplications, "Banerjee applications");
105f4a2713aSLionel Sambuc STATISTIC(BanerjeeIndependence, "Banerjee independence");
106f4a2713aSLionel Sambuc STATISTIC(BanerjeeSuccesses, "Banerjee successes");
107f4a2713aSLionel Sambuc 
108f4a2713aSLionel Sambuc static cl::opt<bool>
109f4a2713aSLionel Sambuc Delinearize("da-delinearize", cl::init(false), cl::Hidden, cl::ZeroOrMore,
110f4a2713aSLionel Sambuc             cl::desc("Try to delinearize array references."));
111f4a2713aSLionel Sambuc 
112f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
113f4a2713aSLionel Sambuc // basics
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc INITIALIZE_PASS_BEGIN(DependenceAnalysis, "da",
116f4a2713aSLionel Sambuc                       "Dependence Analysis", true, true)
117f4a2713aSLionel Sambuc INITIALIZE_PASS_DEPENDENCY(LoopInfo)
118f4a2713aSLionel Sambuc INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
119f4a2713aSLionel Sambuc INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
120f4a2713aSLionel Sambuc INITIALIZE_PASS_END(DependenceAnalysis, "da",
121f4a2713aSLionel Sambuc                     "Dependence Analysis", true, true)
122f4a2713aSLionel Sambuc 
123f4a2713aSLionel Sambuc char DependenceAnalysis::ID = 0;
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc 
createDependenceAnalysisPass()126f4a2713aSLionel Sambuc FunctionPass *llvm::createDependenceAnalysisPass() {
127f4a2713aSLionel Sambuc   return new DependenceAnalysis();
128f4a2713aSLionel Sambuc }
129f4a2713aSLionel Sambuc 
130f4a2713aSLionel Sambuc 
runOnFunction(Function & F)131f4a2713aSLionel Sambuc bool DependenceAnalysis::runOnFunction(Function &F) {
132f4a2713aSLionel Sambuc   this->F = &F;
133f4a2713aSLionel Sambuc   AA = &getAnalysis<AliasAnalysis>();
134f4a2713aSLionel Sambuc   SE = &getAnalysis<ScalarEvolution>();
135f4a2713aSLionel Sambuc   LI = &getAnalysis<LoopInfo>();
136f4a2713aSLionel Sambuc   return false;
137f4a2713aSLionel Sambuc }
138f4a2713aSLionel Sambuc 
139f4a2713aSLionel Sambuc 
releaseMemory()140f4a2713aSLionel Sambuc void DependenceAnalysis::releaseMemory() {
141f4a2713aSLionel Sambuc }
142f4a2713aSLionel Sambuc 
143f4a2713aSLionel Sambuc 
getAnalysisUsage(AnalysisUsage & AU) const144f4a2713aSLionel Sambuc void DependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
145f4a2713aSLionel Sambuc   AU.setPreservesAll();
146f4a2713aSLionel Sambuc   AU.addRequiredTransitive<AliasAnalysis>();
147f4a2713aSLionel Sambuc   AU.addRequiredTransitive<ScalarEvolution>();
148f4a2713aSLionel Sambuc   AU.addRequiredTransitive<LoopInfo>();
149f4a2713aSLionel Sambuc }
150f4a2713aSLionel Sambuc 
151f4a2713aSLionel Sambuc 
152f4a2713aSLionel Sambuc // Used to test the dependence analyzer.
153f4a2713aSLionel Sambuc // Looks through the function, noting loads and stores.
154f4a2713aSLionel Sambuc // Calls depends() on every possible pair and prints out the result.
155f4a2713aSLionel Sambuc // Ignores all other instructions.
156f4a2713aSLionel Sambuc static
dumpExampleDependence(raw_ostream & OS,Function * F,DependenceAnalysis * DA)157f4a2713aSLionel Sambuc void dumpExampleDependence(raw_ostream &OS, Function *F,
158f4a2713aSLionel Sambuc                            DependenceAnalysis *DA) {
159f4a2713aSLionel Sambuc   for (inst_iterator SrcI = inst_begin(F), SrcE = inst_end(F);
160f4a2713aSLionel Sambuc        SrcI != SrcE; ++SrcI) {
161f4a2713aSLionel Sambuc     if (isa<StoreInst>(*SrcI) || isa<LoadInst>(*SrcI)) {
162f4a2713aSLionel Sambuc       for (inst_iterator DstI = SrcI, DstE = inst_end(F);
163f4a2713aSLionel Sambuc            DstI != DstE; ++DstI) {
164f4a2713aSLionel Sambuc         if (isa<StoreInst>(*DstI) || isa<LoadInst>(*DstI)) {
165f4a2713aSLionel Sambuc           OS << "da analyze - ";
166*0a6a1f1dSLionel Sambuc           if (auto D = DA->depends(&*SrcI, &*DstI, true)) {
167f4a2713aSLionel Sambuc             D->dump(OS);
168f4a2713aSLionel Sambuc             for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
169f4a2713aSLionel Sambuc               if (D->isSplitable(Level)) {
170f4a2713aSLionel Sambuc                 OS << "da analyze - split level = " << Level;
171*0a6a1f1dSLionel Sambuc                 OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
172f4a2713aSLionel Sambuc                 OS << "!\n";
173f4a2713aSLionel Sambuc               }
174f4a2713aSLionel Sambuc             }
175f4a2713aSLionel Sambuc           }
176f4a2713aSLionel Sambuc           else
177f4a2713aSLionel Sambuc             OS << "none!\n";
178f4a2713aSLionel Sambuc         }
179f4a2713aSLionel Sambuc       }
180f4a2713aSLionel Sambuc     }
181f4a2713aSLionel Sambuc   }
182f4a2713aSLionel Sambuc }
183f4a2713aSLionel Sambuc 
184f4a2713aSLionel Sambuc 
print(raw_ostream & OS,const Module *) const185f4a2713aSLionel Sambuc void DependenceAnalysis::print(raw_ostream &OS, const Module*) const {
186f4a2713aSLionel Sambuc   dumpExampleDependence(OS, F, const_cast<DependenceAnalysis *>(this));
187f4a2713aSLionel Sambuc }
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
190f4a2713aSLionel Sambuc // Dependence methods
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc // Returns true if this is an input dependence.
isInput() const193f4a2713aSLionel Sambuc bool Dependence::isInput() const {
194f4a2713aSLionel Sambuc   return Src->mayReadFromMemory() && Dst->mayReadFromMemory();
195f4a2713aSLionel Sambuc }
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc 
198f4a2713aSLionel Sambuc // Returns true if this is an output dependence.
isOutput() const199f4a2713aSLionel Sambuc bool Dependence::isOutput() const {
200f4a2713aSLionel Sambuc   return Src->mayWriteToMemory() && Dst->mayWriteToMemory();
201f4a2713aSLionel Sambuc }
202f4a2713aSLionel Sambuc 
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc // Returns true if this is an flow (aka true)  dependence.
isFlow() const205f4a2713aSLionel Sambuc bool Dependence::isFlow() const {
206f4a2713aSLionel Sambuc   return Src->mayWriteToMemory() && Dst->mayReadFromMemory();
207f4a2713aSLionel Sambuc }
208f4a2713aSLionel Sambuc 
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc // Returns true if this is an anti dependence.
isAnti() const211f4a2713aSLionel Sambuc bool Dependence::isAnti() const {
212f4a2713aSLionel Sambuc   return Src->mayReadFromMemory() && Dst->mayWriteToMemory();
213f4a2713aSLionel Sambuc }
214f4a2713aSLionel Sambuc 
215f4a2713aSLionel Sambuc 
216f4a2713aSLionel Sambuc // Returns true if a particular level is scalar; that is,
217f4a2713aSLionel Sambuc // if no subscript in the source or destination mention the induction
218f4a2713aSLionel Sambuc // variable associated with the loop at this level.
219f4a2713aSLionel Sambuc // Leave this out of line, so it will serve as a virtual method anchor
isScalar(unsigned level) const220f4a2713aSLionel Sambuc bool Dependence::isScalar(unsigned level) const {
221f4a2713aSLionel Sambuc   return false;
222f4a2713aSLionel Sambuc }
223f4a2713aSLionel Sambuc 
224f4a2713aSLionel Sambuc 
225f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
226f4a2713aSLionel Sambuc // FullDependence methods
227f4a2713aSLionel Sambuc 
FullDependence(Instruction * Source,Instruction * Destination,bool PossiblyLoopIndependent,unsigned CommonLevels)228f4a2713aSLionel Sambuc FullDependence::FullDependence(Instruction *Source,
229f4a2713aSLionel Sambuc                                Instruction *Destination,
230f4a2713aSLionel Sambuc                                bool PossiblyLoopIndependent,
231f4a2713aSLionel Sambuc                                unsigned CommonLevels) :
232f4a2713aSLionel Sambuc   Dependence(Source, Destination),
233f4a2713aSLionel Sambuc   Levels(CommonLevels),
234f4a2713aSLionel Sambuc   LoopIndependent(PossiblyLoopIndependent) {
235f4a2713aSLionel Sambuc   Consistent = true;
236*0a6a1f1dSLionel Sambuc   DV = CommonLevels ? new DVEntry[CommonLevels] : nullptr;
237f4a2713aSLionel Sambuc }
238f4a2713aSLionel Sambuc 
239f4a2713aSLionel Sambuc // The rest are simple getters that hide the implementation.
240f4a2713aSLionel Sambuc 
241f4a2713aSLionel Sambuc // getDirection - Returns the direction associated with a particular level.
getDirection(unsigned Level) const242f4a2713aSLionel Sambuc unsigned FullDependence::getDirection(unsigned Level) const {
243f4a2713aSLionel Sambuc   assert(0 < Level && Level <= Levels && "Level out of range");
244f4a2713aSLionel Sambuc   return DV[Level - 1].Direction;
245f4a2713aSLionel Sambuc }
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc 
248f4a2713aSLionel Sambuc // Returns the distance (or NULL) associated with a particular level.
getDistance(unsigned Level) const249f4a2713aSLionel Sambuc const SCEV *FullDependence::getDistance(unsigned Level) const {
250f4a2713aSLionel Sambuc   assert(0 < Level && Level <= Levels && "Level out of range");
251f4a2713aSLionel Sambuc   return DV[Level - 1].Distance;
252f4a2713aSLionel Sambuc }
253f4a2713aSLionel Sambuc 
254f4a2713aSLionel Sambuc 
255f4a2713aSLionel Sambuc // Returns true if a particular level is scalar; that is,
256f4a2713aSLionel Sambuc // if no subscript in the source or destination mention the induction
257f4a2713aSLionel Sambuc // variable associated with the loop at this level.
isScalar(unsigned Level) const258f4a2713aSLionel Sambuc bool FullDependence::isScalar(unsigned Level) const {
259f4a2713aSLionel Sambuc   assert(0 < Level && Level <= Levels && "Level out of range");
260f4a2713aSLionel Sambuc   return DV[Level - 1].Scalar;
261f4a2713aSLionel Sambuc }
262f4a2713aSLionel Sambuc 
263f4a2713aSLionel Sambuc 
264f4a2713aSLionel Sambuc // Returns true if peeling the first iteration from this loop
265f4a2713aSLionel Sambuc // will break this dependence.
isPeelFirst(unsigned Level) const266f4a2713aSLionel Sambuc bool FullDependence::isPeelFirst(unsigned Level) const {
267f4a2713aSLionel Sambuc   assert(0 < Level && Level <= Levels && "Level out of range");
268f4a2713aSLionel Sambuc   return DV[Level - 1].PeelFirst;
269f4a2713aSLionel Sambuc }
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc 
272f4a2713aSLionel Sambuc // Returns true if peeling the last iteration from this loop
273f4a2713aSLionel Sambuc // will break this dependence.
isPeelLast(unsigned Level) const274f4a2713aSLionel Sambuc bool FullDependence::isPeelLast(unsigned Level) const {
275f4a2713aSLionel Sambuc   assert(0 < Level && Level <= Levels && "Level out of range");
276f4a2713aSLionel Sambuc   return DV[Level - 1].PeelLast;
277f4a2713aSLionel Sambuc }
278f4a2713aSLionel Sambuc 
279f4a2713aSLionel Sambuc 
280f4a2713aSLionel Sambuc // Returns true if splitting this loop will break the dependence.
isSplitable(unsigned Level) const281f4a2713aSLionel Sambuc bool FullDependence::isSplitable(unsigned Level) const {
282f4a2713aSLionel Sambuc   assert(0 < Level && Level <= Levels && "Level out of range");
283f4a2713aSLionel Sambuc   return DV[Level - 1].Splitable;
284f4a2713aSLionel Sambuc }
285f4a2713aSLionel Sambuc 
286f4a2713aSLionel Sambuc 
287f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
288f4a2713aSLionel Sambuc // DependenceAnalysis::Constraint methods
289f4a2713aSLionel Sambuc 
290f4a2713aSLionel Sambuc // If constraint is a point <X, Y>, returns X.
291f4a2713aSLionel Sambuc // Otherwise assert.
getX() const292f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::Constraint::getX() const {
293f4a2713aSLionel Sambuc   assert(Kind == Point && "Kind should be Point");
294f4a2713aSLionel Sambuc   return A;
295f4a2713aSLionel Sambuc }
296f4a2713aSLionel Sambuc 
297f4a2713aSLionel Sambuc 
298f4a2713aSLionel Sambuc // If constraint is a point <X, Y>, returns Y.
299f4a2713aSLionel Sambuc // Otherwise assert.
getY() const300f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::Constraint::getY() const {
301f4a2713aSLionel Sambuc   assert(Kind == Point && "Kind should be Point");
302f4a2713aSLionel Sambuc   return B;
303f4a2713aSLionel Sambuc }
304f4a2713aSLionel Sambuc 
305f4a2713aSLionel Sambuc 
306f4a2713aSLionel Sambuc // If constraint is a line AX + BY = C, returns A.
307f4a2713aSLionel Sambuc // Otherwise assert.
getA() const308f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::Constraint::getA() const {
309f4a2713aSLionel Sambuc   assert((Kind == Line || Kind == Distance) &&
310f4a2713aSLionel Sambuc          "Kind should be Line (or Distance)");
311f4a2713aSLionel Sambuc   return A;
312f4a2713aSLionel Sambuc }
313f4a2713aSLionel Sambuc 
314f4a2713aSLionel Sambuc 
315f4a2713aSLionel Sambuc // If constraint is a line AX + BY = C, returns B.
316f4a2713aSLionel Sambuc // Otherwise assert.
getB() const317f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::Constraint::getB() const {
318f4a2713aSLionel Sambuc   assert((Kind == Line || Kind == Distance) &&
319f4a2713aSLionel Sambuc          "Kind should be Line (or Distance)");
320f4a2713aSLionel Sambuc   return B;
321f4a2713aSLionel Sambuc }
322f4a2713aSLionel Sambuc 
323f4a2713aSLionel Sambuc 
324f4a2713aSLionel Sambuc // If constraint is a line AX + BY = C, returns C.
325f4a2713aSLionel Sambuc // Otherwise assert.
getC() const326f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::Constraint::getC() const {
327f4a2713aSLionel Sambuc   assert((Kind == Line || Kind == Distance) &&
328f4a2713aSLionel Sambuc          "Kind should be Line (or Distance)");
329f4a2713aSLionel Sambuc   return C;
330f4a2713aSLionel Sambuc }
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc 
333f4a2713aSLionel Sambuc // If constraint is a distance, returns D.
334f4a2713aSLionel Sambuc // Otherwise assert.
getD() const335f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::Constraint::getD() const {
336f4a2713aSLionel Sambuc   assert(Kind == Distance && "Kind should be Distance");
337f4a2713aSLionel Sambuc   return SE->getNegativeSCEV(C);
338f4a2713aSLionel Sambuc }
339f4a2713aSLionel Sambuc 
340f4a2713aSLionel Sambuc 
341f4a2713aSLionel Sambuc // Returns the loop associated with this constraint.
getAssociatedLoop() const342f4a2713aSLionel Sambuc const Loop *DependenceAnalysis::Constraint::getAssociatedLoop() const {
343f4a2713aSLionel Sambuc   assert((Kind == Distance || Kind == Line || Kind == Point) &&
344f4a2713aSLionel Sambuc          "Kind should be Distance, Line, or Point");
345f4a2713aSLionel Sambuc   return AssociatedLoop;
346f4a2713aSLionel Sambuc }
347f4a2713aSLionel Sambuc 
348f4a2713aSLionel Sambuc 
setPoint(const SCEV * X,const SCEV * Y,const Loop * CurLoop)349f4a2713aSLionel Sambuc void DependenceAnalysis::Constraint::setPoint(const SCEV *X,
350f4a2713aSLionel Sambuc                                               const SCEV *Y,
351f4a2713aSLionel Sambuc                                               const Loop *CurLoop) {
352f4a2713aSLionel Sambuc   Kind = Point;
353f4a2713aSLionel Sambuc   A = X;
354f4a2713aSLionel Sambuc   B = Y;
355f4a2713aSLionel Sambuc   AssociatedLoop = CurLoop;
356f4a2713aSLionel Sambuc }
357f4a2713aSLionel Sambuc 
358f4a2713aSLionel Sambuc 
setLine(const SCEV * AA,const SCEV * BB,const SCEV * CC,const Loop * CurLoop)359f4a2713aSLionel Sambuc void DependenceAnalysis::Constraint::setLine(const SCEV *AA,
360f4a2713aSLionel Sambuc                                              const SCEV *BB,
361f4a2713aSLionel Sambuc                                              const SCEV *CC,
362f4a2713aSLionel Sambuc                                              const Loop *CurLoop) {
363f4a2713aSLionel Sambuc   Kind = Line;
364f4a2713aSLionel Sambuc   A = AA;
365f4a2713aSLionel Sambuc   B = BB;
366f4a2713aSLionel Sambuc   C = CC;
367f4a2713aSLionel Sambuc   AssociatedLoop = CurLoop;
368f4a2713aSLionel Sambuc }
369f4a2713aSLionel Sambuc 
370f4a2713aSLionel Sambuc 
setDistance(const SCEV * D,const Loop * CurLoop)371f4a2713aSLionel Sambuc void DependenceAnalysis::Constraint::setDistance(const SCEV *D,
372f4a2713aSLionel Sambuc                                                  const Loop *CurLoop) {
373f4a2713aSLionel Sambuc   Kind = Distance;
374f4a2713aSLionel Sambuc   A = SE->getConstant(D->getType(), 1);
375f4a2713aSLionel Sambuc   B = SE->getNegativeSCEV(A);
376f4a2713aSLionel Sambuc   C = SE->getNegativeSCEV(D);
377f4a2713aSLionel Sambuc   AssociatedLoop = CurLoop;
378f4a2713aSLionel Sambuc }
379f4a2713aSLionel Sambuc 
380f4a2713aSLionel Sambuc 
setEmpty()381f4a2713aSLionel Sambuc void DependenceAnalysis::Constraint::setEmpty() {
382f4a2713aSLionel Sambuc   Kind = Empty;
383f4a2713aSLionel Sambuc }
384f4a2713aSLionel Sambuc 
385f4a2713aSLionel Sambuc 
setAny(ScalarEvolution * NewSE)386f4a2713aSLionel Sambuc void DependenceAnalysis::Constraint::setAny(ScalarEvolution *NewSE) {
387f4a2713aSLionel Sambuc   SE = NewSE;
388f4a2713aSLionel Sambuc   Kind = Any;
389f4a2713aSLionel Sambuc }
390f4a2713aSLionel Sambuc 
391f4a2713aSLionel Sambuc 
392f4a2713aSLionel Sambuc // For debugging purposes. Dumps the constraint out to OS.
dump(raw_ostream & OS) const393f4a2713aSLionel Sambuc void DependenceAnalysis::Constraint::dump(raw_ostream &OS) const {
394f4a2713aSLionel Sambuc   if (isEmpty())
395f4a2713aSLionel Sambuc     OS << " Empty\n";
396f4a2713aSLionel Sambuc   else if (isAny())
397f4a2713aSLionel Sambuc     OS << " Any\n";
398f4a2713aSLionel Sambuc   else if (isPoint())
399f4a2713aSLionel Sambuc     OS << " Point is <" << *getX() << ", " << *getY() << ">\n";
400f4a2713aSLionel Sambuc   else if (isDistance())
401f4a2713aSLionel Sambuc     OS << " Distance is " << *getD() <<
402f4a2713aSLionel Sambuc       " (" << *getA() << "*X + " << *getB() << "*Y = " << *getC() << ")\n";
403f4a2713aSLionel Sambuc   else if (isLine())
404f4a2713aSLionel Sambuc     OS << " Line is " << *getA() << "*X + " <<
405f4a2713aSLionel Sambuc       *getB() << "*Y = " << *getC() << "\n";
406f4a2713aSLionel Sambuc   else
407f4a2713aSLionel Sambuc     llvm_unreachable("unknown constraint type in Constraint::dump");
408f4a2713aSLionel Sambuc }
409f4a2713aSLionel Sambuc 
410f4a2713aSLionel Sambuc 
411f4a2713aSLionel Sambuc // Updates X with the intersection
412f4a2713aSLionel Sambuc // of the Constraints X and Y. Returns true if X has changed.
413f4a2713aSLionel Sambuc // Corresponds to Figure 4 from the paper
414f4a2713aSLionel Sambuc //
415f4a2713aSLionel Sambuc //            Practical Dependence Testing
416f4a2713aSLionel Sambuc //            Goff, Kennedy, Tseng
417f4a2713aSLionel Sambuc //            PLDI 1991
intersectConstraints(Constraint * X,const Constraint * Y)418f4a2713aSLionel Sambuc bool DependenceAnalysis::intersectConstraints(Constraint *X,
419f4a2713aSLionel Sambuc                                               const Constraint *Y) {
420f4a2713aSLionel Sambuc   ++DeltaApplications;
421f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tintersect constraints\n");
422f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    X ="; X->dump(dbgs()));
423f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Y ="; Y->dump(dbgs()));
424f4a2713aSLionel Sambuc   assert(!Y->isPoint() && "Y must not be a Point");
425f4a2713aSLionel Sambuc   if (X->isAny()) {
426f4a2713aSLionel Sambuc     if (Y->isAny())
427f4a2713aSLionel Sambuc       return false;
428f4a2713aSLionel Sambuc     *X = *Y;
429f4a2713aSLionel Sambuc     return true;
430f4a2713aSLionel Sambuc   }
431f4a2713aSLionel Sambuc   if (X->isEmpty())
432f4a2713aSLionel Sambuc     return false;
433f4a2713aSLionel Sambuc   if (Y->isEmpty()) {
434f4a2713aSLionel Sambuc     X->setEmpty();
435f4a2713aSLionel Sambuc     return true;
436f4a2713aSLionel Sambuc   }
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc   if (X->isDistance() && Y->isDistance()) {
439f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    intersect 2 distances\n");
440f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, X->getD(), Y->getD()))
441f4a2713aSLionel Sambuc       return false;
442f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_NE, X->getD(), Y->getD())) {
443f4a2713aSLionel Sambuc       X->setEmpty();
444f4a2713aSLionel Sambuc       ++DeltaSuccesses;
445f4a2713aSLionel Sambuc       return true;
446f4a2713aSLionel Sambuc     }
447f4a2713aSLionel Sambuc     // Hmmm, interesting situation.
448f4a2713aSLionel Sambuc     // I guess if either is constant, keep it and ignore the other.
449f4a2713aSLionel Sambuc     if (isa<SCEVConstant>(Y->getD())) {
450f4a2713aSLionel Sambuc       *X = *Y;
451f4a2713aSLionel Sambuc       return true;
452f4a2713aSLionel Sambuc     }
453f4a2713aSLionel Sambuc     return false;
454f4a2713aSLionel Sambuc   }
455f4a2713aSLionel Sambuc 
456f4a2713aSLionel Sambuc   // At this point, the pseudo-code in Figure 4 of the paper
457f4a2713aSLionel Sambuc   // checks if (X->isPoint() && Y->isPoint()).
458f4a2713aSLionel Sambuc   // This case can't occur in our implementation,
459f4a2713aSLionel Sambuc   // since a Point can only arise as the result of intersecting
460f4a2713aSLionel Sambuc   // two Line constraints, and the right-hand value, Y, is never
461f4a2713aSLionel Sambuc   // the result of an intersection.
462f4a2713aSLionel Sambuc   assert(!(X->isPoint() && Y->isPoint()) &&
463f4a2713aSLionel Sambuc          "We shouldn't ever see X->isPoint() && Y->isPoint()");
464f4a2713aSLionel Sambuc 
465f4a2713aSLionel Sambuc   if (X->isLine() && Y->isLine()) {
466f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    intersect 2 lines\n");
467f4a2713aSLionel Sambuc     const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
468f4a2713aSLionel Sambuc     const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
469f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2)) {
470f4a2713aSLionel Sambuc       // slopes are equal, so lines are parallel
471f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tsame slope\n");
472f4a2713aSLionel Sambuc       Prod1 = SE->getMulExpr(X->getC(), Y->getB());
473f4a2713aSLionel Sambuc       Prod2 = SE->getMulExpr(X->getB(), Y->getC());
474f4a2713aSLionel Sambuc       if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2))
475f4a2713aSLionel Sambuc         return false;
476f4a2713aSLionel Sambuc       if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
477f4a2713aSLionel Sambuc         X->setEmpty();
478f4a2713aSLionel Sambuc         ++DeltaSuccesses;
479f4a2713aSLionel Sambuc         return true;
480f4a2713aSLionel Sambuc       }
481f4a2713aSLionel Sambuc       return false;
482f4a2713aSLionel Sambuc     }
483f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
484f4a2713aSLionel Sambuc       // slopes differ, so lines intersect
485f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tdifferent slopes\n");
486f4a2713aSLionel Sambuc       const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
487f4a2713aSLionel Sambuc       const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
488f4a2713aSLionel Sambuc       const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
489f4a2713aSLionel Sambuc       const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->getA());
490f4a2713aSLionel Sambuc       const SCEV *A1B2 = SE->getMulExpr(X->getA(), Y->getB());
491f4a2713aSLionel Sambuc       const SCEV *A2B1 = SE->getMulExpr(Y->getA(), X->getB());
492f4a2713aSLionel Sambuc       const SCEVConstant *C1A2_C2A1 =
493f4a2713aSLionel Sambuc         dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1A2, C2A1));
494f4a2713aSLionel Sambuc       const SCEVConstant *C1B2_C2B1 =
495f4a2713aSLionel Sambuc         dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1B2, C2B1));
496f4a2713aSLionel Sambuc       const SCEVConstant *A1B2_A2B1 =
497f4a2713aSLionel Sambuc         dyn_cast<SCEVConstant>(SE->getMinusSCEV(A1B2, A2B1));
498f4a2713aSLionel Sambuc       const SCEVConstant *A2B1_A1B2 =
499f4a2713aSLionel Sambuc         dyn_cast<SCEVConstant>(SE->getMinusSCEV(A2B1, A1B2));
500f4a2713aSLionel Sambuc       if (!C1B2_C2B1 || !C1A2_C2A1 ||
501f4a2713aSLionel Sambuc           !A1B2_A2B1 || !A2B1_A1B2)
502f4a2713aSLionel Sambuc         return false;
503f4a2713aSLionel Sambuc       APInt Xtop = C1B2_C2B1->getValue()->getValue();
504f4a2713aSLionel Sambuc       APInt Xbot = A1B2_A2B1->getValue()->getValue();
505f4a2713aSLionel Sambuc       APInt Ytop = C1A2_C2A1->getValue()->getValue();
506f4a2713aSLionel Sambuc       APInt Ybot = A2B1_A1B2->getValue()->getValue();
507f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tXtop = " << Xtop << "\n");
508f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tXbot = " << Xbot << "\n");
509f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tYtop = " << Ytop << "\n");
510f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tYbot = " << Ybot << "\n");
511f4a2713aSLionel Sambuc       APInt Xq = Xtop; // these need to be initialized, even
512f4a2713aSLionel Sambuc       APInt Xr = Xtop; // though they're just going to be overwritten
513f4a2713aSLionel Sambuc       APInt::sdivrem(Xtop, Xbot, Xq, Xr);
514f4a2713aSLionel Sambuc       APInt Yq = Ytop;
515f4a2713aSLionel Sambuc       APInt Yr = Ytop;
516f4a2713aSLionel Sambuc       APInt::sdivrem(Ytop, Ybot, Yq, Yr);
517f4a2713aSLionel Sambuc       if (Xr != 0 || Yr != 0) {
518f4a2713aSLionel Sambuc         X->setEmpty();
519f4a2713aSLionel Sambuc         ++DeltaSuccesses;
520f4a2713aSLionel Sambuc         return true;
521f4a2713aSLionel Sambuc       }
522f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t\tX = " << Xq << ", Y = " << Yq << "\n");
523f4a2713aSLionel Sambuc       if (Xq.slt(0) || Yq.slt(0)) {
524f4a2713aSLionel Sambuc         X->setEmpty();
525f4a2713aSLionel Sambuc         ++DeltaSuccesses;
526f4a2713aSLionel Sambuc         return true;
527f4a2713aSLionel Sambuc       }
528f4a2713aSLionel Sambuc       if (const SCEVConstant *CUB =
529f4a2713aSLionel Sambuc           collectConstantUpperBound(X->getAssociatedLoop(), Prod1->getType())) {
530f4a2713aSLionel Sambuc         APInt UpperBound = CUB->getValue()->getValue();
531f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t\tupper bound = " << UpperBound << "\n");
532f4a2713aSLionel Sambuc         if (Xq.sgt(UpperBound) || Yq.sgt(UpperBound)) {
533f4a2713aSLionel Sambuc           X->setEmpty();
534f4a2713aSLionel Sambuc           ++DeltaSuccesses;
535f4a2713aSLionel Sambuc           return true;
536f4a2713aSLionel Sambuc         }
537f4a2713aSLionel Sambuc       }
538f4a2713aSLionel Sambuc       X->setPoint(SE->getConstant(Xq),
539f4a2713aSLionel Sambuc                   SE->getConstant(Yq),
540f4a2713aSLionel Sambuc                   X->getAssociatedLoop());
541f4a2713aSLionel Sambuc       ++DeltaSuccesses;
542f4a2713aSLionel Sambuc       return true;
543f4a2713aSLionel Sambuc     }
544f4a2713aSLionel Sambuc     return false;
545f4a2713aSLionel Sambuc   }
546f4a2713aSLionel Sambuc 
547f4a2713aSLionel Sambuc   // if (X->isLine() && Y->isPoint()) This case can't occur.
548f4a2713aSLionel Sambuc   assert(!(X->isLine() && Y->isPoint()) && "This case should never occur");
549f4a2713aSLionel Sambuc 
550f4a2713aSLionel Sambuc   if (X->isPoint() && Y->isLine()) {
551f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    intersect Point and Line\n");
552f4a2713aSLionel Sambuc     const SCEV *A1X1 = SE->getMulExpr(Y->getA(), X->getX());
553f4a2713aSLionel Sambuc     const SCEV *B1Y1 = SE->getMulExpr(Y->getB(), X->getY());
554f4a2713aSLionel Sambuc     const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
555f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, Sum, Y->getC()))
556f4a2713aSLionel Sambuc       return false;
557f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_NE, Sum, Y->getC())) {
558f4a2713aSLionel Sambuc       X->setEmpty();
559f4a2713aSLionel Sambuc       ++DeltaSuccesses;
560f4a2713aSLionel Sambuc       return true;
561f4a2713aSLionel Sambuc     }
562f4a2713aSLionel Sambuc     return false;
563f4a2713aSLionel Sambuc   }
564f4a2713aSLionel Sambuc 
565f4a2713aSLionel Sambuc   llvm_unreachable("shouldn't reach the end of Constraint intersection");
566f4a2713aSLionel Sambuc   return false;
567f4a2713aSLionel Sambuc }
568f4a2713aSLionel Sambuc 
569f4a2713aSLionel Sambuc 
570f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
571f4a2713aSLionel Sambuc // DependenceAnalysis methods
572f4a2713aSLionel Sambuc 
573f4a2713aSLionel Sambuc // For debugging purposes. Dumps a dependence to OS.
dump(raw_ostream & OS) const574f4a2713aSLionel Sambuc void Dependence::dump(raw_ostream &OS) const {
575f4a2713aSLionel Sambuc   bool Splitable = false;
576f4a2713aSLionel Sambuc   if (isConfused())
577f4a2713aSLionel Sambuc     OS << "confused";
578f4a2713aSLionel Sambuc   else {
579f4a2713aSLionel Sambuc     if (isConsistent())
580f4a2713aSLionel Sambuc       OS << "consistent ";
581f4a2713aSLionel Sambuc     if (isFlow())
582f4a2713aSLionel Sambuc       OS << "flow";
583f4a2713aSLionel Sambuc     else if (isOutput())
584f4a2713aSLionel Sambuc       OS << "output";
585f4a2713aSLionel Sambuc     else if (isAnti())
586f4a2713aSLionel Sambuc       OS << "anti";
587f4a2713aSLionel Sambuc     else if (isInput())
588f4a2713aSLionel Sambuc       OS << "input";
589f4a2713aSLionel Sambuc     unsigned Levels = getLevels();
590f4a2713aSLionel Sambuc     OS << " [";
591f4a2713aSLionel Sambuc     for (unsigned II = 1; II <= Levels; ++II) {
592f4a2713aSLionel Sambuc       if (isSplitable(II))
593f4a2713aSLionel Sambuc         Splitable = true;
594f4a2713aSLionel Sambuc       if (isPeelFirst(II))
595f4a2713aSLionel Sambuc         OS << 'p';
596f4a2713aSLionel Sambuc       const SCEV *Distance = getDistance(II);
597f4a2713aSLionel Sambuc       if (Distance)
598f4a2713aSLionel Sambuc         OS << *Distance;
599f4a2713aSLionel Sambuc       else if (isScalar(II))
600f4a2713aSLionel Sambuc         OS << "S";
601f4a2713aSLionel Sambuc       else {
602f4a2713aSLionel Sambuc         unsigned Direction = getDirection(II);
603f4a2713aSLionel Sambuc         if (Direction == DVEntry::ALL)
604f4a2713aSLionel Sambuc           OS << "*";
605f4a2713aSLionel Sambuc         else {
606f4a2713aSLionel Sambuc           if (Direction & DVEntry::LT)
607f4a2713aSLionel Sambuc             OS << "<";
608f4a2713aSLionel Sambuc           if (Direction & DVEntry::EQ)
609f4a2713aSLionel Sambuc             OS << "=";
610f4a2713aSLionel Sambuc           if (Direction & DVEntry::GT)
611f4a2713aSLionel Sambuc             OS << ">";
612f4a2713aSLionel Sambuc         }
613f4a2713aSLionel Sambuc       }
614f4a2713aSLionel Sambuc       if (isPeelLast(II))
615f4a2713aSLionel Sambuc         OS << 'p';
616f4a2713aSLionel Sambuc       if (II < Levels)
617f4a2713aSLionel Sambuc         OS << " ";
618f4a2713aSLionel Sambuc     }
619f4a2713aSLionel Sambuc     if (isLoopIndependent())
620f4a2713aSLionel Sambuc       OS << "|<";
621f4a2713aSLionel Sambuc     OS << "]";
622f4a2713aSLionel Sambuc     if (Splitable)
623f4a2713aSLionel Sambuc       OS << " splitable";
624f4a2713aSLionel Sambuc   }
625f4a2713aSLionel Sambuc   OS << "!\n";
626f4a2713aSLionel Sambuc }
627f4a2713aSLionel Sambuc 
628f4a2713aSLionel Sambuc 
629f4a2713aSLionel Sambuc 
630f4a2713aSLionel Sambuc static
underlyingObjectsAlias(AliasAnalysis * AA,const Value * A,const Value * B)631f4a2713aSLionel Sambuc AliasAnalysis::AliasResult underlyingObjectsAlias(AliasAnalysis *AA,
632f4a2713aSLionel Sambuc                                                   const Value *A,
633f4a2713aSLionel Sambuc                                                   const Value *B) {
634f4a2713aSLionel Sambuc   const Value *AObj = GetUnderlyingObject(A);
635f4a2713aSLionel Sambuc   const Value *BObj = GetUnderlyingObject(B);
636f4a2713aSLionel Sambuc   return AA->alias(AObj, AA->getTypeStoreSize(AObj->getType()),
637f4a2713aSLionel Sambuc                    BObj, AA->getTypeStoreSize(BObj->getType()));
638f4a2713aSLionel Sambuc }
639f4a2713aSLionel Sambuc 
640f4a2713aSLionel Sambuc 
641f4a2713aSLionel Sambuc // Returns true if the load or store can be analyzed. Atomic and volatile
642f4a2713aSLionel Sambuc // operations have properties which this analysis does not understand.
643f4a2713aSLionel Sambuc static
isLoadOrStore(const Instruction * I)644f4a2713aSLionel Sambuc bool isLoadOrStore(const Instruction *I) {
645f4a2713aSLionel Sambuc   if (const LoadInst *LI = dyn_cast<LoadInst>(I))
646f4a2713aSLionel Sambuc     return LI->isUnordered();
647f4a2713aSLionel Sambuc   else if (const StoreInst *SI = dyn_cast<StoreInst>(I))
648f4a2713aSLionel Sambuc     return SI->isUnordered();
649f4a2713aSLionel Sambuc   return false;
650f4a2713aSLionel Sambuc }
651f4a2713aSLionel Sambuc 
652f4a2713aSLionel Sambuc 
653f4a2713aSLionel Sambuc static
getPointerOperand(Instruction * I)654f4a2713aSLionel Sambuc Value *getPointerOperand(Instruction *I) {
655f4a2713aSLionel Sambuc   if (LoadInst *LI = dyn_cast<LoadInst>(I))
656f4a2713aSLionel Sambuc     return LI->getPointerOperand();
657f4a2713aSLionel Sambuc   if (StoreInst *SI = dyn_cast<StoreInst>(I))
658f4a2713aSLionel Sambuc     return SI->getPointerOperand();
659f4a2713aSLionel Sambuc   llvm_unreachable("Value is not load or store instruction");
660*0a6a1f1dSLionel Sambuc   return nullptr;
661f4a2713aSLionel Sambuc }
662f4a2713aSLionel Sambuc 
663f4a2713aSLionel Sambuc 
664f4a2713aSLionel Sambuc // Examines the loop nesting of the Src and Dst
665f4a2713aSLionel Sambuc // instructions and establishes their shared loops. Sets the variables
666f4a2713aSLionel Sambuc // CommonLevels, SrcLevels, and MaxLevels.
667f4a2713aSLionel Sambuc // The source and destination instructions needn't be contained in the same
668f4a2713aSLionel Sambuc // loop. The routine establishNestingLevels finds the level of most deeply
669f4a2713aSLionel Sambuc // nested loop that contains them both, CommonLevels. An instruction that's
670f4a2713aSLionel Sambuc // not contained in a loop is at level = 0. MaxLevels is equal to the level
671f4a2713aSLionel Sambuc // of the source plus the level of the destination, minus CommonLevels.
672f4a2713aSLionel Sambuc // This lets us allocate vectors MaxLevels in length, with room for every
673f4a2713aSLionel Sambuc // distinct loop referenced in both the source and destination subscripts.
674f4a2713aSLionel Sambuc // The variable SrcLevels is the nesting depth of the source instruction.
675f4a2713aSLionel Sambuc // It's used to help calculate distinct loops referenced by the destination.
676f4a2713aSLionel Sambuc // Here's the map from loops to levels:
677f4a2713aSLionel Sambuc //            0 - unused
678f4a2713aSLionel Sambuc //            1 - outermost common loop
679f4a2713aSLionel Sambuc //          ... - other common loops
680f4a2713aSLionel Sambuc // CommonLevels - innermost common loop
681f4a2713aSLionel Sambuc //          ... - loops containing Src but not Dst
682f4a2713aSLionel Sambuc //    SrcLevels - innermost loop containing Src but not Dst
683f4a2713aSLionel Sambuc //          ... - loops containing Dst but not Src
684f4a2713aSLionel Sambuc //    MaxLevels - innermost loops containing Dst but not Src
685f4a2713aSLionel Sambuc // Consider the follow code fragment:
686f4a2713aSLionel Sambuc //   for (a = ...) {
687f4a2713aSLionel Sambuc //     for (b = ...) {
688f4a2713aSLionel Sambuc //       for (c = ...) {
689f4a2713aSLionel Sambuc //         for (d = ...) {
690f4a2713aSLionel Sambuc //           A[] = ...;
691f4a2713aSLionel Sambuc //         }
692f4a2713aSLionel Sambuc //       }
693f4a2713aSLionel Sambuc //       for (e = ...) {
694f4a2713aSLionel Sambuc //         for (f = ...) {
695f4a2713aSLionel Sambuc //           for (g = ...) {
696f4a2713aSLionel Sambuc //             ... = A[];
697f4a2713aSLionel Sambuc //           }
698f4a2713aSLionel Sambuc //         }
699f4a2713aSLionel Sambuc //       }
700f4a2713aSLionel Sambuc //     }
701f4a2713aSLionel Sambuc //   }
702f4a2713aSLionel Sambuc // If we're looking at the possibility of a dependence between the store
703f4a2713aSLionel Sambuc // to A (the Src) and the load from A (the Dst), we'll note that they
704f4a2713aSLionel Sambuc // have 2 loops in common, so CommonLevels will equal 2 and the direction
705f4a2713aSLionel Sambuc // vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
706f4a2713aSLionel Sambuc // A map from loop names to loop numbers would look like
707f4a2713aSLionel Sambuc //     a - 1
708f4a2713aSLionel Sambuc //     b - 2 = CommonLevels
709f4a2713aSLionel Sambuc //     c - 3
710f4a2713aSLionel Sambuc //     d - 4 = SrcLevels
711f4a2713aSLionel Sambuc //     e - 5
712f4a2713aSLionel Sambuc //     f - 6
713f4a2713aSLionel Sambuc //     g - 7 = MaxLevels
establishNestingLevels(const Instruction * Src,const Instruction * Dst)714f4a2713aSLionel Sambuc void DependenceAnalysis::establishNestingLevels(const Instruction *Src,
715f4a2713aSLionel Sambuc                                                 const Instruction *Dst) {
716f4a2713aSLionel Sambuc   const BasicBlock *SrcBlock = Src->getParent();
717f4a2713aSLionel Sambuc   const BasicBlock *DstBlock = Dst->getParent();
718f4a2713aSLionel Sambuc   unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
719f4a2713aSLionel Sambuc   unsigned DstLevel = LI->getLoopDepth(DstBlock);
720f4a2713aSLionel Sambuc   const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
721f4a2713aSLionel Sambuc   const Loop *DstLoop = LI->getLoopFor(DstBlock);
722f4a2713aSLionel Sambuc   SrcLevels = SrcLevel;
723f4a2713aSLionel Sambuc   MaxLevels = SrcLevel + DstLevel;
724f4a2713aSLionel Sambuc   while (SrcLevel > DstLevel) {
725f4a2713aSLionel Sambuc     SrcLoop = SrcLoop->getParentLoop();
726f4a2713aSLionel Sambuc     SrcLevel--;
727f4a2713aSLionel Sambuc   }
728f4a2713aSLionel Sambuc   while (DstLevel > SrcLevel) {
729f4a2713aSLionel Sambuc     DstLoop = DstLoop->getParentLoop();
730f4a2713aSLionel Sambuc     DstLevel--;
731f4a2713aSLionel Sambuc   }
732f4a2713aSLionel Sambuc   while (SrcLoop != DstLoop) {
733f4a2713aSLionel Sambuc     SrcLoop = SrcLoop->getParentLoop();
734f4a2713aSLionel Sambuc     DstLoop = DstLoop->getParentLoop();
735f4a2713aSLionel Sambuc     SrcLevel--;
736f4a2713aSLionel Sambuc   }
737f4a2713aSLionel Sambuc   CommonLevels = SrcLevel;
738f4a2713aSLionel Sambuc   MaxLevels -= CommonLevels;
739f4a2713aSLionel Sambuc }
740f4a2713aSLionel Sambuc 
741f4a2713aSLionel Sambuc 
742f4a2713aSLionel Sambuc // Given one of the loops containing the source, return
743f4a2713aSLionel Sambuc // its level index in our numbering scheme.
mapSrcLoop(const Loop * SrcLoop) const744f4a2713aSLionel Sambuc unsigned DependenceAnalysis::mapSrcLoop(const Loop *SrcLoop) const {
745f4a2713aSLionel Sambuc   return SrcLoop->getLoopDepth();
746f4a2713aSLionel Sambuc }
747f4a2713aSLionel Sambuc 
748f4a2713aSLionel Sambuc 
749f4a2713aSLionel Sambuc // Given one of the loops containing the destination,
750f4a2713aSLionel Sambuc // return its level index in our numbering scheme.
mapDstLoop(const Loop * DstLoop) const751f4a2713aSLionel Sambuc unsigned DependenceAnalysis::mapDstLoop(const Loop *DstLoop) const {
752f4a2713aSLionel Sambuc   unsigned D = DstLoop->getLoopDepth();
753f4a2713aSLionel Sambuc   if (D > CommonLevels)
754f4a2713aSLionel Sambuc     return D - CommonLevels + SrcLevels;
755f4a2713aSLionel Sambuc   else
756f4a2713aSLionel Sambuc     return D;
757f4a2713aSLionel Sambuc }
758f4a2713aSLionel Sambuc 
759f4a2713aSLionel Sambuc 
760f4a2713aSLionel Sambuc // Returns true if Expression is loop invariant in LoopNest.
isLoopInvariant(const SCEV * Expression,const Loop * LoopNest) const761f4a2713aSLionel Sambuc bool DependenceAnalysis::isLoopInvariant(const SCEV *Expression,
762f4a2713aSLionel Sambuc                                          const Loop *LoopNest) const {
763f4a2713aSLionel Sambuc   if (!LoopNest)
764f4a2713aSLionel Sambuc     return true;
765f4a2713aSLionel Sambuc   return SE->isLoopInvariant(Expression, LoopNest) &&
766f4a2713aSLionel Sambuc     isLoopInvariant(Expression, LoopNest->getParentLoop());
767f4a2713aSLionel Sambuc }
768f4a2713aSLionel Sambuc 
769f4a2713aSLionel Sambuc 
770f4a2713aSLionel Sambuc 
771f4a2713aSLionel Sambuc // Finds the set of loops from the LoopNest that
772f4a2713aSLionel Sambuc // have a level <= CommonLevels and are referred to by the SCEV Expression.
collectCommonLoops(const SCEV * Expression,const Loop * LoopNest,SmallBitVector & Loops) const773f4a2713aSLionel Sambuc void DependenceAnalysis::collectCommonLoops(const SCEV *Expression,
774f4a2713aSLionel Sambuc                                             const Loop *LoopNest,
775f4a2713aSLionel Sambuc                                             SmallBitVector &Loops) const {
776f4a2713aSLionel Sambuc   while (LoopNest) {
777f4a2713aSLionel Sambuc     unsigned Level = LoopNest->getLoopDepth();
778f4a2713aSLionel Sambuc     if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
779f4a2713aSLionel Sambuc       Loops.set(Level);
780f4a2713aSLionel Sambuc     LoopNest = LoopNest->getParentLoop();
781f4a2713aSLionel Sambuc   }
782f4a2713aSLionel Sambuc }
783f4a2713aSLionel Sambuc 
unifySubscriptType(Subscript * Pair)784*0a6a1f1dSLionel Sambuc void DependenceAnalysis::unifySubscriptType(Subscript *Pair) {
785*0a6a1f1dSLionel Sambuc   const SCEV *Src = Pair->Src;
786*0a6a1f1dSLionel Sambuc   const SCEV *Dst = Pair->Dst;
787*0a6a1f1dSLionel Sambuc   IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
788*0a6a1f1dSLionel Sambuc   IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
789*0a6a1f1dSLionel Sambuc   if (SrcTy == nullptr || DstTy == nullptr) {
790*0a6a1f1dSLionel Sambuc     assert(SrcTy == DstTy && "This function only unify integer types and "
791*0a6a1f1dSLionel Sambuc                              "expect Src and Dst share the same type "
792*0a6a1f1dSLionel Sambuc                              "otherwise.");
793*0a6a1f1dSLionel Sambuc     return;
794*0a6a1f1dSLionel Sambuc   }
795*0a6a1f1dSLionel Sambuc   if (SrcTy->getBitWidth() > DstTy->getBitWidth()) {
796*0a6a1f1dSLionel Sambuc     // Sign-extend Dst to typeof(Src) if typeof(Src) is wider than typeof(Dst).
797*0a6a1f1dSLionel Sambuc     Pair->Dst = SE->getSignExtendExpr(Dst, SrcTy);
798*0a6a1f1dSLionel Sambuc   } else if (SrcTy->getBitWidth() < DstTy->getBitWidth()) {
799*0a6a1f1dSLionel Sambuc     // Sign-extend Src to typeof(Dst) if typeof(Dst) is wider than typeof(Src).
800*0a6a1f1dSLionel Sambuc     Pair->Src = SE->getSignExtendExpr(Src, DstTy);
801*0a6a1f1dSLionel Sambuc   }
802*0a6a1f1dSLionel Sambuc }
803f4a2713aSLionel Sambuc 
804f4a2713aSLionel Sambuc // removeMatchingExtensions - Examines a subscript pair.
805f4a2713aSLionel Sambuc // If the source and destination are identically sign (or zero)
806f4a2713aSLionel Sambuc // extended, it strips off the extension in an effect to simplify
807f4a2713aSLionel Sambuc // the actual analysis.
removeMatchingExtensions(Subscript * Pair)808f4a2713aSLionel Sambuc void DependenceAnalysis::removeMatchingExtensions(Subscript *Pair) {
809f4a2713aSLionel Sambuc   const SCEV *Src = Pair->Src;
810f4a2713aSLionel Sambuc   const SCEV *Dst = Pair->Dst;
811f4a2713aSLionel Sambuc   if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
812f4a2713aSLionel Sambuc       (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
813f4a2713aSLionel Sambuc     const SCEVCastExpr *SrcCast = cast<SCEVCastExpr>(Src);
814f4a2713aSLionel Sambuc     const SCEVCastExpr *DstCast = cast<SCEVCastExpr>(Dst);
815*0a6a1f1dSLionel Sambuc     const SCEV *SrcCastOp = SrcCast->getOperand();
816*0a6a1f1dSLionel Sambuc     const SCEV *DstCastOp = DstCast->getOperand();
817*0a6a1f1dSLionel Sambuc     if (SrcCastOp->getType() == DstCastOp->getType()) {
818*0a6a1f1dSLionel Sambuc       Pair->Src = SrcCastOp;
819*0a6a1f1dSLionel Sambuc       Pair->Dst = DstCastOp;
820f4a2713aSLionel Sambuc     }
821f4a2713aSLionel Sambuc   }
822f4a2713aSLionel Sambuc }
823f4a2713aSLionel Sambuc 
824f4a2713aSLionel Sambuc 
825f4a2713aSLionel Sambuc // Examine the scev and return true iff it's linear.
826f4a2713aSLionel Sambuc // Collect any loops mentioned in the set of "Loops".
checkSrcSubscript(const SCEV * Src,const Loop * LoopNest,SmallBitVector & Loops)827f4a2713aSLionel Sambuc bool DependenceAnalysis::checkSrcSubscript(const SCEV *Src,
828f4a2713aSLionel Sambuc                                            const Loop *LoopNest,
829f4a2713aSLionel Sambuc                                            SmallBitVector &Loops) {
830f4a2713aSLionel Sambuc   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Src);
831f4a2713aSLionel Sambuc   if (!AddRec)
832f4a2713aSLionel Sambuc     return isLoopInvariant(Src, LoopNest);
833f4a2713aSLionel Sambuc   const SCEV *Start = AddRec->getStart();
834f4a2713aSLionel Sambuc   const SCEV *Step = AddRec->getStepRecurrence(*SE);
835f4a2713aSLionel Sambuc   if (!isLoopInvariant(Step, LoopNest))
836f4a2713aSLionel Sambuc     return false;
837f4a2713aSLionel Sambuc   Loops.set(mapSrcLoop(AddRec->getLoop()));
838f4a2713aSLionel Sambuc   return checkSrcSubscript(Start, LoopNest, Loops);
839f4a2713aSLionel Sambuc }
840f4a2713aSLionel Sambuc 
841f4a2713aSLionel Sambuc 
842f4a2713aSLionel Sambuc 
843f4a2713aSLionel Sambuc // Examine the scev and return true iff it's linear.
844f4a2713aSLionel Sambuc // Collect any loops mentioned in the set of "Loops".
checkDstSubscript(const SCEV * Dst,const Loop * LoopNest,SmallBitVector & Loops)845f4a2713aSLionel Sambuc bool DependenceAnalysis::checkDstSubscript(const SCEV *Dst,
846f4a2713aSLionel Sambuc                                            const Loop *LoopNest,
847f4a2713aSLionel Sambuc                                            SmallBitVector &Loops) {
848f4a2713aSLionel Sambuc   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Dst);
849f4a2713aSLionel Sambuc   if (!AddRec)
850f4a2713aSLionel Sambuc     return isLoopInvariant(Dst, LoopNest);
851f4a2713aSLionel Sambuc   const SCEV *Start = AddRec->getStart();
852f4a2713aSLionel Sambuc   const SCEV *Step = AddRec->getStepRecurrence(*SE);
853f4a2713aSLionel Sambuc   if (!isLoopInvariant(Step, LoopNest))
854f4a2713aSLionel Sambuc     return false;
855f4a2713aSLionel Sambuc   Loops.set(mapDstLoop(AddRec->getLoop()));
856f4a2713aSLionel Sambuc   return checkDstSubscript(Start, LoopNest, Loops);
857f4a2713aSLionel Sambuc }
858f4a2713aSLionel Sambuc 
859f4a2713aSLionel Sambuc 
860f4a2713aSLionel Sambuc // Examines the subscript pair (the Src and Dst SCEVs)
861f4a2713aSLionel Sambuc // and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
862f4a2713aSLionel Sambuc // Collects the associated loops in a set.
863f4a2713aSLionel Sambuc DependenceAnalysis::Subscript::ClassificationKind
classifyPair(const SCEV * Src,const Loop * SrcLoopNest,const SCEV * Dst,const Loop * DstLoopNest,SmallBitVector & Loops)864f4a2713aSLionel Sambuc DependenceAnalysis::classifyPair(const SCEV *Src, const Loop *SrcLoopNest,
865f4a2713aSLionel Sambuc                                  const SCEV *Dst, const Loop *DstLoopNest,
866f4a2713aSLionel Sambuc                                  SmallBitVector &Loops) {
867f4a2713aSLionel Sambuc   SmallBitVector SrcLoops(MaxLevels + 1);
868f4a2713aSLionel Sambuc   SmallBitVector DstLoops(MaxLevels + 1);
869f4a2713aSLionel Sambuc   if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
870f4a2713aSLionel Sambuc     return Subscript::NonLinear;
871f4a2713aSLionel Sambuc   if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
872f4a2713aSLionel Sambuc     return Subscript::NonLinear;
873f4a2713aSLionel Sambuc   Loops = SrcLoops;
874f4a2713aSLionel Sambuc   Loops |= DstLoops;
875f4a2713aSLionel Sambuc   unsigned N = Loops.count();
876f4a2713aSLionel Sambuc   if (N == 0)
877f4a2713aSLionel Sambuc     return Subscript::ZIV;
878f4a2713aSLionel Sambuc   if (N == 1)
879f4a2713aSLionel Sambuc     return Subscript::SIV;
880f4a2713aSLionel Sambuc   if (N == 2 && (SrcLoops.count() == 0 ||
881f4a2713aSLionel Sambuc                  DstLoops.count() == 0 ||
882f4a2713aSLionel Sambuc                  (SrcLoops.count() == 1 && DstLoops.count() == 1)))
883f4a2713aSLionel Sambuc     return Subscript::RDIV;
884f4a2713aSLionel Sambuc   return Subscript::MIV;
885f4a2713aSLionel Sambuc }
886f4a2713aSLionel Sambuc 
887f4a2713aSLionel Sambuc 
888f4a2713aSLionel Sambuc // A wrapper around SCEV::isKnownPredicate.
889f4a2713aSLionel Sambuc // Looks for cases where we're interested in comparing for equality.
890f4a2713aSLionel Sambuc // If both X and Y have been identically sign or zero extended,
891f4a2713aSLionel Sambuc // it strips off the (confusing) extensions before invoking
892f4a2713aSLionel Sambuc // SCEV::isKnownPredicate. Perhaps, someday, the ScalarEvolution package
893f4a2713aSLionel Sambuc // will be similarly updated.
894f4a2713aSLionel Sambuc //
895f4a2713aSLionel Sambuc // If SCEV::isKnownPredicate can't prove the predicate,
896f4a2713aSLionel Sambuc // we try simple subtraction, which seems to help in some cases
897f4a2713aSLionel Sambuc // involving symbolics.
isKnownPredicate(ICmpInst::Predicate Pred,const SCEV * X,const SCEV * Y) const898f4a2713aSLionel Sambuc bool DependenceAnalysis::isKnownPredicate(ICmpInst::Predicate Pred,
899f4a2713aSLionel Sambuc                                           const SCEV *X,
900f4a2713aSLionel Sambuc                                           const SCEV *Y) const {
901f4a2713aSLionel Sambuc   if (Pred == CmpInst::ICMP_EQ ||
902f4a2713aSLionel Sambuc       Pred == CmpInst::ICMP_NE) {
903f4a2713aSLionel Sambuc     if ((isa<SCEVSignExtendExpr>(X) &&
904f4a2713aSLionel Sambuc          isa<SCEVSignExtendExpr>(Y)) ||
905f4a2713aSLionel Sambuc         (isa<SCEVZeroExtendExpr>(X) &&
906f4a2713aSLionel Sambuc          isa<SCEVZeroExtendExpr>(Y))) {
907f4a2713aSLionel Sambuc       const SCEVCastExpr *CX = cast<SCEVCastExpr>(X);
908f4a2713aSLionel Sambuc       const SCEVCastExpr *CY = cast<SCEVCastExpr>(Y);
909f4a2713aSLionel Sambuc       const SCEV *Xop = CX->getOperand();
910f4a2713aSLionel Sambuc       const SCEV *Yop = CY->getOperand();
911f4a2713aSLionel Sambuc       if (Xop->getType() == Yop->getType()) {
912f4a2713aSLionel Sambuc         X = Xop;
913f4a2713aSLionel Sambuc         Y = Yop;
914f4a2713aSLionel Sambuc       }
915f4a2713aSLionel Sambuc     }
916f4a2713aSLionel Sambuc   }
917f4a2713aSLionel Sambuc   if (SE->isKnownPredicate(Pred, X, Y))
918f4a2713aSLionel Sambuc     return true;
919f4a2713aSLionel Sambuc   // If SE->isKnownPredicate can't prove the condition,
920f4a2713aSLionel Sambuc   // we try the brute-force approach of subtracting
921f4a2713aSLionel Sambuc   // and testing the difference.
922f4a2713aSLionel Sambuc   // By testing with SE->isKnownPredicate first, we avoid
923f4a2713aSLionel Sambuc   // the possibility of overflow when the arguments are constants.
924f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(X, Y);
925f4a2713aSLionel Sambuc   switch (Pred) {
926f4a2713aSLionel Sambuc   case CmpInst::ICMP_EQ:
927f4a2713aSLionel Sambuc     return Delta->isZero();
928f4a2713aSLionel Sambuc   case CmpInst::ICMP_NE:
929f4a2713aSLionel Sambuc     return SE->isKnownNonZero(Delta);
930f4a2713aSLionel Sambuc   case CmpInst::ICMP_SGE:
931f4a2713aSLionel Sambuc     return SE->isKnownNonNegative(Delta);
932f4a2713aSLionel Sambuc   case CmpInst::ICMP_SLE:
933f4a2713aSLionel Sambuc     return SE->isKnownNonPositive(Delta);
934f4a2713aSLionel Sambuc   case CmpInst::ICMP_SGT:
935f4a2713aSLionel Sambuc     return SE->isKnownPositive(Delta);
936f4a2713aSLionel Sambuc   case CmpInst::ICMP_SLT:
937f4a2713aSLionel Sambuc     return SE->isKnownNegative(Delta);
938f4a2713aSLionel Sambuc   default:
939f4a2713aSLionel Sambuc     llvm_unreachable("unexpected predicate in isKnownPredicate");
940f4a2713aSLionel Sambuc   }
941f4a2713aSLionel Sambuc }
942f4a2713aSLionel Sambuc 
943f4a2713aSLionel Sambuc 
944f4a2713aSLionel Sambuc // All subscripts are all the same type.
945f4a2713aSLionel Sambuc // Loop bound may be smaller (e.g., a char).
946f4a2713aSLionel Sambuc // Should zero extend loop bound, since it's always >= 0.
947f4a2713aSLionel Sambuc // This routine collects upper bound and extends if needed.
948f4a2713aSLionel Sambuc // Return null if no bound available.
collectUpperBound(const Loop * L,Type * T) const949f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::collectUpperBound(const Loop *L,
950f4a2713aSLionel Sambuc                                                   Type *T) const {
951f4a2713aSLionel Sambuc   if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
952f4a2713aSLionel Sambuc     const SCEV *UB = SE->getBackedgeTakenCount(L);
953f4a2713aSLionel Sambuc     return SE->getNoopOrZeroExtend(UB, T);
954f4a2713aSLionel Sambuc   }
955*0a6a1f1dSLionel Sambuc   return nullptr;
956f4a2713aSLionel Sambuc }
957f4a2713aSLionel Sambuc 
958f4a2713aSLionel Sambuc 
959f4a2713aSLionel Sambuc // Calls collectUpperBound(), then attempts to cast it to SCEVConstant.
960f4a2713aSLionel Sambuc // If the cast fails, returns NULL.
collectConstantUpperBound(const Loop * L,Type * T) const961f4a2713aSLionel Sambuc const SCEVConstant *DependenceAnalysis::collectConstantUpperBound(const Loop *L,
962f4a2713aSLionel Sambuc                                                                   Type *T
963f4a2713aSLionel Sambuc                                                                   ) const {
964f4a2713aSLionel Sambuc   if (const SCEV *UB = collectUpperBound(L, T))
965f4a2713aSLionel Sambuc     return dyn_cast<SCEVConstant>(UB);
966*0a6a1f1dSLionel Sambuc   return nullptr;
967f4a2713aSLionel Sambuc }
968f4a2713aSLionel Sambuc 
969f4a2713aSLionel Sambuc 
970f4a2713aSLionel Sambuc // testZIV -
971f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1] and [c2],
972f4a2713aSLionel Sambuc // where c1 and c2 are both loop invariant, we attack it using
973f4a2713aSLionel Sambuc // the ZIV test. Basically, we test by comparing the two values,
974f4a2713aSLionel Sambuc // but there are actually three possible results:
975f4a2713aSLionel Sambuc // 1) the values are equal, so there's a dependence
976f4a2713aSLionel Sambuc // 2) the values are different, so there's no dependence
977f4a2713aSLionel Sambuc // 3) the values might be equal, so we have to assume a dependence.
978f4a2713aSLionel Sambuc //
979f4a2713aSLionel Sambuc // Return true if dependence disproved.
testZIV(const SCEV * Src,const SCEV * Dst,FullDependence & Result) const980f4a2713aSLionel Sambuc bool DependenceAnalysis::testZIV(const SCEV *Src,
981f4a2713aSLionel Sambuc                                  const SCEV *Dst,
982f4a2713aSLionel Sambuc                                  FullDependence &Result) const {
983f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    src = " << *Src << "\n");
984f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    dst = " << *Dst << "\n");
985f4a2713aSLionel Sambuc   ++ZIVapplications;
986f4a2713aSLionel Sambuc   if (isKnownPredicate(CmpInst::ICMP_EQ, Src, Dst)) {
987f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    provably dependent\n");
988f4a2713aSLionel Sambuc     return false; // provably dependent
989f4a2713aSLionel Sambuc   }
990f4a2713aSLionel Sambuc   if (isKnownPredicate(CmpInst::ICMP_NE, Src, Dst)) {
991f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    provably independent\n");
992f4a2713aSLionel Sambuc     ++ZIVindependence;
993f4a2713aSLionel Sambuc     return true; // provably independent
994f4a2713aSLionel Sambuc   }
995f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    possibly dependent\n");
996f4a2713aSLionel Sambuc   Result.Consistent = false;
997f4a2713aSLionel Sambuc   return false; // possibly dependent
998f4a2713aSLionel Sambuc }
999f4a2713aSLionel Sambuc 
1000f4a2713aSLionel Sambuc 
1001f4a2713aSLionel Sambuc // strongSIVtest -
1002f4a2713aSLionel Sambuc // From the paper, Practical Dependence Testing, Section 4.2.1
1003f4a2713aSLionel Sambuc //
1004f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a*i] and [c2 + a*i],
1005f4a2713aSLionel Sambuc // where i is an induction variable, c1 and c2 are loop invariant,
1006f4a2713aSLionel Sambuc //  and a is a constant, we can solve it exactly using the Strong SIV test.
1007f4a2713aSLionel Sambuc //
1008f4a2713aSLionel Sambuc // Can prove independence. Failing that, can compute distance (and direction).
1009f4a2713aSLionel Sambuc // In the presence of symbolic terms, we can sometimes make progress.
1010f4a2713aSLionel Sambuc //
1011f4a2713aSLionel Sambuc // If there's a dependence,
1012f4a2713aSLionel Sambuc //
1013f4a2713aSLionel Sambuc //    c1 + a*i = c2 + a*i'
1014f4a2713aSLionel Sambuc //
1015f4a2713aSLionel Sambuc // The dependence distance is
1016f4a2713aSLionel Sambuc //
1017f4a2713aSLionel Sambuc //    d = i' - i = (c1 - c2)/a
1018f4a2713aSLionel Sambuc //
1019f4a2713aSLionel Sambuc // A dependence only exists if d is an integer and abs(d) <= U, where U is the
1020f4a2713aSLionel Sambuc // loop's upper bound. If a dependence exists, the dependence direction is
1021f4a2713aSLionel Sambuc // defined as
1022f4a2713aSLionel Sambuc //
1023f4a2713aSLionel Sambuc //                { < if d > 0
1024f4a2713aSLionel Sambuc //    direction = { = if d = 0
1025f4a2713aSLionel Sambuc //                { > if d < 0
1026f4a2713aSLionel Sambuc //
1027f4a2713aSLionel Sambuc // Return true if dependence disproved.
strongSIVtest(const SCEV * Coeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const1028f4a2713aSLionel Sambuc bool DependenceAnalysis::strongSIVtest(const SCEV *Coeff,
1029f4a2713aSLionel Sambuc                                        const SCEV *SrcConst,
1030f4a2713aSLionel Sambuc                                        const SCEV *DstConst,
1031f4a2713aSLionel Sambuc                                        const Loop *CurLoop,
1032f4a2713aSLionel Sambuc                                        unsigned Level,
1033f4a2713aSLionel Sambuc                                        FullDependence &Result,
1034f4a2713aSLionel Sambuc                                        Constraint &NewConstraint) const {
1035f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tStrong SIV test\n");
1036f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Coeff = " << *Coeff);
1037f4a2713aSLionel Sambuc   DEBUG(dbgs() << ", " << *Coeff->getType() << "\n");
1038f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst);
1039f4a2713aSLionel Sambuc   DEBUG(dbgs() << ", " << *SrcConst->getType() << "\n");
1040f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstConst = " << *DstConst);
1041f4a2713aSLionel Sambuc   DEBUG(dbgs() << ", " << *DstConst->getType() << "\n");
1042f4a2713aSLionel Sambuc   ++StrongSIVapplications;
1043f4a2713aSLionel Sambuc   assert(0 < Level && Level <= CommonLevels && "level out of range");
1044f4a2713aSLionel Sambuc   Level--;
1045f4a2713aSLionel Sambuc 
1046f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1047f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta);
1048f4a2713aSLionel Sambuc   DEBUG(dbgs() << ", " << *Delta->getType() << "\n");
1049f4a2713aSLionel Sambuc 
1050f4a2713aSLionel Sambuc   // check that |Delta| < iteration count
1051f4a2713aSLionel Sambuc   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1052f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound);
1053f4a2713aSLionel Sambuc     DEBUG(dbgs() << ", " << *UpperBound->getType() << "\n");
1054f4a2713aSLionel Sambuc     const SCEV *AbsDelta =
1055f4a2713aSLionel Sambuc       SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
1056f4a2713aSLionel Sambuc     const SCEV *AbsCoeff =
1057f4a2713aSLionel Sambuc       SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
1058f4a2713aSLionel Sambuc     const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
1059f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product)) {
1060f4a2713aSLionel Sambuc       // Distance greater than trip count - no dependence
1061f4a2713aSLionel Sambuc       ++StrongSIVindependence;
1062f4a2713aSLionel Sambuc       ++StrongSIVsuccesses;
1063f4a2713aSLionel Sambuc       return true;
1064f4a2713aSLionel Sambuc     }
1065f4a2713aSLionel Sambuc   }
1066f4a2713aSLionel Sambuc 
1067f4a2713aSLionel Sambuc   // Can we compute distance?
1068f4a2713aSLionel Sambuc   if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
1069f4a2713aSLionel Sambuc     APInt ConstDelta = cast<SCEVConstant>(Delta)->getValue()->getValue();
1070f4a2713aSLionel Sambuc     APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getValue()->getValue();
1071f4a2713aSLionel Sambuc     APInt Distance  = ConstDelta; // these need to be initialized
1072f4a2713aSLionel Sambuc     APInt Remainder = ConstDelta;
1073f4a2713aSLionel Sambuc     APInt::sdivrem(ConstDelta, ConstCoeff, Distance, Remainder);
1074f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    Distance = " << Distance << "\n");
1075f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
1076f4a2713aSLionel Sambuc     // Make sure Coeff divides Delta exactly
1077f4a2713aSLionel Sambuc     if (Remainder != 0) {
1078f4a2713aSLionel Sambuc       // Coeff doesn't divide Distance, no dependence
1079f4a2713aSLionel Sambuc       ++StrongSIVindependence;
1080f4a2713aSLionel Sambuc       ++StrongSIVsuccesses;
1081f4a2713aSLionel Sambuc       return true;
1082f4a2713aSLionel Sambuc     }
1083f4a2713aSLionel Sambuc     Result.DV[Level].Distance = SE->getConstant(Distance);
1084f4a2713aSLionel Sambuc     NewConstraint.setDistance(SE->getConstant(Distance), CurLoop);
1085f4a2713aSLionel Sambuc     if (Distance.sgt(0))
1086f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= Dependence::DVEntry::LT;
1087f4a2713aSLionel Sambuc     else if (Distance.slt(0))
1088f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= Dependence::DVEntry::GT;
1089f4a2713aSLionel Sambuc     else
1090f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
1091f4a2713aSLionel Sambuc     ++StrongSIVsuccesses;
1092f4a2713aSLionel Sambuc   }
1093f4a2713aSLionel Sambuc   else if (Delta->isZero()) {
1094f4a2713aSLionel Sambuc     // since 0/X == 0
1095f4a2713aSLionel Sambuc     Result.DV[Level].Distance = Delta;
1096f4a2713aSLionel Sambuc     NewConstraint.setDistance(Delta, CurLoop);
1097f4a2713aSLionel Sambuc     Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
1098f4a2713aSLionel Sambuc     ++StrongSIVsuccesses;
1099f4a2713aSLionel Sambuc   }
1100f4a2713aSLionel Sambuc   else {
1101f4a2713aSLionel Sambuc     if (Coeff->isOne()) {
1102f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    Distance = " << *Delta << "\n");
1103f4a2713aSLionel Sambuc       Result.DV[Level].Distance = Delta; // since X/1 == X
1104f4a2713aSLionel Sambuc       NewConstraint.setDistance(Delta, CurLoop);
1105f4a2713aSLionel Sambuc     }
1106f4a2713aSLionel Sambuc     else {
1107f4a2713aSLionel Sambuc       Result.Consistent = false;
1108f4a2713aSLionel Sambuc       NewConstraint.setLine(Coeff,
1109f4a2713aSLionel Sambuc                             SE->getNegativeSCEV(Coeff),
1110f4a2713aSLionel Sambuc                             SE->getNegativeSCEV(Delta), CurLoop);
1111f4a2713aSLionel Sambuc     }
1112f4a2713aSLionel Sambuc 
1113f4a2713aSLionel Sambuc     // maybe we can get a useful direction
1114f4a2713aSLionel Sambuc     bool DeltaMaybeZero     = !SE->isKnownNonZero(Delta);
1115f4a2713aSLionel Sambuc     bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
1116f4a2713aSLionel Sambuc     bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
1117f4a2713aSLionel Sambuc     bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
1118f4a2713aSLionel Sambuc     bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
1119f4a2713aSLionel Sambuc     // The double negatives above are confusing.
1120f4a2713aSLionel Sambuc     // It helps to read !SE->isKnownNonZero(Delta)
1121f4a2713aSLionel Sambuc     // as "Delta might be Zero"
1122f4a2713aSLionel Sambuc     unsigned NewDirection = Dependence::DVEntry::NONE;
1123f4a2713aSLionel Sambuc     if ((DeltaMaybePositive && CoeffMaybePositive) ||
1124f4a2713aSLionel Sambuc         (DeltaMaybeNegative && CoeffMaybeNegative))
1125f4a2713aSLionel Sambuc       NewDirection = Dependence::DVEntry::LT;
1126f4a2713aSLionel Sambuc     if (DeltaMaybeZero)
1127f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::EQ;
1128f4a2713aSLionel Sambuc     if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1129f4a2713aSLionel Sambuc         (DeltaMaybePositive && CoeffMaybeNegative))
1130f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::GT;
1131f4a2713aSLionel Sambuc     if (NewDirection < Result.DV[Level].Direction)
1132f4a2713aSLionel Sambuc       ++StrongSIVsuccesses;
1133f4a2713aSLionel Sambuc     Result.DV[Level].Direction &= NewDirection;
1134f4a2713aSLionel Sambuc   }
1135f4a2713aSLionel Sambuc   return false;
1136f4a2713aSLionel Sambuc }
1137f4a2713aSLionel Sambuc 
1138f4a2713aSLionel Sambuc 
1139f4a2713aSLionel Sambuc // weakCrossingSIVtest -
1140f4a2713aSLionel Sambuc // From the paper, Practical Dependence Testing, Section 4.2.2
1141f4a2713aSLionel Sambuc //
1142f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a*i] and [c2 - a*i],
1143f4a2713aSLionel Sambuc // where i is an induction variable, c1 and c2 are loop invariant,
1144f4a2713aSLionel Sambuc // and a is a constant, we can solve it exactly using the
1145f4a2713aSLionel Sambuc // Weak-Crossing SIV test.
1146f4a2713aSLionel Sambuc //
1147f4a2713aSLionel Sambuc // Given c1 + a*i = c2 - a*i', we can look for the intersection of
1148f4a2713aSLionel Sambuc // the two lines, where i = i', yielding
1149f4a2713aSLionel Sambuc //
1150f4a2713aSLionel Sambuc //    c1 + a*i = c2 - a*i
1151f4a2713aSLionel Sambuc //    2a*i = c2 - c1
1152f4a2713aSLionel Sambuc //    i = (c2 - c1)/2a
1153f4a2713aSLionel Sambuc //
1154f4a2713aSLionel Sambuc // If i < 0, there is no dependence.
1155f4a2713aSLionel Sambuc // If i > upperbound, there is no dependence.
1156f4a2713aSLionel Sambuc // If i = 0 (i.e., if c1 = c2), there's a dependence with distance = 0.
1157f4a2713aSLionel Sambuc // If i = upperbound, there's a dependence with distance = 0.
1158f4a2713aSLionel Sambuc // If i is integral, there's a dependence (all directions).
1159f4a2713aSLionel Sambuc // If the non-integer part = 1/2, there's a dependence (<> directions).
1160f4a2713aSLionel Sambuc // Otherwise, there's no dependence.
1161f4a2713aSLionel Sambuc //
1162f4a2713aSLionel Sambuc // Can prove independence. Failing that,
1163f4a2713aSLionel Sambuc // can sometimes refine the directions.
1164f4a2713aSLionel Sambuc // Can determine iteration for splitting.
1165f4a2713aSLionel Sambuc //
1166f4a2713aSLionel Sambuc // Return true if dependence disproved.
weakCrossingSIVtest(const SCEV * Coeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint,const SCEV * & SplitIter) const1167f4a2713aSLionel Sambuc bool DependenceAnalysis::weakCrossingSIVtest(const SCEV *Coeff,
1168f4a2713aSLionel Sambuc                                              const SCEV *SrcConst,
1169f4a2713aSLionel Sambuc                                              const SCEV *DstConst,
1170f4a2713aSLionel Sambuc                                              const Loop *CurLoop,
1171f4a2713aSLionel Sambuc                                              unsigned Level,
1172f4a2713aSLionel Sambuc                                              FullDependence &Result,
1173f4a2713aSLionel Sambuc                                              Constraint &NewConstraint,
1174f4a2713aSLionel Sambuc                                              const SCEV *&SplitIter) const {
1175f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tWeak-Crossing SIV test\n");
1176f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Coeff = " << *Coeff << "\n");
1177f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
1178f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
1179f4a2713aSLionel Sambuc   ++WeakCrossingSIVapplications;
1180f4a2713aSLionel Sambuc   assert(0 < Level && Level <= CommonLevels && "Level out of range");
1181f4a2713aSLionel Sambuc   Level--;
1182f4a2713aSLionel Sambuc   Result.Consistent = false;
1183f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1184f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1185f4a2713aSLionel Sambuc   NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
1186f4a2713aSLionel Sambuc   if (Delta->isZero()) {
1187f4a2713aSLionel Sambuc     Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::LT);
1188f4a2713aSLionel Sambuc     Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::GT);
1189f4a2713aSLionel Sambuc     ++WeakCrossingSIVsuccesses;
1190f4a2713aSLionel Sambuc     if (!Result.DV[Level].Direction) {
1191f4a2713aSLionel Sambuc       ++WeakCrossingSIVindependence;
1192f4a2713aSLionel Sambuc       return true;
1193f4a2713aSLionel Sambuc     }
1194f4a2713aSLionel Sambuc     Result.DV[Level].Distance = Delta; // = 0
1195f4a2713aSLionel Sambuc     return false;
1196f4a2713aSLionel Sambuc   }
1197f4a2713aSLionel Sambuc   const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(Coeff);
1198f4a2713aSLionel Sambuc   if (!ConstCoeff)
1199f4a2713aSLionel Sambuc     return false;
1200f4a2713aSLionel Sambuc 
1201f4a2713aSLionel Sambuc   Result.DV[Level].Splitable = true;
1202f4a2713aSLionel Sambuc   if (SE->isKnownNegative(ConstCoeff)) {
1203f4a2713aSLionel Sambuc     ConstCoeff = dyn_cast<SCEVConstant>(SE->getNegativeSCEV(ConstCoeff));
1204f4a2713aSLionel Sambuc     assert(ConstCoeff &&
1205f4a2713aSLionel Sambuc            "dynamic cast of negative of ConstCoeff should yield constant");
1206f4a2713aSLionel Sambuc     Delta = SE->getNegativeSCEV(Delta);
1207f4a2713aSLionel Sambuc   }
1208f4a2713aSLionel Sambuc   assert(SE->isKnownPositive(ConstCoeff) && "ConstCoeff should be positive");
1209f4a2713aSLionel Sambuc 
1210f4a2713aSLionel Sambuc   // compute SplitIter for use by DependenceAnalysis::getSplitIteration()
1211f4a2713aSLionel Sambuc   SplitIter =
1212f4a2713aSLionel Sambuc     SE->getUDivExpr(SE->getSMaxExpr(SE->getConstant(Delta->getType(), 0),
1213f4a2713aSLionel Sambuc                                     Delta),
1214f4a2713aSLionel Sambuc                     SE->getMulExpr(SE->getConstant(Delta->getType(), 2),
1215f4a2713aSLionel Sambuc                                    ConstCoeff));
1216f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Split iter = " << *SplitIter << "\n");
1217f4a2713aSLionel Sambuc 
1218f4a2713aSLionel Sambuc   const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
1219f4a2713aSLionel Sambuc   if (!ConstDelta)
1220f4a2713aSLionel Sambuc     return false;
1221f4a2713aSLionel Sambuc 
1222f4a2713aSLionel Sambuc   // We're certain that ConstCoeff > 0; therefore,
1223f4a2713aSLionel Sambuc   // if Delta < 0, then no dependence.
1224f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1225f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    ConstCoeff = " << *ConstCoeff << "\n");
1226f4a2713aSLionel Sambuc   if (SE->isKnownNegative(Delta)) {
1227f4a2713aSLionel Sambuc     // No dependence, Delta < 0
1228f4a2713aSLionel Sambuc     ++WeakCrossingSIVindependence;
1229f4a2713aSLionel Sambuc     ++WeakCrossingSIVsuccesses;
1230f4a2713aSLionel Sambuc     return true;
1231f4a2713aSLionel Sambuc   }
1232f4a2713aSLionel Sambuc 
1233f4a2713aSLionel Sambuc   // We're certain that Delta > 0 and ConstCoeff > 0.
1234f4a2713aSLionel Sambuc   // Check Delta/(2*ConstCoeff) against upper loop bound
1235f4a2713aSLionel Sambuc   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1236f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
1237f4a2713aSLionel Sambuc     const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
1238f4a2713aSLionel Sambuc     const SCEV *ML = SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound),
1239f4a2713aSLionel Sambuc                                     ConstantTwo);
1240f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    ML = " << *ML << "\n");
1241f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, ML)) {
1242f4a2713aSLionel Sambuc       // Delta too big, no dependence
1243f4a2713aSLionel Sambuc       ++WeakCrossingSIVindependence;
1244f4a2713aSLionel Sambuc       ++WeakCrossingSIVsuccesses;
1245f4a2713aSLionel Sambuc       return true;
1246f4a2713aSLionel Sambuc     }
1247f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, Delta, ML)) {
1248f4a2713aSLionel Sambuc       // i = i' = UB
1249f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::LT);
1250f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::GT);
1251f4a2713aSLionel Sambuc       ++WeakCrossingSIVsuccesses;
1252f4a2713aSLionel Sambuc       if (!Result.DV[Level].Direction) {
1253f4a2713aSLionel Sambuc         ++WeakCrossingSIVindependence;
1254f4a2713aSLionel Sambuc         return true;
1255f4a2713aSLionel Sambuc       }
1256f4a2713aSLionel Sambuc       Result.DV[Level].Splitable = false;
1257f4a2713aSLionel Sambuc       Result.DV[Level].Distance = SE->getConstant(Delta->getType(), 0);
1258f4a2713aSLionel Sambuc       return false;
1259f4a2713aSLionel Sambuc     }
1260f4a2713aSLionel Sambuc   }
1261f4a2713aSLionel Sambuc 
1262f4a2713aSLionel Sambuc   // check that Coeff divides Delta
1263f4a2713aSLionel Sambuc   APInt APDelta = ConstDelta->getValue()->getValue();
1264f4a2713aSLionel Sambuc   APInt APCoeff = ConstCoeff->getValue()->getValue();
1265f4a2713aSLionel Sambuc   APInt Distance = APDelta; // these need to be initialzed
1266f4a2713aSLionel Sambuc   APInt Remainder = APDelta;
1267f4a2713aSLionel Sambuc   APInt::sdivrem(APDelta, APCoeff, Distance, Remainder);
1268f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
1269f4a2713aSLionel Sambuc   if (Remainder != 0) {
1270f4a2713aSLionel Sambuc     // Coeff doesn't divide Delta, no dependence
1271f4a2713aSLionel Sambuc     ++WeakCrossingSIVindependence;
1272f4a2713aSLionel Sambuc     ++WeakCrossingSIVsuccesses;
1273f4a2713aSLionel Sambuc     return true;
1274f4a2713aSLionel Sambuc   }
1275f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Distance = " << Distance << "\n");
1276f4a2713aSLionel Sambuc 
1277f4a2713aSLionel Sambuc   // if 2*Coeff doesn't divide Delta, then the equal direction isn't possible
1278f4a2713aSLionel Sambuc   APInt Two = APInt(Distance.getBitWidth(), 2, true);
1279f4a2713aSLionel Sambuc   Remainder = Distance.srem(Two);
1280f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
1281f4a2713aSLionel Sambuc   if (Remainder != 0) {
1282f4a2713aSLionel Sambuc     // Equal direction isn't possible
1283f4a2713aSLionel Sambuc     Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::EQ);
1284f4a2713aSLionel Sambuc     ++WeakCrossingSIVsuccesses;
1285f4a2713aSLionel Sambuc   }
1286f4a2713aSLionel Sambuc   return false;
1287f4a2713aSLionel Sambuc }
1288f4a2713aSLionel Sambuc 
1289f4a2713aSLionel Sambuc 
1290f4a2713aSLionel Sambuc // Kirch's algorithm, from
1291f4a2713aSLionel Sambuc //
1292f4a2713aSLionel Sambuc //        Optimizing Supercompilers for Supercomputers
1293f4a2713aSLionel Sambuc //        Michael Wolfe
1294f4a2713aSLionel Sambuc //        MIT Press, 1989
1295f4a2713aSLionel Sambuc //
1296f4a2713aSLionel Sambuc // Program 2.1, page 29.
1297f4a2713aSLionel Sambuc // Computes the GCD of AM and BM.
1298*0a6a1f1dSLionel Sambuc // Also finds a solution to the equation ax - by = gcd(a, b).
1299*0a6a1f1dSLionel Sambuc // Returns true if dependence disproved; i.e., gcd does not divide Delta.
1300f4a2713aSLionel Sambuc static
findGCD(unsigned Bits,APInt AM,APInt BM,APInt Delta,APInt & G,APInt & X,APInt & Y)1301f4a2713aSLionel Sambuc bool findGCD(unsigned Bits, APInt AM, APInt BM, APInt Delta,
1302f4a2713aSLionel Sambuc              APInt &G, APInt &X, APInt &Y) {
1303f4a2713aSLionel Sambuc   APInt A0(Bits, 1, true), A1(Bits, 0, true);
1304f4a2713aSLionel Sambuc   APInt B0(Bits, 0, true), B1(Bits, 1, true);
1305f4a2713aSLionel Sambuc   APInt G0 = AM.abs();
1306f4a2713aSLionel Sambuc   APInt G1 = BM.abs();
1307f4a2713aSLionel Sambuc   APInt Q = G0; // these need to be initialized
1308f4a2713aSLionel Sambuc   APInt R = G0;
1309f4a2713aSLionel Sambuc   APInt::sdivrem(G0, G1, Q, R);
1310f4a2713aSLionel Sambuc   while (R != 0) {
1311f4a2713aSLionel Sambuc     APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1312f4a2713aSLionel Sambuc     APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1313f4a2713aSLionel Sambuc     G0 = G1; G1 = R;
1314f4a2713aSLionel Sambuc     APInt::sdivrem(G0, G1, Q, R);
1315f4a2713aSLionel Sambuc   }
1316f4a2713aSLionel Sambuc   G = G1;
1317f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    GCD = " << G << "\n");
1318f4a2713aSLionel Sambuc   X = AM.slt(0) ? -A1 : A1;
1319f4a2713aSLionel Sambuc   Y = BM.slt(0) ? B1 : -B1;
1320f4a2713aSLionel Sambuc 
1321f4a2713aSLionel Sambuc   // make sure gcd divides Delta
1322f4a2713aSLionel Sambuc   R = Delta.srem(G);
1323f4a2713aSLionel Sambuc   if (R != 0)
1324f4a2713aSLionel Sambuc     return true; // gcd doesn't divide Delta, no dependence
1325f4a2713aSLionel Sambuc   Q = Delta.sdiv(G);
1326f4a2713aSLionel Sambuc   X *= Q;
1327f4a2713aSLionel Sambuc   Y *= Q;
1328f4a2713aSLionel Sambuc   return false;
1329f4a2713aSLionel Sambuc }
1330f4a2713aSLionel Sambuc 
1331f4a2713aSLionel Sambuc 
1332f4a2713aSLionel Sambuc static
floorOfQuotient(APInt A,APInt B)1333f4a2713aSLionel Sambuc APInt floorOfQuotient(APInt A, APInt B) {
1334f4a2713aSLionel Sambuc   APInt Q = A; // these need to be initialized
1335f4a2713aSLionel Sambuc   APInt R = A;
1336f4a2713aSLionel Sambuc   APInt::sdivrem(A, B, Q, R);
1337f4a2713aSLionel Sambuc   if (R == 0)
1338f4a2713aSLionel Sambuc     return Q;
1339f4a2713aSLionel Sambuc   if ((A.sgt(0) && B.sgt(0)) ||
1340f4a2713aSLionel Sambuc       (A.slt(0) && B.slt(0)))
1341f4a2713aSLionel Sambuc     return Q;
1342f4a2713aSLionel Sambuc   else
1343f4a2713aSLionel Sambuc     return Q - 1;
1344f4a2713aSLionel Sambuc }
1345f4a2713aSLionel Sambuc 
1346f4a2713aSLionel Sambuc 
1347f4a2713aSLionel Sambuc static
ceilingOfQuotient(APInt A,APInt B)1348f4a2713aSLionel Sambuc APInt ceilingOfQuotient(APInt A, APInt B) {
1349f4a2713aSLionel Sambuc   APInt Q = A; // these need to be initialized
1350f4a2713aSLionel Sambuc   APInt R = A;
1351f4a2713aSLionel Sambuc   APInt::sdivrem(A, B, Q, R);
1352f4a2713aSLionel Sambuc   if (R == 0)
1353f4a2713aSLionel Sambuc     return Q;
1354f4a2713aSLionel Sambuc   if ((A.sgt(0) && B.sgt(0)) ||
1355f4a2713aSLionel Sambuc       (A.slt(0) && B.slt(0)))
1356f4a2713aSLionel Sambuc     return Q + 1;
1357f4a2713aSLionel Sambuc   else
1358f4a2713aSLionel Sambuc     return Q;
1359f4a2713aSLionel Sambuc }
1360f4a2713aSLionel Sambuc 
1361f4a2713aSLionel Sambuc 
1362f4a2713aSLionel Sambuc static
maxAPInt(APInt A,APInt B)1363f4a2713aSLionel Sambuc APInt maxAPInt(APInt A, APInt B) {
1364f4a2713aSLionel Sambuc   return A.sgt(B) ? A : B;
1365f4a2713aSLionel Sambuc }
1366f4a2713aSLionel Sambuc 
1367f4a2713aSLionel Sambuc 
1368f4a2713aSLionel Sambuc static
minAPInt(APInt A,APInt B)1369f4a2713aSLionel Sambuc APInt minAPInt(APInt A, APInt B) {
1370f4a2713aSLionel Sambuc   return A.slt(B) ? A : B;
1371f4a2713aSLionel Sambuc }
1372f4a2713aSLionel Sambuc 
1373f4a2713aSLionel Sambuc 
1374f4a2713aSLionel Sambuc // exactSIVtest -
1375f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*i],
1376f4a2713aSLionel Sambuc // where i is an induction variable, c1 and c2 are loop invariant, and a1
1377f4a2713aSLionel Sambuc // and a2 are constant, we can solve it exactly using an algorithm developed
1378f4a2713aSLionel Sambuc // by Banerjee and Wolfe. See Section 2.5.3 in
1379f4a2713aSLionel Sambuc //
1380f4a2713aSLionel Sambuc //        Optimizing Supercompilers for Supercomputers
1381f4a2713aSLionel Sambuc //        Michael Wolfe
1382f4a2713aSLionel Sambuc //        MIT Press, 1989
1383f4a2713aSLionel Sambuc //
1384f4a2713aSLionel Sambuc // It's slower than the specialized tests (strong SIV, weak-zero SIV, etc),
1385f4a2713aSLionel Sambuc // so use them if possible. They're also a bit better with symbolics and,
1386f4a2713aSLionel Sambuc // in the case of the strong SIV test, can compute Distances.
1387f4a2713aSLionel Sambuc //
1388f4a2713aSLionel Sambuc // Return true if dependence disproved.
exactSIVtest(const SCEV * SrcCoeff,const SCEV * DstCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const1389f4a2713aSLionel Sambuc bool DependenceAnalysis::exactSIVtest(const SCEV *SrcCoeff,
1390f4a2713aSLionel Sambuc                                       const SCEV *DstCoeff,
1391f4a2713aSLionel Sambuc                                       const SCEV *SrcConst,
1392f4a2713aSLionel Sambuc                                       const SCEV *DstConst,
1393f4a2713aSLionel Sambuc                                       const Loop *CurLoop,
1394f4a2713aSLionel Sambuc                                       unsigned Level,
1395f4a2713aSLionel Sambuc                                       FullDependence &Result,
1396f4a2713aSLionel Sambuc                                       Constraint &NewConstraint) const {
1397f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tExact SIV test\n");
1398f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << " = AM\n");
1399f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << " = BM\n");
1400f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
1401f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
1402f4a2713aSLionel Sambuc   ++ExactSIVapplications;
1403f4a2713aSLionel Sambuc   assert(0 < Level && Level <= CommonLevels && "Level out of range");
1404f4a2713aSLionel Sambuc   Level--;
1405f4a2713aSLionel Sambuc   Result.Consistent = false;
1406f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1407f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1408f4a2713aSLionel Sambuc   NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff),
1409f4a2713aSLionel Sambuc                         Delta, CurLoop);
1410f4a2713aSLionel Sambuc   const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
1411f4a2713aSLionel Sambuc   const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
1412f4a2713aSLionel Sambuc   const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
1413f4a2713aSLionel Sambuc   if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1414f4a2713aSLionel Sambuc     return false;
1415f4a2713aSLionel Sambuc 
1416f4a2713aSLionel Sambuc   // find gcd
1417f4a2713aSLionel Sambuc   APInt G, X, Y;
1418f4a2713aSLionel Sambuc   APInt AM = ConstSrcCoeff->getValue()->getValue();
1419f4a2713aSLionel Sambuc   APInt BM = ConstDstCoeff->getValue()->getValue();
1420f4a2713aSLionel Sambuc   unsigned Bits = AM.getBitWidth();
1421f4a2713aSLionel Sambuc   if (findGCD(Bits, AM, BM, ConstDelta->getValue()->getValue(), G, X, Y)) {
1422f4a2713aSLionel Sambuc     // gcd doesn't divide Delta, no dependence
1423f4a2713aSLionel Sambuc     ++ExactSIVindependence;
1424f4a2713aSLionel Sambuc     ++ExactSIVsuccesses;
1425f4a2713aSLionel Sambuc     return true;
1426f4a2713aSLionel Sambuc   }
1427f4a2713aSLionel Sambuc 
1428f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    X = " << X << ", Y = " << Y << "\n");
1429f4a2713aSLionel Sambuc 
1430f4a2713aSLionel Sambuc   // since SCEV construction normalizes, LM = 0
1431f4a2713aSLionel Sambuc   APInt UM(Bits, 1, true);
1432f4a2713aSLionel Sambuc   bool UMvalid = false;
1433f4a2713aSLionel Sambuc   // UM is perhaps unavailable, let's check
1434f4a2713aSLionel Sambuc   if (const SCEVConstant *CUB =
1435f4a2713aSLionel Sambuc       collectConstantUpperBound(CurLoop, Delta->getType())) {
1436f4a2713aSLionel Sambuc     UM = CUB->getValue()->getValue();
1437f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    UM = " << UM << "\n");
1438f4a2713aSLionel Sambuc     UMvalid = true;
1439f4a2713aSLionel Sambuc   }
1440f4a2713aSLionel Sambuc 
1441f4a2713aSLionel Sambuc   APInt TU(APInt::getSignedMaxValue(Bits));
1442f4a2713aSLionel Sambuc   APInt TL(APInt::getSignedMinValue(Bits));
1443f4a2713aSLionel Sambuc 
1444f4a2713aSLionel Sambuc   // test(BM/G, LM-X) and test(-BM/G, X-UM)
1445f4a2713aSLionel Sambuc   APInt TMUL = BM.sdiv(G);
1446f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1447f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(-X, TMUL));
1448f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1449f4a2713aSLionel Sambuc     if (UMvalid) {
1450f4a2713aSLionel Sambuc       TU = minAPInt(TU, floorOfQuotient(UM - X, TMUL));
1451f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1452f4a2713aSLionel Sambuc     }
1453f4a2713aSLionel Sambuc   }
1454f4a2713aSLionel Sambuc   else {
1455f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(-X, TMUL));
1456f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1457f4a2713aSLionel Sambuc     if (UMvalid) {
1458f4a2713aSLionel Sambuc       TL = maxAPInt(TL, ceilingOfQuotient(UM - X, TMUL));
1459f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1460f4a2713aSLionel Sambuc     }
1461f4a2713aSLionel Sambuc   }
1462f4a2713aSLionel Sambuc 
1463f4a2713aSLionel Sambuc   // test(AM/G, LM-Y) and test(-AM/G, Y-UM)
1464f4a2713aSLionel Sambuc   TMUL = AM.sdiv(G);
1465f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1466f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(-Y, TMUL));
1467f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1468f4a2713aSLionel Sambuc     if (UMvalid) {
1469f4a2713aSLionel Sambuc       TU = minAPInt(TU, floorOfQuotient(UM - Y, TMUL));
1470f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1471f4a2713aSLionel Sambuc     }
1472f4a2713aSLionel Sambuc   }
1473f4a2713aSLionel Sambuc   else {
1474f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(-Y, TMUL));
1475f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1476f4a2713aSLionel Sambuc     if (UMvalid) {
1477f4a2713aSLionel Sambuc       TL = maxAPInt(TL, ceilingOfQuotient(UM - Y, TMUL));
1478f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1479f4a2713aSLionel Sambuc     }
1480f4a2713aSLionel Sambuc   }
1481f4a2713aSLionel Sambuc   if (TL.sgt(TU)) {
1482f4a2713aSLionel Sambuc     ++ExactSIVindependence;
1483f4a2713aSLionel Sambuc     ++ExactSIVsuccesses;
1484f4a2713aSLionel Sambuc     return true;
1485f4a2713aSLionel Sambuc   }
1486f4a2713aSLionel Sambuc 
1487f4a2713aSLionel Sambuc   // explore directions
1488f4a2713aSLionel Sambuc   unsigned NewDirection = Dependence::DVEntry::NONE;
1489f4a2713aSLionel Sambuc 
1490f4a2713aSLionel Sambuc   // less than
1491f4a2713aSLionel Sambuc   APInt SaveTU(TU); // save these
1492f4a2713aSLionel Sambuc   APInt SaveTL(TL);
1493f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    exploring LT direction\n");
1494f4a2713aSLionel Sambuc   TMUL = AM - BM;
1495f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1496f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(X - Y + 1, TMUL));
1497f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TL = " << TL << "\n");
1498f4a2713aSLionel Sambuc   }
1499f4a2713aSLionel Sambuc   else {
1500f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(X - Y + 1, TMUL));
1501f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TU = " << TU << "\n");
1502f4a2713aSLionel Sambuc   }
1503f4a2713aSLionel Sambuc   if (TL.sle(TU)) {
1504f4a2713aSLionel Sambuc     NewDirection |= Dependence::DVEntry::LT;
1505f4a2713aSLionel Sambuc     ++ExactSIVsuccesses;
1506f4a2713aSLionel Sambuc   }
1507f4a2713aSLionel Sambuc 
1508f4a2713aSLionel Sambuc   // equal
1509f4a2713aSLionel Sambuc   TU = SaveTU; // restore
1510f4a2713aSLionel Sambuc   TL = SaveTL;
1511f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    exploring EQ direction\n");
1512f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1513f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(X - Y, TMUL));
1514f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TL = " << TL << "\n");
1515f4a2713aSLionel Sambuc   }
1516f4a2713aSLionel Sambuc   else {
1517f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(X - Y, TMUL));
1518f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TU = " << TU << "\n");
1519f4a2713aSLionel Sambuc   }
1520f4a2713aSLionel Sambuc   TMUL = BM - AM;
1521f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1522f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(Y - X, TMUL));
1523f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TL = " << TL << "\n");
1524f4a2713aSLionel Sambuc   }
1525f4a2713aSLionel Sambuc   else {
1526f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(Y - X, TMUL));
1527f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TU = " << TU << "\n");
1528f4a2713aSLionel Sambuc   }
1529f4a2713aSLionel Sambuc   if (TL.sle(TU)) {
1530f4a2713aSLionel Sambuc     NewDirection |= Dependence::DVEntry::EQ;
1531f4a2713aSLionel Sambuc     ++ExactSIVsuccesses;
1532f4a2713aSLionel Sambuc   }
1533f4a2713aSLionel Sambuc 
1534f4a2713aSLionel Sambuc   // greater than
1535f4a2713aSLionel Sambuc   TU = SaveTU; // restore
1536f4a2713aSLionel Sambuc   TL = SaveTL;
1537f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    exploring GT direction\n");
1538f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1539f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(Y - X + 1, TMUL));
1540f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TL = " << TL << "\n");
1541f4a2713aSLionel Sambuc   }
1542f4a2713aSLionel Sambuc   else {
1543f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(Y - X + 1, TMUL));
1544f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t\t    TU = " << TU << "\n");
1545f4a2713aSLionel Sambuc   }
1546f4a2713aSLionel Sambuc   if (TL.sle(TU)) {
1547f4a2713aSLionel Sambuc     NewDirection |= Dependence::DVEntry::GT;
1548f4a2713aSLionel Sambuc     ++ExactSIVsuccesses;
1549f4a2713aSLionel Sambuc   }
1550f4a2713aSLionel Sambuc 
1551f4a2713aSLionel Sambuc   // finished
1552f4a2713aSLionel Sambuc   Result.DV[Level].Direction &= NewDirection;
1553f4a2713aSLionel Sambuc   if (Result.DV[Level].Direction == Dependence::DVEntry::NONE)
1554f4a2713aSLionel Sambuc     ++ExactSIVindependence;
1555f4a2713aSLionel Sambuc   return Result.DV[Level].Direction == Dependence::DVEntry::NONE;
1556f4a2713aSLionel Sambuc }
1557f4a2713aSLionel Sambuc 
1558f4a2713aSLionel Sambuc 
1559f4a2713aSLionel Sambuc 
1560f4a2713aSLionel Sambuc // Return true if the divisor evenly divides the dividend.
1561f4a2713aSLionel Sambuc static
isRemainderZero(const SCEVConstant * Dividend,const SCEVConstant * Divisor)1562f4a2713aSLionel Sambuc bool isRemainderZero(const SCEVConstant *Dividend,
1563f4a2713aSLionel Sambuc                      const SCEVConstant *Divisor) {
1564f4a2713aSLionel Sambuc   APInt ConstDividend = Dividend->getValue()->getValue();
1565f4a2713aSLionel Sambuc   APInt ConstDivisor = Divisor->getValue()->getValue();
1566f4a2713aSLionel Sambuc   return ConstDividend.srem(ConstDivisor) == 0;
1567f4a2713aSLionel Sambuc }
1568f4a2713aSLionel Sambuc 
1569f4a2713aSLionel Sambuc 
1570f4a2713aSLionel Sambuc // weakZeroSrcSIVtest -
1571f4a2713aSLionel Sambuc // From the paper, Practical Dependence Testing, Section 4.2.2
1572f4a2713aSLionel Sambuc //
1573f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1] and [c2 + a*i],
1574f4a2713aSLionel Sambuc // where i is an induction variable, c1 and c2 are loop invariant,
1575f4a2713aSLionel Sambuc // and a is a constant, we can solve it exactly using the
1576f4a2713aSLionel Sambuc // Weak-Zero SIV test.
1577f4a2713aSLionel Sambuc //
1578f4a2713aSLionel Sambuc // Given
1579f4a2713aSLionel Sambuc //
1580f4a2713aSLionel Sambuc //    c1 = c2 + a*i
1581f4a2713aSLionel Sambuc //
1582f4a2713aSLionel Sambuc // we get
1583f4a2713aSLionel Sambuc //
1584f4a2713aSLionel Sambuc //    (c1 - c2)/a = i
1585f4a2713aSLionel Sambuc //
1586f4a2713aSLionel Sambuc // If i is not an integer, there's no dependence.
1587f4a2713aSLionel Sambuc // If i < 0 or > UB, there's no dependence.
1588f4a2713aSLionel Sambuc // If i = 0, the direction is <= and peeling the
1589f4a2713aSLionel Sambuc // 1st iteration will break the dependence.
1590f4a2713aSLionel Sambuc // If i = UB, the direction is >= and peeling the
1591f4a2713aSLionel Sambuc // last iteration will break the dependence.
1592f4a2713aSLionel Sambuc // Otherwise, the direction is *.
1593f4a2713aSLionel Sambuc //
1594f4a2713aSLionel Sambuc // Can prove independence. Failing that, we can sometimes refine
1595f4a2713aSLionel Sambuc // the directions. Can sometimes show that first or last
1596f4a2713aSLionel Sambuc // iteration carries all the dependences (so worth peeling).
1597f4a2713aSLionel Sambuc //
1598f4a2713aSLionel Sambuc // (see also weakZeroDstSIVtest)
1599f4a2713aSLionel Sambuc //
1600f4a2713aSLionel Sambuc // Return true if dependence disproved.
weakZeroSrcSIVtest(const SCEV * DstCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const1601f4a2713aSLionel Sambuc bool DependenceAnalysis::weakZeroSrcSIVtest(const SCEV *DstCoeff,
1602f4a2713aSLionel Sambuc                                             const SCEV *SrcConst,
1603f4a2713aSLionel Sambuc                                             const SCEV *DstConst,
1604f4a2713aSLionel Sambuc                                             const Loop *CurLoop,
1605f4a2713aSLionel Sambuc                                             unsigned Level,
1606f4a2713aSLionel Sambuc                                             FullDependence &Result,
1607f4a2713aSLionel Sambuc                                             Constraint &NewConstraint) const {
1608f4a2713aSLionel Sambuc   // For the WeakSIV test, it's possible the loop isn't common to
1609f4a2713aSLionel Sambuc   // the Src and Dst loops. If it isn't, then there's no need to
1610f4a2713aSLionel Sambuc   // record a direction.
1611f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tWeak-Zero (src) SIV test\n");
1612f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << "\n");
1613f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
1614f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
1615f4a2713aSLionel Sambuc   ++WeakZeroSIVapplications;
1616f4a2713aSLionel Sambuc   assert(0 < Level && Level <= MaxLevels && "Level out of range");
1617f4a2713aSLionel Sambuc   Level--;
1618f4a2713aSLionel Sambuc   Result.Consistent = false;
1619f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1620f4a2713aSLionel Sambuc   NewConstraint.setLine(SE->getConstant(Delta->getType(), 0),
1621f4a2713aSLionel Sambuc                         DstCoeff, Delta, CurLoop);
1622f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1623f4a2713aSLionel Sambuc   if (isKnownPredicate(CmpInst::ICMP_EQ, SrcConst, DstConst)) {
1624f4a2713aSLionel Sambuc     if (Level < CommonLevels) {
1625f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= Dependence::DVEntry::LE;
1626f4a2713aSLionel Sambuc       Result.DV[Level].PeelFirst = true;
1627f4a2713aSLionel Sambuc       ++WeakZeroSIVsuccesses;
1628f4a2713aSLionel Sambuc     }
1629f4a2713aSLionel Sambuc     return false; // dependences caused by first iteration
1630f4a2713aSLionel Sambuc   }
1631f4a2713aSLionel Sambuc   const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
1632f4a2713aSLionel Sambuc   if (!ConstCoeff)
1633f4a2713aSLionel Sambuc     return false;
1634f4a2713aSLionel Sambuc   const SCEV *AbsCoeff =
1635f4a2713aSLionel Sambuc     SE->isKnownNegative(ConstCoeff) ?
1636f4a2713aSLionel Sambuc     SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
1637f4a2713aSLionel Sambuc   const SCEV *NewDelta =
1638f4a2713aSLionel Sambuc     SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1639f4a2713aSLionel Sambuc 
1640f4a2713aSLionel Sambuc   // check that Delta/SrcCoeff < iteration count
1641f4a2713aSLionel Sambuc   // really check NewDelta < count*AbsCoeff
1642f4a2713aSLionel Sambuc   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1643f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
1644f4a2713aSLionel Sambuc     const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
1645f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
1646f4a2713aSLionel Sambuc       ++WeakZeroSIVindependence;
1647f4a2713aSLionel Sambuc       ++WeakZeroSIVsuccesses;
1648f4a2713aSLionel Sambuc       return true;
1649f4a2713aSLionel Sambuc     }
1650f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
1651f4a2713aSLionel Sambuc       // dependences caused by last iteration
1652f4a2713aSLionel Sambuc       if (Level < CommonLevels) {
1653f4a2713aSLionel Sambuc         Result.DV[Level].Direction &= Dependence::DVEntry::GE;
1654f4a2713aSLionel Sambuc         Result.DV[Level].PeelLast = true;
1655f4a2713aSLionel Sambuc         ++WeakZeroSIVsuccesses;
1656f4a2713aSLionel Sambuc       }
1657f4a2713aSLionel Sambuc       return false;
1658f4a2713aSLionel Sambuc     }
1659f4a2713aSLionel Sambuc   }
1660f4a2713aSLionel Sambuc 
1661f4a2713aSLionel Sambuc   // check that Delta/SrcCoeff >= 0
1662f4a2713aSLionel Sambuc   // really check that NewDelta >= 0
1663f4a2713aSLionel Sambuc   if (SE->isKnownNegative(NewDelta)) {
1664f4a2713aSLionel Sambuc     // No dependence, newDelta < 0
1665f4a2713aSLionel Sambuc     ++WeakZeroSIVindependence;
1666f4a2713aSLionel Sambuc     ++WeakZeroSIVsuccesses;
1667f4a2713aSLionel Sambuc     return true;
1668f4a2713aSLionel Sambuc   }
1669f4a2713aSLionel Sambuc 
1670f4a2713aSLionel Sambuc   // if SrcCoeff doesn't divide Delta, then no dependence
1671f4a2713aSLionel Sambuc   if (isa<SCEVConstant>(Delta) &&
1672f4a2713aSLionel Sambuc       !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
1673f4a2713aSLionel Sambuc     ++WeakZeroSIVindependence;
1674f4a2713aSLionel Sambuc     ++WeakZeroSIVsuccesses;
1675f4a2713aSLionel Sambuc     return true;
1676f4a2713aSLionel Sambuc   }
1677f4a2713aSLionel Sambuc   return false;
1678f4a2713aSLionel Sambuc }
1679f4a2713aSLionel Sambuc 
1680f4a2713aSLionel Sambuc 
1681f4a2713aSLionel Sambuc // weakZeroDstSIVtest -
1682f4a2713aSLionel Sambuc // From the paper, Practical Dependence Testing, Section 4.2.2
1683f4a2713aSLionel Sambuc //
1684f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a*i] and [c2],
1685f4a2713aSLionel Sambuc // where i is an induction variable, c1 and c2 are loop invariant,
1686f4a2713aSLionel Sambuc // and a is a constant, we can solve it exactly using the
1687f4a2713aSLionel Sambuc // Weak-Zero SIV test.
1688f4a2713aSLionel Sambuc //
1689f4a2713aSLionel Sambuc // Given
1690f4a2713aSLionel Sambuc //
1691f4a2713aSLionel Sambuc //    c1 + a*i = c2
1692f4a2713aSLionel Sambuc //
1693f4a2713aSLionel Sambuc // we get
1694f4a2713aSLionel Sambuc //
1695f4a2713aSLionel Sambuc //    i = (c2 - c1)/a
1696f4a2713aSLionel Sambuc //
1697f4a2713aSLionel Sambuc // If i is not an integer, there's no dependence.
1698f4a2713aSLionel Sambuc // If i < 0 or > UB, there's no dependence.
1699f4a2713aSLionel Sambuc // If i = 0, the direction is <= and peeling the
1700f4a2713aSLionel Sambuc // 1st iteration will break the dependence.
1701f4a2713aSLionel Sambuc // If i = UB, the direction is >= and peeling the
1702f4a2713aSLionel Sambuc // last iteration will break the dependence.
1703f4a2713aSLionel Sambuc // Otherwise, the direction is *.
1704f4a2713aSLionel Sambuc //
1705f4a2713aSLionel Sambuc // Can prove independence. Failing that, we can sometimes refine
1706f4a2713aSLionel Sambuc // the directions. Can sometimes show that first or last
1707f4a2713aSLionel Sambuc // iteration carries all the dependences (so worth peeling).
1708f4a2713aSLionel Sambuc //
1709f4a2713aSLionel Sambuc // (see also weakZeroSrcSIVtest)
1710f4a2713aSLionel Sambuc //
1711f4a2713aSLionel Sambuc // Return true if dependence disproved.
weakZeroDstSIVtest(const SCEV * SrcCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const1712f4a2713aSLionel Sambuc bool DependenceAnalysis::weakZeroDstSIVtest(const SCEV *SrcCoeff,
1713f4a2713aSLionel Sambuc                                             const SCEV *SrcConst,
1714f4a2713aSLionel Sambuc                                             const SCEV *DstConst,
1715f4a2713aSLionel Sambuc                                             const Loop *CurLoop,
1716f4a2713aSLionel Sambuc                                             unsigned Level,
1717f4a2713aSLionel Sambuc                                             FullDependence &Result,
1718f4a2713aSLionel Sambuc                                             Constraint &NewConstraint) const {
1719f4a2713aSLionel Sambuc   // For the WeakSIV test, it's possible the loop isn't common to the
1720f4a2713aSLionel Sambuc   // Src and Dst loops. If it isn't, then there's no need to record a direction.
1721f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tWeak-Zero (dst) SIV test\n");
1722f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << "\n");
1723f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
1724f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
1725f4a2713aSLionel Sambuc   ++WeakZeroSIVapplications;
1726f4a2713aSLionel Sambuc   assert(0 < Level && Level <= SrcLevels && "Level out of range");
1727f4a2713aSLionel Sambuc   Level--;
1728f4a2713aSLionel Sambuc   Result.Consistent = false;
1729f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1730f4a2713aSLionel Sambuc   NewConstraint.setLine(SrcCoeff, SE->getConstant(Delta->getType(), 0),
1731f4a2713aSLionel Sambuc                         Delta, CurLoop);
1732f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1733f4a2713aSLionel Sambuc   if (isKnownPredicate(CmpInst::ICMP_EQ, DstConst, SrcConst)) {
1734f4a2713aSLionel Sambuc     if (Level < CommonLevels) {
1735f4a2713aSLionel Sambuc       Result.DV[Level].Direction &= Dependence::DVEntry::LE;
1736f4a2713aSLionel Sambuc       Result.DV[Level].PeelFirst = true;
1737f4a2713aSLionel Sambuc       ++WeakZeroSIVsuccesses;
1738f4a2713aSLionel Sambuc     }
1739f4a2713aSLionel Sambuc     return false; // dependences caused by first iteration
1740f4a2713aSLionel Sambuc   }
1741f4a2713aSLionel Sambuc   const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
1742f4a2713aSLionel Sambuc   if (!ConstCoeff)
1743f4a2713aSLionel Sambuc     return false;
1744f4a2713aSLionel Sambuc   const SCEV *AbsCoeff =
1745f4a2713aSLionel Sambuc     SE->isKnownNegative(ConstCoeff) ?
1746f4a2713aSLionel Sambuc     SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
1747f4a2713aSLionel Sambuc   const SCEV *NewDelta =
1748f4a2713aSLionel Sambuc     SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1749f4a2713aSLionel Sambuc 
1750f4a2713aSLionel Sambuc   // check that Delta/SrcCoeff < iteration count
1751f4a2713aSLionel Sambuc   // really check NewDelta < count*AbsCoeff
1752f4a2713aSLionel Sambuc   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1753f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
1754f4a2713aSLionel Sambuc     const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
1755f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
1756f4a2713aSLionel Sambuc       ++WeakZeroSIVindependence;
1757f4a2713aSLionel Sambuc       ++WeakZeroSIVsuccesses;
1758f4a2713aSLionel Sambuc       return true;
1759f4a2713aSLionel Sambuc     }
1760f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
1761f4a2713aSLionel Sambuc       // dependences caused by last iteration
1762f4a2713aSLionel Sambuc       if (Level < CommonLevels) {
1763f4a2713aSLionel Sambuc         Result.DV[Level].Direction &= Dependence::DVEntry::GE;
1764f4a2713aSLionel Sambuc         Result.DV[Level].PeelLast = true;
1765f4a2713aSLionel Sambuc         ++WeakZeroSIVsuccesses;
1766f4a2713aSLionel Sambuc       }
1767f4a2713aSLionel Sambuc       return false;
1768f4a2713aSLionel Sambuc     }
1769f4a2713aSLionel Sambuc   }
1770f4a2713aSLionel Sambuc 
1771f4a2713aSLionel Sambuc   // check that Delta/SrcCoeff >= 0
1772f4a2713aSLionel Sambuc   // really check that NewDelta >= 0
1773f4a2713aSLionel Sambuc   if (SE->isKnownNegative(NewDelta)) {
1774f4a2713aSLionel Sambuc     // No dependence, newDelta < 0
1775f4a2713aSLionel Sambuc     ++WeakZeroSIVindependence;
1776f4a2713aSLionel Sambuc     ++WeakZeroSIVsuccesses;
1777f4a2713aSLionel Sambuc     return true;
1778f4a2713aSLionel Sambuc   }
1779f4a2713aSLionel Sambuc 
1780f4a2713aSLionel Sambuc   // if SrcCoeff doesn't divide Delta, then no dependence
1781f4a2713aSLionel Sambuc   if (isa<SCEVConstant>(Delta) &&
1782f4a2713aSLionel Sambuc       !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
1783f4a2713aSLionel Sambuc     ++WeakZeroSIVindependence;
1784f4a2713aSLionel Sambuc     ++WeakZeroSIVsuccesses;
1785f4a2713aSLionel Sambuc     return true;
1786f4a2713aSLionel Sambuc   }
1787f4a2713aSLionel Sambuc   return false;
1788f4a2713aSLionel Sambuc }
1789f4a2713aSLionel Sambuc 
1790f4a2713aSLionel Sambuc 
1791f4a2713aSLionel Sambuc // exactRDIVtest - Tests the RDIV subscript pair for dependence.
1792f4a2713aSLionel Sambuc // Things of the form [c1 + a*i] and [c2 + b*j],
1793f4a2713aSLionel Sambuc // where i and j are induction variable, c1 and c2 are loop invariant,
1794f4a2713aSLionel Sambuc // and a and b are constants.
1795f4a2713aSLionel Sambuc // Returns true if any possible dependence is disproved.
1796f4a2713aSLionel Sambuc // Marks the result as inconsistent.
1797f4a2713aSLionel Sambuc // Works in some cases that symbolicRDIVtest doesn't, and vice versa.
exactRDIVtest(const SCEV * SrcCoeff,const SCEV * DstCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * SrcLoop,const Loop * DstLoop,FullDependence & Result) const1798f4a2713aSLionel Sambuc bool DependenceAnalysis::exactRDIVtest(const SCEV *SrcCoeff,
1799f4a2713aSLionel Sambuc                                        const SCEV *DstCoeff,
1800f4a2713aSLionel Sambuc                                        const SCEV *SrcConst,
1801f4a2713aSLionel Sambuc                                        const SCEV *DstConst,
1802f4a2713aSLionel Sambuc                                        const Loop *SrcLoop,
1803f4a2713aSLionel Sambuc                                        const Loop *DstLoop,
1804f4a2713aSLionel Sambuc                                        FullDependence &Result) const {
1805f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tExact RDIV test\n");
1806f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << " = AM\n");
1807f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << " = BM\n");
1808f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
1809f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
1810f4a2713aSLionel Sambuc   ++ExactRDIVapplications;
1811f4a2713aSLionel Sambuc   Result.Consistent = false;
1812f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1813f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1814f4a2713aSLionel Sambuc   const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
1815f4a2713aSLionel Sambuc   const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
1816f4a2713aSLionel Sambuc   const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
1817f4a2713aSLionel Sambuc   if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1818f4a2713aSLionel Sambuc     return false;
1819f4a2713aSLionel Sambuc 
1820f4a2713aSLionel Sambuc   // find gcd
1821f4a2713aSLionel Sambuc   APInt G, X, Y;
1822f4a2713aSLionel Sambuc   APInt AM = ConstSrcCoeff->getValue()->getValue();
1823f4a2713aSLionel Sambuc   APInt BM = ConstDstCoeff->getValue()->getValue();
1824f4a2713aSLionel Sambuc   unsigned Bits = AM.getBitWidth();
1825f4a2713aSLionel Sambuc   if (findGCD(Bits, AM, BM, ConstDelta->getValue()->getValue(), G, X, Y)) {
1826f4a2713aSLionel Sambuc     // gcd doesn't divide Delta, no dependence
1827f4a2713aSLionel Sambuc     ++ExactRDIVindependence;
1828f4a2713aSLionel Sambuc     return true;
1829f4a2713aSLionel Sambuc   }
1830f4a2713aSLionel Sambuc 
1831f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    X = " << X << ", Y = " << Y << "\n");
1832f4a2713aSLionel Sambuc 
1833f4a2713aSLionel Sambuc   // since SCEV construction seems to normalize, LM = 0
1834f4a2713aSLionel Sambuc   APInt SrcUM(Bits, 1, true);
1835f4a2713aSLionel Sambuc   bool SrcUMvalid = false;
1836f4a2713aSLionel Sambuc   // SrcUM is perhaps unavailable, let's check
1837f4a2713aSLionel Sambuc   if (const SCEVConstant *UpperBound =
1838f4a2713aSLionel Sambuc       collectConstantUpperBound(SrcLoop, Delta->getType())) {
1839f4a2713aSLionel Sambuc     SrcUM = UpperBound->getValue()->getValue();
1840f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    SrcUM = " << SrcUM << "\n");
1841f4a2713aSLionel Sambuc     SrcUMvalid = true;
1842f4a2713aSLionel Sambuc   }
1843f4a2713aSLionel Sambuc 
1844f4a2713aSLionel Sambuc   APInt DstUM(Bits, 1, true);
1845f4a2713aSLionel Sambuc   bool DstUMvalid = false;
1846f4a2713aSLionel Sambuc   // UM is perhaps unavailable, let's check
1847f4a2713aSLionel Sambuc   if (const SCEVConstant *UpperBound =
1848f4a2713aSLionel Sambuc       collectConstantUpperBound(DstLoop, Delta->getType())) {
1849f4a2713aSLionel Sambuc     DstUM = UpperBound->getValue()->getValue();
1850f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    DstUM = " << DstUM << "\n");
1851f4a2713aSLionel Sambuc     DstUMvalid = true;
1852f4a2713aSLionel Sambuc   }
1853f4a2713aSLionel Sambuc 
1854f4a2713aSLionel Sambuc   APInt TU(APInt::getSignedMaxValue(Bits));
1855f4a2713aSLionel Sambuc   APInt TL(APInt::getSignedMinValue(Bits));
1856f4a2713aSLionel Sambuc 
1857f4a2713aSLionel Sambuc   // test(BM/G, LM-X) and test(-BM/G, X-UM)
1858f4a2713aSLionel Sambuc   APInt TMUL = BM.sdiv(G);
1859f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1860f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(-X, TMUL));
1861f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1862f4a2713aSLionel Sambuc     if (SrcUMvalid) {
1863f4a2713aSLionel Sambuc       TU = minAPInt(TU, floorOfQuotient(SrcUM - X, TMUL));
1864f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1865f4a2713aSLionel Sambuc     }
1866f4a2713aSLionel Sambuc   }
1867f4a2713aSLionel Sambuc   else {
1868f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(-X, TMUL));
1869f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1870f4a2713aSLionel Sambuc     if (SrcUMvalid) {
1871f4a2713aSLionel Sambuc       TL = maxAPInt(TL, ceilingOfQuotient(SrcUM - X, TMUL));
1872f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1873f4a2713aSLionel Sambuc     }
1874f4a2713aSLionel Sambuc   }
1875f4a2713aSLionel Sambuc 
1876f4a2713aSLionel Sambuc   // test(AM/G, LM-Y) and test(-AM/G, Y-UM)
1877f4a2713aSLionel Sambuc   TMUL = AM.sdiv(G);
1878f4a2713aSLionel Sambuc   if (TMUL.sgt(0)) {
1879f4a2713aSLionel Sambuc     TL = maxAPInt(TL, ceilingOfQuotient(-Y, TMUL));
1880f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1881f4a2713aSLionel Sambuc     if (DstUMvalid) {
1882f4a2713aSLionel Sambuc       TU = minAPInt(TU, floorOfQuotient(DstUM - Y, TMUL));
1883f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1884f4a2713aSLionel Sambuc     }
1885f4a2713aSLionel Sambuc   }
1886f4a2713aSLionel Sambuc   else {
1887f4a2713aSLionel Sambuc     TU = minAPInt(TU, floorOfQuotient(-Y, TMUL));
1888f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1889f4a2713aSLionel Sambuc     if (DstUMvalid) {
1890f4a2713aSLionel Sambuc       TL = maxAPInt(TL, ceilingOfQuotient(DstUM - Y, TMUL));
1891f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    TL = " << TL << "\n");
1892f4a2713aSLionel Sambuc     }
1893f4a2713aSLionel Sambuc   }
1894f4a2713aSLionel Sambuc   if (TL.sgt(TU))
1895f4a2713aSLionel Sambuc     ++ExactRDIVindependence;
1896f4a2713aSLionel Sambuc   return TL.sgt(TU);
1897f4a2713aSLionel Sambuc }
1898f4a2713aSLionel Sambuc 
1899f4a2713aSLionel Sambuc 
1900f4a2713aSLionel Sambuc // symbolicRDIVtest -
1901f4a2713aSLionel Sambuc // In Section 4.5 of the Practical Dependence Testing paper,the authors
1902f4a2713aSLionel Sambuc // introduce a special case of Banerjee's Inequalities (also called the
1903f4a2713aSLionel Sambuc // Extreme-Value Test) that can handle some of the SIV and RDIV cases,
1904f4a2713aSLionel Sambuc // particularly cases with symbolics. Since it's only able to disprove
1905f4a2713aSLionel Sambuc // dependence (not compute distances or directions), we'll use it as a
1906f4a2713aSLionel Sambuc // fall back for the other tests.
1907f4a2713aSLionel Sambuc //
1908f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
1909f4a2713aSLionel Sambuc // where i and j are induction variables and c1 and c2 are loop invariants,
1910f4a2713aSLionel Sambuc // we can use the symbolic tests to disprove some dependences, serving as a
1911f4a2713aSLionel Sambuc // backup for the RDIV test. Note that i and j can be the same variable,
1912f4a2713aSLionel Sambuc // letting this test serve as a backup for the various SIV tests.
1913f4a2713aSLionel Sambuc //
1914f4a2713aSLionel Sambuc // For a dependence to exist, c1 + a1*i must equal c2 + a2*j for some
1915f4a2713aSLionel Sambuc //  0 <= i <= N1 and some 0 <= j <= N2, where N1 and N2 are the (normalized)
1916f4a2713aSLionel Sambuc // loop bounds for the i and j loops, respectively. So, ...
1917f4a2713aSLionel Sambuc //
1918f4a2713aSLionel Sambuc // c1 + a1*i = c2 + a2*j
1919f4a2713aSLionel Sambuc // a1*i - a2*j = c2 - c1
1920f4a2713aSLionel Sambuc //
1921f4a2713aSLionel Sambuc // To test for a dependence, we compute c2 - c1 and make sure it's in the
1922f4a2713aSLionel Sambuc // range of the maximum and minimum possible values of a1*i - a2*j.
1923f4a2713aSLionel Sambuc // Considering the signs of a1 and a2, we have 4 possible cases:
1924f4a2713aSLionel Sambuc //
1925f4a2713aSLionel Sambuc // 1) If a1 >= 0 and a2 >= 0, then
1926f4a2713aSLionel Sambuc //        a1*0 - a2*N2 <= c2 - c1 <= a1*N1 - a2*0
1927f4a2713aSLionel Sambuc //              -a2*N2 <= c2 - c1 <= a1*N1
1928f4a2713aSLionel Sambuc //
1929f4a2713aSLionel Sambuc // 2) If a1 >= 0 and a2 <= 0, then
1930f4a2713aSLionel Sambuc //        a1*0 - a2*0 <= c2 - c1 <= a1*N1 - a2*N2
1931f4a2713aSLionel Sambuc //                  0 <= c2 - c1 <= a1*N1 - a2*N2
1932f4a2713aSLionel Sambuc //
1933f4a2713aSLionel Sambuc // 3) If a1 <= 0 and a2 >= 0, then
1934f4a2713aSLionel Sambuc //        a1*N1 - a2*N2 <= c2 - c1 <= a1*0 - a2*0
1935f4a2713aSLionel Sambuc //        a1*N1 - a2*N2 <= c2 - c1 <= 0
1936f4a2713aSLionel Sambuc //
1937f4a2713aSLionel Sambuc // 4) If a1 <= 0 and a2 <= 0, then
1938f4a2713aSLionel Sambuc //        a1*N1 - a2*0  <= c2 - c1 <= a1*0 - a2*N2
1939f4a2713aSLionel Sambuc //        a1*N1         <= c2 - c1 <=       -a2*N2
1940f4a2713aSLionel Sambuc //
1941f4a2713aSLionel Sambuc // return true if dependence disproved
symbolicRDIVtest(const SCEV * A1,const SCEV * A2,const SCEV * C1,const SCEV * C2,const Loop * Loop1,const Loop * Loop2) const1942f4a2713aSLionel Sambuc bool DependenceAnalysis::symbolicRDIVtest(const SCEV *A1,
1943f4a2713aSLionel Sambuc                                           const SCEV *A2,
1944f4a2713aSLionel Sambuc                                           const SCEV *C1,
1945f4a2713aSLionel Sambuc                                           const SCEV *C2,
1946f4a2713aSLionel Sambuc                                           const Loop *Loop1,
1947f4a2713aSLionel Sambuc                                           const Loop *Loop2) const {
1948f4a2713aSLionel Sambuc   ++SymbolicRDIVapplications;
1949f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\ttry symbolic RDIV test\n");
1950f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    A1 = " << *A1);
1951f4a2713aSLionel Sambuc   DEBUG(dbgs() << ", type = " << *A1->getType() << "\n");
1952f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    A2 = " << *A2 << "\n");
1953f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    C1 = " << *C1 << "\n");
1954f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    C2 = " << *C2 << "\n");
1955f4a2713aSLionel Sambuc   const SCEV *N1 = collectUpperBound(Loop1, A1->getType());
1956f4a2713aSLionel Sambuc   const SCEV *N2 = collectUpperBound(Loop2, A1->getType());
1957f4a2713aSLionel Sambuc   DEBUG(if (N1) dbgs() << "\t    N1 = " << *N1 << "\n");
1958f4a2713aSLionel Sambuc   DEBUG(if (N2) dbgs() << "\t    N2 = " << *N2 << "\n");
1959f4a2713aSLionel Sambuc   const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
1960f4a2713aSLionel Sambuc   const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
1961f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    C2 - C1 = " << *C2_C1 << "\n");
1962f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    C1 - C2 = " << *C1_C2 << "\n");
1963f4a2713aSLionel Sambuc   if (SE->isKnownNonNegative(A1)) {
1964f4a2713aSLionel Sambuc     if (SE->isKnownNonNegative(A2)) {
1965f4a2713aSLionel Sambuc       // A1 >= 0 && A2 >= 0
1966f4a2713aSLionel Sambuc       if (N1) {
1967f4a2713aSLionel Sambuc         // make sure that c2 - c1 <= a1*N1
1968f4a2713aSLionel Sambuc         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
1969f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t    A1*N1 = " << *A1N1 << "\n");
1970f4a2713aSLionel Sambuc         if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1)) {
1971f4a2713aSLionel Sambuc           ++SymbolicRDIVindependence;
1972f4a2713aSLionel Sambuc           return true;
1973f4a2713aSLionel Sambuc         }
1974f4a2713aSLionel Sambuc       }
1975f4a2713aSLionel Sambuc       if (N2) {
1976f4a2713aSLionel Sambuc         // make sure that -a2*N2 <= c2 - c1, or a2*N2 >= c1 - c2
1977f4a2713aSLionel Sambuc         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
1978f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t    A2*N2 = " << *A2N2 << "\n");
1979f4a2713aSLionel Sambuc         if (isKnownPredicate(CmpInst::ICMP_SLT, A2N2, C1_C2)) {
1980f4a2713aSLionel Sambuc           ++SymbolicRDIVindependence;
1981f4a2713aSLionel Sambuc           return true;
1982f4a2713aSLionel Sambuc         }
1983f4a2713aSLionel Sambuc       }
1984f4a2713aSLionel Sambuc     }
1985f4a2713aSLionel Sambuc     else if (SE->isKnownNonPositive(A2)) {
1986f4a2713aSLionel Sambuc       // a1 >= 0 && a2 <= 0
1987f4a2713aSLionel Sambuc       if (N1 && N2) {
1988f4a2713aSLionel Sambuc         // make sure that c2 - c1 <= a1*N1 - a2*N2
1989f4a2713aSLionel Sambuc         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
1990f4a2713aSLionel Sambuc         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
1991f4a2713aSLionel Sambuc         const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
1992f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t    A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
1993f4a2713aSLionel Sambuc         if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1_A2N2)) {
1994f4a2713aSLionel Sambuc           ++SymbolicRDIVindependence;
1995f4a2713aSLionel Sambuc           return true;
1996f4a2713aSLionel Sambuc         }
1997f4a2713aSLionel Sambuc       }
1998f4a2713aSLionel Sambuc       // make sure that 0 <= c2 - c1
1999f4a2713aSLionel Sambuc       if (SE->isKnownNegative(C2_C1)) {
2000f4a2713aSLionel Sambuc         ++SymbolicRDIVindependence;
2001f4a2713aSLionel Sambuc         return true;
2002f4a2713aSLionel Sambuc       }
2003f4a2713aSLionel Sambuc     }
2004f4a2713aSLionel Sambuc   }
2005f4a2713aSLionel Sambuc   else if (SE->isKnownNonPositive(A1)) {
2006f4a2713aSLionel Sambuc     if (SE->isKnownNonNegative(A2)) {
2007f4a2713aSLionel Sambuc       // a1 <= 0 && a2 >= 0
2008f4a2713aSLionel Sambuc       if (N1 && N2) {
2009f4a2713aSLionel Sambuc         // make sure that a1*N1 - a2*N2 <= c2 - c1
2010f4a2713aSLionel Sambuc         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2011f4a2713aSLionel Sambuc         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2012f4a2713aSLionel Sambuc         const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2013f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t    A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
2014f4a2713aSLionel Sambuc         if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1_A2N2, C2_C1)) {
2015f4a2713aSLionel Sambuc           ++SymbolicRDIVindependence;
2016f4a2713aSLionel Sambuc           return true;
2017f4a2713aSLionel Sambuc         }
2018f4a2713aSLionel Sambuc       }
2019f4a2713aSLionel Sambuc       // make sure that c2 - c1 <= 0
2020f4a2713aSLionel Sambuc       if (SE->isKnownPositive(C2_C1)) {
2021f4a2713aSLionel Sambuc         ++SymbolicRDIVindependence;
2022f4a2713aSLionel Sambuc         return true;
2023f4a2713aSLionel Sambuc       }
2024f4a2713aSLionel Sambuc     }
2025f4a2713aSLionel Sambuc     else if (SE->isKnownNonPositive(A2)) {
2026f4a2713aSLionel Sambuc       // a1 <= 0 && a2 <= 0
2027f4a2713aSLionel Sambuc       if (N1) {
2028f4a2713aSLionel Sambuc         // make sure that a1*N1 <= c2 - c1
2029f4a2713aSLionel Sambuc         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2030f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t    A1*N1 = " << *A1N1 << "\n");
2031f4a2713aSLionel Sambuc         if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1, C2_C1)) {
2032f4a2713aSLionel Sambuc           ++SymbolicRDIVindependence;
2033f4a2713aSLionel Sambuc           return true;
2034f4a2713aSLionel Sambuc         }
2035f4a2713aSLionel Sambuc       }
2036f4a2713aSLionel Sambuc       if (N2) {
2037f4a2713aSLionel Sambuc         // make sure that c2 - c1 <= -a2*N2, or c1 - c2 >= a2*N2
2038f4a2713aSLionel Sambuc         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2039f4a2713aSLionel Sambuc         DEBUG(dbgs() << "\t    A2*N2 = " << *A2N2 << "\n");
2040f4a2713aSLionel Sambuc         if (isKnownPredicate(CmpInst::ICMP_SLT, C1_C2, A2N2)) {
2041f4a2713aSLionel Sambuc           ++SymbolicRDIVindependence;
2042f4a2713aSLionel Sambuc           return true;
2043f4a2713aSLionel Sambuc         }
2044f4a2713aSLionel Sambuc       }
2045f4a2713aSLionel Sambuc     }
2046f4a2713aSLionel Sambuc   }
2047f4a2713aSLionel Sambuc   return false;
2048f4a2713aSLionel Sambuc }
2049f4a2713aSLionel Sambuc 
2050f4a2713aSLionel Sambuc 
2051f4a2713aSLionel Sambuc // testSIV -
2052f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 - a2*i]
2053f4a2713aSLionel Sambuc // where i is an induction variable, c1 and c2 are loop invariant, and a1 and
2054f4a2713aSLionel Sambuc // a2 are constant, we attack it with an SIV test. While they can all be
2055f4a2713aSLionel Sambuc // solved with the Exact SIV test, it's worthwhile to use simpler tests when
2056f4a2713aSLionel Sambuc // they apply; they're cheaper and sometimes more precise.
2057f4a2713aSLionel Sambuc //
2058f4a2713aSLionel Sambuc // Return true if dependence disproved.
testSIV(const SCEV * Src,const SCEV * Dst,unsigned & Level,FullDependence & Result,Constraint & NewConstraint,const SCEV * & SplitIter) const2059f4a2713aSLionel Sambuc bool DependenceAnalysis::testSIV(const SCEV *Src,
2060f4a2713aSLionel Sambuc                                  const SCEV *Dst,
2061f4a2713aSLionel Sambuc                                  unsigned &Level,
2062f4a2713aSLionel Sambuc                                  FullDependence &Result,
2063f4a2713aSLionel Sambuc                                  Constraint &NewConstraint,
2064f4a2713aSLionel Sambuc                                  const SCEV *&SplitIter) const {
2065f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    src = " << *Src << "\n");
2066f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    dst = " << *Dst << "\n");
2067f4a2713aSLionel Sambuc   const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
2068f4a2713aSLionel Sambuc   const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
2069f4a2713aSLionel Sambuc   if (SrcAddRec && DstAddRec) {
2070f4a2713aSLionel Sambuc     const SCEV *SrcConst = SrcAddRec->getStart();
2071f4a2713aSLionel Sambuc     const SCEV *DstConst = DstAddRec->getStart();
2072f4a2713aSLionel Sambuc     const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
2073f4a2713aSLionel Sambuc     const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2074f4a2713aSLionel Sambuc     const Loop *CurLoop = SrcAddRec->getLoop();
2075f4a2713aSLionel Sambuc     assert(CurLoop == DstAddRec->getLoop() &&
2076f4a2713aSLionel Sambuc            "both loops in SIV should be same");
2077f4a2713aSLionel Sambuc     Level = mapSrcLoop(CurLoop);
2078f4a2713aSLionel Sambuc     bool disproven;
2079f4a2713aSLionel Sambuc     if (SrcCoeff == DstCoeff)
2080f4a2713aSLionel Sambuc       disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2081f4a2713aSLionel Sambuc                                 Level, Result, NewConstraint);
2082f4a2713aSLionel Sambuc     else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
2083f4a2713aSLionel Sambuc       disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2084f4a2713aSLionel Sambuc                                       Level, Result, NewConstraint, SplitIter);
2085f4a2713aSLionel Sambuc     else
2086f4a2713aSLionel Sambuc       disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
2087f4a2713aSLionel Sambuc                                Level, Result, NewConstraint);
2088f4a2713aSLionel Sambuc     return disproven ||
2089f4a2713aSLionel Sambuc       gcdMIVtest(Src, Dst, Result) ||
2090f4a2713aSLionel Sambuc       symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop, CurLoop);
2091f4a2713aSLionel Sambuc   }
2092f4a2713aSLionel Sambuc   if (SrcAddRec) {
2093f4a2713aSLionel Sambuc     const SCEV *SrcConst = SrcAddRec->getStart();
2094f4a2713aSLionel Sambuc     const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
2095f4a2713aSLionel Sambuc     const SCEV *DstConst = Dst;
2096f4a2713aSLionel Sambuc     const Loop *CurLoop = SrcAddRec->getLoop();
2097f4a2713aSLionel Sambuc     Level = mapSrcLoop(CurLoop);
2098f4a2713aSLionel Sambuc     return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2099f4a2713aSLionel Sambuc                               Level, Result, NewConstraint) ||
2100f4a2713aSLionel Sambuc       gcdMIVtest(Src, Dst, Result);
2101f4a2713aSLionel Sambuc   }
2102f4a2713aSLionel Sambuc   if (DstAddRec) {
2103f4a2713aSLionel Sambuc     const SCEV *DstConst = DstAddRec->getStart();
2104f4a2713aSLionel Sambuc     const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2105f4a2713aSLionel Sambuc     const SCEV *SrcConst = Src;
2106f4a2713aSLionel Sambuc     const Loop *CurLoop = DstAddRec->getLoop();
2107f4a2713aSLionel Sambuc     Level = mapDstLoop(CurLoop);
2108f4a2713aSLionel Sambuc     return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst,
2109f4a2713aSLionel Sambuc                               CurLoop, Level, Result, NewConstraint) ||
2110f4a2713aSLionel Sambuc       gcdMIVtest(Src, Dst, Result);
2111f4a2713aSLionel Sambuc   }
2112f4a2713aSLionel Sambuc   llvm_unreachable("SIV test expected at least one AddRec");
2113f4a2713aSLionel Sambuc   return false;
2114f4a2713aSLionel Sambuc }
2115f4a2713aSLionel Sambuc 
2116f4a2713aSLionel Sambuc 
2117f4a2713aSLionel Sambuc // testRDIV -
2118f4a2713aSLionel Sambuc // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
2119f4a2713aSLionel Sambuc // where i and j are induction variables, c1 and c2 are loop invariant,
2120f4a2713aSLionel Sambuc // and a1 and a2 are constant, we can solve it exactly with an easy adaptation
2121f4a2713aSLionel Sambuc // of the Exact SIV test, the Restricted Double Index Variable (RDIV) test.
2122f4a2713aSLionel Sambuc // It doesn't make sense to talk about distance or direction in this case,
2123f4a2713aSLionel Sambuc // so there's no point in making special versions of the Strong SIV test or
2124f4a2713aSLionel Sambuc // the Weak-crossing SIV test.
2125f4a2713aSLionel Sambuc //
2126f4a2713aSLionel Sambuc // With minor algebra, this test can also be used for things like
2127f4a2713aSLionel Sambuc // [c1 + a1*i + a2*j][c2].
2128f4a2713aSLionel Sambuc //
2129f4a2713aSLionel Sambuc // Return true if dependence disproved.
testRDIV(const SCEV * Src,const SCEV * Dst,FullDependence & Result) const2130f4a2713aSLionel Sambuc bool DependenceAnalysis::testRDIV(const SCEV *Src,
2131f4a2713aSLionel Sambuc                                   const SCEV *Dst,
2132f4a2713aSLionel Sambuc                                   FullDependence &Result) const {
2133f4a2713aSLionel Sambuc   // we have 3 possible situations here:
2134f4a2713aSLionel Sambuc   //   1) [a*i + b] and [c*j + d]
2135f4a2713aSLionel Sambuc   //   2) [a*i + c*j + b] and [d]
2136f4a2713aSLionel Sambuc   //   3) [b] and [a*i + c*j + d]
2137f4a2713aSLionel Sambuc   // We need to find what we've got and get organized
2138f4a2713aSLionel Sambuc 
2139f4a2713aSLionel Sambuc   const SCEV *SrcConst, *DstConst;
2140f4a2713aSLionel Sambuc   const SCEV *SrcCoeff, *DstCoeff;
2141f4a2713aSLionel Sambuc   const Loop *SrcLoop, *DstLoop;
2142f4a2713aSLionel Sambuc 
2143f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    src = " << *Src << "\n");
2144f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    dst = " << *Dst << "\n");
2145f4a2713aSLionel Sambuc   const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
2146f4a2713aSLionel Sambuc   const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
2147f4a2713aSLionel Sambuc   if (SrcAddRec && DstAddRec) {
2148f4a2713aSLionel Sambuc     SrcConst = SrcAddRec->getStart();
2149f4a2713aSLionel Sambuc     SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
2150f4a2713aSLionel Sambuc     SrcLoop = SrcAddRec->getLoop();
2151f4a2713aSLionel Sambuc     DstConst = DstAddRec->getStart();
2152f4a2713aSLionel Sambuc     DstCoeff = DstAddRec->getStepRecurrence(*SE);
2153f4a2713aSLionel Sambuc     DstLoop = DstAddRec->getLoop();
2154f4a2713aSLionel Sambuc   }
2155f4a2713aSLionel Sambuc   else if (SrcAddRec) {
2156f4a2713aSLionel Sambuc     if (const SCEVAddRecExpr *tmpAddRec =
2157f4a2713aSLionel Sambuc         dyn_cast<SCEVAddRecExpr>(SrcAddRec->getStart())) {
2158f4a2713aSLionel Sambuc       SrcConst = tmpAddRec->getStart();
2159f4a2713aSLionel Sambuc       SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
2160f4a2713aSLionel Sambuc       SrcLoop = tmpAddRec->getLoop();
2161f4a2713aSLionel Sambuc       DstConst = Dst;
2162f4a2713aSLionel Sambuc       DstCoeff = SE->getNegativeSCEV(SrcAddRec->getStepRecurrence(*SE));
2163f4a2713aSLionel Sambuc       DstLoop = SrcAddRec->getLoop();
2164f4a2713aSLionel Sambuc     }
2165f4a2713aSLionel Sambuc     else
2166f4a2713aSLionel Sambuc       llvm_unreachable("RDIV reached by surprising SCEVs");
2167f4a2713aSLionel Sambuc   }
2168f4a2713aSLionel Sambuc   else if (DstAddRec) {
2169f4a2713aSLionel Sambuc     if (const SCEVAddRecExpr *tmpAddRec =
2170f4a2713aSLionel Sambuc         dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
2171f4a2713aSLionel Sambuc       DstConst = tmpAddRec->getStart();
2172f4a2713aSLionel Sambuc       DstCoeff = tmpAddRec->getStepRecurrence(*SE);
2173f4a2713aSLionel Sambuc       DstLoop = tmpAddRec->getLoop();
2174f4a2713aSLionel Sambuc       SrcConst = Src;
2175f4a2713aSLionel Sambuc       SrcCoeff = SE->getNegativeSCEV(DstAddRec->getStepRecurrence(*SE));
2176f4a2713aSLionel Sambuc       SrcLoop = DstAddRec->getLoop();
2177f4a2713aSLionel Sambuc     }
2178f4a2713aSLionel Sambuc     else
2179f4a2713aSLionel Sambuc       llvm_unreachable("RDIV reached by surprising SCEVs");
2180f4a2713aSLionel Sambuc   }
2181f4a2713aSLionel Sambuc   else
2182f4a2713aSLionel Sambuc     llvm_unreachable("RDIV expected at least one AddRec");
2183f4a2713aSLionel Sambuc   return exactRDIVtest(SrcCoeff, DstCoeff,
2184f4a2713aSLionel Sambuc                        SrcConst, DstConst,
2185f4a2713aSLionel Sambuc                        SrcLoop, DstLoop,
2186f4a2713aSLionel Sambuc                        Result) ||
2187f4a2713aSLionel Sambuc     gcdMIVtest(Src, Dst, Result) ||
2188f4a2713aSLionel Sambuc     symbolicRDIVtest(SrcCoeff, DstCoeff,
2189f4a2713aSLionel Sambuc                      SrcConst, DstConst,
2190f4a2713aSLionel Sambuc                      SrcLoop, DstLoop);
2191f4a2713aSLionel Sambuc }
2192f4a2713aSLionel Sambuc 
2193f4a2713aSLionel Sambuc 
2194f4a2713aSLionel Sambuc // Tests the single-subscript MIV pair (Src and Dst) for dependence.
2195f4a2713aSLionel Sambuc // Return true if dependence disproved.
2196f4a2713aSLionel Sambuc // Can sometimes refine direction vectors.
testMIV(const SCEV * Src,const SCEV * Dst,const SmallBitVector & Loops,FullDependence & Result) const2197f4a2713aSLionel Sambuc bool DependenceAnalysis::testMIV(const SCEV *Src,
2198f4a2713aSLionel Sambuc                                  const SCEV *Dst,
2199f4a2713aSLionel Sambuc                                  const SmallBitVector &Loops,
2200f4a2713aSLionel Sambuc                                  FullDependence &Result) const {
2201f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    src = " << *Src << "\n");
2202f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    dst = " << *Dst << "\n");
2203f4a2713aSLionel Sambuc   Result.Consistent = false;
2204f4a2713aSLionel Sambuc   return gcdMIVtest(Src, Dst, Result) ||
2205f4a2713aSLionel Sambuc     banerjeeMIVtest(Src, Dst, Loops, Result);
2206f4a2713aSLionel Sambuc }
2207f4a2713aSLionel Sambuc 
2208f4a2713aSLionel Sambuc 
2209f4a2713aSLionel Sambuc // Given a product, e.g., 10*X*Y, returns the first constant operand,
2210f4a2713aSLionel Sambuc // in this case 10. If there is no constant part, returns NULL.
2211f4a2713aSLionel Sambuc static
getConstantPart(const SCEVMulExpr * Product)2212f4a2713aSLionel Sambuc const SCEVConstant *getConstantPart(const SCEVMulExpr *Product) {
2213f4a2713aSLionel Sambuc   for (unsigned Op = 0, Ops = Product->getNumOperands(); Op < Ops; Op++) {
2214f4a2713aSLionel Sambuc     if (const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Product->getOperand(Op)))
2215f4a2713aSLionel Sambuc       return Constant;
2216f4a2713aSLionel Sambuc   }
2217*0a6a1f1dSLionel Sambuc   return nullptr;
2218f4a2713aSLionel Sambuc }
2219f4a2713aSLionel Sambuc 
2220f4a2713aSLionel Sambuc 
2221f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2222f4a2713aSLionel Sambuc // gcdMIVtest -
2223f4a2713aSLionel Sambuc // Tests an MIV subscript pair for dependence.
2224f4a2713aSLionel Sambuc // Returns true if any possible dependence is disproved.
2225f4a2713aSLionel Sambuc // Marks the result as inconsistent.
2226f4a2713aSLionel Sambuc // Can sometimes disprove the equal direction for 1 or more loops,
2227f4a2713aSLionel Sambuc // as discussed in Michael Wolfe's book,
2228f4a2713aSLionel Sambuc // High Performance Compilers for Parallel Computing, page 235.
2229f4a2713aSLionel Sambuc //
2230f4a2713aSLionel Sambuc // We spend some effort (code!) to handle cases like
2231f4a2713aSLionel Sambuc // [10*i + 5*N*j + 15*M + 6], where i and j are induction variables,
2232f4a2713aSLionel Sambuc // but M and N are just loop-invariant variables.
2233f4a2713aSLionel Sambuc // This should help us handle linearized subscripts;
2234f4a2713aSLionel Sambuc // also makes this test a useful backup to the various SIV tests.
2235f4a2713aSLionel Sambuc //
2236f4a2713aSLionel Sambuc // It occurs to me that the presence of loop-invariant variables
2237f4a2713aSLionel Sambuc // changes the nature of the test from "greatest common divisor"
2238f4a2713aSLionel Sambuc // to "a common divisor".
gcdMIVtest(const SCEV * Src,const SCEV * Dst,FullDependence & Result) const2239f4a2713aSLionel Sambuc bool DependenceAnalysis::gcdMIVtest(const SCEV *Src,
2240f4a2713aSLionel Sambuc                                     const SCEV *Dst,
2241f4a2713aSLionel Sambuc                                     FullDependence &Result) const {
2242f4a2713aSLionel Sambuc   DEBUG(dbgs() << "starting gcd\n");
2243f4a2713aSLionel Sambuc   ++GCDapplications;
2244f4a2713aSLionel Sambuc   unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
2245f4a2713aSLionel Sambuc   APInt RunningGCD = APInt::getNullValue(BitWidth);
2246f4a2713aSLionel Sambuc 
2247f4a2713aSLionel Sambuc   // Examine Src coefficients.
2248f4a2713aSLionel Sambuc   // Compute running GCD and record source constant.
2249f4a2713aSLionel Sambuc   // Because we're looking for the constant at the end of the chain,
2250f4a2713aSLionel Sambuc   // we can't quit the loop just because the GCD == 1.
2251f4a2713aSLionel Sambuc   const SCEV *Coefficients = Src;
2252f4a2713aSLionel Sambuc   while (const SCEVAddRecExpr *AddRec =
2253f4a2713aSLionel Sambuc          dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2254f4a2713aSLionel Sambuc     const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2255f4a2713aSLionel Sambuc     const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Coeff);
2256f4a2713aSLionel Sambuc     if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2257f4a2713aSLionel Sambuc       // If the coefficient is the product of a constant and other stuff,
2258f4a2713aSLionel Sambuc       // we can use the constant in the GCD computation.
2259f4a2713aSLionel Sambuc       Constant = getConstantPart(Product);
2260f4a2713aSLionel Sambuc     if (!Constant)
2261f4a2713aSLionel Sambuc       return false;
2262f4a2713aSLionel Sambuc     APInt ConstCoeff = Constant->getValue()->getValue();
2263f4a2713aSLionel Sambuc     RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
2264f4a2713aSLionel Sambuc     Coefficients = AddRec->getStart();
2265f4a2713aSLionel Sambuc   }
2266f4a2713aSLionel Sambuc   const SCEV *SrcConst = Coefficients;
2267f4a2713aSLionel Sambuc 
2268f4a2713aSLionel Sambuc   // Examine Dst coefficients.
2269f4a2713aSLionel Sambuc   // Compute running GCD and record destination constant.
2270f4a2713aSLionel Sambuc   // Because we're looking for the constant at the end of the chain,
2271f4a2713aSLionel Sambuc   // we can't quit the loop just because the GCD == 1.
2272f4a2713aSLionel Sambuc   Coefficients = Dst;
2273f4a2713aSLionel Sambuc   while (const SCEVAddRecExpr *AddRec =
2274f4a2713aSLionel Sambuc          dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2275f4a2713aSLionel Sambuc     const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2276f4a2713aSLionel Sambuc     const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Coeff);
2277f4a2713aSLionel Sambuc     if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2278f4a2713aSLionel Sambuc       // If the coefficient is the product of a constant and other stuff,
2279f4a2713aSLionel Sambuc       // we can use the constant in the GCD computation.
2280f4a2713aSLionel Sambuc       Constant = getConstantPart(Product);
2281f4a2713aSLionel Sambuc     if (!Constant)
2282f4a2713aSLionel Sambuc       return false;
2283f4a2713aSLionel Sambuc     APInt ConstCoeff = Constant->getValue()->getValue();
2284f4a2713aSLionel Sambuc     RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
2285f4a2713aSLionel Sambuc     Coefficients = AddRec->getStart();
2286f4a2713aSLionel Sambuc   }
2287f4a2713aSLionel Sambuc   const SCEV *DstConst = Coefficients;
2288f4a2713aSLionel Sambuc 
2289f4a2713aSLionel Sambuc   APInt ExtraGCD = APInt::getNullValue(BitWidth);
2290f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2291f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    Delta = " << *Delta << "\n");
2292f4a2713aSLionel Sambuc   const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Delta);
2293f4a2713aSLionel Sambuc   if (const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
2294f4a2713aSLionel Sambuc     // If Delta is a sum of products, we may be able to make further progress.
2295f4a2713aSLionel Sambuc     for (unsigned Op = 0, Ops = Sum->getNumOperands(); Op < Ops; Op++) {
2296f4a2713aSLionel Sambuc       const SCEV *Operand = Sum->getOperand(Op);
2297f4a2713aSLionel Sambuc       if (isa<SCEVConstant>(Operand)) {
2298f4a2713aSLionel Sambuc         assert(!Constant && "Surprised to find multiple constants");
2299f4a2713aSLionel Sambuc         Constant = cast<SCEVConstant>(Operand);
2300f4a2713aSLionel Sambuc       }
2301f4a2713aSLionel Sambuc       else if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
2302f4a2713aSLionel Sambuc         // Search for constant operand to participate in GCD;
2303f4a2713aSLionel Sambuc         // If none found; return false.
2304f4a2713aSLionel Sambuc         const SCEVConstant *ConstOp = getConstantPart(Product);
2305f4a2713aSLionel Sambuc         if (!ConstOp)
2306f4a2713aSLionel Sambuc           return false;
2307f4a2713aSLionel Sambuc         APInt ConstOpValue = ConstOp->getValue()->getValue();
2308f4a2713aSLionel Sambuc         ExtraGCD = APIntOps::GreatestCommonDivisor(ExtraGCD,
2309f4a2713aSLionel Sambuc                                                    ConstOpValue.abs());
2310f4a2713aSLionel Sambuc       }
2311f4a2713aSLionel Sambuc       else
2312f4a2713aSLionel Sambuc         return false;
2313f4a2713aSLionel Sambuc     }
2314f4a2713aSLionel Sambuc   }
2315f4a2713aSLionel Sambuc   if (!Constant)
2316f4a2713aSLionel Sambuc     return false;
2317f4a2713aSLionel Sambuc   APInt ConstDelta = cast<SCEVConstant>(Constant)->getValue()->getValue();
2318f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    ConstDelta = " << ConstDelta << "\n");
2319f4a2713aSLionel Sambuc   if (ConstDelta == 0)
2320f4a2713aSLionel Sambuc     return false;
2321f4a2713aSLionel Sambuc   RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ExtraGCD);
2322f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    RunningGCD = " << RunningGCD << "\n");
2323f4a2713aSLionel Sambuc   APInt Remainder = ConstDelta.srem(RunningGCD);
2324f4a2713aSLionel Sambuc   if (Remainder != 0) {
2325f4a2713aSLionel Sambuc     ++GCDindependence;
2326f4a2713aSLionel Sambuc     return true;
2327f4a2713aSLionel Sambuc   }
2328f4a2713aSLionel Sambuc 
2329f4a2713aSLionel Sambuc   // Try to disprove equal directions.
2330f4a2713aSLionel Sambuc   // For example, given a subscript pair [3*i + 2*j] and [i' + 2*j' - 1],
2331f4a2713aSLionel Sambuc   // the code above can't disprove the dependence because the GCD = 1.
2332f4a2713aSLionel Sambuc   // So we consider what happen if i = i' and what happens if j = j'.
2333f4a2713aSLionel Sambuc   // If i = i', we can simplify the subscript to [2*i + 2*j] and [2*j' - 1],
2334f4a2713aSLionel Sambuc   // which is infeasible, so we can disallow the = direction for the i level.
2335f4a2713aSLionel Sambuc   // Setting j = j' doesn't help matters, so we end up with a direction vector
2336f4a2713aSLionel Sambuc   // of [<>, *]
2337f4a2713aSLionel Sambuc   //
2338f4a2713aSLionel Sambuc   // Given A[5*i + 10*j*M + 9*M*N] and A[15*i + 20*j*M - 21*N*M + 5],
2339f4a2713aSLionel Sambuc   // we need to remember that the constant part is 5 and the RunningGCD should
2340f4a2713aSLionel Sambuc   // be initialized to ExtraGCD = 30.
2341f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    ExtraGCD = " << ExtraGCD << '\n');
2342f4a2713aSLionel Sambuc 
2343f4a2713aSLionel Sambuc   bool Improved = false;
2344f4a2713aSLionel Sambuc   Coefficients = Src;
2345f4a2713aSLionel Sambuc   while (const SCEVAddRecExpr *AddRec =
2346f4a2713aSLionel Sambuc          dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2347f4a2713aSLionel Sambuc     Coefficients = AddRec->getStart();
2348f4a2713aSLionel Sambuc     const Loop *CurLoop = AddRec->getLoop();
2349f4a2713aSLionel Sambuc     RunningGCD = ExtraGCD;
2350f4a2713aSLionel Sambuc     const SCEV *SrcCoeff = AddRec->getStepRecurrence(*SE);
2351f4a2713aSLionel Sambuc     const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);
2352f4a2713aSLionel Sambuc     const SCEV *Inner = Src;
2353f4a2713aSLionel Sambuc     while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2354f4a2713aSLionel Sambuc       AddRec = cast<SCEVAddRecExpr>(Inner);
2355f4a2713aSLionel Sambuc       const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2356f4a2713aSLionel Sambuc       if (CurLoop == AddRec->getLoop())
2357f4a2713aSLionel Sambuc         ; // SrcCoeff == Coeff
2358f4a2713aSLionel Sambuc       else {
2359f4a2713aSLionel Sambuc         if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2360f4a2713aSLionel Sambuc           // If the coefficient is the product of a constant and other stuff,
2361f4a2713aSLionel Sambuc           // we can use the constant in the GCD computation.
2362f4a2713aSLionel Sambuc           Constant = getConstantPart(Product);
2363f4a2713aSLionel Sambuc         else
2364f4a2713aSLionel Sambuc           Constant = cast<SCEVConstant>(Coeff);
2365f4a2713aSLionel Sambuc         APInt ConstCoeff = Constant->getValue()->getValue();
2366f4a2713aSLionel Sambuc         RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
2367f4a2713aSLionel Sambuc       }
2368f4a2713aSLionel Sambuc       Inner = AddRec->getStart();
2369f4a2713aSLionel Sambuc     }
2370f4a2713aSLionel Sambuc     Inner = Dst;
2371f4a2713aSLionel Sambuc     while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2372f4a2713aSLionel Sambuc       AddRec = cast<SCEVAddRecExpr>(Inner);
2373f4a2713aSLionel Sambuc       const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2374f4a2713aSLionel Sambuc       if (CurLoop == AddRec->getLoop())
2375f4a2713aSLionel Sambuc         DstCoeff = Coeff;
2376f4a2713aSLionel Sambuc       else {
2377f4a2713aSLionel Sambuc         if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2378f4a2713aSLionel Sambuc           // If the coefficient is the product of a constant and other stuff,
2379f4a2713aSLionel Sambuc           // we can use the constant in the GCD computation.
2380f4a2713aSLionel Sambuc           Constant = getConstantPart(Product);
2381f4a2713aSLionel Sambuc         else
2382f4a2713aSLionel Sambuc           Constant = cast<SCEVConstant>(Coeff);
2383f4a2713aSLionel Sambuc         APInt ConstCoeff = Constant->getValue()->getValue();
2384f4a2713aSLionel Sambuc         RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
2385f4a2713aSLionel Sambuc       }
2386f4a2713aSLionel Sambuc       Inner = AddRec->getStart();
2387f4a2713aSLionel Sambuc     }
2388f4a2713aSLionel Sambuc     Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
2389f4a2713aSLionel Sambuc     if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Delta))
2390f4a2713aSLionel Sambuc       // If the coefficient is the product of a constant and other stuff,
2391f4a2713aSLionel Sambuc       // we can use the constant in the GCD computation.
2392f4a2713aSLionel Sambuc       Constant = getConstantPart(Product);
2393f4a2713aSLionel Sambuc     else if (isa<SCEVConstant>(Delta))
2394f4a2713aSLionel Sambuc       Constant = cast<SCEVConstant>(Delta);
2395f4a2713aSLionel Sambuc     else {
2396f4a2713aSLionel Sambuc       // The difference of the two coefficients might not be a product
2397f4a2713aSLionel Sambuc       // or constant, in which case we give up on this direction.
2398f4a2713aSLionel Sambuc       continue;
2399f4a2713aSLionel Sambuc     }
2400f4a2713aSLionel Sambuc     APInt ConstCoeff = Constant->getValue()->getValue();
2401f4a2713aSLionel Sambuc     RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
2402f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tRunningGCD = " << RunningGCD << "\n");
2403f4a2713aSLionel Sambuc     if (RunningGCD != 0) {
2404f4a2713aSLionel Sambuc       Remainder = ConstDelta.srem(RunningGCD);
2405f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\tRemainder = " << Remainder << "\n");
2406f4a2713aSLionel Sambuc       if (Remainder != 0) {
2407f4a2713aSLionel Sambuc         unsigned Level = mapSrcLoop(CurLoop);
2408f4a2713aSLionel Sambuc         Result.DV[Level - 1].Direction &= unsigned(~Dependence::DVEntry::EQ);
2409f4a2713aSLionel Sambuc         Improved = true;
2410f4a2713aSLionel Sambuc       }
2411f4a2713aSLionel Sambuc     }
2412f4a2713aSLionel Sambuc   }
2413f4a2713aSLionel Sambuc   if (Improved)
2414f4a2713aSLionel Sambuc     ++GCDsuccesses;
2415f4a2713aSLionel Sambuc   DEBUG(dbgs() << "all done\n");
2416f4a2713aSLionel Sambuc   return false;
2417f4a2713aSLionel Sambuc }
2418f4a2713aSLionel Sambuc 
2419f4a2713aSLionel Sambuc 
2420f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2421f4a2713aSLionel Sambuc // banerjeeMIVtest -
2422f4a2713aSLionel Sambuc // Use Banerjee's Inequalities to test an MIV subscript pair.
2423f4a2713aSLionel Sambuc // (Wolfe, in the race-car book, calls this the Extreme Value Test.)
2424f4a2713aSLionel Sambuc // Generally follows the discussion in Section 2.5.2 of
2425f4a2713aSLionel Sambuc //
2426f4a2713aSLionel Sambuc //    Optimizing Supercompilers for Supercomputers
2427f4a2713aSLionel Sambuc //    Michael Wolfe
2428f4a2713aSLionel Sambuc //
2429f4a2713aSLionel Sambuc // The inequalities given on page 25 are simplified in that loops are
2430f4a2713aSLionel Sambuc // normalized so that the lower bound is always 0 and the stride is always 1.
2431f4a2713aSLionel Sambuc // For example, Wolfe gives
2432f4a2713aSLionel Sambuc //
2433f4a2713aSLionel Sambuc //     LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
2434f4a2713aSLionel Sambuc //
2435f4a2713aSLionel Sambuc // where A_k is the coefficient of the kth index in the source subscript,
2436f4a2713aSLionel Sambuc // B_k is the coefficient of the kth index in the destination subscript,
2437f4a2713aSLionel Sambuc // U_k is the upper bound of the kth index, L_k is the lower bound of the Kth
2438f4a2713aSLionel Sambuc // index, and N_k is the stride of the kth index. Since all loops are normalized
2439f4a2713aSLionel Sambuc // by the SCEV package, N_k = 1 and L_k = 0, allowing us to simplify the
2440f4a2713aSLionel Sambuc // equation to
2441f4a2713aSLionel Sambuc //
2442f4a2713aSLionel Sambuc //     LB^<_k = (A^-_k - B_k)^- (U_k - 0 - 1) + (A_k - B_k)0 - B_k 1
2443f4a2713aSLionel Sambuc //            = (A^-_k - B_k)^- (U_k - 1)  - B_k
2444f4a2713aSLionel Sambuc //
2445f4a2713aSLionel Sambuc // Similar simplifications are possible for the other equations.
2446f4a2713aSLionel Sambuc //
2447f4a2713aSLionel Sambuc // When we can't determine the number of iterations for a loop,
2448f4a2713aSLionel Sambuc // we use NULL as an indicator for the worst case, infinity.
2449f4a2713aSLionel Sambuc // When computing the upper bound, NULL denotes +inf;
2450f4a2713aSLionel Sambuc // for the lower bound, NULL denotes -inf.
2451f4a2713aSLionel Sambuc //
2452f4a2713aSLionel Sambuc // Return true if dependence disproved.
banerjeeMIVtest(const SCEV * Src,const SCEV * Dst,const SmallBitVector & Loops,FullDependence & Result) const2453f4a2713aSLionel Sambuc bool DependenceAnalysis::banerjeeMIVtest(const SCEV *Src,
2454f4a2713aSLionel Sambuc                                          const SCEV *Dst,
2455f4a2713aSLionel Sambuc                                          const SmallBitVector &Loops,
2456f4a2713aSLionel Sambuc                                          FullDependence &Result) const {
2457f4a2713aSLionel Sambuc   DEBUG(dbgs() << "starting Banerjee\n");
2458f4a2713aSLionel Sambuc   ++BanerjeeApplications;
2459f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    Src = " << *Src << '\n');
2460f4a2713aSLionel Sambuc   const SCEV *A0;
2461f4a2713aSLionel Sambuc   CoefficientInfo *A = collectCoeffInfo(Src, true, A0);
2462f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    Dst = " << *Dst << '\n');
2463f4a2713aSLionel Sambuc   const SCEV *B0;
2464f4a2713aSLionel Sambuc   CoefficientInfo *B = collectCoeffInfo(Dst, false, B0);
2465f4a2713aSLionel Sambuc   BoundInfo *Bound = new BoundInfo[MaxLevels + 1];
2466f4a2713aSLionel Sambuc   const SCEV *Delta = SE->getMinusSCEV(B0, A0);
2467f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tDelta = " << *Delta << '\n');
2468f4a2713aSLionel Sambuc 
2469f4a2713aSLionel Sambuc   // Compute bounds for all the * directions.
2470f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tBounds[*]\n");
2471f4a2713aSLionel Sambuc   for (unsigned K = 1; K <= MaxLevels; ++K) {
2472f4a2713aSLionel Sambuc     Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
2473f4a2713aSLionel Sambuc     Bound[K].Direction = Dependence::DVEntry::ALL;
2474f4a2713aSLionel Sambuc     Bound[K].DirSet = Dependence::DVEntry::NONE;
2475f4a2713aSLionel Sambuc     findBoundsALL(A, B, Bound, K);
2476f4a2713aSLionel Sambuc #ifndef NDEBUG
2477f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    " << K << '\t');
2478f4a2713aSLionel Sambuc     if (Bound[K].Lower[Dependence::DVEntry::ALL])
2479f4a2713aSLionel Sambuc       DEBUG(dbgs() << *Bound[K].Lower[Dependence::DVEntry::ALL] << '\t');
2480f4a2713aSLionel Sambuc     else
2481f4a2713aSLionel Sambuc       DEBUG(dbgs() << "-inf\t");
2482f4a2713aSLionel Sambuc     if (Bound[K].Upper[Dependence::DVEntry::ALL])
2483f4a2713aSLionel Sambuc       DEBUG(dbgs() << *Bound[K].Upper[Dependence::DVEntry::ALL] << '\n');
2484f4a2713aSLionel Sambuc     else
2485f4a2713aSLionel Sambuc       DEBUG(dbgs() << "+inf\n");
2486f4a2713aSLionel Sambuc #endif
2487f4a2713aSLionel Sambuc   }
2488f4a2713aSLionel Sambuc 
2489f4a2713aSLionel Sambuc   // Test the *, *, *, ... case.
2490f4a2713aSLionel Sambuc   bool Disproved = false;
2491f4a2713aSLionel Sambuc   if (testBounds(Dependence::DVEntry::ALL, 0, Bound, Delta)) {
2492f4a2713aSLionel Sambuc     // Explore the direction vector hierarchy.
2493f4a2713aSLionel Sambuc     unsigned DepthExpanded = 0;
2494f4a2713aSLionel Sambuc     unsigned NewDeps = exploreDirections(1, A, B, Bound,
2495f4a2713aSLionel Sambuc                                          Loops, DepthExpanded, Delta);
2496f4a2713aSLionel Sambuc     if (NewDeps > 0) {
2497f4a2713aSLionel Sambuc       bool Improved = false;
2498f4a2713aSLionel Sambuc       for (unsigned K = 1; K <= CommonLevels; ++K) {
2499f4a2713aSLionel Sambuc         if (Loops[K]) {
2500f4a2713aSLionel Sambuc           unsigned Old = Result.DV[K - 1].Direction;
2501f4a2713aSLionel Sambuc           Result.DV[K - 1].Direction = Old & Bound[K].DirSet;
2502f4a2713aSLionel Sambuc           Improved |= Old != Result.DV[K - 1].Direction;
2503f4a2713aSLionel Sambuc           if (!Result.DV[K - 1].Direction) {
2504f4a2713aSLionel Sambuc             Improved = false;
2505f4a2713aSLionel Sambuc             Disproved = true;
2506f4a2713aSLionel Sambuc             break;
2507f4a2713aSLionel Sambuc           }
2508f4a2713aSLionel Sambuc         }
2509f4a2713aSLionel Sambuc       }
2510f4a2713aSLionel Sambuc       if (Improved)
2511f4a2713aSLionel Sambuc         ++BanerjeeSuccesses;
2512f4a2713aSLionel Sambuc     }
2513f4a2713aSLionel Sambuc     else {
2514f4a2713aSLionel Sambuc       ++BanerjeeIndependence;
2515f4a2713aSLionel Sambuc       Disproved = true;
2516f4a2713aSLionel Sambuc     }
2517f4a2713aSLionel Sambuc   }
2518f4a2713aSLionel Sambuc   else {
2519f4a2713aSLionel Sambuc     ++BanerjeeIndependence;
2520f4a2713aSLionel Sambuc     Disproved = true;
2521f4a2713aSLionel Sambuc   }
2522f4a2713aSLionel Sambuc   delete [] Bound;
2523f4a2713aSLionel Sambuc   delete [] A;
2524f4a2713aSLionel Sambuc   delete [] B;
2525f4a2713aSLionel Sambuc   return Disproved;
2526f4a2713aSLionel Sambuc }
2527f4a2713aSLionel Sambuc 
2528f4a2713aSLionel Sambuc 
2529f4a2713aSLionel Sambuc // Hierarchically expands the direction vector
2530f4a2713aSLionel Sambuc // search space, combining the directions of discovered dependences
2531f4a2713aSLionel Sambuc // in the DirSet field of Bound. Returns the number of distinct
2532f4a2713aSLionel Sambuc // dependences discovered. If the dependence is disproved,
2533f4a2713aSLionel Sambuc // it will return 0.
exploreDirections(unsigned Level,CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,const SmallBitVector & Loops,unsigned & DepthExpanded,const SCEV * Delta) const2534f4a2713aSLionel Sambuc unsigned DependenceAnalysis::exploreDirections(unsigned Level,
2535f4a2713aSLionel Sambuc                                                CoefficientInfo *A,
2536f4a2713aSLionel Sambuc                                                CoefficientInfo *B,
2537f4a2713aSLionel Sambuc                                                BoundInfo *Bound,
2538f4a2713aSLionel Sambuc                                                const SmallBitVector &Loops,
2539f4a2713aSLionel Sambuc                                                unsigned &DepthExpanded,
2540f4a2713aSLionel Sambuc                                                const SCEV *Delta) const {
2541f4a2713aSLionel Sambuc   if (Level > CommonLevels) {
2542f4a2713aSLionel Sambuc     // record result
2543f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t[");
2544f4a2713aSLionel Sambuc     for (unsigned K = 1; K <= CommonLevels; ++K) {
2545f4a2713aSLionel Sambuc       if (Loops[K]) {
2546f4a2713aSLionel Sambuc         Bound[K].DirSet |= Bound[K].Direction;
2547f4a2713aSLionel Sambuc #ifndef NDEBUG
2548f4a2713aSLionel Sambuc         switch (Bound[K].Direction) {
2549f4a2713aSLionel Sambuc         case Dependence::DVEntry::LT:
2550f4a2713aSLionel Sambuc           DEBUG(dbgs() << " <");
2551f4a2713aSLionel Sambuc           break;
2552f4a2713aSLionel Sambuc         case Dependence::DVEntry::EQ:
2553f4a2713aSLionel Sambuc           DEBUG(dbgs() << " =");
2554f4a2713aSLionel Sambuc           break;
2555f4a2713aSLionel Sambuc         case Dependence::DVEntry::GT:
2556f4a2713aSLionel Sambuc           DEBUG(dbgs() << " >");
2557f4a2713aSLionel Sambuc           break;
2558f4a2713aSLionel Sambuc         case Dependence::DVEntry::ALL:
2559f4a2713aSLionel Sambuc           DEBUG(dbgs() << " *");
2560f4a2713aSLionel Sambuc           break;
2561f4a2713aSLionel Sambuc         default:
2562f4a2713aSLionel Sambuc           llvm_unreachable("unexpected Bound[K].Direction");
2563f4a2713aSLionel Sambuc         }
2564f4a2713aSLionel Sambuc #endif
2565f4a2713aSLionel Sambuc       }
2566f4a2713aSLionel Sambuc     }
2567f4a2713aSLionel Sambuc     DEBUG(dbgs() << " ]\n");
2568f4a2713aSLionel Sambuc     return 1;
2569f4a2713aSLionel Sambuc   }
2570f4a2713aSLionel Sambuc   if (Loops[Level]) {
2571f4a2713aSLionel Sambuc     if (Level > DepthExpanded) {
2572f4a2713aSLionel Sambuc       DepthExpanded = Level;
2573f4a2713aSLionel Sambuc       // compute bounds for <, =, > at current level
2574f4a2713aSLionel Sambuc       findBoundsLT(A, B, Bound, Level);
2575f4a2713aSLionel Sambuc       findBoundsGT(A, B, Bound, Level);
2576f4a2713aSLionel Sambuc       findBoundsEQ(A, B, Bound, Level);
2577f4a2713aSLionel Sambuc #ifndef NDEBUG
2578f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\tBound for level = " << Level << '\n');
2579f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    <\t");
2580f4a2713aSLionel Sambuc       if (Bound[Level].Lower[Dependence::DVEntry::LT])
2581f4a2713aSLionel Sambuc         DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::LT] << '\t');
2582f4a2713aSLionel Sambuc       else
2583f4a2713aSLionel Sambuc         DEBUG(dbgs() << "-inf\t");
2584f4a2713aSLionel Sambuc       if (Bound[Level].Upper[Dependence::DVEntry::LT])
2585f4a2713aSLionel Sambuc         DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::LT] << '\n');
2586f4a2713aSLionel Sambuc       else
2587f4a2713aSLionel Sambuc         DEBUG(dbgs() << "+inf\n");
2588f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    =\t");
2589f4a2713aSLionel Sambuc       if (Bound[Level].Lower[Dependence::DVEntry::EQ])
2590f4a2713aSLionel Sambuc         DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::EQ] << '\t');
2591f4a2713aSLionel Sambuc       else
2592f4a2713aSLionel Sambuc         DEBUG(dbgs() << "-inf\t");
2593f4a2713aSLionel Sambuc       if (Bound[Level].Upper[Dependence::DVEntry::EQ])
2594f4a2713aSLionel Sambuc         DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::EQ] << '\n');
2595f4a2713aSLionel Sambuc       else
2596f4a2713aSLionel Sambuc         DEBUG(dbgs() << "+inf\n");
2597f4a2713aSLionel Sambuc       DEBUG(dbgs() << "\t    >\t");
2598f4a2713aSLionel Sambuc       if (Bound[Level].Lower[Dependence::DVEntry::GT])
2599f4a2713aSLionel Sambuc         DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::GT] << '\t');
2600f4a2713aSLionel Sambuc       else
2601f4a2713aSLionel Sambuc         DEBUG(dbgs() << "-inf\t");
2602f4a2713aSLionel Sambuc       if (Bound[Level].Upper[Dependence::DVEntry::GT])
2603f4a2713aSLionel Sambuc         DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::GT] << '\n');
2604f4a2713aSLionel Sambuc       else
2605f4a2713aSLionel Sambuc         DEBUG(dbgs() << "+inf\n");
2606f4a2713aSLionel Sambuc #endif
2607f4a2713aSLionel Sambuc     }
2608f4a2713aSLionel Sambuc 
2609f4a2713aSLionel Sambuc     unsigned NewDeps = 0;
2610f4a2713aSLionel Sambuc 
2611f4a2713aSLionel Sambuc     // test bounds for <, *, *, ...
2612f4a2713aSLionel Sambuc     if (testBounds(Dependence::DVEntry::LT, Level, Bound, Delta))
2613f4a2713aSLionel Sambuc       NewDeps += exploreDirections(Level + 1, A, B, Bound,
2614f4a2713aSLionel Sambuc                                    Loops, DepthExpanded, Delta);
2615f4a2713aSLionel Sambuc 
2616f4a2713aSLionel Sambuc     // Test bounds for =, *, *, ...
2617f4a2713aSLionel Sambuc     if (testBounds(Dependence::DVEntry::EQ, Level, Bound, Delta))
2618f4a2713aSLionel Sambuc       NewDeps += exploreDirections(Level + 1, A, B, Bound,
2619f4a2713aSLionel Sambuc                                    Loops, DepthExpanded, Delta);
2620f4a2713aSLionel Sambuc 
2621f4a2713aSLionel Sambuc     // test bounds for >, *, *, ...
2622f4a2713aSLionel Sambuc     if (testBounds(Dependence::DVEntry::GT, Level, Bound, Delta))
2623f4a2713aSLionel Sambuc       NewDeps += exploreDirections(Level + 1, A, B, Bound,
2624f4a2713aSLionel Sambuc                                    Loops, DepthExpanded, Delta);
2625f4a2713aSLionel Sambuc 
2626f4a2713aSLionel Sambuc     Bound[Level].Direction = Dependence::DVEntry::ALL;
2627f4a2713aSLionel Sambuc     return NewDeps;
2628f4a2713aSLionel Sambuc   }
2629f4a2713aSLionel Sambuc   else
2630f4a2713aSLionel Sambuc     return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded, Delta);
2631f4a2713aSLionel Sambuc }
2632f4a2713aSLionel Sambuc 
2633f4a2713aSLionel Sambuc 
2634f4a2713aSLionel Sambuc // Returns true iff the current bounds are plausible.
testBounds(unsigned char DirKind,unsigned Level,BoundInfo * Bound,const SCEV * Delta) const2635f4a2713aSLionel Sambuc bool DependenceAnalysis::testBounds(unsigned char DirKind,
2636f4a2713aSLionel Sambuc                                     unsigned Level,
2637f4a2713aSLionel Sambuc                                     BoundInfo *Bound,
2638f4a2713aSLionel Sambuc                                     const SCEV *Delta) const {
2639f4a2713aSLionel Sambuc   Bound[Level].Direction = DirKind;
2640f4a2713aSLionel Sambuc   if (const SCEV *LowerBound = getLowerBound(Bound))
2641f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_SGT, LowerBound, Delta))
2642f4a2713aSLionel Sambuc       return false;
2643f4a2713aSLionel Sambuc   if (const SCEV *UpperBound = getUpperBound(Bound))
2644f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, UpperBound))
2645f4a2713aSLionel Sambuc       return false;
2646f4a2713aSLionel Sambuc   return true;
2647f4a2713aSLionel Sambuc }
2648f4a2713aSLionel Sambuc 
2649f4a2713aSLionel Sambuc 
2650f4a2713aSLionel Sambuc // Computes the upper and lower bounds for level K
2651f4a2713aSLionel Sambuc // using the * direction. Records them in Bound.
2652f4a2713aSLionel Sambuc // Wolfe gives the equations
2653f4a2713aSLionel Sambuc //
2654f4a2713aSLionel Sambuc //    LB^*_k = (A^-_k - B^+_k)(U_k - L_k) + (A_k - B_k)L_k
2655f4a2713aSLionel Sambuc //    UB^*_k = (A^+_k - B^-_k)(U_k - L_k) + (A_k - B_k)L_k
2656f4a2713aSLionel Sambuc //
2657f4a2713aSLionel Sambuc // Since we normalize loops, we can simplify these equations to
2658f4a2713aSLionel Sambuc //
2659f4a2713aSLionel Sambuc //    LB^*_k = (A^-_k - B^+_k)U_k
2660f4a2713aSLionel Sambuc //    UB^*_k = (A^+_k - B^-_k)U_k
2661f4a2713aSLionel Sambuc //
2662f4a2713aSLionel Sambuc // We must be careful to handle the case where the upper bound is unknown.
2663f4a2713aSLionel Sambuc // Note that the lower bound is always <= 0
2664f4a2713aSLionel Sambuc // and the upper bound is always >= 0.
findBoundsALL(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const2665f4a2713aSLionel Sambuc void DependenceAnalysis::findBoundsALL(CoefficientInfo *A,
2666f4a2713aSLionel Sambuc                                        CoefficientInfo *B,
2667f4a2713aSLionel Sambuc                                        BoundInfo *Bound,
2668f4a2713aSLionel Sambuc                                        unsigned K) const {
2669*0a6a1f1dSLionel Sambuc   Bound[K].Lower[Dependence::DVEntry::ALL] = nullptr; // Default value = -infinity.
2670*0a6a1f1dSLionel Sambuc   Bound[K].Upper[Dependence::DVEntry::ALL] = nullptr; // Default value = +infinity.
2671f4a2713aSLionel Sambuc   if (Bound[K].Iterations) {
2672f4a2713aSLionel Sambuc     Bound[K].Lower[Dependence::DVEntry::ALL] =
2673f4a2713aSLionel Sambuc       SE->getMulExpr(SE->getMinusSCEV(A[K].NegPart, B[K].PosPart),
2674f4a2713aSLionel Sambuc                      Bound[K].Iterations);
2675f4a2713aSLionel Sambuc     Bound[K].Upper[Dependence::DVEntry::ALL] =
2676f4a2713aSLionel Sambuc       SE->getMulExpr(SE->getMinusSCEV(A[K].PosPart, B[K].NegPart),
2677f4a2713aSLionel Sambuc                      Bound[K].Iterations);
2678f4a2713aSLionel Sambuc   }
2679f4a2713aSLionel Sambuc   else {
2680f4a2713aSLionel Sambuc     // If the difference is 0, we won't need to know the number of iterations.
2681f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].NegPart, B[K].PosPart))
2682f4a2713aSLionel Sambuc       Bound[K].Lower[Dependence::DVEntry::ALL] =
2683f4a2713aSLionel Sambuc         SE->getConstant(A[K].Coeff->getType(), 0);
2684f4a2713aSLionel Sambuc     if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].PosPart, B[K].NegPart))
2685f4a2713aSLionel Sambuc       Bound[K].Upper[Dependence::DVEntry::ALL] =
2686f4a2713aSLionel Sambuc         SE->getConstant(A[K].Coeff->getType(), 0);
2687f4a2713aSLionel Sambuc   }
2688f4a2713aSLionel Sambuc }
2689f4a2713aSLionel Sambuc 
2690f4a2713aSLionel Sambuc 
2691f4a2713aSLionel Sambuc // Computes the upper and lower bounds for level K
2692f4a2713aSLionel Sambuc // using the = direction. Records them in Bound.
2693f4a2713aSLionel Sambuc // Wolfe gives the equations
2694f4a2713aSLionel Sambuc //
2695f4a2713aSLionel Sambuc //    LB^=_k = (A_k - B_k)^- (U_k - L_k) + (A_k - B_k)L_k
2696f4a2713aSLionel Sambuc //    UB^=_k = (A_k - B_k)^+ (U_k - L_k) + (A_k - B_k)L_k
2697f4a2713aSLionel Sambuc //
2698f4a2713aSLionel Sambuc // Since we normalize loops, we can simplify these equations to
2699f4a2713aSLionel Sambuc //
2700f4a2713aSLionel Sambuc //    LB^=_k = (A_k - B_k)^- U_k
2701f4a2713aSLionel Sambuc //    UB^=_k = (A_k - B_k)^+ U_k
2702f4a2713aSLionel Sambuc //
2703f4a2713aSLionel Sambuc // We must be careful to handle the case where the upper bound is unknown.
2704f4a2713aSLionel Sambuc // Note that the lower bound is always <= 0
2705f4a2713aSLionel Sambuc // and the upper bound is always >= 0.
findBoundsEQ(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const2706f4a2713aSLionel Sambuc void DependenceAnalysis::findBoundsEQ(CoefficientInfo *A,
2707f4a2713aSLionel Sambuc                                       CoefficientInfo *B,
2708f4a2713aSLionel Sambuc                                       BoundInfo *Bound,
2709f4a2713aSLionel Sambuc                                       unsigned K) const {
2710*0a6a1f1dSLionel Sambuc   Bound[K].Lower[Dependence::DVEntry::EQ] = nullptr; // Default value = -infinity.
2711*0a6a1f1dSLionel Sambuc   Bound[K].Upper[Dependence::DVEntry::EQ] = nullptr; // Default value = +infinity.
2712f4a2713aSLionel Sambuc   if (Bound[K].Iterations) {
2713f4a2713aSLionel Sambuc     const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
2714f4a2713aSLionel Sambuc     const SCEV *NegativePart = getNegativePart(Delta);
2715f4a2713aSLionel Sambuc     Bound[K].Lower[Dependence::DVEntry::EQ] =
2716f4a2713aSLionel Sambuc       SE->getMulExpr(NegativePart, Bound[K].Iterations);
2717f4a2713aSLionel Sambuc     const SCEV *PositivePart = getPositivePart(Delta);
2718f4a2713aSLionel Sambuc     Bound[K].Upper[Dependence::DVEntry::EQ] =
2719f4a2713aSLionel Sambuc       SE->getMulExpr(PositivePart, Bound[K].Iterations);
2720f4a2713aSLionel Sambuc   }
2721f4a2713aSLionel Sambuc   else {
2722f4a2713aSLionel Sambuc     // If the positive/negative part of the difference is 0,
2723f4a2713aSLionel Sambuc     // we won't need to know the number of iterations.
2724f4a2713aSLionel Sambuc     const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
2725f4a2713aSLionel Sambuc     const SCEV *NegativePart = getNegativePart(Delta);
2726f4a2713aSLionel Sambuc     if (NegativePart->isZero())
2727f4a2713aSLionel Sambuc       Bound[K].Lower[Dependence::DVEntry::EQ] = NegativePart; // Zero
2728f4a2713aSLionel Sambuc     const SCEV *PositivePart = getPositivePart(Delta);
2729f4a2713aSLionel Sambuc     if (PositivePart->isZero())
2730f4a2713aSLionel Sambuc       Bound[K].Upper[Dependence::DVEntry::EQ] = PositivePart; // Zero
2731f4a2713aSLionel Sambuc   }
2732f4a2713aSLionel Sambuc }
2733f4a2713aSLionel Sambuc 
2734f4a2713aSLionel Sambuc 
2735f4a2713aSLionel Sambuc // Computes the upper and lower bounds for level K
2736f4a2713aSLionel Sambuc // using the < direction. Records them in Bound.
2737f4a2713aSLionel Sambuc // Wolfe gives the equations
2738f4a2713aSLionel Sambuc //
2739f4a2713aSLionel Sambuc //    LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
2740f4a2713aSLionel Sambuc //    UB^<_k = (A^+_k - B_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
2741f4a2713aSLionel Sambuc //
2742f4a2713aSLionel Sambuc // Since we normalize loops, we can simplify these equations to
2743f4a2713aSLionel Sambuc //
2744f4a2713aSLionel Sambuc //    LB^<_k = (A^-_k - B_k)^- (U_k - 1) - B_k
2745f4a2713aSLionel Sambuc //    UB^<_k = (A^+_k - B_k)^+ (U_k - 1) - B_k
2746f4a2713aSLionel Sambuc //
2747f4a2713aSLionel Sambuc // We must be careful to handle the case where the upper bound is unknown.
findBoundsLT(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const2748f4a2713aSLionel Sambuc void DependenceAnalysis::findBoundsLT(CoefficientInfo *A,
2749f4a2713aSLionel Sambuc                                       CoefficientInfo *B,
2750f4a2713aSLionel Sambuc                                       BoundInfo *Bound,
2751f4a2713aSLionel Sambuc                                       unsigned K) const {
2752*0a6a1f1dSLionel Sambuc   Bound[K].Lower[Dependence::DVEntry::LT] = nullptr; // Default value = -infinity.
2753*0a6a1f1dSLionel Sambuc   Bound[K].Upper[Dependence::DVEntry::LT] = nullptr; // Default value = +infinity.
2754f4a2713aSLionel Sambuc   if (Bound[K].Iterations) {
2755f4a2713aSLionel Sambuc     const SCEV *Iter_1 =
2756f4a2713aSLionel Sambuc       SE->getMinusSCEV(Bound[K].Iterations,
2757f4a2713aSLionel Sambuc                        SE->getConstant(Bound[K].Iterations->getType(), 1));
2758f4a2713aSLionel Sambuc     const SCEV *NegPart =
2759f4a2713aSLionel Sambuc       getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
2760f4a2713aSLionel Sambuc     Bound[K].Lower[Dependence::DVEntry::LT] =
2761f4a2713aSLionel Sambuc       SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1), B[K].Coeff);
2762f4a2713aSLionel Sambuc     const SCEV *PosPart =
2763f4a2713aSLionel Sambuc       getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
2764f4a2713aSLionel Sambuc     Bound[K].Upper[Dependence::DVEntry::LT] =
2765f4a2713aSLionel Sambuc       SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1), B[K].Coeff);
2766f4a2713aSLionel Sambuc   }
2767f4a2713aSLionel Sambuc   else {
2768f4a2713aSLionel Sambuc     // If the positive/negative part of the difference is 0,
2769f4a2713aSLionel Sambuc     // we won't need to know the number of iterations.
2770f4a2713aSLionel Sambuc     const SCEV *NegPart =
2771f4a2713aSLionel Sambuc       getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
2772f4a2713aSLionel Sambuc     if (NegPart->isZero())
2773f4a2713aSLionel Sambuc       Bound[K].Lower[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
2774f4a2713aSLionel Sambuc     const SCEV *PosPart =
2775f4a2713aSLionel Sambuc       getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
2776f4a2713aSLionel Sambuc     if (PosPart->isZero())
2777f4a2713aSLionel Sambuc       Bound[K].Upper[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
2778f4a2713aSLionel Sambuc   }
2779f4a2713aSLionel Sambuc }
2780f4a2713aSLionel Sambuc 
2781f4a2713aSLionel Sambuc 
2782f4a2713aSLionel Sambuc // Computes the upper and lower bounds for level K
2783f4a2713aSLionel Sambuc // using the > direction. Records them in Bound.
2784f4a2713aSLionel Sambuc // Wolfe gives the equations
2785f4a2713aSLionel Sambuc //
2786f4a2713aSLionel Sambuc //    LB^>_k = (A_k - B^+_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
2787f4a2713aSLionel Sambuc //    UB^>_k = (A_k - B^-_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
2788f4a2713aSLionel Sambuc //
2789f4a2713aSLionel Sambuc // Since we normalize loops, we can simplify these equations to
2790f4a2713aSLionel Sambuc //
2791f4a2713aSLionel Sambuc //    LB^>_k = (A_k - B^+_k)^- (U_k - 1) + A_k
2792f4a2713aSLionel Sambuc //    UB^>_k = (A_k - B^-_k)^+ (U_k - 1) + A_k
2793f4a2713aSLionel Sambuc //
2794f4a2713aSLionel Sambuc // We must be careful to handle the case where the upper bound is unknown.
findBoundsGT(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const2795f4a2713aSLionel Sambuc void DependenceAnalysis::findBoundsGT(CoefficientInfo *A,
2796f4a2713aSLionel Sambuc                                       CoefficientInfo *B,
2797f4a2713aSLionel Sambuc                                       BoundInfo *Bound,
2798f4a2713aSLionel Sambuc                                       unsigned K) const {
2799*0a6a1f1dSLionel Sambuc   Bound[K].Lower[Dependence::DVEntry::GT] = nullptr; // Default value = -infinity.
2800*0a6a1f1dSLionel Sambuc   Bound[K].Upper[Dependence::DVEntry::GT] = nullptr; // Default value = +infinity.
2801f4a2713aSLionel Sambuc   if (Bound[K].Iterations) {
2802f4a2713aSLionel Sambuc     const SCEV *Iter_1 =
2803f4a2713aSLionel Sambuc       SE->getMinusSCEV(Bound[K].Iterations,
2804f4a2713aSLionel Sambuc                        SE->getConstant(Bound[K].Iterations->getType(), 1));
2805f4a2713aSLionel Sambuc     const SCEV *NegPart =
2806f4a2713aSLionel Sambuc       getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
2807f4a2713aSLionel Sambuc     Bound[K].Lower[Dependence::DVEntry::GT] =
2808f4a2713aSLionel Sambuc       SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1), A[K].Coeff);
2809f4a2713aSLionel Sambuc     const SCEV *PosPart =
2810f4a2713aSLionel Sambuc       getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
2811f4a2713aSLionel Sambuc     Bound[K].Upper[Dependence::DVEntry::GT] =
2812f4a2713aSLionel Sambuc       SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1), A[K].Coeff);
2813f4a2713aSLionel Sambuc   }
2814f4a2713aSLionel Sambuc   else {
2815f4a2713aSLionel Sambuc     // If the positive/negative part of the difference is 0,
2816f4a2713aSLionel Sambuc     // we won't need to know the number of iterations.
2817f4a2713aSLionel Sambuc     const SCEV *NegPart = getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
2818f4a2713aSLionel Sambuc     if (NegPart->isZero())
2819f4a2713aSLionel Sambuc       Bound[K].Lower[Dependence::DVEntry::GT] = A[K].Coeff;
2820f4a2713aSLionel Sambuc     const SCEV *PosPart = getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
2821f4a2713aSLionel Sambuc     if (PosPart->isZero())
2822f4a2713aSLionel Sambuc       Bound[K].Upper[Dependence::DVEntry::GT] = A[K].Coeff;
2823f4a2713aSLionel Sambuc   }
2824f4a2713aSLionel Sambuc }
2825f4a2713aSLionel Sambuc 
2826f4a2713aSLionel Sambuc 
2827f4a2713aSLionel Sambuc // X^+ = max(X, 0)
getPositivePart(const SCEV * X) const2828f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::getPositivePart(const SCEV *X) const {
2829f4a2713aSLionel Sambuc   return SE->getSMaxExpr(X, SE->getConstant(X->getType(), 0));
2830f4a2713aSLionel Sambuc }
2831f4a2713aSLionel Sambuc 
2832f4a2713aSLionel Sambuc 
2833f4a2713aSLionel Sambuc // X^- = min(X, 0)
getNegativePart(const SCEV * X) const2834f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::getNegativePart(const SCEV *X) const {
2835f4a2713aSLionel Sambuc   return SE->getSMinExpr(X, SE->getConstant(X->getType(), 0));
2836f4a2713aSLionel Sambuc }
2837f4a2713aSLionel Sambuc 
2838f4a2713aSLionel Sambuc 
2839f4a2713aSLionel Sambuc // Walks through the subscript,
2840f4a2713aSLionel Sambuc // collecting each coefficient, the associated loop bounds,
2841f4a2713aSLionel Sambuc // and recording its positive and negative parts for later use.
2842f4a2713aSLionel Sambuc DependenceAnalysis::CoefficientInfo *
collectCoeffInfo(const SCEV * Subscript,bool SrcFlag,const SCEV * & Constant) const2843f4a2713aSLionel Sambuc DependenceAnalysis::collectCoeffInfo(const SCEV *Subscript,
2844f4a2713aSLionel Sambuc                                      bool SrcFlag,
2845f4a2713aSLionel Sambuc                                      const SCEV *&Constant) const {
2846f4a2713aSLionel Sambuc   const SCEV *Zero = SE->getConstant(Subscript->getType(), 0);
2847f4a2713aSLionel Sambuc   CoefficientInfo *CI = new CoefficientInfo[MaxLevels + 1];
2848f4a2713aSLionel Sambuc   for (unsigned K = 1; K <= MaxLevels; ++K) {
2849f4a2713aSLionel Sambuc     CI[K].Coeff = Zero;
2850f4a2713aSLionel Sambuc     CI[K].PosPart = Zero;
2851f4a2713aSLionel Sambuc     CI[K].NegPart = Zero;
2852*0a6a1f1dSLionel Sambuc     CI[K].Iterations = nullptr;
2853f4a2713aSLionel Sambuc   }
2854f4a2713aSLionel Sambuc   while (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
2855f4a2713aSLionel Sambuc     const Loop *L = AddRec->getLoop();
2856f4a2713aSLionel Sambuc     unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
2857f4a2713aSLionel Sambuc     CI[K].Coeff = AddRec->getStepRecurrence(*SE);
2858f4a2713aSLionel Sambuc     CI[K].PosPart = getPositivePart(CI[K].Coeff);
2859f4a2713aSLionel Sambuc     CI[K].NegPart = getNegativePart(CI[K].Coeff);
2860f4a2713aSLionel Sambuc     CI[K].Iterations = collectUpperBound(L, Subscript->getType());
2861f4a2713aSLionel Sambuc     Subscript = AddRec->getStart();
2862f4a2713aSLionel Sambuc   }
2863f4a2713aSLionel Sambuc   Constant = Subscript;
2864f4a2713aSLionel Sambuc #ifndef NDEBUG
2865f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tCoefficient Info\n");
2866f4a2713aSLionel Sambuc   for (unsigned K = 1; K <= MaxLevels; ++K) {
2867f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    " << K << "\t" << *CI[K].Coeff);
2868f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tPos Part = ");
2869f4a2713aSLionel Sambuc     DEBUG(dbgs() << *CI[K].PosPart);
2870f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tNeg Part = ");
2871f4a2713aSLionel Sambuc     DEBUG(dbgs() << *CI[K].NegPart);
2872f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tUpper Bound = ");
2873f4a2713aSLionel Sambuc     if (CI[K].Iterations)
2874f4a2713aSLionel Sambuc       DEBUG(dbgs() << *CI[K].Iterations);
2875f4a2713aSLionel Sambuc     else
2876f4a2713aSLionel Sambuc       DEBUG(dbgs() << "+inf");
2877f4a2713aSLionel Sambuc     DEBUG(dbgs() << '\n');
2878f4a2713aSLionel Sambuc   }
2879f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t    Constant = " << *Subscript << '\n');
2880f4a2713aSLionel Sambuc #endif
2881f4a2713aSLionel Sambuc   return CI;
2882f4a2713aSLionel Sambuc }
2883f4a2713aSLionel Sambuc 
2884f4a2713aSLionel Sambuc 
2885f4a2713aSLionel Sambuc // Looks through all the bounds info and
2886f4a2713aSLionel Sambuc // computes the lower bound given the current direction settings
2887f4a2713aSLionel Sambuc // at each level. If the lower bound for any level is -inf,
2888f4a2713aSLionel Sambuc // the result is -inf.
getLowerBound(BoundInfo * Bound) const2889f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::getLowerBound(BoundInfo *Bound) const {
2890f4a2713aSLionel Sambuc   const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
2891f4a2713aSLionel Sambuc   for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2892f4a2713aSLionel Sambuc     if (Bound[K].Lower[Bound[K].Direction])
2893f4a2713aSLionel Sambuc       Sum = SE->getAddExpr(Sum, Bound[K].Lower[Bound[K].Direction]);
2894f4a2713aSLionel Sambuc     else
2895*0a6a1f1dSLionel Sambuc       Sum = nullptr;
2896f4a2713aSLionel Sambuc   }
2897f4a2713aSLionel Sambuc   return Sum;
2898f4a2713aSLionel Sambuc }
2899f4a2713aSLionel Sambuc 
2900f4a2713aSLionel Sambuc 
2901f4a2713aSLionel Sambuc // Looks through all the bounds info and
2902f4a2713aSLionel Sambuc // computes the upper bound given the current direction settings
2903f4a2713aSLionel Sambuc // at each level. If the upper bound at any level is +inf,
2904f4a2713aSLionel Sambuc // the result is +inf.
getUpperBound(BoundInfo * Bound) const2905f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::getUpperBound(BoundInfo *Bound) const {
2906f4a2713aSLionel Sambuc   const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
2907f4a2713aSLionel Sambuc   for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2908f4a2713aSLionel Sambuc     if (Bound[K].Upper[Bound[K].Direction])
2909f4a2713aSLionel Sambuc       Sum = SE->getAddExpr(Sum, Bound[K].Upper[Bound[K].Direction]);
2910f4a2713aSLionel Sambuc     else
2911*0a6a1f1dSLionel Sambuc       Sum = nullptr;
2912f4a2713aSLionel Sambuc   }
2913f4a2713aSLionel Sambuc   return Sum;
2914f4a2713aSLionel Sambuc }
2915f4a2713aSLionel Sambuc 
2916f4a2713aSLionel Sambuc 
2917f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2918f4a2713aSLionel Sambuc // Constraint manipulation for Delta test.
2919f4a2713aSLionel Sambuc 
2920f4a2713aSLionel Sambuc // Given a linear SCEV,
2921f4a2713aSLionel Sambuc // return the coefficient (the step)
2922f4a2713aSLionel Sambuc // corresponding to the specified loop.
2923f4a2713aSLionel Sambuc // If there isn't one, return 0.
2924f4a2713aSLionel Sambuc // For example, given a*i + b*j + c*k, zeroing the coefficient
2925f4a2713aSLionel Sambuc // corresponding to the j loop would yield b.
findCoefficient(const SCEV * Expr,const Loop * TargetLoop) const2926f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::findCoefficient(const SCEV *Expr,
2927f4a2713aSLionel Sambuc                                                 const Loop *TargetLoop)  const {
2928f4a2713aSLionel Sambuc   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
2929f4a2713aSLionel Sambuc   if (!AddRec)
2930f4a2713aSLionel Sambuc     return SE->getConstant(Expr->getType(), 0);
2931f4a2713aSLionel Sambuc   if (AddRec->getLoop() == TargetLoop)
2932f4a2713aSLionel Sambuc     return AddRec->getStepRecurrence(*SE);
2933f4a2713aSLionel Sambuc   return findCoefficient(AddRec->getStart(), TargetLoop);
2934f4a2713aSLionel Sambuc }
2935f4a2713aSLionel Sambuc 
2936f4a2713aSLionel Sambuc 
2937f4a2713aSLionel Sambuc // Given a linear SCEV,
2938f4a2713aSLionel Sambuc // return the SCEV given by zeroing out the coefficient
2939f4a2713aSLionel Sambuc // corresponding to the specified loop.
2940f4a2713aSLionel Sambuc // For example, given a*i + b*j + c*k, zeroing the coefficient
2941f4a2713aSLionel Sambuc // corresponding to the j loop would yield a*i + c*k.
zeroCoefficient(const SCEV * Expr,const Loop * TargetLoop) const2942f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::zeroCoefficient(const SCEV *Expr,
2943f4a2713aSLionel Sambuc                                                 const Loop *TargetLoop)  const {
2944f4a2713aSLionel Sambuc   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
2945f4a2713aSLionel Sambuc   if (!AddRec)
2946f4a2713aSLionel Sambuc     return Expr; // ignore
2947f4a2713aSLionel Sambuc   if (AddRec->getLoop() == TargetLoop)
2948f4a2713aSLionel Sambuc     return AddRec->getStart();
2949f4a2713aSLionel Sambuc   return SE->getAddRecExpr(zeroCoefficient(AddRec->getStart(), TargetLoop),
2950f4a2713aSLionel Sambuc                            AddRec->getStepRecurrence(*SE),
2951f4a2713aSLionel Sambuc                            AddRec->getLoop(),
2952f4a2713aSLionel Sambuc                            AddRec->getNoWrapFlags());
2953f4a2713aSLionel Sambuc }
2954f4a2713aSLionel Sambuc 
2955f4a2713aSLionel Sambuc 
2956f4a2713aSLionel Sambuc // Given a linear SCEV Expr,
2957f4a2713aSLionel Sambuc // return the SCEV given by adding some Value to the
2958f4a2713aSLionel Sambuc // coefficient corresponding to the specified TargetLoop.
2959f4a2713aSLionel Sambuc // For example, given a*i + b*j + c*k, adding 1 to the coefficient
2960f4a2713aSLionel Sambuc // corresponding to the j loop would yield a*i + (b+1)*j + c*k.
addToCoefficient(const SCEV * Expr,const Loop * TargetLoop,const SCEV * Value) const2961f4a2713aSLionel Sambuc const SCEV *DependenceAnalysis::addToCoefficient(const SCEV *Expr,
2962f4a2713aSLionel Sambuc                                                  const Loop *TargetLoop,
2963f4a2713aSLionel Sambuc                                                  const SCEV *Value)  const {
2964f4a2713aSLionel Sambuc   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
2965f4a2713aSLionel Sambuc   if (!AddRec) // create a new addRec
2966f4a2713aSLionel Sambuc     return SE->getAddRecExpr(Expr,
2967f4a2713aSLionel Sambuc                              Value,
2968f4a2713aSLionel Sambuc                              TargetLoop,
2969f4a2713aSLionel Sambuc                              SCEV::FlagAnyWrap); // Worst case, with no info.
2970f4a2713aSLionel Sambuc   if (AddRec->getLoop() == TargetLoop) {
2971f4a2713aSLionel Sambuc     const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
2972f4a2713aSLionel Sambuc     if (Sum->isZero())
2973f4a2713aSLionel Sambuc       return AddRec->getStart();
2974f4a2713aSLionel Sambuc     return SE->getAddRecExpr(AddRec->getStart(),
2975f4a2713aSLionel Sambuc                              Sum,
2976f4a2713aSLionel Sambuc                              AddRec->getLoop(),
2977f4a2713aSLionel Sambuc                              AddRec->getNoWrapFlags());
2978f4a2713aSLionel Sambuc   }
2979f4a2713aSLionel Sambuc   if (SE->isLoopInvariant(AddRec, TargetLoop))
2980*0a6a1f1dSLionel Sambuc     return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
2981*0a6a1f1dSLionel Sambuc   return SE->getAddRecExpr(
2982*0a6a1f1dSLionel Sambuc       addToCoefficient(AddRec->getStart(), TargetLoop, Value),
2983*0a6a1f1dSLionel Sambuc       AddRec->getStepRecurrence(*SE), AddRec->getLoop(),
2984f4a2713aSLionel Sambuc       AddRec->getNoWrapFlags());
2985f4a2713aSLionel Sambuc }
2986f4a2713aSLionel Sambuc 
2987f4a2713aSLionel Sambuc 
2988f4a2713aSLionel Sambuc // Review the constraints, looking for opportunities
2989f4a2713aSLionel Sambuc // to simplify a subscript pair (Src and Dst).
2990f4a2713aSLionel Sambuc // Return true if some simplification occurs.
2991f4a2713aSLionel Sambuc // If the simplification isn't exact (that is, if it is conservative
2992f4a2713aSLionel Sambuc // in terms of dependence), set consistent to false.
2993f4a2713aSLionel Sambuc // Corresponds to Figure 5 from the paper
2994f4a2713aSLionel Sambuc //
2995f4a2713aSLionel Sambuc //            Practical Dependence Testing
2996f4a2713aSLionel Sambuc //            Goff, Kennedy, Tseng
2997f4a2713aSLionel Sambuc //            PLDI 1991
propagate(const SCEV * & Src,const SCEV * & Dst,SmallBitVector & Loops,SmallVectorImpl<Constraint> & Constraints,bool & Consistent)2998f4a2713aSLionel Sambuc bool DependenceAnalysis::propagate(const SCEV *&Src,
2999f4a2713aSLionel Sambuc                                    const SCEV *&Dst,
3000f4a2713aSLionel Sambuc                                    SmallBitVector &Loops,
3001f4a2713aSLionel Sambuc                                    SmallVectorImpl<Constraint> &Constraints,
3002f4a2713aSLionel Sambuc                                    bool &Consistent) {
3003f4a2713aSLionel Sambuc   bool Result = false;
3004f4a2713aSLionel Sambuc   for (int LI = Loops.find_first(); LI >= 0; LI = Loops.find_next(LI)) {
3005f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\t    Constraint[" << LI << "] is");
3006f4a2713aSLionel Sambuc     DEBUG(Constraints[LI].dump(dbgs()));
3007f4a2713aSLionel Sambuc     if (Constraints[LI].isDistance())
3008f4a2713aSLionel Sambuc       Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
3009f4a2713aSLionel Sambuc     else if (Constraints[LI].isLine())
3010f4a2713aSLionel Sambuc       Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
3011f4a2713aSLionel Sambuc     else if (Constraints[LI].isPoint())
3012f4a2713aSLionel Sambuc       Result |= propagatePoint(Src, Dst, Constraints[LI]);
3013f4a2713aSLionel Sambuc   }
3014f4a2713aSLionel Sambuc   return Result;
3015f4a2713aSLionel Sambuc }
3016f4a2713aSLionel Sambuc 
3017f4a2713aSLionel Sambuc 
3018f4a2713aSLionel Sambuc // Attempt to propagate a distance
3019f4a2713aSLionel Sambuc // constraint into a subscript pair (Src and Dst).
3020f4a2713aSLionel Sambuc // Return true if some simplification occurs.
3021f4a2713aSLionel Sambuc // If the simplification isn't exact (that is, if it is conservative
3022f4a2713aSLionel Sambuc // in terms of dependence), set consistent to false.
propagateDistance(const SCEV * & Src,const SCEV * & Dst,Constraint & CurConstraint,bool & Consistent)3023f4a2713aSLionel Sambuc bool DependenceAnalysis::propagateDistance(const SCEV *&Src,
3024f4a2713aSLionel Sambuc                                            const SCEV *&Dst,
3025f4a2713aSLionel Sambuc                                            Constraint &CurConstraint,
3026f4a2713aSLionel Sambuc                                            bool &Consistent) {
3027f4a2713aSLionel Sambuc   const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3028f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
3029f4a2713aSLionel Sambuc   const SCEV *A_K = findCoefficient(Src, CurLoop);
3030f4a2713aSLionel Sambuc   if (A_K->isZero())
3031f4a2713aSLionel Sambuc     return false;
3032f4a2713aSLionel Sambuc   const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
3033f4a2713aSLionel Sambuc   Src = SE->getMinusSCEV(Src, DA_K);
3034f4a2713aSLionel Sambuc   Src = zeroCoefficient(Src, CurLoop);
3035f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
3036f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
3037f4a2713aSLionel Sambuc   Dst = addToCoefficient(Dst, CurLoop, SE->getNegativeSCEV(A_K));
3038f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
3039f4a2713aSLionel Sambuc   if (!findCoefficient(Dst, CurLoop)->isZero())
3040f4a2713aSLionel Sambuc     Consistent = false;
3041f4a2713aSLionel Sambuc   return true;
3042f4a2713aSLionel Sambuc }
3043f4a2713aSLionel Sambuc 
3044f4a2713aSLionel Sambuc 
3045f4a2713aSLionel Sambuc // Attempt to propagate a line
3046f4a2713aSLionel Sambuc // constraint into a subscript pair (Src and Dst).
3047f4a2713aSLionel Sambuc // Return true if some simplification occurs.
3048f4a2713aSLionel Sambuc // If the simplification isn't exact (that is, if it is conservative
3049f4a2713aSLionel Sambuc // in terms of dependence), set consistent to false.
propagateLine(const SCEV * & Src,const SCEV * & Dst,Constraint & CurConstraint,bool & Consistent)3050f4a2713aSLionel Sambuc bool DependenceAnalysis::propagateLine(const SCEV *&Src,
3051f4a2713aSLionel Sambuc                                        const SCEV *&Dst,
3052f4a2713aSLionel Sambuc                                        Constraint &CurConstraint,
3053f4a2713aSLionel Sambuc                                        bool &Consistent) {
3054f4a2713aSLionel Sambuc   const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3055f4a2713aSLionel Sambuc   const SCEV *A = CurConstraint.getA();
3056f4a2713aSLionel Sambuc   const SCEV *B = CurConstraint.getB();
3057f4a2713aSLionel Sambuc   const SCEV *C = CurConstraint.getC();
3058f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tA = " << *A << ", B = " << *B << ", C = " << *C << "\n");
3059f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tSrc = " << *Src << "\n");
3060f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tDst = " << *Dst << "\n");
3061f4a2713aSLionel Sambuc   if (A->isZero()) {
3062f4a2713aSLionel Sambuc     const SCEVConstant *Bconst = dyn_cast<SCEVConstant>(B);
3063f4a2713aSLionel Sambuc     const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
3064f4a2713aSLionel Sambuc     if (!Bconst || !Cconst) return false;
3065f4a2713aSLionel Sambuc     APInt Beta = Bconst->getValue()->getValue();
3066f4a2713aSLionel Sambuc     APInt Charlie = Cconst->getValue()->getValue();
3067f4a2713aSLionel Sambuc     APInt CdivB = Charlie.sdiv(Beta);
3068f4a2713aSLionel Sambuc     assert(Charlie.srem(Beta) == 0 && "C should be evenly divisible by B");
3069f4a2713aSLionel Sambuc     const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3070f4a2713aSLionel Sambuc     //    Src = SE->getAddExpr(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
3071f4a2713aSLionel Sambuc     Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
3072f4a2713aSLionel Sambuc     Dst = zeroCoefficient(Dst, CurLoop);
3073f4a2713aSLionel Sambuc     if (!findCoefficient(Src, CurLoop)->isZero())
3074f4a2713aSLionel Sambuc       Consistent = false;
3075f4a2713aSLionel Sambuc   }
3076f4a2713aSLionel Sambuc   else if (B->isZero()) {
3077f4a2713aSLionel Sambuc     const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
3078f4a2713aSLionel Sambuc     const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
3079f4a2713aSLionel Sambuc     if (!Aconst || !Cconst) return false;
3080f4a2713aSLionel Sambuc     APInt Alpha = Aconst->getValue()->getValue();
3081f4a2713aSLionel Sambuc     APInt Charlie = Cconst->getValue()->getValue();
3082f4a2713aSLionel Sambuc     APInt CdivA = Charlie.sdiv(Alpha);
3083f4a2713aSLionel Sambuc     assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
3084f4a2713aSLionel Sambuc     const SCEV *A_K = findCoefficient(Src, CurLoop);
3085f4a2713aSLionel Sambuc     Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3086f4a2713aSLionel Sambuc     Src = zeroCoefficient(Src, CurLoop);
3087f4a2713aSLionel Sambuc     if (!findCoefficient(Dst, CurLoop)->isZero())
3088f4a2713aSLionel Sambuc       Consistent = false;
3089f4a2713aSLionel Sambuc   }
3090f4a2713aSLionel Sambuc   else if (isKnownPredicate(CmpInst::ICMP_EQ, A, B)) {
3091f4a2713aSLionel Sambuc     const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
3092f4a2713aSLionel Sambuc     const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
3093f4a2713aSLionel Sambuc     if (!Aconst || !Cconst) return false;
3094f4a2713aSLionel Sambuc     APInt Alpha = Aconst->getValue()->getValue();
3095f4a2713aSLionel Sambuc     APInt Charlie = Cconst->getValue()->getValue();
3096f4a2713aSLionel Sambuc     APInt CdivA = Charlie.sdiv(Alpha);
3097f4a2713aSLionel Sambuc     assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
3098f4a2713aSLionel Sambuc     const SCEV *A_K = findCoefficient(Src, CurLoop);
3099f4a2713aSLionel Sambuc     Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3100f4a2713aSLionel Sambuc     Src = zeroCoefficient(Src, CurLoop);
3101f4a2713aSLionel Sambuc     Dst = addToCoefficient(Dst, CurLoop, A_K);
3102f4a2713aSLionel Sambuc     if (!findCoefficient(Dst, CurLoop)->isZero())
3103f4a2713aSLionel Sambuc       Consistent = false;
3104f4a2713aSLionel Sambuc   }
3105f4a2713aSLionel Sambuc   else {
3106f4a2713aSLionel Sambuc     // paper is incorrect here, or perhaps just misleading
3107f4a2713aSLionel Sambuc     const SCEV *A_K = findCoefficient(Src, CurLoop);
3108f4a2713aSLionel Sambuc     Src = SE->getMulExpr(Src, A);
3109f4a2713aSLionel Sambuc     Dst = SE->getMulExpr(Dst, A);
3110f4a2713aSLionel Sambuc     Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, C));
3111f4a2713aSLionel Sambuc     Src = zeroCoefficient(Src, CurLoop);
3112f4a2713aSLionel Sambuc     Dst = addToCoefficient(Dst, CurLoop, SE->getMulExpr(A_K, B));
3113f4a2713aSLionel Sambuc     if (!findCoefficient(Dst, CurLoop)->isZero())
3114f4a2713aSLionel Sambuc       Consistent = false;
3115f4a2713aSLionel Sambuc   }
3116f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tnew Src = " << *Src << "\n");
3117f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tnew Dst = " << *Dst << "\n");
3118f4a2713aSLionel Sambuc   return true;
3119f4a2713aSLionel Sambuc }
3120f4a2713aSLionel Sambuc 
3121f4a2713aSLionel Sambuc 
3122f4a2713aSLionel Sambuc // Attempt to propagate a point
3123f4a2713aSLionel Sambuc // constraint into a subscript pair (Src and Dst).
3124f4a2713aSLionel Sambuc // Return true if some simplification occurs.
propagatePoint(const SCEV * & Src,const SCEV * & Dst,Constraint & CurConstraint)3125f4a2713aSLionel Sambuc bool DependenceAnalysis::propagatePoint(const SCEV *&Src,
3126f4a2713aSLionel Sambuc                                         const SCEV *&Dst,
3127f4a2713aSLionel Sambuc                                         Constraint &CurConstraint) {
3128f4a2713aSLionel Sambuc   const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3129f4a2713aSLionel Sambuc   const SCEV *A_K = findCoefficient(Src, CurLoop);
3130f4a2713aSLionel Sambuc   const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3131f4a2713aSLionel Sambuc   const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
3132f4a2713aSLionel Sambuc   const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
3133f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
3134f4a2713aSLionel Sambuc   Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
3135f4a2713aSLionel Sambuc   Src = zeroCoefficient(Src, CurLoop);
3136f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
3137f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
3138f4a2713aSLionel Sambuc   Dst = zeroCoefficient(Dst, CurLoop);
3139f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
3140f4a2713aSLionel Sambuc   return true;
3141f4a2713aSLionel Sambuc }
3142f4a2713aSLionel Sambuc 
3143f4a2713aSLionel Sambuc 
3144f4a2713aSLionel Sambuc // Update direction vector entry based on the current constraint.
updateDirection(Dependence::DVEntry & Level,const Constraint & CurConstraint) const3145f4a2713aSLionel Sambuc void DependenceAnalysis::updateDirection(Dependence::DVEntry &Level,
3146f4a2713aSLionel Sambuc                                          const Constraint &CurConstraint
3147f4a2713aSLionel Sambuc                                          ) const {
3148f4a2713aSLionel Sambuc   DEBUG(dbgs() << "\tUpdate direction, constraint =");
3149f4a2713aSLionel Sambuc   DEBUG(CurConstraint.dump(dbgs()));
3150f4a2713aSLionel Sambuc   if (CurConstraint.isAny())
3151f4a2713aSLionel Sambuc     ; // use defaults
3152f4a2713aSLionel Sambuc   else if (CurConstraint.isDistance()) {
3153f4a2713aSLionel Sambuc     // this one is consistent, the others aren't
3154f4a2713aSLionel Sambuc     Level.Scalar = false;
3155f4a2713aSLionel Sambuc     Level.Distance = CurConstraint.getD();
3156f4a2713aSLionel Sambuc     unsigned NewDirection = Dependence::DVEntry::NONE;
3157f4a2713aSLionel Sambuc     if (!SE->isKnownNonZero(Level.Distance)) // if may be zero
3158f4a2713aSLionel Sambuc       NewDirection = Dependence::DVEntry::EQ;
3159f4a2713aSLionel Sambuc     if (!SE->isKnownNonPositive(Level.Distance)) // if may be positive
3160f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::LT;
3161f4a2713aSLionel Sambuc     if (!SE->isKnownNonNegative(Level.Distance)) // if may be negative
3162f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::GT;
3163f4a2713aSLionel Sambuc     Level.Direction &= NewDirection;
3164f4a2713aSLionel Sambuc   }
3165f4a2713aSLionel Sambuc   else if (CurConstraint.isLine()) {
3166f4a2713aSLionel Sambuc     Level.Scalar = false;
3167*0a6a1f1dSLionel Sambuc     Level.Distance = nullptr;
3168f4a2713aSLionel Sambuc     // direction should be accurate
3169f4a2713aSLionel Sambuc   }
3170f4a2713aSLionel Sambuc   else if (CurConstraint.isPoint()) {
3171f4a2713aSLionel Sambuc     Level.Scalar = false;
3172*0a6a1f1dSLionel Sambuc     Level.Distance = nullptr;
3173f4a2713aSLionel Sambuc     unsigned NewDirection = Dependence::DVEntry::NONE;
3174f4a2713aSLionel Sambuc     if (!isKnownPredicate(CmpInst::ICMP_NE,
3175f4a2713aSLionel Sambuc                           CurConstraint.getY(),
3176f4a2713aSLionel Sambuc                           CurConstraint.getX()))
3177f4a2713aSLionel Sambuc       // if X may be = Y
3178f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::EQ;
3179f4a2713aSLionel Sambuc     if (!isKnownPredicate(CmpInst::ICMP_SLE,
3180f4a2713aSLionel Sambuc                           CurConstraint.getY(),
3181f4a2713aSLionel Sambuc                           CurConstraint.getX()))
3182f4a2713aSLionel Sambuc       // if Y may be > X
3183f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::LT;
3184f4a2713aSLionel Sambuc     if (!isKnownPredicate(CmpInst::ICMP_SGE,
3185f4a2713aSLionel Sambuc                           CurConstraint.getY(),
3186f4a2713aSLionel Sambuc                           CurConstraint.getX()))
3187f4a2713aSLionel Sambuc       // if Y may be < X
3188f4a2713aSLionel Sambuc       NewDirection |= Dependence::DVEntry::GT;
3189f4a2713aSLionel Sambuc     Level.Direction &= NewDirection;
3190f4a2713aSLionel Sambuc   }
3191f4a2713aSLionel Sambuc   else
3192f4a2713aSLionel Sambuc     llvm_unreachable("constraint has unexpected kind");
3193f4a2713aSLionel Sambuc }
3194f4a2713aSLionel Sambuc 
3195f4a2713aSLionel Sambuc /// Check if we can delinearize the subscripts. If the SCEVs representing the
3196f4a2713aSLionel Sambuc /// source and destination array references are recurrences on a nested loop,
3197*0a6a1f1dSLionel Sambuc /// this function flattens the nested recurrences into separate recurrences
3198f4a2713aSLionel Sambuc /// for each loop level.
tryDelinearize(const SCEV * SrcSCEV,const SCEV * DstSCEV,SmallVectorImpl<Subscript> & Pair,const SCEV * ElementSize)3199*0a6a1f1dSLionel Sambuc bool DependenceAnalysis::tryDelinearize(const SCEV *SrcSCEV,
3200*0a6a1f1dSLionel Sambuc                                         const SCEV *DstSCEV,
3201*0a6a1f1dSLionel Sambuc                                         SmallVectorImpl<Subscript> &Pair,
3202*0a6a1f1dSLionel Sambuc                                         const SCEV *ElementSize) {
3203*0a6a1f1dSLionel Sambuc   const SCEVUnknown *SrcBase =
3204*0a6a1f1dSLionel Sambuc       dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcSCEV));
3205*0a6a1f1dSLionel Sambuc   const SCEVUnknown *DstBase =
3206*0a6a1f1dSLionel Sambuc       dyn_cast<SCEVUnknown>(SE->getPointerBase(DstSCEV));
3207*0a6a1f1dSLionel Sambuc 
3208*0a6a1f1dSLionel Sambuc   if (!SrcBase || !DstBase || SrcBase != DstBase)
3209*0a6a1f1dSLionel Sambuc     return false;
3210*0a6a1f1dSLionel Sambuc 
3211*0a6a1f1dSLionel Sambuc   SrcSCEV = SE->getMinusSCEV(SrcSCEV, SrcBase);
3212*0a6a1f1dSLionel Sambuc   DstSCEV = SE->getMinusSCEV(DstSCEV, DstBase);
3213*0a6a1f1dSLionel Sambuc 
3214f4a2713aSLionel Sambuc   const SCEVAddRecExpr *SrcAR = dyn_cast<SCEVAddRecExpr>(SrcSCEV);
3215f4a2713aSLionel Sambuc   const SCEVAddRecExpr *DstAR = dyn_cast<SCEVAddRecExpr>(DstSCEV);
3216f4a2713aSLionel Sambuc   if (!SrcAR || !DstAR || !SrcAR->isAffine() || !DstAR->isAffine())
3217f4a2713aSLionel Sambuc     return false;
3218f4a2713aSLionel Sambuc 
3219*0a6a1f1dSLionel Sambuc   // First step: collect parametric terms in both array references.
3220*0a6a1f1dSLionel Sambuc   SmallVector<const SCEV *, 4> Terms;
3221*0a6a1f1dSLionel Sambuc   SrcAR->collectParametricTerms(*SE, Terms);
3222*0a6a1f1dSLionel Sambuc   DstAR->collectParametricTerms(*SE, Terms);
3223f4a2713aSLionel Sambuc 
3224*0a6a1f1dSLionel Sambuc   // Second step: find subscript sizes.
3225*0a6a1f1dSLionel Sambuc   SmallVector<const SCEV *, 4> Sizes;
3226*0a6a1f1dSLionel Sambuc   SE->findArrayDimensions(Terms, Sizes, ElementSize);
3227*0a6a1f1dSLionel Sambuc 
3228*0a6a1f1dSLionel Sambuc   // Third step: compute the access functions for each subscript.
3229*0a6a1f1dSLionel Sambuc   SmallVector<const SCEV *, 4> SrcSubscripts, DstSubscripts;
3230*0a6a1f1dSLionel Sambuc   SrcAR->computeAccessFunctions(*SE, SrcSubscripts, Sizes);
3231*0a6a1f1dSLionel Sambuc   DstAR->computeAccessFunctions(*SE, DstSubscripts, Sizes);
3232*0a6a1f1dSLionel Sambuc 
3233*0a6a1f1dSLionel Sambuc   // Fail when there is only a subscript: that's a linearized access function.
3234*0a6a1f1dSLionel Sambuc   if (SrcSubscripts.size() < 2 || DstSubscripts.size() < 2 ||
3235*0a6a1f1dSLionel Sambuc       SrcSubscripts.size() != DstSubscripts.size())
3236f4a2713aSLionel Sambuc     return false;
3237f4a2713aSLionel Sambuc 
3238*0a6a1f1dSLionel Sambuc   int size = SrcSubscripts.size();
3239*0a6a1f1dSLionel Sambuc 
3240*0a6a1f1dSLionel Sambuc   DEBUG({
3241*0a6a1f1dSLionel Sambuc       dbgs() << "\nSrcSubscripts: ";
3242f4a2713aSLionel Sambuc     for (int i = 0; i < size; i++)
3243*0a6a1f1dSLionel Sambuc       dbgs() << *SrcSubscripts[i];
3244*0a6a1f1dSLionel Sambuc     dbgs() << "\nDstSubscripts: ";
3245f4a2713aSLionel Sambuc     for (int i = 0; i < size; i++)
3246*0a6a1f1dSLionel Sambuc       dbgs() << *DstSubscripts[i];
3247*0a6a1f1dSLionel Sambuc     });
3248f4a2713aSLionel Sambuc 
3249f4a2713aSLionel Sambuc   // The delinearization transforms a single-subscript MIV dependence test into
3250f4a2713aSLionel Sambuc   // a multi-subscript SIV dependence test that is easier to compute. So we
3251f4a2713aSLionel Sambuc   // resize Pair to contain as many pairs of subscripts as the delinearization
3252f4a2713aSLionel Sambuc   // has found, and then initialize the pairs following the delinearization.
3253f4a2713aSLionel Sambuc   Pair.resize(size);
3254f4a2713aSLionel Sambuc   for (int i = 0; i < size; ++i) {
3255f4a2713aSLionel Sambuc     Pair[i].Src = SrcSubscripts[i];
3256f4a2713aSLionel Sambuc     Pair[i].Dst = DstSubscripts[i];
3257*0a6a1f1dSLionel Sambuc     unifySubscriptType(&Pair[i]);
3258f4a2713aSLionel Sambuc 
3259f4a2713aSLionel Sambuc     // FIXME: we should record the bounds SrcSizes[i] and DstSizes[i] that the
3260f4a2713aSLionel Sambuc     // delinearization has found, and add these constraints to the dependence
3261f4a2713aSLionel Sambuc     // check to avoid memory accesses overflow from one dimension into another.
3262f4a2713aSLionel Sambuc     // This is related to the problem of determining the existence of data
3263f4a2713aSLionel Sambuc     // dependences in array accesses using a different number of subscripts: in
3264f4a2713aSLionel Sambuc     // C one can access an array A[100][100]; as A[0][9999], *A[9999], etc.
3265f4a2713aSLionel Sambuc   }
3266f4a2713aSLionel Sambuc 
3267f4a2713aSLionel Sambuc   return true;
3268f4a2713aSLionel Sambuc }
3269f4a2713aSLionel Sambuc 
3270f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3271f4a2713aSLionel Sambuc 
3272f4a2713aSLionel Sambuc #ifndef NDEBUG
3273f4a2713aSLionel Sambuc // For debugging purposes, dump a small bit vector to dbgs().
dumpSmallBitVector(SmallBitVector & BV)3274f4a2713aSLionel Sambuc static void dumpSmallBitVector(SmallBitVector &BV) {
3275f4a2713aSLionel Sambuc   dbgs() << "{";
3276f4a2713aSLionel Sambuc   for (int VI = BV.find_first(); VI >= 0; VI = BV.find_next(VI)) {
3277f4a2713aSLionel Sambuc     dbgs() << VI;
3278f4a2713aSLionel Sambuc     if (BV.find_next(VI) >= 0)
3279f4a2713aSLionel Sambuc       dbgs() << ' ';
3280f4a2713aSLionel Sambuc   }
3281f4a2713aSLionel Sambuc   dbgs() << "}\n";
3282f4a2713aSLionel Sambuc }
3283f4a2713aSLionel Sambuc #endif
3284f4a2713aSLionel Sambuc 
3285f4a2713aSLionel Sambuc 
3286f4a2713aSLionel Sambuc // depends -
3287f4a2713aSLionel Sambuc // Returns NULL if there is no dependence.
3288f4a2713aSLionel Sambuc // Otherwise, return a Dependence with as many details as possible.
3289f4a2713aSLionel Sambuc // Corresponds to Section 3.1 in the paper
3290f4a2713aSLionel Sambuc //
3291f4a2713aSLionel Sambuc //            Practical Dependence Testing
3292f4a2713aSLionel Sambuc //            Goff, Kennedy, Tseng
3293f4a2713aSLionel Sambuc //            PLDI 1991
3294f4a2713aSLionel Sambuc //
3295f4a2713aSLionel Sambuc // Care is required to keep the routine below, getSplitIteration(),
3296f4a2713aSLionel Sambuc // up to date with respect to this routine.
3297*0a6a1f1dSLionel Sambuc std::unique_ptr<Dependence>
depends(Instruction * Src,Instruction * Dst,bool PossiblyLoopIndependent)3298*0a6a1f1dSLionel Sambuc DependenceAnalysis::depends(Instruction *Src, Instruction *Dst,
3299f4a2713aSLionel Sambuc                             bool PossiblyLoopIndependent) {
3300f4a2713aSLionel Sambuc   if (Src == Dst)
3301f4a2713aSLionel Sambuc     PossiblyLoopIndependent = false;
3302f4a2713aSLionel Sambuc 
3303f4a2713aSLionel Sambuc   if ((!Src->mayReadFromMemory() && !Src->mayWriteToMemory()) ||
3304f4a2713aSLionel Sambuc       (!Dst->mayReadFromMemory() && !Dst->mayWriteToMemory()))
3305f4a2713aSLionel Sambuc     // if both instructions don't reference memory, there's no dependence
3306*0a6a1f1dSLionel Sambuc     return nullptr;
3307f4a2713aSLionel Sambuc 
3308f4a2713aSLionel Sambuc   if (!isLoadOrStore(Src) || !isLoadOrStore(Dst)) {
3309f4a2713aSLionel Sambuc     // can only analyze simple loads and stores, i.e., no calls, invokes, etc.
3310f4a2713aSLionel Sambuc     DEBUG(dbgs() << "can only handle simple loads and stores\n");
3311*0a6a1f1dSLionel Sambuc     return make_unique<Dependence>(Src, Dst);
3312f4a2713aSLionel Sambuc   }
3313f4a2713aSLionel Sambuc 
3314f4a2713aSLionel Sambuc   Value *SrcPtr = getPointerOperand(Src);
3315f4a2713aSLionel Sambuc   Value *DstPtr = getPointerOperand(Dst);
3316f4a2713aSLionel Sambuc 
3317f4a2713aSLionel Sambuc   switch (underlyingObjectsAlias(AA, DstPtr, SrcPtr)) {
3318f4a2713aSLionel Sambuc   case AliasAnalysis::MayAlias:
3319f4a2713aSLionel Sambuc   case AliasAnalysis::PartialAlias:
3320f4a2713aSLionel Sambuc     // cannot analyse objects if we don't understand their aliasing.
3321f4a2713aSLionel Sambuc     DEBUG(dbgs() << "can't analyze may or partial alias\n");
3322*0a6a1f1dSLionel Sambuc     return make_unique<Dependence>(Src, Dst);
3323f4a2713aSLionel Sambuc   case AliasAnalysis::NoAlias:
3324f4a2713aSLionel Sambuc     // If the objects noalias, they are distinct, accesses are independent.
3325f4a2713aSLionel Sambuc     DEBUG(dbgs() << "no alias\n");
3326*0a6a1f1dSLionel Sambuc     return nullptr;
3327f4a2713aSLionel Sambuc   case AliasAnalysis::MustAlias:
3328f4a2713aSLionel Sambuc     break; // The underlying objects alias; test accesses for dependence.
3329f4a2713aSLionel Sambuc   }
3330f4a2713aSLionel Sambuc 
3331f4a2713aSLionel Sambuc   // establish loop nesting levels
3332f4a2713aSLionel Sambuc   establishNestingLevels(Src, Dst);
3333f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    common nesting levels = " << CommonLevels << "\n");
3334f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    maximum nesting levels = " << MaxLevels << "\n");
3335f4a2713aSLionel Sambuc 
3336f4a2713aSLionel Sambuc   FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
3337f4a2713aSLionel Sambuc   ++TotalArrayPairs;
3338f4a2713aSLionel Sambuc 
3339f4a2713aSLionel Sambuc   // See if there are GEPs we can use.
3340f4a2713aSLionel Sambuc   bool UsefulGEP = false;
3341f4a2713aSLionel Sambuc   GEPOperator *SrcGEP = dyn_cast<GEPOperator>(SrcPtr);
3342f4a2713aSLionel Sambuc   GEPOperator *DstGEP = dyn_cast<GEPOperator>(DstPtr);
3343f4a2713aSLionel Sambuc   if (SrcGEP && DstGEP &&
3344f4a2713aSLionel Sambuc       SrcGEP->getPointerOperandType() == DstGEP->getPointerOperandType()) {
3345f4a2713aSLionel Sambuc     const SCEV *SrcPtrSCEV = SE->getSCEV(SrcGEP->getPointerOperand());
3346f4a2713aSLionel Sambuc     const SCEV *DstPtrSCEV = SE->getSCEV(DstGEP->getPointerOperand());
3347f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    SrcPtrSCEV = " << *SrcPtrSCEV << "\n");
3348f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    DstPtrSCEV = " << *DstPtrSCEV << "\n");
3349f4a2713aSLionel Sambuc 
3350f4a2713aSLionel Sambuc     UsefulGEP =
3351f4a2713aSLionel Sambuc       isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
3352f4a2713aSLionel Sambuc       isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent()));
3353f4a2713aSLionel Sambuc   }
3354f4a2713aSLionel Sambuc   unsigned Pairs = UsefulGEP ? SrcGEP->idx_end() - SrcGEP->idx_begin() : 1;
3355f4a2713aSLionel Sambuc   SmallVector<Subscript, 4> Pair(Pairs);
3356f4a2713aSLionel Sambuc   if (UsefulGEP) {
3357f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    using GEPs\n");
3358f4a2713aSLionel Sambuc     unsigned P = 0;
3359f4a2713aSLionel Sambuc     for (GEPOperator::const_op_iterator SrcIdx = SrcGEP->idx_begin(),
3360f4a2713aSLionel Sambuc            SrcEnd = SrcGEP->idx_end(),
3361f4a2713aSLionel Sambuc            DstIdx = DstGEP->idx_begin();
3362f4a2713aSLionel Sambuc          SrcIdx != SrcEnd;
3363f4a2713aSLionel Sambuc          ++SrcIdx, ++DstIdx, ++P) {
3364f4a2713aSLionel Sambuc       Pair[P].Src = SE->getSCEV(*SrcIdx);
3365f4a2713aSLionel Sambuc       Pair[P].Dst = SE->getSCEV(*DstIdx);
3366*0a6a1f1dSLionel Sambuc       unifySubscriptType(&Pair[P]);
3367f4a2713aSLionel Sambuc     }
3368f4a2713aSLionel Sambuc   }
3369f4a2713aSLionel Sambuc   else {
3370f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    ignoring GEPs\n");
3371f4a2713aSLionel Sambuc     const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
3372f4a2713aSLionel Sambuc     const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3373f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    SrcSCEV = " << *SrcSCEV << "\n");
3374f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    DstSCEV = " << *DstSCEV << "\n");
3375f4a2713aSLionel Sambuc     Pair[0].Src = SrcSCEV;
3376f4a2713aSLionel Sambuc     Pair[0].Dst = DstSCEV;
3377f4a2713aSLionel Sambuc   }
3378f4a2713aSLionel Sambuc 
3379f4a2713aSLionel Sambuc   if (Delinearize && Pairs == 1 && CommonLevels > 1 &&
3380*0a6a1f1dSLionel Sambuc       tryDelinearize(Pair[0].Src, Pair[0].Dst, Pair, SE->getElementSize(Src))) {
3381f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    delinerized GEP\n");
3382f4a2713aSLionel Sambuc     Pairs = Pair.size();
3383f4a2713aSLionel Sambuc   }
3384f4a2713aSLionel Sambuc 
3385f4a2713aSLionel Sambuc   for (unsigned P = 0; P < Pairs; ++P) {
3386f4a2713aSLionel Sambuc     Pair[P].Loops.resize(MaxLevels + 1);
3387f4a2713aSLionel Sambuc     Pair[P].GroupLoops.resize(MaxLevels + 1);
3388f4a2713aSLionel Sambuc     Pair[P].Group.resize(Pairs);
3389f4a2713aSLionel Sambuc     removeMatchingExtensions(&Pair[P]);
3390f4a2713aSLionel Sambuc     Pair[P].Classification =
3391f4a2713aSLionel Sambuc       classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
3392f4a2713aSLionel Sambuc                    Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
3393f4a2713aSLionel Sambuc                    Pair[P].Loops);
3394f4a2713aSLionel Sambuc     Pair[P].GroupLoops = Pair[P].Loops;
3395f4a2713aSLionel Sambuc     Pair[P].Group.set(P);
3396f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    subscript " << P << "\n");
3397f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tsrc = " << *Pair[P].Src << "\n");
3398f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tdst = " << *Pair[P].Dst << "\n");
3399f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tclass = " << Pair[P].Classification << "\n");
3400f4a2713aSLionel Sambuc     DEBUG(dbgs() << "\tloops = ");
3401f4a2713aSLionel Sambuc     DEBUG(dumpSmallBitVector(Pair[P].Loops));
3402f4a2713aSLionel Sambuc   }
3403f4a2713aSLionel Sambuc 
3404f4a2713aSLionel Sambuc   SmallBitVector Separable(Pairs);
3405f4a2713aSLionel Sambuc   SmallBitVector Coupled(Pairs);
3406f4a2713aSLionel Sambuc 
3407f4a2713aSLionel Sambuc   // Partition subscripts into separable and minimally-coupled groups
3408f4a2713aSLionel Sambuc   // Algorithm in paper is algorithmically better;
3409f4a2713aSLionel Sambuc   // this may be faster in practice. Check someday.
3410f4a2713aSLionel Sambuc   //
3411f4a2713aSLionel Sambuc   // Here's an example of how it works. Consider this code:
3412f4a2713aSLionel Sambuc   //
3413f4a2713aSLionel Sambuc   //   for (i = ...) {
3414f4a2713aSLionel Sambuc   //     for (j = ...) {
3415f4a2713aSLionel Sambuc   //       for (k = ...) {
3416f4a2713aSLionel Sambuc   //         for (l = ...) {
3417f4a2713aSLionel Sambuc   //           for (m = ...) {
3418f4a2713aSLionel Sambuc   //             A[i][j][k][m] = ...;
3419f4a2713aSLionel Sambuc   //             ... = A[0][j][l][i + j];
3420f4a2713aSLionel Sambuc   //           }
3421f4a2713aSLionel Sambuc   //         }
3422f4a2713aSLionel Sambuc   //       }
3423f4a2713aSLionel Sambuc   //     }
3424f4a2713aSLionel Sambuc   //   }
3425f4a2713aSLionel Sambuc   //
3426f4a2713aSLionel Sambuc   // There are 4 subscripts here:
3427f4a2713aSLionel Sambuc   //    0 [i] and [0]
3428f4a2713aSLionel Sambuc   //    1 [j] and [j]
3429f4a2713aSLionel Sambuc   //    2 [k] and [l]
3430f4a2713aSLionel Sambuc   //    3 [m] and [i + j]
3431f4a2713aSLionel Sambuc   //
3432f4a2713aSLionel Sambuc   // We've already classified each subscript pair as ZIV, SIV, etc.,
3433f4a2713aSLionel Sambuc   // and collected all the loops mentioned by pair P in Pair[P].Loops.
3434f4a2713aSLionel Sambuc   // In addition, we've initialized Pair[P].GroupLoops to Pair[P].Loops
3435f4a2713aSLionel Sambuc   // and set Pair[P].Group = {P}.
3436f4a2713aSLionel Sambuc   //
3437f4a2713aSLionel Sambuc   //      Src Dst    Classification Loops  GroupLoops Group
3438f4a2713aSLionel Sambuc   //    0 [i] [0]         SIV       {1}      {1}        {0}
3439f4a2713aSLionel Sambuc   //    1 [j] [j]         SIV       {2}      {2}        {1}
3440f4a2713aSLionel Sambuc   //    2 [k] [l]         RDIV      {3,4}    {3,4}      {2}
3441f4a2713aSLionel Sambuc   //    3 [m] [i + j]     MIV       {1,2,5}  {1,2,5}    {3}
3442f4a2713aSLionel Sambuc   //
3443f4a2713aSLionel Sambuc   // For each subscript SI 0 .. 3, we consider each remaining subscript, SJ.
3444f4a2713aSLionel Sambuc   // So, 0 is compared against 1, 2, and 3; 1 is compared against 2 and 3, etc.
3445f4a2713aSLionel Sambuc   //
3446f4a2713aSLionel Sambuc   // We begin by comparing 0 and 1. The intersection of the GroupLoops is empty.
3447f4a2713aSLionel Sambuc   // Next, 0 and 2. Again, the intersection of their GroupLoops is empty.
3448f4a2713aSLionel Sambuc   // Next 0 and 3. The intersection of their GroupLoop = {1}, not empty,
3449f4a2713aSLionel Sambuc   // so Pair[3].Group = {0,3} and Done = false (that is, 0 will not be added
3450f4a2713aSLionel Sambuc   // to either Separable or Coupled).
3451f4a2713aSLionel Sambuc   //
3452f4a2713aSLionel Sambuc   // Next, we consider 1 and 2. The intersection of the GroupLoops is empty.
3453f4a2713aSLionel Sambuc   // Next, 1 and 3. The intersectionof their GroupLoops = {2}, not empty,
3454f4a2713aSLionel Sambuc   // so Pair[3].Group = {0, 1, 3} and Done = false.
3455f4a2713aSLionel Sambuc   //
3456f4a2713aSLionel Sambuc   // Next, we compare 2 against 3. The intersection of the GroupLoops is empty.
3457f4a2713aSLionel Sambuc   // Since Done remains true, we add 2 to the set of Separable pairs.
3458f4a2713aSLionel Sambuc   //
3459f4a2713aSLionel Sambuc   // Finally, we consider 3. There's nothing to compare it with,
3460f4a2713aSLionel Sambuc   // so Done remains true and we add it to the Coupled set.
3461f4a2713aSLionel Sambuc   // Pair[3].Group = {0, 1, 3} and GroupLoops = {1, 2, 5}.
3462f4a2713aSLionel Sambuc   //
3463f4a2713aSLionel Sambuc   // In the end, we've got 1 separable subscript and 1 coupled group.
3464f4a2713aSLionel Sambuc   for (unsigned SI = 0; SI < Pairs; ++SI) {
3465f4a2713aSLionel Sambuc     if (Pair[SI].Classification == Subscript::NonLinear) {
3466f4a2713aSLionel Sambuc       // ignore these, but collect loops for later
3467f4a2713aSLionel Sambuc       ++NonlinearSubscriptPairs;
3468f4a2713aSLionel Sambuc       collectCommonLoops(Pair[SI].Src,
3469f4a2713aSLionel Sambuc                          LI->getLoopFor(Src->getParent()),
3470f4a2713aSLionel Sambuc                          Pair[SI].Loops);
3471f4a2713aSLionel Sambuc       collectCommonLoops(Pair[SI].Dst,
3472f4a2713aSLionel Sambuc                          LI->getLoopFor(Dst->getParent()),
3473f4a2713aSLionel Sambuc                          Pair[SI].Loops);
3474f4a2713aSLionel Sambuc       Result.Consistent = false;
3475f4a2713aSLionel Sambuc     }
3476f4a2713aSLionel Sambuc     else if (Pair[SI].Classification == Subscript::ZIV) {
3477f4a2713aSLionel Sambuc       // always separable
3478f4a2713aSLionel Sambuc       Separable.set(SI);
3479f4a2713aSLionel Sambuc     }
3480f4a2713aSLionel Sambuc     else {
3481f4a2713aSLionel Sambuc       // SIV, RDIV, or MIV, so check for coupled group
3482f4a2713aSLionel Sambuc       bool Done = true;
3483f4a2713aSLionel Sambuc       for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
3484f4a2713aSLionel Sambuc         SmallBitVector Intersection = Pair[SI].GroupLoops;
3485f4a2713aSLionel Sambuc         Intersection &= Pair[SJ].GroupLoops;
3486f4a2713aSLionel Sambuc         if (Intersection.any()) {
3487f4a2713aSLionel Sambuc           // accumulate set of all the loops in group
3488f4a2713aSLionel Sambuc           Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
3489f4a2713aSLionel Sambuc           // accumulate set of all subscripts in group
3490f4a2713aSLionel Sambuc           Pair[SJ].Group |= Pair[SI].Group;
3491f4a2713aSLionel Sambuc           Done = false;
3492f4a2713aSLionel Sambuc         }
3493f4a2713aSLionel Sambuc       }
3494f4a2713aSLionel Sambuc       if (Done) {
3495f4a2713aSLionel Sambuc         if (Pair[SI].Group.count() == 1) {
3496f4a2713aSLionel Sambuc           Separable.set(SI);
3497f4a2713aSLionel Sambuc           ++SeparableSubscriptPairs;
3498f4a2713aSLionel Sambuc         }
3499f4a2713aSLionel Sambuc         else {
3500f4a2713aSLionel Sambuc           Coupled.set(SI);
3501f4a2713aSLionel Sambuc           ++CoupledSubscriptPairs;
3502f4a2713aSLionel Sambuc         }
3503f4a2713aSLionel Sambuc       }
3504f4a2713aSLionel Sambuc     }
3505f4a2713aSLionel Sambuc   }
3506f4a2713aSLionel Sambuc 
3507f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    Separable = ");
3508f4a2713aSLionel Sambuc   DEBUG(dumpSmallBitVector(Separable));
3509f4a2713aSLionel Sambuc   DEBUG(dbgs() << "    Coupled = ");
3510f4a2713aSLionel Sambuc   DEBUG(dumpSmallBitVector(Coupled));
3511f4a2713aSLionel Sambuc 
3512f4a2713aSLionel Sambuc   Constraint NewConstraint;
3513f4a2713aSLionel Sambuc   NewConstraint.setAny(SE);
3514f4a2713aSLionel Sambuc 
3515f4a2713aSLionel Sambuc   // test separable subscripts
3516f4a2713aSLionel Sambuc   for (int SI = Separable.find_first(); SI >= 0; SI = Separable.find_next(SI)) {
3517f4a2713aSLionel Sambuc     DEBUG(dbgs() << "testing subscript " << SI);
3518f4a2713aSLionel Sambuc     switch (Pair[SI].Classification) {
3519f4a2713aSLionel Sambuc     case Subscript::ZIV:
3520f4a2713aSLionel Sambuc       DEBUG(dbgs() << ", ZIV\n");
3521f4a2713aSLionel Sambuc       if (testZIV(Pair[SI].Src, Pair[SI].Dst, Result))
3522*0a6a1f1dSLionel Sambuc         return nullptr;
3523f4a2713aSLionel Sambuc       break;
3524f4a2713aSLionel Sambuc     case Subscript::SIV: {
3525f4a2713aSLionel Sambuc       DEBUG(dbgs() << ", SIV\n");
3526f4a2713aSLionel Sambuc       unsigned Level;
3527*0a6a1f1dSLionel Sambuc       const SCEV *SplitIter = nullptr;
3528f4a2713aSLionel Sambuc       if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level,
3529f4a2713aSLionel Sambuc                   Result, NewConstraint, SplitIter))
3530*0a6a1f1dSLionel Sambuc         return nullptr;
3531f4a2713aSLionel Sambuc       break;
3532f4a2713aSLionel Sambuc     }
3533f4a2713aSLionel Sambuc     case Subscript::RDIV:
3534f4a2713aSLionel Sambuc       DEBUG(dbgs() << ", RDIV\n");
3535f4a2713aSLionel Sambuc       if (testRDIV(Pair[SI].Src, Pair[SI].Dst, Result))
3536*0a6a1f1dSLionel Sambuc         return nullptr;
3537f4a2713aSLionel Sambuc       break;
3538f4a2713aSLionel Sambuc     case Subscript::MIV:
3539f4a2713aSLionel Sambuc       DEBUG(dbgs() << ", MIV\n");
3540f4a2713aSLionel Sambuc       if (testMIV(Pair[SI].Src, Pair[SI].Dst, Pair[SI].Loops, Result))
3541*0a6a1f1dSLionel Sambuc         return nullptr;
3542f4a2713aSLionel Sambuc       break;
3543f4a2713aSLionel Sambuc     default:
3544f4a2713aSLionel Sambuc       llvm_unreachable("subscript has unexpected classification");
3545f4a2713aSLionel Sambuc     }
3546f4a2713aSLionel Sambuc   }
3547f4a2713aSLionel Sambuc 
3548f4a2713aSLionel Sambuc   if (Coupled.count()) {
3549f4a2713aSLionel Sambuc     // test coupled subscript groups
3550f4a2713aSLionel Sambuc     DEBUG(dbgs() << "starting on coupled subscripts\n");
3551f4a2713aSLionel Sambuc     DEBUG(dbgs() << "MaxLevels + 1 = " << MaxLevels + 1 << "\n");
3552f4a2713aSLionel Sambuc     SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
3553f4a2713aSLionel Sambuc     for (unsigned II = 0; II <= MaxLevels; ++II)
3554f4a2713aSLionel Sambuc       Constraints[II].setAny(SE);
3555f4a2713aSLionel Sambuc     for (int SI = Coupled.find_first(); SI >= 0; SI = Coupled.find_next(SI)) {
3556f4a2713aSLionel Sambuc       DEBUG(dbgs() << "testing subscript group " << SI << " { ");
3557f4a2713aSLionel Sambuc       SmallBitVector Group(Pair[SI].Group);
3558f4a2713aSLionel Sambuc       SmallBitVector Sivs(Pairs);
3559f4a2713aSLionel Sambuc       SmallBitVector Mivs(Pairs);
3560f4a2713aSLionel Sambuc       SmallBitVector ConstrainedLevels(MaxLevels + 1);
3561f4a2713aSLionel Sambuc       for (int SJ = Group.find_first(); SJ >= 0; SJ = Group.find_next(SJ)) {
3562f4a2713aSLionel Sambuc         DEBUG(dbgs() << SJ << " ");
3563f4a2713aSLionel Sambuc         if (Pair[SJ].Classification == Subscript::SIV)
3564f4a2713aSLionel Sambuc           Sivs.set(SJ);
3565f4a2713aSLionel Sambuc         else
3566f4a2713aSLionel Sambuc           Mivs.set(SJ);
3567f4a2713aSLionel Sambuc       }
3568f4a2713aSLionel Sambuc       DEBUG(dbgs() << "}\n");
3569f4a2713aSLionel Sambuc       while (Sivs.any()) {
3570f4a2713aSLionel Sambuc         bool Changed = false;
3571f4a2713aSLionel Sambuc         for (int SJ = Sivs.find_first(); SJ >= 0; SJ = Sivs.find_next(SJ)) {
3572f4a2713aSLionel Sambuc           DEBUG(dbgs() << "testing subscript " << SJ << ", SIV\n");
3573f4a2713aSLionel Sambuc           // SJ is an SIV subscript that's part of the current coupled group
3574f4a2713aSLionel Sambuc           unsigned Level;
3575*0a6a1f1dSLionel Sambuc           const SCEV *SplitIter = nullptr;
3576f4a2713aSLionel Sambuc           DEBUG(dbgs() << "SIV\n");
3577f4a2713aSLionel Sambuc           if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
3578f4a2713aSLionel Sambuc                       Result, NewConstraint, SplitIter))
3579*0a6a1f1dSLionel Sambuc             return nullptr;
3580f4a2713aSLionel Sambuc           ConstrainedLevels.set(Level);
3581f4a2713aSLionel Sambuc           if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
3582f4a2713aSLionel Sambuc             if (Constraints[Level].isEmpty()) {
3583f4a2713aSLionel Sambuc               ++DeltaIndependence;
3584*0a6a1f1dSLionel Sambuc               return nullptr;
3585f4a2713aSLionel Sambuc             }
3586f4a2713aSLionel Sambuc             Changed = true;
3587f4a2713aSLionel Sambuc           }
3588f4a2713aSLionel Sambuc           Sivs.reset(SJ);
3589f4a2713aSLionel Sambuc         }
3590f4a2713aSLionel Sambuc         if (Changed) {
3591f4a2713aSLionel Sambuc           // propagate, possibly creating new SIVs and ZIVs
3592f4a2713aSLionel Sambuc           DEBUG(dbgs() << "    propagating\n");
3593f4a2713aSLionel Sambuc           DEBUG(dbgs() << "\tMivs = ");
3594f4a2713aSLionel Sambuc           DEBUG(dumpSmallBitVector(Mivs));
3595f4a2713aSLionel Sambuc           for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3596f4a2713aSLionel Sambuc             // SJ is an MIV subscript that's part of the current coupled group
3597f4a2713aSLionel Sambuc             DEBUG(dbgs() << "\tSJ = " << SJ << "\n");
3598f4a2713aSLionel Sambuc             if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
3599f4a2713aSLionel Sambuc                           Constraints, Result.Consistent)) {
3600f4a2713aSLionel Sambuc               DEBUG(dbgs() << "\t    Changed\n");
3601f4a2713aSLionel Sambuc               ++DeltaPropagations;
3602f4a2713aSLionel Sambuc               Pair[SJ].Classification =
3603f4a2713aSLionel Sambuc                 classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
3604f4a2713aSLionel Sambuc                              Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
3605f4a2713aSLionel Sambuc                              Pair[SJ].Loops);
3606f4a2713aSLionel Sambuc               switch (Pair[SJ].Classification) {
3607f4a2713aSLionel Sambuc               case Subscript::ZIV:
3608f4a2713aSLionel Sambuc                 DEBUG(dbgs() << "ZIV\n");
3609f4a2713aSLionel Sambuc                 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3610*0a6a1f1dSLionel Sambuc                   return nullptr;
3611f4a2713aSLionel Sambuc                 Mivs.reset(SJ);
3612f4a2713aSLionel Sambuc                 break;
3613f4a2713aSLionel Sambuc               case Subscript::SIV:
3614f4a2713aSLionel Sambuc                 Sivs.set(SJ);
3615f4a2713aSLionel Sambuc                 Mivs.reset(SJ);
3616f4a2713aSLionel Sambuc                 break;
3617f4a2713aSLionel Sambuc               case Subscript::RDIV:
3618f4a2713aSLionel Sambuc               case Subscript::MIV:
3619f4a2713aSLionel Sambuc                 break;
3620f4a2713aSLionel Sambuc               default:
3621f4a2713aSLionel Sambuc                 llvm_unreachable("bad subscript classification");
3622f4a2713aSLionel Sambuc               }
3623f4a2713aSLionel Sambuc             }
3624f4a2713aSLionel Sambuc           }
3625f4a2713aSLionel Sambuc         }
3626f4a2713aSLionel Sambuc       }
3627f4a2713aSLionel Sambuc 
3628f4a2713aSLionel Sambuc       // test & propagate remaining RDIVs
3629f4a2713aSLionel Sambuc       for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3630f4a2713aSLionel Sambuc         if (Pair[SJ].Classification == Subscript::RDIV) {
3631f4a2713aSLionel Sambuc           DEBUG(dbgs() << "RDIV test\n");
3632f4a2713aSLionel Sambuc           if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3633*0a6a1f1dSLionel Sambuc             return nullptr;
3634f4a2713aSLionel Sambuc           // I don't yet understand how to propagate RDIV results
3635f4a2713aSLionel Sambuc           Mivs.reset(SJ);
3636f4a2713aSLionel Sambuc         }
3637f4a2713aSLionel Sambuc       }
3638f4a2713aSLionel Sambuc 
3639f4a2713aSLionel Sambuc       // test remaining MIVs
3640f4a2713aSLionel Sambuc       // This code is temporary.
3641f4a2713aSLionel Sambuc       // Better to somehow test all remaining subscripts simultaneously.
3642f4a2713aSLionel Sambuc       for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3643f4a2713aSLionel Sambuc         if (Pair[SJ].Classification == Subscript::MIV) {
3644f4a2713aSLionel Sambuc           DEBUG(dbgs() << "MIV test\n");
3645f4a2713aSLionel Sambuc           if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
3646*0a6a1f1dSLionel Sambuc             return nullptr;
3647f4a2713aSLionel Sambuc         }
3648f4a2713aSLionel Sambuc         else
3649f4a2713aSLionel Sambuc           llvm_unreachable("expected only MIV subscripts at this point");
3650f4a2713aSLionel Sambuc       }
3651f4a2713aSLionel Sambuc 
3652f4a2713aSLionel Sambuc       // update Result.DV from constraint vector
3653f4a2713aSLionel Sambuc       DEBUG(dbgs() << "    updating\n");
3654f4a2713aSLionel Sambuc       for (int SJ = ConstrainedLevels.find_first();
3655f4a2713aSLionel Sambuc            SJ >= 0; SJ = ConstrainedLevels.find_next(SJ)) {
3656f4a2713aSLionel Sambuc         updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
3657f4a2713aSLionel Sambuc         if (Result.DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
3658*0a6a1f1dSLionel Sambuc           return nullptr;
3659f4a2713aSLionel Sambuc       }
3660f4a2713aSLionel Sambuc     }
3661f4a2713aSLionel Sambuc   }
3662f4a2713aSLionel Sambuc 
3663f4a2713aSLionel Sambuc   // Make sure the Scalar flags are set correctly.
3664f4a2713aSLionel Sambuc   SmallBitVector CompleteLoops(MaxLevels + 1);
3665f4a2713aSLionel Sambuc   for (unsigned SI = 0; SI < Pairs; ++SI)
3666f4a2713aSLionel Sambuc     CompleteLoops |= Pair[SI].Loops;
3667f4a2713aSLionel Sambuc   for (unsigned II = 1; II <= CommonLevels; ++II)
3668f4a2713aSLionel Sambuc     if (CompleteLoops[II])
3669f4a2713aSLionel Sambuc       Result.DV[II - 1].Scalar = false;
3670f4a2713aSLionel Sambuc 
3671f4a2713aSLionel Sambuc   if (PossiblyLoopIndependent) {
3672f4a2713aSLionel Sambuc     // Make sure the LoopIndependent flag is set correctly.
3673f4a2713aSLionel Sambuc     // All directions must include equal, otherwise no
3674f4a2713aSLionel Sambuc     // loop-independent dependence is possible.
3675f4a2713aSLionel Sambuc     for (unsigned II = 1; II <= CommonLevels; ++II) {
3676f4a2713aSLionel Sambuc       if (!(Result.getDirection(II) & Dependence::DVEntry::EQ)) {
3677f4a2713aSLionel Sambuc         Result.LoopIndependent = false;
3678f4a2713aSLionel Sambuc         break;
3679f4a2713aSLionel Sambuc       }
3680f4a2713aSLionel Sambuc     }
3681f4a2713aSLionel Sambuc   }
3682f4a2713aSLionel Sambuc   else {
3683f4a2713aSLionel Sambuc     // On the other hand, if all directions are equal and there's no
3684f4a2713aSLionel Sambuc     // loop-independent dependence possible, then no dependence exists.
3685f4a2713aSLionel Sambuc     bool AllEqual = true;
3686f4a2713aSLionel Sambuc     for (unsigned II = 1; II <= CommonLevels; ++II) {
3687f4a2713aSLionel Sambuc       if (Result.getDirection(II) != Dependence::DVEntry::EQ) {
3688f4a2713aSLionel Sambuc         AllEqual = false;
3689f4a2713aSLionel Sambuc         break;
3690f4a2713aSLionel Sambuc       }
3691f4a2713aSLionel Sambuc     }
3692f4a2713aSLionel Sambuc     if (AllEqual)
3693*0a6a1f1dSLionel Sambuc       return nullptr;
3694f4a2713aSLionel Sambuc   }
3695f4a2713aSLionel Sambuc 
3696*0a6a1f1dSLionel Sambuc   auto Final = make_unique<FullDependence>(Result);
3697*0a6a1f1dSLionel Sambuc   Result.DV = nullptr;
3698*0a6a1f1dSLionel Sambuc   return std::move(Final);
3699f4a2713aSLionel Sambuc }
3700f4a2713aSLionel Sambuc 
3701f4a2713aSLionel Sambuc 
3702f4a2713aSLionel Sambuc 
3703f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3704f4a2713aSLionel Sambuc // getSplitIteration -
3705f4a2713aSLionel Sambuc // Rather than spend rarely-used space recording the splitting iteration
3706f4a2713aSLionel Sambuc // during the Weak-Crossing SIV test, we re-compute it on demand.
3707f4a2713aSLionel Sambuc // The re-computation is basically a repeat of the entire dependence test,
3708f4a2713aSLionel Sambuc // though simplified since we know that the dependence exists.
3709f4a2713aSLionel Sambuc // It's tedious, since we must go through all propagations, etc.
3710f4a2713aSLionel Sambuc //
3711f4a2713aSLionel Sambuc // Care is required to keep this code up to date with respect to the routine
3712f4a2713aSLionel Sambuc // above, depends().
3713f4a2713aSLionel Sambuc //
3714f4a2713aSLionel Sambuc // Generally, the dependence analyzer will be used to build
3715f4a2713aSLionel Sambuc // a dependence graph for a function (basically a map from instructions
3716f4a2713aSLionel Sambuc // to dependences). Looking for cycles in the graph shows us loops
3717f4a2713aSLionel Sambuc // that cannot be trivially vectorized/parallelized.
3718f4a2713aSLionel Sambuc //
3719f4a2713aSLionel Sambuc // We can try to improve the situation by examining all the dependences
3720f4a2713aSLionel Sambuc // that make up the cycle, looking for ones we can break.
3721f4a2713aSLionel Sambuc // Sometimes, peeling the first or last iteration of a loop will break
3722f4a2713aSLionel Sambuc // dependences, and we've got flags for those possibilities.
3723f4a2713aSLionel Sambuc // Sometimes, splitting a loop at some other iteration will do the trick,
3724f4a2713aSLionel Sambuc // and we've got a flag for that case. Rather than waste the space to
3725f4a2713aSLionel Sambuc // record the exact iteration (since we rarely know), we provide
3726f4a2713aSLionel Sambuc // a method that calculates the iteration. It's a drag that it must work
3727f4a2713aSLionel Sambuc // from scratch, but wonderful in that it's possible.
3728f4a2713aSLionel Sambuc //
3729f4a2713aSLionel Sambuc // Here's an example:
3730f4a2713aSLionel Sambuc //
3731f4a2713aSLionel Sambuc //    for (i = 0; i < 10; i++)
3732f4a2713aSLionel Sambuc //        A[i] = ...
3733f4a2713aSLionel Sambuc //        ... = A[11 - i]
3734f4a2713aSLionel Sambuc //
3735f4a2713aSLionel Sambuc // There's a loop-carried flow dependence from the store to the load,
3736f4a2713aSLionel Sambuc // found by the weak-crossing SIV test. The dependence will have a flag,
3737f4a2713aSLionel Sambuc // indicating that the dependence can be broken by splitting the loop.
3738f4a2713aSLionel Sambuc // Calling getSplitIteration will return 5.
3739f4a2713aSLionel Sambuc // Splitting the loop breaks the dependence, like so:
3740f4a2713aSLionel Sambuc //
3741f4a2713aSLionel Sambuc //    for (i = 0; i <= 5; i++)
3742f4a2713aSLionel Sambuc //        A[i] = ...
3743f4a2713aSLionel Sambuc //        ... = A[11 - i]
3744f4a2713aSLionel Sambuc //    for (i = 6; i < 10; i++)
3745f4a2713aSLionel Sambuc //        A[i] = ...
3746f4a2713aSLionel Sambuc //        ... = A[11 - i]
3747f4a2713aSLionel Sambuc //
3748f4a2713aSLionel Sambuc // breaks the dependence and allows us to vectorize/parallelize
3749f4a2713aSLionel Sambuc // both loops.
getSplitIteration(const Dependence & Dep,unsigned SplitLevel)3750*0a6a1f1dSLionel Sambuc const  SCEV *DependenceAnalysis::getSplitIteration(const Dependence &Dep,
3751f4a2713aSLionel Sambuc                                                    unsigned SplitLevel) {
3752*0a6a1f1dSLionel Sambuc   assert(Dep.isSplitable(SplitLevel) &&
3753f4a2713aSLionel Sambuc          "Dep should be splitable at SplitLevel");
3754*0a6a1f1dSLionel Sambuc   Instruction *Src = Dep.getSrc();
3755*0a6a1f1dSLionel Sambuc   Instruction *Dst = Dep.getDst();
3756f4a2713aSLionel Sambuc   assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
3757f4a2713aSLionel Sambuc   assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
3758f4a2713aSLionel Sambuc   assert(isLoadOrStore(Src));
3759f4a2713aSLionel Sambuc   assert(isLoadOrStore(Dst));
3760f4a2713aSLionel Sambuc   Value *SrcPtr = getPointerOperand(Src);
3761f4a2713aSLionel Sambuc   Value *DstPtr = getPointerOperand(Dst);
3762f4a2713aSLionel Sambuc   assert(underlyingObjectsAlias(AA, DstPtr, SrcPtr) ==
3763f4a2713aSLionel Sambuc          AliasAnalysis::MustAlias);
3764f4a2713aSLionel Sambuc 
3765f4a2713aSLionel Sambuc   // establish loop nesting levels
3766f4a2713aSLionel Sambuc   establishNestingLevels(Src, Dst);
3767f4a2713aSLionel Sambuc 
3768f4a2713aSLionel Sambuc   FullDependence Result(Src, Dst, false, CommonLevels);
3769f4a2713aSLionel Sambuc 
3770f4a2713aSLionel Sambuc   // See if there are GEPs we can use.
3771f4a2713aSLionel Sambuc   bool UsefulGEP = false;
3772f4a2713aSLionel Sambuc   GEPOperator *SrcGEP = dyn_cast<GEPOperator>(SrcPtr);
3773f4a2713aSLionel Sambuc   GEPOperator *DstGEP = dyn_cast<GEPOperator>(DstPtr);
3774f4a2713aSLionel Sambuc   if (SrcGEP && DstGEP &&
3775f4a2713aSLionel Sambuc       SrcGEP->getPointerOperandType() == DstGEP->getPointerOperandType()) {
3776f4a2713aSLionel Sambuc     const SCEV *SrcPtrSCEV = SE->getSCEV(SrcGEP->getPointerOperand());
3777f4a2713aSLionel Sambuc     const SCEV *DstPtrSCEV = SE->getSCEV(DstGEP->getPointerOperand());
3778f4a2713aSLionel Sambuc     UsefulGEP =
3779f4a2713aSLionel Sambuc       isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
3780f4a2713aSLionel Sambuc       isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent()));
3781f4a2713aSLionel Sambuc   }
3782f4a2713aSLionel Sambuc   unsigned Pairs = UsefulGEP ? SrcGEP->idx_end() - SrcGEP->idx_begin() : 1;
3783f4a2713aSLionel Sambuc   SmallVector<Subscript, 4> Pair(Pairs);
3784f4a2713aSLionel Sambuc   if (UsefulGEP) {
3785f4a2713aSLionel Sambuc     unsigned P = 0;
3786f4a2713aSLionel Sambuc     for (GEPOperator::const_op_iterator SrcIdx = SrcGEP->idx_begin(),
3787f4a2713aSLionel Sambuc            SrcEnd = SrcGEP->idx_end(),
3788f4a2713aSLionel Sambuc            DstIdx = DstGEP->idx_begin();
3789f4a2713aSLionel Sambuc          SrcIdx != SrcEnd;
3790f4a2713aSLionel Sambuc          ++SrcIdx, ++DstIdx, ++P) {
3791f4a2713aSLionel Sambuc       Pair[P].Src = SE->getSCEV(*SrcIdx);
3792f4a2713aSLionel Sambuc       Pair[P].Dst = SE->getSCEV(*DstIdx);
3793f4a2713aSLionel Sambuc     }
3794f4a2713aSLionel Sambuc   }
3795f4a2713aSLionel Sambuc   else {
3796f4a2713aSLionel Sambuc     const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
3797f4a2713aSLionel Sambuc     const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3798f4a2713aSLionel Sambuc     Pair[0].Src = SrcSCEV;
3799f4a2713aSLionel Sambuc     Pair[0].Dst = DstSCEV;
3800f4a2713aSLionel Sambuc   }
3801f4a2713aSLionel Sambuc 
3802f4a2713aSLionel Sambuc   if (Delinearize && Pairs == 1 && CommonLevels > 1 &&
3803*0a6a1f1dSLionel Sambuc       tryDelinearize(Pair[0].Src, Pair[0].Dst, Pair, SE->getElementSize(Src))) {
3804f4a2713aSLionel Sambuc     DEBUG(dbgs() << "    delinerized GEP\n");
3805f4a2713aSLionel Sambuc     Pairs = Pair.size();
3806f4a2713aSLionel Sambuc   }
3807f4a2713aSLionel Sambuc 
3808f4a2713aSLionel Sambuc   for (unsigned P = 0; P < Pairs; ++P) {
3809f4a2713aSLionel Sambuc     Pair[P].Loops.resize(MaxLevels + 1);
3810f4a2713aSLionel Sambuc     Pair[P].GroupLoops.resize(MaxLevels + 1);
3811f4a2713aSLionel Sambuc     Pair[P].Group.resize(Pairs);
3812f4a2713aSLionel Sambuc     removeMatchingExtensions(&Pair[P]);
3813f4a2713aSLionel Sambuc     Pair[P].Classification =
3814f4a2713aSLionel Sambuc       classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
3815f4a2713aSLionel Sambuc                    Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
3816f4a2713aSLionel Sambuc                    Pair[P].Loops);
3817f4a2713aSLionel Sambuc     Pair[P].GroupLoops = Pair[P].Loops;
3818f4a2713aSLionel Sambuc     Pair[P].Group.set(P);
3819f4a2713aSLionel Sambuc   }
3820f4a2713aSLionel Sambuc 
3821f4a2713aSLionel Sambuc   SmallBitVector Separable(Pairs);
3822f4a2713aSLionel Sambuc   SmallBitVector Coupled(Pairs);
3823f4a2713aSLionel Sambuc 
3824f4a2713aSLionel Sambuc   // partition subscripts into separable and minimally-coupled groups
3825f4a2713aSLionel Sambuc   for (unsigned SI = 0; SI < Pairs; ++SI) {
3826f4a2713aSLionel Sambuc     if (Pair[SI].Classification == Subscript::NonLinear) {
3827f4a2713aSLionel Sambuc       // ignore these, but collect loops for later
3828f4a2713aSLionel Sambuc       collectCommonLoops(Pair[SI].Src,
3829f4a2713aSLionel Sambuc                          LI->getLoopFor(Src->getParent()),
3830f4a2713aSLionel Sambuc                          Pair[SI].Loops);
3831f4a2713aSLionel Sambuc       collectCommonLoops(Pair[SI].Dst,
3832f4a2713aSLionel Sambuc                          LI->getLoopFor(Dst->getParent()),
3833f4a2713aSLionel Sambuc                          Pair[SI].Loops);
3834f4a2713aSLionel Sambuc       Result.Consistent = false;
3835f4a2713aSLionel Sambuc     }
3836f4a2713aSLionel Sambuc     else if (Pair[SI].Classification == Subscript::ZIV)
3837f4a2713aSLionel Sambuc       Separable.set(SI);
3838f4a2713aSLionel Sambuc     else {
3839f4a2713aSLionel Sambuc       // SIV, RDIV, or MIV, so check for coupled group
3840f4a2713aSLionel Sambuc       bool Done = true;
3841f4a2713aSLionel Sambuc       for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
3842f4a2713aSLionel Sambuc         SmallBitVector Intersection = Pair[SI].GroupLoops;
3843f4a2713aSLionel Sambuc         Intersection &= Pair[SJ].GroupLoops;
3844f4a2713aSLionel Sambuc         if (Intersection.any()) {
3845f4a2713aSLionel Sambuc           // accumulate set of all the loops in group
3846f4a2713aSLionel Sambuc           Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
3847f4a2713aSLionel Sambuc           // accumulate set of all subscripts in group
3848f4a2713aSLionel Sambuc           Pair[SJ].Group |= Pair[SI].Group;
3849f4a2713aSLionel Sambuc           Done = false;
3850f4a2713aSLionel Sambuc         }
3851f4a2713aSLionel Sambuc       }
3852f4a2713aSLionel Sambuc       if (Done) {
3853f4a2713aSLionel Sambuc         if (Pair[SI].Group.count() == 1)
3854f4a2713aSLionel Sambuc           Separable.set(SI);
3855f4a2713aSLionel Sambuc         else
3856f4a2713aSLionel Sambuc           Coupled.set(SI);
3857f4a2713aSLionel Sambuc       }
3858f4a2713aSLionel Sambuc     }
3859f4a2713aSLionel Sambuc   }
3860f4a2713aSLionel Sambuc 
3861f4a2713aSLionel Sambuc   Constraint NewConstraint;
3862f4a2713aSLionel Sambuc   NewConstraint.setAny(SE);
3863f4a2713aSLionel Sambuc 
3864f4a2713aSLionel Sambuc   // test separable subscripts
3865f4a2713aSLionel Sambuc   for (int SI = Separable.find_first(); SI >= 0; SI = Separable.find_next(SI)) {
3866f4a2713aSLionel Sambuc     switch (Pair[SI].Classification) {
3867f4a2713aSLionel Sambuc     case Subscript::SIV: {
3868f4a2713aSLionel Sambuc       unsigned Level;
3869*0a6a1f1dSLionel Sambuc       const SCEV *SplitIter = nullptr;
3870f4a2713aSLionel Sambuc       (void) testSIV(Pair[SI].Src, Pair[SI].Dst, Level,
3871f4a2713aSLionel Sambuc                      Result, NewConstraint, SplitIter);
3872f4a2713aSLionel Sambuc       if (Level == SplitLevel) {
3873*0a6a1f1dSLionel Sambuc         assert(SplitIter != nullptr);
3874f4a2713aSLionel Sambuc         return SplitIter;
3875f4a2713aSLionel Sambuc       }
3876f4a2713aSLionel Sambuc       break;
3877f4a2713aSLionel Sambuc     }
3878f4a2713aSLionel Sambuc     case Subscript::ZIV:
3879f4a2713aSLionel Sambuc     case Subscript::RDIV:
3880f4a2713aSLionel Sambuc     case Subscript::MIV:
3881f4a2713aSLionel Sambuc       break;
3882f4a2713aSLionel Sambuc     default:
3883f4a2713aSLionel Sambuc       llvm_unreachable("subscript has unexpected classification");
3884f4a2713aSLionel Sambuc     }
3885f4a2713aSLionel Sambuc   }
3886f4a2713aSLionel Sambuc 
3887f4a2713aSLionel Sambuc   if (Coupled.count()) {
3888f4a2713aSLionel Sambuc     // test coupled subscript groups
3889f4a2713aSLionel Sambuc     SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
3890f4a2713aSLionel Sambuc     for (unsigned II = 0; II <= MaxLevels; ++II)
3891f4a2713aSLionel Sambuc       Constraints[II].setAny(SE);
3892f4a2713aSLionel Sambuc     for (int SI = Coupled.find_first(); SI >= 0; SI = Coupled.find_next(SI)) {
3893f4a2713aSLionel Sambuc       SmallBitVector Group(Pair[SI].Group);
3894f4a2713aSLionel Sambuc       SmallBitVector Sivs(Pairs);
3895f4a2713aSLionel Sambuc       SmallBitVector Mivs(Pairs);
3896f4a2713aSLionel Sambuc       SmallBitVector ConstrainedLevels(MaxLevels + 1);
3897f4a2713aSLionel Sambuc       for (int SJ = Group.find_first(); SJ >= 0; SJ = Group.find_next(SJ)) {
3898f4a2713aSLionel Sambuc         if (Pair[SJ].Classification == Subscript::SIV)
3899f4a2713aSLionel Sambuc           Sivs.set(SJ);
3900f4a2713aSLionel Sambuc         else
3901f4a2713aSLionel Sambuc           Mivs.set(SJ);
3902f4a2713aSLionel Sambuc       }
3903f4a2713aSLionel Sambuc       while (Sivs.any()) {
3904f4a2713aSLionel Sambuc         bool Changed = false;
3905f4a2713aSLionel Sambuc         for (int SJ = Sivs.find_first(); SJ >= 0; SJ = Sivs.find_next(SJ)) {
3906f4a2713aSLionel Sambuc           // SJ is an SIV subscript that's part of the current coupled group
3907f4a2713aSLionel Sambuc           unsigned Level;
3908*0a6a1f1dSLionel Sambuc           const SCEV *SplitIter = nullptr;
3909f4a2713aSLionel Sambuc           (void) testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
3910f4a2713aSLionel Sambuc                          Result, NewConstraint, SplitIter);
3911f4a2713aSLionel Sambuc           if (Level == SplitLevel && SplitIter)
3912f4a2713aSLionel Sambuc             return SplitIter;
3913f4a2713aSLionel Sambuc           ConstrainedLevels.set(Level);
3914f4a2713aSLionel Sambuc           if (intersectConstraints(&Constraints[Level], &NewConstraint))
3915f4a2713aSLionel Sambuc             Changed = true;
3916f4a2713aSLionel Sambuc           Sivs.reset(SJ);
3917f4a2713aSLionel Sambuc         }
3918f4a2713aSLionel Sambuc         if (Changed) {
3919f4a2713aSLionel Sambuc           // propagate, possibly creating new SIVs and ZIVs
3920f4a2713aSLionel Sambuc           for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3921f4a2713aSLionel Sambuc             // SJ is an MIV subscript that's part of the current coupled group
3922f4a2713aSLionel Sambuc             if (propagate(Pair[SJ].Src, Pair[SJ].Dst,
3923f4a2713aSLionel Sambuc                           Pair[SJ].Loops, Constraints, Result.Consistent)) {
3924f4a2713aSLionel Sambuc               Pair[SJ].Classification =
3925f4a2713aSLionel Sambuc                 classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
3926f4a2713aSLionel Sambuc                              Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
3927f4a2713aSLionel Sambuc                              Pair[SJ].Loops);
3928f4a2713aSLionel Sambuc               switch (Pair[SJ].Classification) {
3929f4a2713aSLionel Sambuc               case Subscript::ZIV:
3930f4a2713aSLionel Sambuc                 Mivs.reset(SJ);
3931f4a2713aSLionel Sambuc                 break;
3932f4a2713aSLionel Sambuc               case Subscript::SIV:
3933f4a2713aSLionel Sambuc                 Sivs.set(SJ);
3934f4a2713aSLionel Sambuc                 Mivs.reset(SJ);
3935f4a2713aSLionel Sambuc                 break;
3936f4a2713aSLionel Sambuc               case Subscript::RDIV:
3937f4a2713aSLionel Sambuc               case Subscript::MIV:
3938f4a2713aSLionel Sambuc                 break;
3939f4a2713aSLionel Sambuc               default:
3940f4a2713aSLionel Sambuc                 llvm_unreachable("bad subscript classification");
3941f4a2713aSLionel Sambuc               }
3942f4a2713aSLionel Sambuc             }
3943f4a2713aSLionel Sambuc           }
3944f4a2713aSLionel Sambuc         }
3945f4a2713aSLionel Sambuc       }
3946f4a2713aSLionel Sambuc     }
3947f4a2713aSLionel Sambuc   }
3948f4a2713aSLionel Sambuc   llvm_unreachable("somehow reached end of routine");
3949*0a6a1f1dSLionel Sambuc   return nullptr;
3950f4a2713aSLionel Sambuc }
3951