xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/DependenceAnalysis.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- DependenceAnalysis.cpp - DA Implementation --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // DependenceAnalysis is an LLVM pass that analyses dependences between memory
100b57cec5SDimitry Andric // accesses. Currently, it is an (incomplete) implementation of the approach
110b57cec5SDimitry Andric // described in
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //            Practical Dependence Testing
140b57cec5SDimitry Andric //            Goff, Kennedy, Tseng
150b57cec5SDimitry Andric //            PLDI 1991
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric // There's a single entry point that analyzes the dependence between a pair
180b57cec5SDimitry Andric // of memory references in a function, returning either NULL, for no dependence,
190b57cec5SDimitry Andric // or a more-or-less detailed description of the dependence between them.
200b57cec5SDimitry Andric //
210b57cec5SDimitry Andric // Currently, the implementation cannot propagate constraints between
220b57cec5SDimitry Andric // coupled RDIV subscripts and lacks a multi-subscript MIV test.
230b57cec5SDimitry Andric // Both of these are conservative weaknesses;
240b57cec5SDimitry Andric // that is, not a source of correctness problems.
250b57cec5SDimitry Andric //
260b57cec5SDimitry Andric // Since Clang linearizes some array subscripts, the dependence
270b57cec5SDimitry Andric // analysis is using SCEV->delinearize to recover the representation of multiple
280b57cec5SDimitry Andric // subscripts, and thus avoid the more expensive and less precise MIV tests. The
290b57cec5SDimitry Andric // delinearization is controlled by the flag -da-delinearize.
300b57cec5SDimitry Andric //
310b57cec5SDimitry Andric // We should pay some careful attention to the possibility of integer overflow
320b57cec5SDimitry Andric // in the implementation of the various tests. This could happen with Add,
330b57cec5SDimitry Andric // Subtract, or Multiply, with both APInt's and SCEV's.
340b57cec5SDimitry Andric //
350b57cec5SDimitry Andric // Some non-linear subscript pairs can be handled by the GCD test
360b57cec5SDimitry Andric // (and perhaps other tests).
370b57cec5SDimitry Andric // Should explore how often these things occur.
380b57cec5SDimitry Andric //
390b57cec5SDimitry Andric // Finally, it seems like certain test cases expose weaknesses in the SCEV
400b57cec5SDimitry Andric // simplification, especially in the handling of sign and zero extensions.
410b57cec5SDimitry Andric // It could be useful to spend time exploring these.
420b57cec5SDimitry Andric //
430b57cec5SDimitry Andric // Please note that this is work in progress and the interface is subject to
440b57cec5SDimitry Andric // change.
450b57cec5SDimitry Andric //
460b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
470b57cec5SDimitry Andric //                                                                            //
480b57cec5SDimitry Andric //                   In memory of Ken Kennedy, 1945 - 2007                    //
490b57cec5SDimitry Andric //                                                                            //
500b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric #include "llvm/Analysis/DependenceAnalysis.h"
530b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
540b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
55349cc55cSDimitry Andric #include "llvm/Analysis/Delinearization.h"
560b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
570b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h"
580b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h"
590b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
600b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h"
610b57cec5SDimitry Andric #include "llvm/IR/Module.h"
62480093f4SDimitry Andric #include "llvm/InitializePasses.h"
630b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
640b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
650b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
660b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric using namespace llvm;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric #define DEBUG_TYPE "da"
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
730b57cec5SDimitry Andric // statistics
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric STATISTIC(TotalArrayPairs, "Array pairs tested");
760b57cec5SDimitry Andric STATISTIC(SeparableSubscriptPairs, "Separable subscript pairs");
770b57cec5SDimitry Andric STATISTIC(CoupledSubscriptPairs, "Coupled subscript pairs");
780b57cec5SDimitry Andric STATISTIC(NonlinearSubscriptPairs, "Nonlinear subscript pairs");
790b57cec5SDimitry Andric STATISTIC(ZIVapplications, "ZIV applications");
800b57cec5SDimitry Andric STATISTIC(ZIVindependence, "ZIV independence");
810b57cec5SDimitry Andric STATISTIC(StrongSIVapplications, "Strong SIV applications");
820b57cec5SDimitry Andric STATISTIC(StrongSIVsuccesses, "Strong SIV successes");
830b57cec5SDimitry Andric STATISTIC(StrongSIVindependence, "Strong SIV independence");
840b57cec5SDimitry Andric STATISTIC(WeakCrossingSIVapplications, "Weak-Crossing SIV applications");
850b57cec5SDimitry Andric STATISTIC(WeakCrossingSIVsuccesses, "Weak-Crossing SIV successes");
860b57cec5SDimitry Andric STATISTIC(WeakCrossingSIVindependence, "Weak-Crossing SIV independence");
870b57cec5SDimitry Andric STATISTIC(ExactSIVapplications, "Exact SIV applications");
880b57cec5SDimitry Andric STATISTIC(ExactSIVsuccesses, "Exact SIV successes");
890b57cec5SDimitry Andric STATISTIC(ExactSIVindependence, "Exact SIV independence");
900b57cec5SDimitry Andric STATISTIC(WeakZeroSIVapplications, "Weak-Zero SIV applications");
910b57cec5SDimitry Andric STATISTIC(WeakZeroSIVsuccesses, "Weak-Zero SIV successes");
920b57cec5SDimitry Andric STATISTIC(WeakZeroSIVindependence, "Weak-Zero SIV independence");
930b57cec5SDimitry Andric STATISTIC(ExactRDIVapplications, "Exact RDIV applications");
940b57cec5SDimitry Andric STATISTIC(ExactRDIVindependence, "Exact RDIV independence");
950b57cec5SDimitry Andric STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
960b57cec5SDimitry Andric STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
970b57cec5SDimitry Andric STATISTIC(DeltaApplications, "Delta applications");
980b57cec5SDimitry Andric STATISTIC(DeltaSuccesses, "Delta successes");
990b57cec5SDimitry Andric STATISTIC(DeltaIndependence, "Delta independence");
1000b57cec5SDimitry Andric STATISTIC(DeltaPropagations, "Delta propagations");
1010b57cec5SDimitry Andric STATISTIC(GCDapplications, "GCD applications");
1020b57cec5SDimitry Andric STATISTIC(GCDsuccesses, "GCD successes");
1030b57cec5SDimitry Andric STATISTIC(GCDindependence, "GCD independence");
1040b57cec5SDimitry Andric STATISTIC(BanerjeeApplications, "Banerjee applications");
1050b57cec5SDimitry Andric STATISTIC(BanerjeeIndependence, "Banerjee independence");
1060b57cec5SDimitry Andric STATISTIC(BanerjeeSuccesses, "Banerjee successes");
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric static cl::opt<bool>
10981ad6265SDimitry Andric     Delinearize("da-delinearize", cl::init(true), cl::Hidden,
1100b57cec5SDimitry Andric                 cl::desc("Try to delinearize array references."));
1110b57cec5SDimitry Andric static cl::opt<bool> DisableDelinearizationChecks(
11281ad6265SDimitry Andric     "da-disable-delinearization-checks", cl::Hidden,
1130b57cec5SDimitry Andric     cl::desc(
1140b57cec5SDimitry Andric         "Disable checks that try to statically verify validity of "
1150b57cec5SDimitry Andric         "delinearized subscripts. Enabling this option may result in incorrect "
1160b57cec5SDimitry Andric         "dependence vectors for languages that allow the subscript of one "
1170b57cec5SDimitry Andric         "dimension to underflow or overflow into another dimension."));
1180b57cec5SDimitry Andric 
119349cc55cSDimitry Andric static cl::opt<unsigned> MIVMaxLevelThreshold(
12081ad6265SDimitry Andric     "da-miv-max-level-threshold", cl::init(7), cl::Hidden,
121349cc55cSDimitry Andric     cl::desc("Maximum depth allowed for the recursive algorithm used to "
122349cc55cSDimitry Andric              "explore MIV direction vectors."));
123349cc55cSDimitry Andric 
1240b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1250b57cec5SDimitry Andric // basics
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric DependenceAnalysis::Result
1280b57cec5SDimitry Andric DependenceAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
1290b57cec5SDimitry Andric   auto &AA = FAM.getResult<AAManager>(F);
1300b57cec5SDimitry Andric   auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
1310b57cec5SDimitry Andric   auto &LI = FAM.getResult<LoopAnalysis>(F);
1320b57cec5SDimitry Andric   return DependenceInfo(&F, &AA, &SE, &LI);
1330b57cec5SDimitry Andric }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric AnalysisKey DependenceAnalysis::Key;
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(DependenceAnalysisWrapperPass, "da",
1380b57cec5SDimitry Andric                       "Dependence Analysis", true, true)
1390b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
1400b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
1410b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
1420b57cec5SDimitry Andric INITIALIZE_PASS_END(DependenceAnalysisWrapperPass, "da", "Dependence Analysis",
1430b57cec5SDimitry Andric                     true, true)
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric char DependenceAnalysisWrapperPass::ID = 0;
1460b57cec5SDimitry Andric 
147480093f4SDimitry Andric DependenceAnalysisWrapperPass::DependenceAnalysisWrapperPass()
148480093f4SDimitry Andric     : FunctionPass(ID) {
149480093f4SDimitry Andric   initializeDependenceAnalysisWrapperPassPass(*PassRegistry::getPassRegistry());
150480093f4SDimitry Andric }
151480093f4SDimitry Andric 
1520b57cec5SDimitry Andric FunctionPass *llvm::createDependenceAnalysisWrapperPass() {
1530b57cec5SDimitry Andric   return new DependenceAnalysisWrapperPass();
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric bool DependenceAnalysisWrapperPass::runOnFunction(Function &F) {
1570b57cec5SDimitry Andric   auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
1580b57cec5SDimitry Andric   auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1590b57cec5SDimitry Andric   auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1600b57cec5SDimitry Andric   info.reset(new DependenceInfo(&F, &AA, &SE, &LI));
1610b57cec5SDimitry Andric   return false;
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric DependenceInfo &DependenceAnalysisWrapperPass::getDI() const { return *info; }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric void DependenceAnalysisWrapperPass::releaseMemory() { info.reset(); }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric void DependenceAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
1690b57cec5SDimitry Andric   AU.setPreservesAll();
1700b57cec5SDimitry Andric   AU.addRequiredTransitive<AAResultsWrapperPass>();
1710b57cec5SDimitry Andric   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
1720b57cec5SDimitry Andric   AU.addRequiredTransitive<LoopInfoWrapperPass>();
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric // Used to test the dependence analyzer.
176480093f4SDimitry Andric // Looks through the function, noting instructions that may access memory.
1770b57cec5SDimitry Andric // Calls depends() on every possible pair and prints out the result.
1780b57cec5SDimitry Andric // Ignores all other instructions.
179bdd1243dSDimitry Andric static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
180bdd1243dSDimitry Andric                                   ScalarEvolution &SE, bool NormalizeResults) {
1810b57cec5SDimitry Andric   auto *F = DA->getFunction();
1820b57cec5SDimitry Andric   for (inst_iterator SrcI = inst_begin(F), SrcE = inst_end(F); SrcI != SrcE;
1830b57cec5SDimitry Andric        ++SrcI) {
184480093f4SDimitry Andric     if (SrcI->mayReadOrWriteMemory()) {
1850b57cec5SDimitry Andric       for (inst_iterator DstI = SrcI, DstE = inst_end(F);
1860b57cec5SDimitry Andric            DstI != DstE; ++DstI) {
187480093f4SDimitry Andric         if (DstI->mayReadOrWriteMemory()) {
188480093f4SDimitry Andric           OS << "Src:" << *SrcI << " --> Dst:" << *DstI << "\n";
1890b57cec5SDimitry Andric           OS << "  da analyze - ";
1900b57cec5SDimitry Andric           if (auto D = DA->depends(&*SrcI, &*DstI, true)) {
191bdd1243dSDimitry Andric             // Normalize negative direction vectors if required by clients.
192bdd1243dSDimitry Andric             if (NormalizeResults && D->normalize(&SE))
193bdd1243dSDimitry Andric                 OS << "normalized - ";
1940b57cec5SDimitry Andric             D->dump(OS);
1950b57cec5SDimitry Andric             for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
1960b57cec5SDimitry Andric               if (D->isSplitable(Level)) {
1970b57cec5SDimitry Andric                 OS << "  da analyze - split level = " << Level;
1980b57cec5SDimitry Andric                 OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
1990b57cec5SDimitry Andric                 OS << "!\n";
2000b57cec5SDimitry Andric               }
2010b57cec5SDimitry Andric             }
2020b57cec5SDimitry Andric           }
2030b57cec5SDimitry Andric           else
2040b57cec5SDimitry Andric             OS << "none!\n";
2050b57cec5SDimitry Andric         }
2060b57cec5SDimitry Andric       }
2070b57cec5SDimitry Andric     }
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric void DependenceAnalysisWrapperPass::print(raw_ostream &OS,
2120b57cec5SDimitry Andric                                           const Module *) const {
213bdd1243dSDimitry Andric   dumpExampleDependence(OS, info.get(),
214bdd1243dSDimitry Andric                         getAnalysis<ScalarEvolutionWrapperPass>().getSE(), false);
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric PreservedAnalyses
2180b57cec5SDimitry Andric DependenceAnalysisPrinterPass::run(Function &F, FunctionAnalysisManager &FAM) {
2190b57cec5SDimitry Andric   OS << "'Dependence Analysis' for function '" << F.getName() << "':\n";
220bdd1243dSDimitry Andric   dumpExampleDependence(OS, &FAM.getResult<DependenceAnalysis>(F),
221bdd1243dSDimitry Andric                         FAM.getResult<ScalarEvolutionAnalysis>(F),
222bdd1243dSDimitry Andric                         NormalizeResults);
2230b57cec5SDimitry Andric   return PreservedAnalyses::all();
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2270b57cec5SDimitry Andric // Dependence methods
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric // Returns true if this is an input dependence.
2300b57cec5SDimitry Andric bool Dependence::isInput() const {
2310b57cec5SDimitry Andric   return Src->mayReadFromMemory() && Dst->mayReadFromMemory();
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric // Returns true if this is an output dependence.
2360b57cec5SDimitry Andric bool Dependence::isOutput() const {
2370b57cec5SDimitry Andric   return Src->mayWriteToMemory() && Dst->mayWriteToMemory();
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric // Returns true if this is an flow (aka true)  dependence.
2420b57cec5SDimitry Andric bool Dependence::isFlow() const {
2430b57cec5SDimitry Andric   return Src->mayWriteToMemory() && Dst->mayReadFromMemory();
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric // Returns true if this is an anti dependence.
2480b57cec5SDimitry Andric bool Dependence::isAnti() const {
2490b57cec5SDimitry Andric   return Src->mayReadFromMemory() && Dst->mayWriteToMemory();
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric // Returns true if a particular level is scalar; that is,
2540b57cec5SDimitry Andric // if no subscript in the source or destination mention the induction
2550b57cec5SDimitry Andric // variable associated with the loop at this level.
2560b57cec5SDimitry Andric // Leave this out of line, so it will serve as a virtual method anchor
2570b57cec5SDimitry Andric bool Dependence::isScalar(unsigned level) const {
2580b57cec5SDimitry Andric   return false;
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2630b57cec5SDimitry Andric // FullDependence methods
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric FullDependence::FullDependence(Instruction *Source, Instruction *Destination,
2660b57cec5SDimitry Andric                                bool PossiblyLoopIndependent,
2670b57cec5SDimitry Andric                                unsigned CommonLevels)
2680b57cec5SDimitry Andric     : Dependence(Source, Destination), Levels(CommonLevels),
2690b57cec5SDimitry Andric       LoopIndependent(PossiblyLoopIndependent) {
2700b57cec5SDimitry Andric   Consistent = true;
2710b57cec5SDimitry Andric   if (CommonLevels)
2728bcb0991SDimitry Andric     DV = std::make_unique<DVEntry[]>(CommonLevels);
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric 
275bdd1243dSDimitry Andric // FIXME: in some cases the meaning of a negative direction vector
276bdd1243dSDimitry Andric // may not be straightforward, e.g.,
277bdd1243dSDimitry Andric // for (int i = 0; i < 32; ++i) {
278bdd1243dSDimitry Andric //   Src:    A[i] = ...;
279bdd1243dSDimitry Andric //   Dst:    use(A[31 - i]);
280bdd1243dSDimitry Andric // }
281bdd1243dSDimitry Andric // The dependency is
282bdd1243dSDimitry Andric //   flow { Src[i] -> Dst[31 - i] : when i >= 16 } and
283bdd1243dSDimitry Andric //   anti { Dst[i] -> Src[31 - i] : when i < 16 },
284bdd1243dSDimitry Andric // -- hence a [<>].
285bdd1243dSDimitry Andric // As long as a dependence result contains '>' ('<>', '<=>', "*"), it
286bdd1243dSDimitry Andric // means that a reversed/normalized dependence needs to be considered
287bdd1243dSDimitry Andric // as well. Nevertheless, current isDirectionNegative() only returns
288bdd1243dSDimitry Andric // true with a '>' or '>=' dependency for ease of canonicalizing the
289bdd1243dSDimitry Andric // dependency vector, since the reverse of '<>', '<=>' and "*" is itself.
290bdd1243dSDimitry Andric bool FullDependence::isDirectionNegative() const {
291bdd1243dSDimitry Andric   for (unsigned Level = 1; Level <= Levels; ++Level) {
292bdd1243dSDimitry Andric     unsigned char Direction = DV[Level - 1].Direction;
293bdd1243dSDimitry Andric     if (Direction == Dependence::DVEntry::EQ)
294bdd1243dSDimitry Andric       continue;
295bdd1243dSDimitry Andric     if (Direction == Dependence::DVEntry::GT ||
296bdd1243dSDimitry Andric         Direction == Dependence::DVEntry::GE)
297bdd1243dSDimitry Andric       return true;
298bdd1243dSDimitry Andric     return false;
299bdd1243dSDimitry Andric   }
300bdd1243dSDimitry Andric   return false;
301bdd1243dSDimitry Andric }
302bdd1243dSDimitry Andric 
303bdd1243dSDimitry Andric bool FullDependence::normalize(ScalarEvolution *SE) {
304bdd1243dSDimitry Andric   if (!isDirectionNegative())
305bdd1243dSDimitry Andric     return false;
306bdd1243dSDimitry Andric 
307bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Before normalizing negative direction vectors:\n";
308bdd1243dSDimitry Andric              dump(dbgs()););
309bdd1243dSDimitry Andric   std::swap(Src, Dst);
310bdd1243dSDimitry Andric   for (unsigned Level = 1; Level <= Levels; ++Level) {
311bdd1243dSDimitry Andric     unsigned char Direction = DV[Level - 1].Direction;
312bdd1243dSDimitry Andric     // Reverse the direction vector, this means LT becomes GT
313bdd1243dSDimitry Andric     // and GT becomes LT.
314bdd1243dSDimitry Andric     unsigned char RevDirection = Direction & Dependence::DVEntry::EQ;
315bdd1243dSDimitry Andric     if (Direction & Dependence::DVEntry::LT)
316bdd1243dSDimitry Andric       RevDirection |= Dependence::DVEntry::GT;
317bdd1243dSDimitry Andric     if (Direction & Dependence::DVEntry::GT)
318bdd1243dSDimitry Andric       RevDirection |= Dependence::DVEntry::LT;
319bdd1243dSDimitry Andric     DV[Level - 1].Direction = RevDirection;
320bdd1243dSDimitry Andric     // Reverse the dependence distance as well.
321bdd1243dSDimitry Andric     if (DV[Level - 1].Distance != nullptr)
322bdd1243dSDimitry Andric       DV[Level - 1].Distance =
323bdd1243dSDimitry Andric           SE->getNegativeSCEV(DV[Level - 1].Distance);
324bdd1243dSDimitry Andric   }
325bdd1243dSDimitry Andric 
326bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "After normalizing negative direction vectors:\n";
327bdd1243dSDimitry Andric              dump(dbgs()););
328bdd1243dSDimitry Andric   return true;
329bdd1243dSDimitry Andric }
330bdd1243dSDimitry Andric 
3310b57cec5SDimitry Andric // The rest are simple getters that hide the implementation.
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric // getDirection - Returns the direction associated with a particular level.
3340b57cec5SDimitry Andric unsigned FullDependence::getDirection(unsigned Level) const {
3350b57cec5SDimitry Andric   assert(0 < Level && Level <= Levels && "Level out of range");
3360b57cec5SDimitry Andric   return DV[Level - 1].Direction;
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric // Returns the distance (or NULL) associated with a particular level.
3410b57cec5SDimitry Andric const SCEV *FullDependence::getDistance(unsigned Level) const {
3420b57cec5SDimitry Andric   assert(0 < Level && Level <= Levels && "Level out of range");
3430b57cec5SDimitry Andric   return DV[Level - 1].Distance;
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric // Returns true if a particular level is scalar; that is,
3480b57cec5SDimitry Andric // if no subscript in the source or destination mention the induction
3490b57cec5SDimitry Andric // variable associated with the loop at this level.
3500b57cec5SDimitry Andric bool FullDependence::isScalar(unsigned Level) const {
3510b57cec5SDimitry Andric   assert(0 < Level && Level <= Levels && "Level out of range");
3520b57cec5SDimitry Andric   return DV[Level - 1].Scalar;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric // Returns true if peeling the first iteration from this loop
3570b57cec5SDimitry Andric // will break this dependence.
3580b57cec5SDimitry Andric bool FullDependence::isPeelFirst(unsigned Level) const {
3590b57cec5SDimitry Andric   assert(0 < Level && Level <= Levels && "Level out of range");
3600b57cec5SDimitry Andric   return DV[Level - 1].PeelFirst;
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric // Returns true if peeling the last iteration from this loop
3650b57cec5SDimitry Andric // will break this dependence.
3660b57cec5SDimitry Andric bool FullDependence::isPeelLast(unsigned Level) const {
3670b57cec5SDimitry Andric   assert(0 < Level && Level <= Levels && "Level out of range");
3680b57cec5SDimitry Andric   return DV[Level - 1].PeelLast;
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric // Returns true if splitting this loop will break the dependence.
3730b57cec5SDimitry Andric bool FullDependence::isSplitable(unsigned Level) const {
3740b57cec5SDimitry Andric   assert(0 < Level && Level <= Levels && "Level out of range");
3750b57cec5SDimitry Andric   return DV[Level - 1].Splitable;
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3800b57cec5SDimitry Andric // DependenceInfo::Constraint methods
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric // If constraint is a point <X, Y>, returns X.
3830b57cec5SDimitry Andric // Otherwise assert.
3840b57cec5SDimitry Andric const SCEV *DependenceInfo::Constraint::getX() const {
3850b57cec5SDimitry Andric   assert(Kind == Point && "Kind should be Point");
3860b57cec5SDimitry Andric   return A;
3870b57cec5SDimitry Andric }
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric // If constraint is a point <X, Y>, returns Y.
3910b57cec5SDimitry Andric // Otherwise assert.
3920b57cec5SDimitry Andric const SCEV *DependenceInfo::Constraint::getY() const {
3930b57cec5SDimitry Andric   assert(Kind == Point && "Kind should be Point");
3940b57cec5SDimitry Andric   return B;
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric // If constraint is a line AX + BY = C, returns A.
3990b57cec5SDimitry Andric // Otherwise assert.
4000b57cec5SDimitry Andric const SCEV *DependenceInfo::Constraint::getA() const {
4010b57cec5SDimitry Andric   assert((Kind == Line || Kind == Distance) &&
4020b57cec5SDimitry Andric          "Kind should be Line (or Distance)");
4030b57cec5SDimitry Andric   return A;
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric // If constraint is a line AX + BY = C, returns B.
4080b57cec5SDimitry Andric // Otherwise assert.
4090b57cec5SDimitry Andric const SCEV *DependenceInfo::Constraint::getB() const {
4100b57cec5SDimitry Andric   assert((Kind == Line || Kind == Distance) &&
4110b57cec5SDimitry Andric          "Kind should be Line (or Distance)");
4120b57cec5SDimitry Andric   return B;
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric // If constraint is a line AX + BY = C, returns C.
4170b57cec5SDimitry Andric // Otherwise assert.
4180b57cec5SDimitry Andric const SCEV *DependenceInfo::Constraint::getC() const {
4190b57cec5SDimitry Andric   assert((Kind == Line || Kind == Distance) &&
4200b57cec5SDimitry Andric          "Kind should be Line (or Distance)");
4210b57cec5SDimitry Andric   return C;
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric // If constraint is a distance, returns D.
4260b57cec5SDimitry Andric // Otherwise assert.
4270b57cec5SDimitry Andric const SCEV *DependenceInfo::Constraint::getD() const {
4280b57cec5SDimitry Andric   assert(Kind == Distance && "Kind should be Distance");
4290b57cec5SDimitry Andric   return SE->getNegativeSCEV(C);
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric // Returns the loop associated with this constraint.
4340b57cec5SDimitry Andric const Loop *DependenceInfo::Constraint::getAssociatedLoop() const {
4350b57cec5SDimitry Andric   assert((Kind == Distance || Kind == Line || Kind == Point) &&
4360b57cec5SDimitry Andric          "Kind should be Distance, Line, or Point");
4370b57cec5SDimitry Andric   return AssociatedLoop;
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric void DependenceInfo::Constraint::setPoint(const SCEV *X, const SCEV *Y,
4410b57cec5SDimitry Andric                                           const Loop *CurLoop) {
4420b57cec5SDimitry Andric   Kind = Point;
4430b57cec5SDimitry Andric   A = X;
4440b57cec5SDimitry Andric   B = Y;
4450b57cec5SDimitry Andric   AssociatedLoop = CurLoop;
4460b57cec5SDimitry Andric }
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric void DependenceInfo::Constraint::setLine(const SCEV *AA, const SCEV *BB,
4490b57cec5SDimitry Andric                                          const SCEV *CC, const Loop *CurLoop) {
4500b57cec5SDimitry Andric   Kind = Line;
4510b57cec5SDimitry Andric   A = AA;
4520b57cec5SDimitry Andric   B = BB;
4530b57cec5SDimitry Andric   C = CC;
4540b57cec5SDimitry Andric   AssociatedLoop = CurLoop;
4550b57cec5SDimitry Andric }
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric void DependenceInfo::Constraint::setDistance(const SCEV *D,
4580b57cec5SDimitry Andric                                              const Loop *CurLoop) {
4590b57cec5SDimitry Andric   Kind = Distance;
4600b57cec5SDimitry Andric   A = SE->getOne(D->getType());
4610b57cec5SDimitry Andric   B = SE->getNegativeSCEV(A);
4620b57cec5SDimitry Andric   C = SE->getNegativeSCEV(D);
4630b57cec5SDimitry Andric   AssociatedLoop = CurLoop;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric void DependenceInfo::Constraint::setEmpty() { Kind = Empty; }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
4690b57cec5SDimitry Andric   SE = NewSE;
4700b57cec5SDimitry Andric   Kind = Any;
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4740b57cec5SDimitry Andric // For debugging purposes. Dumps the constraint out to OS.
4750b57cec5SDimitry Andric LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS) const {
4760b57cec5SDimitry Andric   if (isEmpty())
4770b57cec5SDimitry Andric     OS << " Empty\n";
4780b57cec5SDimitry Andric   else if (isAny())
4790b57cec5SDimitry Andric     OS << " Any\n";
4800b57cec5SDimitry Andric   else if (isPoint())
4810b57cec5SDimitry Andric     OS << " Point is <" << *getX() << ", " << *getY() << ">\n";
4820b57cec5SDimitry Andric   else if (isDistance())
4830b57cec5SDimitry Andric     OS << " Distance is " << *getD() <<
4840b57cec5SDimitry Andric       " (" << *getA() << "*X + " << *getB() << "*Y = " << *getC() << ")\n";
4850b57cec5SDimitry Andric   else if (isLine())
4860b57cec5SDimitry Andric     OS << " Line is " << *getA() << "*X + " <<
4870b57cec5SDimitry Andric       *getB() << "*Y = " << *getC() << "\n";
4880b57cec5SDimitry Andric   else
4890b57cec5SDimitry Andric     llvm_unreachable("unknown constraint type in Constraint::dump");
4900b57cec5SDimitry Andric }
4910b57cec5SDimitry Andric #endif
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric // Updates X with the intersection
4950b57cec5SDimitry Andric // of the Constraints X and Y. Returns true if X has changed.
4960b57cec5SDimitry Andric // Corresponds to Figure 4 from the paper
4970b57cec5SDimitry Andric //
4980b57cec5SDimitry Andric //            Practical Dependence Testing
4990b57cec5SDimitry Andric //            Goff, Kennedy, Tseng
5000b57cec5SDimitry Andric //            PLDI 1991
5010b57cec5SDimitry Andric bool DependenceInfo::intersectConstraints(Constraint *X, const Constraint *Y) {
5020b57cec5SDimitry Andric   ++DeltaApplications;
5030b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tintersect constraints\n");
5040b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    X ="; X->dump(dbgs()));
5050b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Y ="; Y->dump(dbgs()));
5060b57cec5SDimitry Andric   assert(!Y->isPoint() && "Y must not be a Point");
5070b57cec5SDimitry Andric   if (X->isAny()) {
5080b57cec5SDimitry Andric     if (Y->isAny())
5090b57cec5SDimitry Andric       return false;
5100b57cec5SDimitry Andric     *X = *Y;
5110b57cec5SDimitry Andric     return true;
5120b57cec5SDimitry Andric   }
5130b57cec5SDimitry Andric   if (X->isEmpty())
5140b57cec5SDimitry Andric     return false;
5150b57cec5SDimitry Andric   if (Y->isEmpty()) {
5160b57cec5SDimitry Andric     X->setEmpty();
5170b57cec5SDimitry Andric     return true;
5180b57cec5SDimitry Andric   }
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   if (X->isDistance() && Y->isDistance()) {
5210b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    intersect 2 distances\n");
5220b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, X->getD(), Y->getD()))
5230b57cec5SDimitry Andric       return false;
5240b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_NE, X->getD(), Y->getD())) {
5250b57cec5SDimitry Andric       X->setEmpty();
5260b57cec5SDimitry Andric       ++DeltaSuccesses;
5270b57cec5SDimitry Andric       return true;
5280b57cec5SDimitry Andric     }
5290b57cec5SDimitry Andric     // Hmmm, interesting situation.
5300b57cec5SDimitry Andric     // I guess if either is constant, keep it and ignore the other.
5310b57cec5SDimitry Andric     if (isa<SCEVConstant>(Y->getD())) {
5320b57cec5SDimitry Andric       *X = *Y;
5330b57cec5SDimitry Andric       return true;
5340b57cec5SDimitry Andric     }
5350b57cec5SDimitry Andric     return false;
5360b57cec5SDimitry Andric   }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   // At this point, the pseudo-code in Figure 4 of the paper
5390b57cec5SDimitry Andric   // checks if (X->isPoint() && Y->isPoint()).
5400b57cec5SDimitry Andric   // This case can't occur in our implementation,
5410b57cec5SDimitry Andric   // since a Point can only arise as the result of intersecting
5420b57cec5SDimitry Andric   // two Line constraints, and the right-hand value, Y, is never
5430b57cec5SDimitry Andric   // the result of an intersection.
5440b57cec5SDimitry Andric   assert(!(X->isPoint() && Y->isPoint()) &&
5450b57cec5SDimitry Andric          "We shouldn't ever see X->isPoint() && Y->isPoint()");
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   if (X->isLine() && Y->isLine()) {
5480b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    intersect 2 lines\n");
5490b57cec5SDimitry Andric     const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
5500b57cec5SDimitry Andric     const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
5510b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2)) {
5520b57cec5SDimitry Andric       // slopes are equal, so lines are parallel
5530b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tsame slope\n");
5540b57cec5SDimitry Andric       Prod1 = SE->getMulExpr(X->getC(), Y->getB());
5550b57cec5SDimitry Andric       Prod2 = SE->getMulExpr(X->getB(), Y->getC());
5560b57cec5SDimitry Andric       if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2))
5570b57cec5SDimitry Andric         return false;
5580b57cec5SDimitry Andric       if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
5590b57cec5SDimitry Andric         X->setEmpty();
5600b57cec5SDimitry Andric         ++DeltaSuccesses;
5610b57cec5SDimitry Andric         return true;
5620b57cec5SDimitry Andric       }
5630b57cec5SDimitry Andric       return false;
5640b57cec5SDimitry Andric     }
5650b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
5660b57cec5SDimitry Andric       // slopes differ, so lines intersect
5670b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tdifferent slopes\n");
5680b57cec5SDimitry Andric       const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
5690b57cec5SDimitry Andric       const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
5700b57cec5SDimitry Andric       const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
5710b57cec5SDimitry Andric       const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->getA());
5720b57cec5SDimitry Andric       const SCEV *A1B2 = SE->getMulExpr(X->getA(), Y->getB());
5730b57cec5SDimitry Andric       const SCEV *A2B1 = SE->getMulExpr(Y->getA(), X->getB());
5740b57cec5SDimitry Andric       const SCEVConstant *C1A2_C2A1 =
5750b57cec5SDimitry Andric         dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1A2, C2A1));
5760b57cec5SDimitry Andric       const SCEVConstant *C1B2_C2B1 =
5770b57cec5SDimitry Andric         dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1B2, C2B1));
5780b57cec5SDimitry Andric       const SCEVConstant *A1B2_A2B1 =
5790b57cec5SDimitry Andric         dyn_cast<SCEVConstant>(SE->getMinusSCEV(A1B2, A2B1));
5800b57cec5SDimitry Andric       const SCEVConstant *A2B1_A1B2 =
5810b57cec5SDimitry Andric         dyn_cast<SCEVConstant>(SE->getMinusSCEV(A2B1, A1B2));
5820b57cec5SDimitry Andric       if (!C1B2_C2B1 || !C1A2_C2A1 ||
5830b57cec5SDimitry Andric           !A1B2_A2B1 || !A2B1_A1B2)
5840b57cec5SDimitry Andric         return false;
5850b57cec5SDimitry Andric       APInt Xtop = C1B2_C2B1->getAPInt();
5860b57cec5SDimitry Andric       APInt Xbot = A1B2_A2B1->getAPInt();
5870b57cec5SDimitry Andric       APInt Ytop = C1A2_C2A1->getAPInt();
5880b57cec5SDimitry Andric       APInt Ybot = A2B1_A1B2->getAPInt();
5890b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tXtop = " << Xtop << "\n");
5900b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tXbot = " << Xbot << "\n");
5910b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tYtop = " << Ytop << "\n");
5920b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tYbot = " << Ybot << "\n");
5930b57cec5SDimitry Andric       APInt Xq = Xtop; // these need to be initialized, even
5940b57cec5SDimitry Andric       APInt Xr = Xtop; // though they're just going to be overwritten
5950b57cec5SDimitry Andric       APInt::sdivrem(Xtop, Xbot, Xq, Xr);
5960b57cec5SDimitry Andric       APInt Yq = Ytop;
5970b57cec5SDimitry Andric       APInt Yr = Ytop;
5980b57cec5SDimitry Andric       APInt::sdivrem(Ytop, Ybot, Yq, Yr);
5990b57cec5SDimitry Andric       if (Xr != 0 || Yr != 0) {
6000b57cec5SDimitry Andric         X->setEmpty();
6010b57cec5SDimitry Andric         ++DeltaSuccesses;
6020b57cec5SDimitry Andric         return true;
6030b57cec5SDimitry Andric       }
6040b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t\tX = " << Xq << ", Y = " << Yq << "\n");
6050b57cec5SDimitry Andric       if (Xq.slt(0) || Yq.slt(0)) {
6060b57cec5SDimitry Andric         X->setEmpty();
6070b57cec5SDimitry Andric         ++DeltaSuccesses;
6080b57cec5SDimitry Andric         return true;
6090b57cec5SDimitry Andric       }
6100b57cec5SDimitry Andric       if (const SCEVConstant *CUB =
6110b57cec5SDimitry Andric           collectConstantUpperBound(X->getAssociatedLoop(), Prod1->getType())) {
6120b57cec5SDimitry Andric         const APInt &UpperBound = CUB->getAPInt();
6130b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t\tupper bound = " << UpperBound << "\n");
6140b57cec5SDimitry Andric         if (Xq.sgt(UpperBound) || Yq.sgt(UpperBound)) {
6150b57cec5SDimitry Andric           X->setEmpty();
6160b57cec5SDimitry Andric           ++DeltaSuccesses;
6170b57cec5SDimitry Andric           return true;
6180b57cec5SDimitry Andric         }
6190b57cec5SDimitry Andric       }
6200b57cec5SDimitry Andric       X->setPoint(SE->getConstant(Xq),
6210b57cec5SDimitry Andric                   SE->getConstant(Yq),
6220b57cec5SDimitry Andric                   X->getAssociatedLoop());
6230b57cec5SDimitry Andric       ++DeltaSuccesses;
6240b57cec5SDimitry Andric       return true;
6250b57cec5SDimitry Andric     }
6260b57cec5SDimitry Andric     return false;
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   // if (X->isLine() && Y->isPoint()) This case can't occur.
6300b57cec5SDimitry Andric   assert(!(X->isLine() && Y->isPoint()) && "This case should never occur");
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   if (X->isPoint() && Y->isLine()) {
6330b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    intersect Point and Line\n");
6340b57cec5SDimitry Andric     const SCEV *A1X1 = SE->getMulExpr(Y->getA(), X->getX());
6350b57cec5SDimitry Andric     const SCEV *B1Y1 = SE->getMulExpr(Y->getB(), X->getY());
6360b57cec5SDimitry Andric     const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
6370b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, Sum, Y->getC()))
6380b57cec5SDimitry Andric       return false;
6390b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_NE, Sum, Y->getC())) {
6400b57cec5SDimitry Andric       X->setEmpty();
6410b57cec5SDimitry Andric       ++DeltaSuccesses;
6420b57cec5SDimitry Andric       return true;
6430b57cec5SDimitry Andric     }
6440b57cec5SDimitry Andric     return false;
6450b57cec5SDimitry Andric   }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric   llvm_unreachable("shouldn't reach the end of Constraint intersection");
6480b57cec5SDimitry Andric   return false;
6490b57cec5SDimitry Andric }
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6530b57cec5SDimitry Andric // DependenceInfo methods
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric // For debugging purposes. Dumps a dependence to OS.
6560b57cec5SDimitry Andric void Dependence::dump(raw_ostream &OS) const {
6570b57cec5SDimitry Andric   bool Splitable = false;
6580b57cec5SDimitry Andric   if (isConfused())
6590b57cec5SDimitry Andric     OS << "confused";
6600b57cec5SDimitry Andric   else {
6610b57cec5SDimitry Andric     if (isConsistent())
6620b57cec5SDimitry Andric       OS << "consistent ";
6630b57cec5SDimitry Andric     if (isFlow())
6640b57cec5SDimitry Andric       OS << "flow";
6650b57cec5SDimitry Andric     else if (isOutput())
6660b57cec5SDimitry Andric       OS << "output";
6670b57cec5SDimitry Andric     else if (isAnti())
6680b57cec5SDimitry Andric       OS << "anti";
6690b57cec5SDimitry Andric     else if (isInput())
6700b57cec5SDimitry Andric       OS << "input";
6710b57cec5SDimitry Andric     unsigned Levels = getLevels();
6720b57cec5SDimitry Andric     OS << " [";
6730b57cec5SDimitry Andric     for (unsigned II = 1; II <= Levels; ++II) {
6740b57cec5SDimitry Andric       if (isSplitable(II))
6750b57cec5SDimitry Andric         Splitable = true;
6760b57cec5SDimitry Andric       if (isPeelFirst(II))
6770b57cec5SDimitry Andric         OS << 'p';
6780b57cec5SDimitry Andric       const SCEV *Distance = getDistance(II);
6790b57cec5SDimitry Andric       if (Distance)
6800b57cec5SDimitry Andric         OS << *Distance;
6810b57cec5SDimitry Andric       else if (isScalar(II))
6820b57cec5SDimitry Andric         OS << "S";
6830b57cec5SDimitry Andric       else {
6840b57cec5SDimitry Andric         unsigned Direction = getDirection(II);
6850b57cec5SDimitry Andric         if (Direction == DVEntry::ALL)
6860b57cec5SDimitry Andric           OS << "*";
6870b57cec5SDimitry Andric         else {
6880b57cec5SDimitry Andric           if (Direction & DVEntry::LT)
6890b57cec5SDimitry Andric             OS << "<";
6900b57cec5SDimitry Andric           if (Direction & DVEntry::EQ)
6910b57cec5SDimitry Andric             OS << "=";
6920b57cec5SDimitry Andric           if (Direction & DVEntry::GT)
6930b57cec5SDimitry Andric             OS << ">";
6940b57cec5SDimitry Andric         }
6950b57cec5SDimitry Andric       }
6960b57cec5SDimitry Andric       if (isPeelLast(II))
6970b57cec5SDimitry Andric         OS << 'p';
6980b57cec5SDimitry Andric       if (II < Levels)
6990b57cec5SDimitry Andric         OS << " ";
7000b57cec5SDimitry Andric     }
7010b57cec5SDimitry Andric     if (isLoopIndependent())
7020b57cec5SDimitry Andric       OS << "|<";
7030b57cec5SDimitry Andric     OS << "]";
7040b57cec5SDimitry Andric     if (Splitable)
7050b57cec5SDimitry Andric       OS << " splitable";
7060b57cec5SDimitry Andric   }
7070b57cec5SDimitry Andric   OS << "!\n";
7080b57cec5SDimitry Andric }
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric // Returns NoAlias/MayAliass/MustAlias for two memory locations based upon their
7110b57cec5SDimitry Andric // underlaying objects. If LocA and LocB are known to not alias (for any reason:
7120b57cec5SDimitry Andric // tbaa, non-overlapping regions etc), then it is known there is no dependecy.
7130b57cec5SDimitry Andric // Otherwise the underlying objects are checked to see if they point to
7140b57cec5SDimitry Andric // different identifiable objects.
7155ffd83dbSDimitry Andric static AliasResult underlyingObjectsAlias(AAResults *AA,
7160b57cec5SDimitry Andric                                           const DataLayout &DL,
7170b57cec5SDimitry Andric                                           const MemoryLocation &LocA,
7180b57cec5SDimitry Andric                                           const MemoryLocation &LocB) {
7190b57cec5SDimitry Andric   // Check the original locations (minus size) for noalias, which can happen for
7200b57cec5SDimitry Andric   // tbaa, incompatible underlying object locations, etc.
721e8d8bef9SDimitry Andric   MemoryLocation LocAS =
722e8d8bef9SDimitry Andric       MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
723e8d8bef9SDimitry Andric   MemoryLocation LocBS =
724e8d8bef9SDimitry Andric       MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
725fe6060f1SDimitry Andric   if (AA->isNoAlias(LocAS, LocBS))
726fe6060f1SDimitry Andric     return AliasResult::NoAlias;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   // Check the underlying objects are the same
729e8d8bef9SDimitry Andric   const Value *AObj = getUnderlyingObject(LocA.Ptr);
730e8d8bef9SDimitry Andric   const Value *BObj = getUnderlyingObject(LocB.Ptr);
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric   // If the underlying objects are the same, they must alias
7330b57cec5SDimitry Andric   if (AObj == BObj)
734fe6060f1SDimitry Andric     return AliasResult::MustAlias;
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   // We may have hit the recursion limit for underlying objects, or have
7370b57cec5SDimitry Andric   // underlying objects where we don't know they will alias.
7380b57cec5SDimitry Andric   if (!isIdentifiedObject(AObj) || !isIdentifiedObject(BObj))
739fe6060f1SDimitry Andric     return AliasResult::MayAlias;
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric   // Otherwise we know the objects are different and both identified objects so
7420b57cec5SDimitry Andric   // must not alias.
743fe6060f1SDimitry Andric   return AliasResult::NoAlias;
7440b57cec5SDimitry Andric }
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric // Returns true if the load or store can be analyzed. Atomic and volatile
7480b57cec5SDimitry Andric // operations have properties which this analysis does not understand.
7490b57cec5SDimitry Andric static
7500b57cec5SDimitry Andric bool isLoadOrStore(const Instruction *I) {
7510b57cec5SDimitry Andric   if (const LoadInst *LI = dyn_cast<LoadInst>(I))
7520b57cec5SDimitry Andric     return LI->isUnordered();
7530b57cec5SDimitry Andric   else if (const StoreInst *SI = dyn_cast<StoreInst>(I))
7540b57cec5SDimitry Andric     return SI->isUnordered();
7550b57cec5SDimitry Andric   return false;
7560b57cec5SDimitry Andric }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric // Examines the loop nesting of the Src and Dst
7600b57cec5SDimitry Andric // instructions and establishes their shared loops. Sets the variables
7610b57cec5SDimitry Andric // CommonLevels, SrcLevels, and MaxLevels.
7620b57cec5SDimitry Andric // The source and destination instructions needn't be contained in the same
7630b57cec5SDimitry Andric // loop. The routine establishNestingLevels finds the level of most deeply
7640b57cec5SDimitry Andric // nested loop that contains them both, CommonLevels. An instruction that's
7650b57cec5SDimitry Andric // not contained in a loop is at level = 0. MaxLevels is equal to the level
7660b57cec5SDimitry Andric // of the source plus the level of the destination, minus CommonLevels.
7670b57cec5SDimitry Andric // This lets us allocate vectors MaxLevels in length, with room for every
7680b57cec5SDimitry Andric // distinct loop referenced in both the source and destination subscripts.
7690b57cec5SDimitry Andric // The variable SrcLevels is the nesting depth of the source instruction.
7700b57cec5SDimitry Andric // It's used to help calculate distinct loops referenced by the destination.
7710b57cec5SDimitry Andric // Here's the map from loops to levels:
7720b57cec5SDimitry Andric //            0 - unused
7730b57cec5SDimitry Andric //            1 - outermost common loop
7740b57cec5SDimitry Andric //          ... - other common loops
7750b57cec5SDimitry Andric // CommonLevels - innermost common loop
7760b57cec5SDimitry Andric //          ... - loops containing Src but not Dst
7770b57cec5SDimitry Andric //    SrcLevels - innermost loop containing Src but not Dst
7780b57cec5SDimitry Andric //          ... - loops containing Dst but not Src
7790b57cec5SDimitry Andric //    MaxLevels - innermost loops containing Dst but not Src
7800b57cec5SDimitry Andric // Consider the follow code fragment:
7810b57cec5SDimitry Andric //   for (a = ...) {
7820b57cec5SDimitry Andric //     for (b = ...) {
7830b57cec5SDimitry Andric //       for (c = ...) {
7840b57cec5SDimitry Andric //         for (d = ...) {
7850b57cec5SDimitry Andric //           A[] = ...;
7860b57cec5SDimitry Andric //         }
7870b57cec5SDimitry Andric //       }
7880b57cec5SDimitry Andric //       for (e = ...) {
7890b57cec5SDimitry Andric //         for (f = ...) {
7900b57cec5SDimitry Andric //           for (g = ...) {
7910b57cec5SDimitry Andric //             ... = A[];
7920b57cec5SDimitry Andric //           }
7930b57cec5SDimitry Andric //         }
7940b57cec5SDimitry Andric //       }
7950b57cec5SDimitry Andric //     }
7960b57cec5SDimitry Andric //   }
7970b57cec5SDimitry Andric // If we're looking at the possibility of a dependence between the store
7980b57cec5SDimitry Andric // to A (the Src) and the load from A (the Dst), we'll note that they
7990b57cec5SDimitry Andric // have 2 loops in common, so CommonLevels will equal 2 and the direction
8000b57cec5SDimitry Andric // vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
8010b57cec5SDimitry Andric // A map from loop names to loop numbers would look like
8020b57cec5SDimitry Andric //     a - 1
8030b57cec5SDimitry Andric //     b - 2 = CommonLevels
8040b57cec5SDimitry Andric //     c - 3
8050b57cec5SDimitry Andric //     d - 4 = SrcLevels
8060b57cec5SDimitry Andric //     e - 5
8070b57cec5SDimitry Andric //     f - 6
8080b57cec5SDimitry Andric //     g - 7 = MaxLevels
8090b57cec5SDimitry Andric void DependenceInfo::establishNestingLevels(const Instruction *Src,
8100b57cec5SDimitry Andric                                             const Instruction *Dst) {
8110b57cec5SDimitry Andric   const BasicBlock *SrcBlock = Src->getParent();
8120b57cec5SDimitry Andric   const BasicBlock *DstBlock = Dst->getParent();
8130b57cec5SDimitry Andric   unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
8140b57cec5SDimitry Andric   unsigned DstLevel = LI->getLoopDepth(DstBlock);
8150b57cec5SDimitry Andric   const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
8160b57cec5SDimitry Andric   const Loop *DstLoop = LI->getLoopFor(DstBlock);
8170b57cec5SDimitry Andric   SrcLevels = SrcLevel;
8180b57cec5SDimitry Andric   MaxLevels = SrcLevel + DstLevel;
8190b57cec5SDimitry Andric   while (SrcLevel > DstLevel) {
8200b57cec5SDimitry Andric     SrcLoop = SrcLoop->getParentLoop();
8210b57cec5SDimitry Andric     SrcLevel--;
8220b57cec5SDimitry Andric   }
8230b57cec5SDimitry Andric   while (DstLevel > SrcLevel) {
8240b57cec5SDimitry Andric     DstLoop = DstLoop->getParentLoop();
8250b57cec5SDimitry Andric     DstLevel--;
8260b57cec5SDimitry Andric   }
8270b57cec5SDimitry Andric   while (SrcLoop != DstLoop) {
8280b57cec5SDimitry Andric     SrcLoop = SrcLoop->getParentLoop();
8290b57cec5SDimitry Andric     DstLoop = DstLoop->getParentLoop();
8300b57cec5SDimitry Andric     SrcLevel--;
8310b57cec5SDimitry Andric   }
8320b57cec5SDimitry Andric   CommonLevels = SrcLevel;
8330b57cec5SDimitry Andric   MaxLevels -= CommonLevels;
8340b57cec5SDimitry Andric }
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric // Given one of the loops containing the source, return
8380b57cec5SDimitry Andric // its level index in our numbering scheme.
8390b57cec5SDimitry Andric unsigned DependenceInfo::mapSrcLoop(const Loop *SrcLoop) const {
8400b57cec5SDimitry Andric   return SrcLoop->getLoopDepth();
8410b57cec5SDimitry Andric }
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric // Given one of the loops containing the destination,
8450b57cec5SDimitry Andric // return its level index in our numbering scheme.
8460b57cec5SDimitry Andric unsigned DependenceInfo::mapDstLoop(const Loop *DstLoop) const {
8470b57cec5SDimitry Andric   unsigned D = DstLoop->getLoopDepth();
8480b57cec5SDimitry Andric   if (D > CommonLevels)
84981ad6265SDimitry Andric     // This tries to make sure that we assign unique numbers to src and dst when
85081ad6265SDimitry Andric     // the memory accesses reside in different loops that have the same depth.
8510b57cec5SDimitry Andric     return D - CommonLevels + SrcLevels;
8520b57cec5SDimitry Andric   else
8530b57cec5SDimitry Andric     return D;
8540b57cec5SDimitry Andric }
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric // Returns true if Expression is loop invariant in LoopNest.
8580b57cec5SDimitry Andric bool DependenceInfo::isLoopInvariant(const SCEV *Expression,
8590b57cec5SDimitry Andric                                      const Loop *LoopNest) const {
86081ad6265SDimitry Andric   // Unlike ScalarEvolution::isLoopInvariant() we consider an access outside of
86181ad6265SDimitry Andric   // any loop as invariant, because we only consier expression evaluation at a
86281ad6265SDimitry Andric   // specific position (where the array access takes place), and not across the
86381ad6265SDimitry Andric   // entire function.
8640b57cec5SDimitry Andric   if (!LoopNest)
8650b57cec5SDimitry Andric     return true;
86681ad6265SDimitry Andric 
86781ad6265SDimitry Andric   // If the expression is invariant in the outermost loop of the loop nest, it
86881ad6265SDimitry Andric   // is invariant anywhere in the loop nest.
86981ad6265SDimitry Andric   return SE->isLoopInvariant(Expression, LoopNest->getOutermostLoop());
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric 
8730b57cec5SDimitry Andric 
8740b57cec5SDimitry Andric // Finds the set of loops from the LoopNest that
8750b57cec5SDimitry Andric // have a level <= CommonLevels and are referred to by the SCEV Expression.
8760b57cec5SDimitry Andric void DependenceInfo::collectCommonLoops(const SCEV *Expression,
8770b57cec5SDimitry Andric                                         const Loop *LoopNest,
8780b57cec5SDimitry Andric                                         SmallBitVector &Loops) const {
8790b57cec5SDimitry Andric   while (LoopNest) {
8800b57cec5SDimitry Andric     unsigned Level = LoopNest->getLoopDepth();
8810b57cec5SDimitry Andric     if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
8820b57cec5SDimitry Andric       Loops.set(Level);
8830b57cec5SDimitry Andric     LoopNest = LoopNest->getParentLoop();
8840b57cec5SDimitry Andric   }
8850b57cec5SDimitry Andric }
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric void DependenceInfo::unifySubscriptType(ArrayRef<Subscript *> Pairs) {
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   unsigned widestWidthSeen = 0;
8900b57cec5SDimitry Andric   Type *widestType;
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   // Go through each pair and find the widest bit to which we need
8930b57cec5SDimitry Andric   // to extend all of them.
8940b57cec5SDimitry Andric   for (Subscript *Pair : Pairs) {
8950b57cec5SDimitry Andric     const SCEV *Src = Pair->Src;
8960b57cec5SDimitry Andric     const SCEV *Dst = Pair->Dst;
8970b57cec5SDimitry Andric     IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
8980b57cec5SDimitry Andric     IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
8990b57cec5SDimitry Andric     if (SrcTy == nullptr || DstTy == nullptr) {
9000b57cec5SDimitry Andric       assert(SrcTy == DstTy && "This function only unify integer types and "
9010b57cec5SDimitry Andric              "expect Src and Dst share the same type "
9020b57cec5SDimitry Andric              "otherwise.");
9030b57cec5SDimitry Andric       continue;
9040b57cec5SDimitry Andric     }
9050b57cec5SDimitry Andric     if (SrcTy->getBitWidth() > widestWidthSeen) {
9060b57cec5SDimitry Andric       widestWidthSeen = SrcTy->getBitWidth();
9070b57cec5SDimitry Andric       widestType = SrcTy;
9080b57cec5SDimitry Andric     }
9090b57cec5SDimitry Andric     if (DstTy->getBitWidth() > widestWidthSeen) {
9100b57cec5SDimitry Andric       widestWidthSeen = DstTy->getBitWidth();
9110b57cec5SDimitry Andric       widestType = DstTy;
9120b57cec5SDimitry Andric     }
9130b57cec5SDimitry Andric   }
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   assert(widestWidthSeen > 0);
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric   // Now extend each pair to the widest seen.
9190b57cec5SDimitry Andric   for (Subscript *Pair : Pairs) {
9200b57cec5SDimitry Andric     const SCEV *Src = Pair->Src;
9210b57cec5SDimitry Andric     const SCEV *Dst = Pair->Dst;
9220b57cec5SDimitry Andric     IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
9230b57cec5SDimitry Andric     IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
9240b57cec5SDimitry Andric     if (SrcTy == nullptr || DstTy == nullptr) {
9250b57cec5SDimitry Andric       assert(SrcTy == DstTy && "This function only unify integer types and "
9260b57cec5SDimitry Andric              "expect Src and Dst share the same type "
9270b57cec5SDimitry Andric              "otherwise.");
9280b57cec5SDimitry Andric       continue;
9290b57cec5SDimitry Andric     }
9300b57cec5SDimitry Andric     if (SrcTy->getBitWidth() < widestWidthSeen)
9310b57cec5SDimitry Andric       // Sign-extend Src to widestType
9320b57cec5SDimitry Andric       Pair->Src = SE->getSignExtendExpr(Src, widestType);
9330b57cec5SDimitry Andric     if (DstTy->getBitWidth() < widestWidthSeen) {
9340b57cec5SDimitry Andric       // Sign-extend Dst to widestType
9350b57cec5SDimitry Andric       Pair->Dst = SE->getSignExtendExpr(Dst, widestType);
9360b57cec5SDimitry Andric     }
9370b57cec5SDimitry Andric   }
9380b57cec5SDimitry Andric }
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric // removeMatchingExtensions - Examines a subscript pair.
9410b57cec5SDimitry Andric // If the source and destination are identically sign (or zero)
9420b57cec5SDimitry Andric // extended, it strips off the extension in an effect to simplify
9430b57cec5SDimitry Andric // the actual analysis.
9440b57cec5SDimitry Andric void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
9450b57cec5SDimitry Andric   const SCEV *Src = Pair->Src;
9460b57cec5SDimitry Andric   const SCEV *Dst = Pair->Dst;
9470b57cec5SDimitry Andric   if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
9480b57cec5SDimitry Andric       (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
949e8d8bef9SDimitry Andric     const SCEVIntegralCastExpr *SrcCast = cast<SCEVIntegralCastExpr>(Src);
950e8d8bef9SDimitry Andric     const SCEVIntegralCastExpr *DstCast = cast<SCEVIntegralCastExpr>(Dst);
9510b57cec5SDimitry Andric     const SCEV *SrcCastOp = SrcCast->getOperand();
9520b57cec5SDimitry Andric     const SCEV *DstCastOp = DstCast->getOperand();
9530b57cec5SDimitry Andric     if (SrcCastOp->getType() == DstCastOp->getType()) {
9540b57cec5SDimitry Andric       Pair->Src = SrcCastOp;
9550b57cec5SDimitry Andric       Pair->Dst = DstCastOp;
9560b57cec5SDimitry Andric     }
9570b57cec5SDimitry Andric   }
9580b57cec5SDimitry Andric }
9590b57cec5SDimitry Andric 
96081ad6265SDimitry Andric // Examine the scev and return true iff it's affine.
961480093f4SDimitry Andric // Collect any loops mentioned in the set of "Loops".
962480093f4SDimitry Andric bool DependenceInfo::checkSubscript(const SCEV *Expr, const Loop *LoopNest,
963480093f4SDimitry Andric                                     SmallBitVector &Loops, bool IsSrc) {
964480093f4SDimitry Andric   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
965480093f4SDimitry Andric   if (!AddRec)
966480093f4SDimitry Andric     return isLoopInvariant(Expr, LoopNest);
96781ad6265SDimitry Andric 
96881ad6265SDimitry Andric   // The AddRec must depend on one of the containing loops. Otherwise,
96981ad6265SDimitry Andric   // mapSrcLoop and mapDstLoop return indices outside the intended range. This
97081ad6265SDimitry Andric   // can happen when a subscript in one loop references an IV from a sibling
97181ad6265SDimitry Andric   // loop that could not be replaced with a concrete exit value by
97281ad6265SDimitry Andric   // getSCEVAtScope.
97381ad6265SDimitry Andric   const Loop *L = LoopNest;
97481ad6265SDimitry Andric   while (L && AddRec->getLoop() != L)
97581ad6265SDimitry Andric     L = L->getParentLoop();
97681ad6265SDimitry Andric   if (!L)
97781ad6265SDimitry Andric     return false;
97881ad6265SDimitry Andric 
979480093f4SDimitry Andric   const SCEV *Start = AddRec->getStart();
980480093f4SDimitry Andric   const SCEV *Step = AddRec->getStepRecurrence(*SE);
981480093f4SDimitry Andric   const SCEV *UB = SE->getBackedgeTakenCount(AddRec->getLoop());
982480093f4SDimitry Andric   if (!isa<SCEVCouldNotCompute>(UB)) {
983480093f4SDimitry Andric     if (SE->getTypeSizeInBits(Start->getType()) <
984480093f4SDimitry Andric         SE->getTypeSizeInBits(UB->getType())) {
985480093f4SDimitry Andric       if (!AddRec->getNoWrapFlags())
986480093f4SDimitry Andric         return false;
987480093f4SDimitry Andric     }
988480093f4SDimitry Andric   }
989480093f4SDimitry Andric   if (!isLoopInvariant(Step, LoopNest))
990480093f4SDimitry Andric     return false;
991480093f4SDimitry Andric   if (IsSrc)
992480093f4SDimitry Andric     Loops.set(mapSrcLoop(AddRec->getLoop()));
993480093f4SDimitry Andric   else
994480093f4SDimitry Andric     Loops.set(mapDstLoop(AddRec->getLoop()));
995480093f4SDimitry Andric   return checkSubscript(Start, LoopNest, Loops, IsSrc);
996480093f4SDimitry Andric }
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric // Examine the scev and return true iff it's linear.
9990b57cec5SDimitry Andric // Collect any loops mentioned in the set of "Loops".
10000b57cec5SDimitry Andric bool DependenceInfo::checkSrcSubscript(const SCEV *Src, const Loop *LoopNest,
10010b57cec5SDimitry Andric                                        SmallBitVector &Loops) {
1002480093f4SDimitry Andric   return checkSubscript(Src, LoopNest, Loops, true);
10030b57cec5SDimitry Andric }
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric // Examine the scev and return true iff it's linear.
10060b57cec5SDimitry Andric // Collect any loops mentioned in the set of "Loops".
10070b57cec5SDimitry Andric bool DependenceInfo::checkDstSubscript(const SCEV *Dst, const Loop *LoopNest,
10080b57cec5SDimitry Andric                                        SmallBitVector &Loops) {
1009480093f4SDimitry Andric   return checkSubscript(Dst, LoopNest, Loops, false);
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric // Examines the subscript pair (the Src and Dst SCEVs)
10140b57cec5SDimitry Andric // and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
10150b57cec5SDimitry Andric // Collects the associated loops in a set.
10160b57cec5SDimitry Andric DependenceInfo::Subscript::ClassificationKind
10170b57cec5SDimitry Andric DependenceInfo::classifyPair(const SCEV *Src, const Loop *SrcLoopNest,
10180b57cec5SDimitry Andric                              const SCEV *Dst, const Loop *DstLoopNest,
10190b57cec5SDimitry Andric                              SmallBitVector &Loops) {
10200b57cec5SDimitry Andric   SmallBitVector SrcLoops(MaxLevels + 1);
10210b57cec5SDimitry Andric   SmallBitVector DstLoops(MaxLevels + 1);
10220b57cec5SDimitry Andric   if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
10230b57cec5SDimitry Andric     return Subscript::NonLinear;
10240b57cec5SDimitry Andric   if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
10250b57cec5SDimitry Andric     return Subscript::NonLinear;
10260b57cec5SDimitry Andric   Loops = SrcLoops;
10270b57cec5SDimitry Andric   Loops |= DstLoops;
10280b57cec5SDimitry Andric   unsigned N = Loops.count();
10290b57cec5SDimitry Andric   if (N == 0)
10300b57cec5SDimitry Andric     return Subscript::ZIV;
10310b57cec5SDimitry Andric   if (N == 1)
10320b57cec5SDimitry Andric     return Subscript::SIV;
10330b57cec5SDimitry Andric   if (N == 2 && (SrcLoops.count() == 0 ||
10340b57cec5SDimitry Andric                  DstLoops.count() == 0 ||
10350b57cec5SDimitry Andric                  (SrcLoops.count() == 1 && DstLoops.count() == 1)))
10360b57cec5SDimitry Andric     return Subscript::RDIV;
10370b57cec5SDimitry Andric   return Subscript::MIV;
10380b57cec5SDimitry Andric }
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric // A wrapper around SCEV::isKnownPredicate.
10420b57cec5SDimitry Andric // Looks for cases where we're interested in comparing for equality.
10430b57cec5SDimitry Andric // If both X and Y have been identically sign or zero extended,
10440b57cec5SDimitry Andric // it strips off the (confusing) extensions before invoking
10450b57cec5SDimitry Andric // SCEV::isKnownPredicate. Perhaps, someday, the ScalarEvolution package
10460b57cec5SDimitry Andric // will be similarly updated.
10470b57cec5SDimitry Andric //
10480b57cec5SDimitry Andric // If SCEV::isKnownPredicate can't prove the predicate,
10490b57cec5SDimitry Andric // we try simple subtraction, which seems to help in some cases
10500b57cec5SDimitry Andric // involving symbolics.
10510b57cec5SDimitry Andric bool DependenceInfo::isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *X,
10520b57cec5SDimitry Andric                                       const SCEV *Y) const {
10530b57cec5SDimitry Andric   if (Pred == CmpInst::ICMP_EQ ||
10540b57cec5SDimitry Andric       Pred == CmpInst::ICMP_NE) {
10550b57cec5SDimitry Andric     if ((isa<SCEVSignExtendExpr>(X) &&
10560b57cec5SDimitry Andric          isa<SCEVSignExtendExpr>(Y)) ||
10570b57cec5SDimitry Andric         (isa<SCEVZeroExtendExpr>(X) &&
10580b57cec5SDimitry Andric          isa<SCEVZeroExtendExpr>(Y))) {
1059e8d8bef9SDimitry Andric       const SCEVIntegralCastExpr *CX = cast<SCEVIntegralCastExpr>(X);
1060e8d8bef9SDimitry Andric       const SCEVIntegralCastExpr *CY = cast<SCEVIntegralCastExpr>(Y);
10610b57cec5SDimitry Andric       const SCEV *Xop = CX->getOperand();
10620b57cec5SDimitry Andric       const SCEV *Yop = CY->getOperand();
10630b57cec5SDimitry Andric       if (Xop->getType() == Yop->getType()) {
10640b57cec5SDimitry Andric         X = Xop;
10650b57cec5SDimitry Andric         Y = Yop;
10660b57cec5SDimitry Andric       }
10670b57cec5SDimitry Andric     }
10680b57cec5SDimitry Andric   }
10690b57cec5SDimitry Andric   if (SE->isKnownPredicate(Pred, X, Y))
10700b57cec5SDimitry Andric     return true;
10710b57cec5SDimitry Andric   // If SE->isKnownPredicate can't prove the condition,
10720b57cec5SDimitry Andric   // we try the brute-force approach of subtracting
10730b57cec5SDimitry Andric   // and testing the difference.
10740b57cec5SDimitry Andric   // By testing with SE->isKnownPredicate first, we avoid
10750b57cec5SDimitry Andric   // the possibility of overflow when the arguments are constants.
10760b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(X, Y);
10770b57cec5SDimitry Andric   switch (Pred) {
10780b57cec5SDimitry Andric   case CmpInst::ICMP_EQ:
10790b57cec5SDimitry Andric     return Delta->isZero();
10800b57cec5SDimitry Andric   case CmpInst::ICMP_NE:
10810b57cec5SDimitry Andric     return SE->isKnownNonZero(Delta);
10820b57cec5SDimitry Andric   case CmpInst::ICMP_SGE:
10830b57cec5SDimitry Andric     return SE->isKnownNonNegative(Delta);
10840b57cec5SDimitry Andric   case CmpInst::ICMP_SLE:
10850b57cec5SDimitry Andric     return SE->isKnownNonPositive(Delta);
10860b57cec5SDimitry Andric   case CmpInst::ICMP_SGT:
10870b57cec5SDimitry Andric     return SE->isKnownPositive(Delta);
10880b57cec5SDimitry Andric   case CmpInst::ICMP_SLT:
10890b57cec5SDimitry Andric     return SE->isKnownNegative(Delta);
10900b57cec5SDimitry Andric   default:
10910b57cec5SDimitry Andric     llvm_unreachable("unexpected predicate in isKnownPredicate");
10920b57cec5SDimitry Andric   }
10930b57cec5SDimitry Andric }
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric /// Compare to see if S is less than Size, using isKnownNegative(S - max(Size, 1))
10960b57cec5SDimitry Andric /// with some extra checking if S is an AddRec and we can prove less-than using
10970b57cec5SDimitry Andric /// the loop bounds.
10980b57cec5SDimitry Andric bool DependenceInfo::isKnownLessThan(const SCEV *S, const SCEV *Size) const {
10990b57cec5SDimitry Andric   // First unify to the same type
11000b57cec5SDimitry Andric   auto *SType = dyn_cast<IntegerType>(S->getType());
11010b57cec5SDimitry Andric   auto *SizeType = dyn_cast<IntegerType>(Size->getType());
11020b57cec5SDimitry Andric   if (!SType || !SizeType)
11030b57cec5SDimitry Andric     return false;
11040b57cec5SDimitry Andric   Type *MaxType =
11050b57cec5SDimitry Andric       (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
11060b57cec5SDimitry Andric   S = SE->getTruncateOrZeroExtend(S, MaxType);
11070b57cec5SDimitry Andric   Size = SE->getTruncateOrZeroExtend(Size, MaxType);
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric   // Special check for addrecs using BE taken count
11100b57cec5SDimitry Andric   const SCEV *Bound = SE->getMinusSCEV(S, Size);
11110b57cec5SDimitry Andric   if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Bound)) {
11120b57cec5SDimitry Andric     if (AddRec->isAffine()) {
11130b57cec5SDimitry Andric       const SCEV *BECount = SE->getBackedgeTakenCount(AddRec->getLoop());
11140b57cec5SDimitry Andric       if (!isa<SCEVCouldNotCompute>(BECount)) {
11150b57cec5SDimitry Andric         const SCEV *Limit = AddRec->evaluateAtIteration(BECount, *SE);
11160b57cec5SDimitry Andric         if (SE->isKnownNegative(Limit))
11170b57cec5SDimitry Andric           return true;
11180b57cec5SDimitry Andric       }
11190b57cec5SDimitry Andric     }
11200b57cec5SDimitry Andric   }
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   // Check using normal isKnownNegative
11230b57cec5SDimitry Andric   const SCEV *LimitedBound =
11240b57cec5SDimitry Andric       SE->getMinusSCEV(S, SE->getSMaxExpr(Size, SE->getOne(Size->getType())));
11250b57cec5SDimitry Andric   return SE->isKnownNegative(LimitedBound);
11260b57cec5SDimitry Andric }
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric bool DependenceInfo::isKnownNonNegative(const SCEV *S, const Value *Ptr) const {
11290b57cec5SDimitry Andric   bool Inbounds = false;
11300b57cec5SDimitry Andric   if (auto *SrcGEP = dyn_cast<GetElementPtrInst>(Ptr))
11310b57cec5SDimitry Andric     Inbounds = SrcGEP->isInBounds();
11320b57cec5SDimitry Andric   if (Inbounds) {
11330b57cec5SDimitry Andric     if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
11340b57cec5SDimitry Andric       if (AddRec->isAffine()) {
11350b57cec5SDimitry Andric         // We know S is for Ptr, the operand on a load/store, so doesn't wrap.
11360b57cec5SDimitry Andric         // If both parts are NonNegative, the end result will be NonNegative
11370b57cec5SDimitry Andric         if (SE->isKnownNonNegative(AddRec->getStart()) &&
11380b57cec5SDimitry Andric             SE->isKnownNonNegative(AddRec->getOperand(1)))
11390b57cec5SDimitry Andric           return true;
11400b57cec5SDimitry Andric       }
11410b57cec5SDimitry Andric     }
11420b57cec5SDimitry Andric   }
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric   return SE->isKnownNonNegative(S);
11450b57cec5SDimitry Andric }
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric // All subscripts are all the same type.
11480b57cec5SDimitry Andric // Loop bound may be smaller (e.g., a char).
11490b57cec5SDimitry Andric // Should zero extend loop bound, since it's always >= 0.
11500b57cec5SDimitry Andric // This routine collects upper bound and extends or truncates if needed.
11510b57cec5SDimitry Andric // Truncating is safe when subscripts are known not to wrap. Cases without
11520b57cec5SDimitry Andric // nowrap flags should have been rejected earlier.
11530b57cec5SDimitry Andric // Return null if no bound available.
11540b57cec5SDimitry Andric const SCEV *DependenceInfo::collectUpperBound(const Loop *L, Type *T) const {
11550b57cec5SDimitry Andric   if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
11560b57cec5SDimitry Andric     const SCEV *UB = SE->getBackedgeTakenCount(L);
11570b57cec5SDimitry Andric     return SE->getTruncateOrZeroExtend(UB, T);
11580b57cec5SDimitry Andric   }
11590b57cec5SDimitry Andric   return nullptr;
11600b57cec5SDimitry Andric }
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric // Calls collectUpperBound(), then attempts to cast it to SCEVConstant.
11640b57cec5SDimitry Andric // If the cast fails, returns NULL.
11650b57cec5SDimitry Andric const SCEVConstant *DependenceInfo::collectConstantUpperBound(const Loop *L,
11660b57cec5SDimitry Andric                                                               Type *T) const {
11670b57cec5SDimitry Andric   if (const SCEV *UB = collectUpperBound(L, T))
11680b57cec5SDimitry Andric     return dyn_cast<SCEVConstant>(UB);
11690b57cec5SDimitry Andric   return nullptr;
11700b57cec5SDimitry Andric }
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric 
11730b57cec5SDimitry Andric // testZIV -
11740b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1] and [c2],
11750b57cec5SDimitry Andric // where c1 and c2 are both loop invariant, we attack it using
11760b57cec5SDimitry Andric // the ZIV test. Basically, we test by comparing the two values,
11770b57cec5SDimitry Andric // but there are actually three possible results:
11780b57cec5SDimitry Andric // 1) the values are equal, so there's a dependence
11790b57cec5SDimitry Andric // 2) the values are different, so there's no dependence
11800b57cec5SDimitry Andric // 3) the values might be equal, so we have to assume a dependence.
11810b57cec5SDimitry Andric //
11820b57cec5SDimitry Andric // Return true if dependence disproved.
11830b57cec5SDimitry Andric bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
11840b57cec5SDimitry Andric                              FullDependence &Result) const {
11850b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
11860b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
11870b57cec5SDimitry Andric   ++ZIVapplications;
11880b57cec5SDimitry Andric   if (isKnownPredicate(CmpInst::ICMP_EQ, Src, Dst)) {
11890b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "    provably dependent\n");
11900b57cec5SDimitry Andric     return false; // provably dependent
11910b57cec5SDimitry Andric   }
11920b57cec5SDimitry Andric   if (isKnownPredicate(CmpInst::ICMP_NE, Src, Dst)) {
11930b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "    provably independent\n");
11940b57cec5SDimitry Andric     ++ZIVindependence;
11950b57cec5SDimitry Andric     return true; // provably independent
11960b57cec5SDimitry Andric   }
11970b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    possibly dependent\n");
11980b57cec5SDimitry Andric   Result.Consistent = false;
11990b57cec5SDimitry Andric   return false; // possibly dependent
12000b57cec5SDimitry Andric }
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric // strongSIVtest -
12040b57cec5SDimitry Andric // From the paper, Practical Dependence Testing, Section 4.2.1
12050b57cec5SDimitry Andric //
12060b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a*i] and [c2 + a*i],
12070b57cec5SDimitry Andric // where i is an induction variable, c1 and c2 are loop invariant,
12080b57cec5SDimitry Andric //  and a is a constant, we can solve it exactly using the Strong SIV test.
12090b57cec5SDimitry Andric //
12100b57cec5SDimitry Andric // Can prove independence. Failing that, can compute distance (and direction).
12110b57cec5SDimitry Andric // In the presence of symbolic terms, we can sometimes make progress.
12120b57cec5SDimitry Andric //
12130b57cec5SDimitry Andric // If there's a dependence,
12140b57cec5SDimitry Andric //
12150b57cec5SDimitry Andric //    c1 + a*i = c2 + a*i'
12160b57cec5SDimitry Andric //
12170b57cec5SDimitry Andric // The dependence distance is
12180b57cec5SDimitry Andric //
12190b57cec5SDimitry Andric //    d = i' - i = (c1 - c2)/a
12200b57cec5SDimitry Andric //
12210b57cec5SDimitry Andric // A dependence only exists if d is an integer and abs(d) <= U, where U is the
12220b57cec5SDimitry Andric // loop's upper bound. If a dependence exists, the dependence direction is
12230b57cec5SDimitry Andric // defined as
12240b57cec5SDimitry Andric //
12250b57cec5SDimitry Andric //                { < if d > 0
12260b57cec5SDimitry Andric //    direction = { = if d = 0
12270b57cec5SDimitry Andric //                { > if d < 0
12280b57cec5SDimitry Andric //
12290b57cec5SDimitry Andric // Return true if dependence disproved.
12300b57cec5SDimitry Andric bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
12310b57cec5SDimitry Andric                                    const SCEV *DstConst, const Loop *CurLoop,
12320b57cec5SDimitry Andric                                    unsigned Level, FullDependence &Result,
12330b57cec5SDimitry Andric                                    Constraint &NewConstraint) const {
12340b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tStrong SIV test\n");
12350b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Coeff = " << *Coeff);
12360b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << ", " << *Coeff->getType() << "\n");
12370b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst);
12380b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << ", " << *SrcConst->getType() << "\n");
12390b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst);
12400b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << ", " << *DstConst->getType() << "\n");
12410b57cec5SDimitry Andric   ++StrongSIVapplications;
12420b57cec5SDimitry Andric   assert(0 < Level && Level <= CommonLevels && "level out of range");
12430b57cec5SDimitry Andric   Level--;
12440b57cec5SDimitry Andric 
12450b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
12460b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta);
12470b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << ", " << *Delta->getType() << "\n");
12480b57cec5SDimitry Andric 
12490b57cec5SDimitry Andric   // check that |Delta| < iteration count
12500b57cec5SDimitry Andric   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
12510b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound);
12520b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << ", " << *UpperBound->getType() << "\n");
12530b57cec5SDimitry Andric     const SCEV *AbsDelta =
12540b57cec5SDimitry Andric       SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
12550b57cec5SDimitry Andric     const SCEV *AbsCoeff =
12560b57cec5SDimitry Andric       SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
12570b57cec5SDimitry Andric     const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
12580b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product)) {
12590b57cec5SDimitry Andric       // Distance greater than trip count - no dependence
12600b57cec5SDimitry Andric       ++StrongSIVindependence;
12610b57cec5SDimitry Andric       ++StrongSIVsuccesses;
12620b57cec5SDimitry Andric       return true;
12630b57cec5SDimitry Andric     }
12640b57cec5SDimitry Andric   }
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric   // Can we compute distance?
12670b57cec5SDimitry Andric   if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
12680b57cec5SDimitry Andric     APInt ConstDelta = cast<SCEVConstant>(Delta)->getAPInt();
12690b57cec5SDimitry Andric     APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getAPInt();
12700b57cec5SDimitry Andric     APInt Distance  = ConstDelta; // these need to be initialized
12710b57cec5SDimitry Andric     APInt Remainder = ConstDelta;
12720b57cec5SDimitry Andric     APInt::sdivrem(ConstDelta, ConstCoeff, Distance, Remainder);
12730b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Distance = " << Distance << "\n");
12740b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
12750b57cec5SDimitry Andric     // Make sure Coeff divides Delta exactly
12760b57cec5SDimitry Andric     if (Remainder != 0) {
12770b57cec5SDimitry Andric       // Coeff doesn't divide Distance, no dependence
12780b57cec5SDimitry Andric       ++StrongSIVindependence;
12790b57cec5SDimitry Andric       ++StrongSIVsuccesses;
12800b57cec5SDimitry Andric       return true;
12810b57cec5SDimitry Andric     }
12820b57cec5SDimitry Andric     Result.DV[Level].Distance = SE->getConstant(Distance);
12830b57cec5SDimitry Andric     NewConstraint.setDistance(SE->getConstant(Distance), CurLoop);
12840b57cec5SDimitry Andric     if (Distance.sgt(0))
12850b57cec5SDimitry Andric       Result.DV[Level].Direction &= Dependence::DVEntry::LT;
12860b57cec5SDimitry Andric     else if (Distance.slt(0))
12870b57cec5SDimitry Andric       Result.DV[Level].Direction &= Dependence::DVEntry::GT;
12880b57cec5SDimitry Andric     else
12890b57cec5SDimitry Andric       Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
12900b57cec5SDimitry Andric     ++StrongSIVsuccesses;
12910b57cec5SDimitry Andric   }
12920b57cec5SDimitry Andric   else if (Delta->isZero()) {
12930b57cec5SDimitry Andric     // since 0/X == 0
12940b57cec5SDimitry Andric     Result.DV[Level].Distance = Delta;
12950b57cec5SDimitry Andric     NewConstraint.setDistance(Delta, CurLoop);
12960b57cec5SDimitry Andric     Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
12970b57cec5SDimitry Andric     ++StrongSIVsuccesses;
12980b57cec5SDimitry Andric   }
12990b57cec5SDimitry Andric   else {
13000b57cec5SDimitry Andric     if (Coeff->isOne()) {
13010b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Distance = " << *Delta << "\n");
13020b57cec5SDimitry Andric       Result.DV[Level].Distance = Delta; // since X/1 == X
13030b57cec5SDimitry Andric       NewConstraint.setDistance(Delta, CurLoop);
13040b57cec5SDimitry Andric     }
13050b57cec5SDimitry Andric     else {
13060b57cec5SDimitry Andric       Result.Consistent = false;
13070b57cec5SDimitry Andric       NewConstraint.setLine(Coeff,
13080b57cec5SDimitry Andric                             SE->getNegativeSCEV(Coeff),
13090b57cec5SDimitry Andric                             SE->getNegativeSCEV(Delta), CurLoop);
13100b57cec5SDimitry Andric     }
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric     // maybe we can get a useful direction
13130b57cec5SDimitry Andric     bool DeltaMaybeZero     = !SE->isKnownNonZero(Delta);
13140b57cec5SDimitry Andric     bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
13150b57cec5SDimitry Andric     bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
13160b57cec5SDimitry Andric     bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
13170b57cec5SDimitry Andric     bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
13180b57cec5SDimitry Andric     // The double negatives above are confusing.
13190b57cec5SDimitry Andric     // It helps to read !SE->isKnownNonZero(Delta)
13200b57cec5SDimitry Andric     // as "Delta might be Zero"
13210b57cec5SDimitry Andric     unsigned NewDirection = Dependence::DVEntry::NONE;
13220b57cec5SDimitry Andric     if ((DeltaMaybePositive && CoeffMaybePositive) ||
13230b57cec5SDimitry Andric         (DeltaMaybeNegative && CoeffMaybeNegative))
13240b57cec5SDimitry Andric       NewDirection = Dependence::DVEntry::LT;
13250b57cec5SDimitry Andric     if (DeltaMaybeZero)
13260b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::EQ;
13270b57cec5SDimitry Andric     if ((DeltaMaybeNegative && CoeffMaybePositive) ||
13280b57cec5SDimitry Andric         (DeltaMaybePositive && CoeffMaybeNegative))
13290b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::GT;
13300b57cec5SDimitry Andric     if (NewDirection < Result.DV[Level].Direction)
13310b57cec5SDimitry Andric       ++StrongSIVsuccesses;
13320b57cec5SDimitry Andric     Result.DV[Level].Direction &= NewDirection;
13330b57cec5SDimitry Andric   }
13340b57cec5SDimitry Andric   return false;
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric 
13370b57cec5SDimitry Andric 
13380b57cec5SDimitry Andric // weakCrossingSIVtest -
13390b57cec5SDimitry Andric // From the paper, Practical Dependence Testing, Section 4.2.2
13400b57cec5SDimitry Andric //
13410b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a*i] and [c2 - a*i],
13420b57cec5SDimitry Andric // where i is an induction variable, c1 and c2 are loop invariant,
13430b57cec5SDimitry Andric // and a is a constant, we can solve it exactly using the
13440b57cec5SDimitry Andric // Weak-Crossing SIV test.
13450b57cec5SDimitry Andric //
13460b57cec5SDimitry Andric // Given c1 + a*i = c2 - a*i', we can look for the intersection of
13470b57cec5SDimitry Andric // the two lines, where i = i', yielding
13480b57cec5SDimitry Andric //
13490b57cec5SDimitry Andric //    c1 + a*i = c2 - a*i
13500b57cec5SDimitry Andric //    2a*i = c2 - c1
13510b57cec5SDimitry Andric //    i = (c2 - c1)/2a
13520b57cec5SDimitry Andric //
13530b57cec5SDimitry Andric // If i < 0, there is no dependence.
13540b57cec5SDimitry Andric // If i > upperbound, there is no dependence.
13550b57cec5SDimitry Andric // If i = 0 (i.e., if c1 = c2), there's a dependence with distance = 0.
13560b57cec5SDimitry Andric // If i = upperbound, there's a dependence with distance = 0.
13570b57cec5SDimitry Andric // If i is integral, there's a dependence (all directions).
13580b57cec5SDimitry Andric // If the non-integer part = 1/2, there's a dependence (<> directions).
13590b57cec5SDimitry Andric // Otherwise, there's no dependence.
13600b57cec5SDimitry Andric //
13610b57cec5SDimitry Andric // Can prove independence. Failing that,
13620b57cec5SDimitry Andric // can sometimes refine the directions.
13630b57cec5SDimitry Andric // Can determine iteration for splitting.
13640b57cec5SDimitry Andric //
13650b57cec5SDimitry Andric // Return true if dependence disproved.
13660b57cec5SDimitry Andric bool DependenceInfo::weakCrossingSIVtest(
13670b57cec5SDimitry Andric     const SCEV *Coeff, const SCEV *SrcConst, const SCEV *DstConst,
13680b57cec5SDimitry Andric     const Loop *CurLoop, unsigned Level, FullDependence &Result,
13690b57cec5SDimitry Andric     Constraint &NewConstraint, const SCEV *&SplitIter) const {
13700b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tWeak-Crossing SIV test\n");
13710b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Coeff = " << *Coeff << "\n");
13720b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
13730b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
13740b57cec5SDimitry Andric   ++WeakCrossingSIVapplications;
13750b57cec5SDimitry Andric   assert(0 < Level && Level <= CommonLevels && "Level out of range");
13760b57cec5SDimitry Andric   Level--;
13770b57cec5SDimitry Andric   Result.Consistent = false;
13780b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
13790b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
13800b57cec5SDimitry Andric   NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
13810b57cec5SDimitry Andric   if (Delta->isZero()) {
1382bdd1243dSDimitry Andric     Result.DV[Level].Direction &= ~Dependence::DVEntry::LT;
1383bdd1243dSDimitry Andric     Result.DV[Level].Direction &= ~Dependence::DVEntry::GT;
13840b57cec5SDimitry Andric     ++WeakCrossingSIVsuccesses;
13850b57cec5SDimitry Andric     if (!Result.DV[Level].Direction) {
13860b57cec5SDimitry Andric       ++WeakCrossingSIVindependence;
13870b57cec5SDimitry Andric       return true;
13880b57cec5SDimitry Andric     }
13890b57cec5SDimitry Andric     Result.DV[Level].Distance = Delta; // = 0
13900b57cec5SDimitry Andric     return false;
13910b57cec5SDimitry Andric   }
13920b57cec5SDimitry Andric   const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(Coeff);
13930b57cec5SDimitry Andric   if (!ConstCoeff)
13940b57cec5SDimitry Andric     return false;
13950b57cec5SDimitry Andric 
13960b57cec5SDimitry Andric   Result.DV[Level].Splitable = true;
13970b57cec5SDimitry Andric   if (SE->isKnownNegative(ConstCoeff)) {
13980b57cec5SDimitry Andric     ConstCoeff = dyn_cast<SCEVConstant>(SE->getNegativeSCEV(ConstCoeff));
13990b57cec5SDimitry Andric     assert(ConstCoeff &&
14000b57cec5SDimitry Andric            "dynamic cast of negative of ConstCoeff should yield constant");
14010b57cec5SDimitry Andric     Delta = SE->getNegativeSCEV(Delta);
14020b57cec5SDimitry Andric   }
14030b57cec5SDimitry Andric   assert(SE->isKnownPositive(ConstCoeff) && "ConstCoeff should be positive");
14040b57cec5SDimitry Andric 
14050b57cec5SDimitry Andric   // compute SplitIter for use by DependenceInfo::getSplitIteration()
14060b57cec5SDimitry Andric   SplitIter = SE->getUDivExpr(
14070b57cec5SDimitry Andric       SE->getSMaxExpr(SE->getZero(Delta->getType()), Delta),
14080b57cec5SDimitry Andric       SE->getMulExpr(SE->getConstant(Delta->getType(), 2), ConstCoeff));
14090b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Split iter = " << *SplitIter << "\n");
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric   const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
14120b57cec5SDimitry Andric   if (!ConstDelta)
14130b57cec5SDimitry Andric     return false;
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   // We're certain that ConstCoeff > 0; therefore,
14160b57cec5SDimitry Andric   // if Delta < 0, then no dependence.
14170b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
14180b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    ConstCoeff = " << *ConstCoeff << "\n");
14190b57cec5SDimitry Andric   if (SE->isKnownNegative(Delta)) {
14200b57cec5SDimitry Andric     // No dependence, Delta < 0
14210b57cec5SDimitry Andric     ++WeakCrossingSIVindependence;
14220b57cec5SDimitry Andric     ++WeakCrossingSIVsuccesses;
14230b57cec5SDimitry Andric     return true;
14240b57cec5SDimitry Andric   }
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric   // We're certain that Delta > 0 and ConstCoeff > 0.
14270b57cec5SDimitry Andric   // Check Delta/(2*ConstCoeff) against upper loop bound
14280b57cec5SDimitry Andric   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
14290b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
14300b57cec5SDimitry Andric     const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
14310b57cec5SDimitry Andric     const SCEV *ML = SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound),
14320b57cec5SDimitry Andric                                     ConstantTwo);
14330b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    ML = " << *ML << "\n");
14340b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, ML)) {
14350b57cec5SDimitry Andric       // Delta too big, no dependence
14360b57cec5SDimitry Andric       ++WeakCrossingSIVindependence;
14370b57cec5SDimitry Andric       ++WeakCrossingSIVsuccesses;
14380b57cec5SDimitry Andric       return true;
14390b57cec5SDimitry Andric     }
14400b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, Delta, ML)) {
14410b57cec5SDimitry Andric       // i = i' = UB
1442bdd1243dSDimitry Andric       Result.DV[Level].Direction &= ~Dependence::DVEntry::LT;
1443bdd1243dSDimitry Andric       Result.DV[Level].Direction &= ~Dependence::DVEntry::GT;
14440b57cec5SDimitry Andric       ++WeakCrossingSIVsuccesses;
14450b57cec5SDimitry Andric       if (!Result.DV[Level].Direction) {
14460b57cec5SDimitry Andric         ++WeakCrossingSIVindependence;
14470b57cec5SDimitry Andric         return true;
14480b57cec5SDimitry Andric       }
14490b57cec5SDimitry Andric       Result.DV[Level].Splitable = false;
14500b57cec5SDimitry Andric       Result.DV[Level].Distance = SE->getZero(Delta->getType());
14510b57cec5SDimitry Andric       return false;
14520b57cec5SDimitry Andric     }
14530b57cec5SDimitry Andric   }
14540b57cec5SDimitry Andric 
14550b57cec5SDimitry Andric   // check that Coeff divides Delta
14560b57cec5SDimitry Andric   APInt APDelta = ConstDelta->getAPInt();
14570b57cec5SDimitry Andric   APInt APCoeff = ConstCoeff->getAPInt();
14580b57cec5SDimitry Andric   APInt Distance = APDelta; // these need to be initialzed
14590b57cec5SDimitry Andric   APInt Remainder = APDelta;
14600b57cec5SDimitry Andric   APInt::sdivrem(APDelta, APCoeff, Distance, Remainder);
14610b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
14620b57cec5SDimitry Andric   if (Remainder != 0) {
14630b57cec5SDimitry Andric     // Coeff doesn't divide Delta, no dependence
14640b57cec5SDimitry Andric     ++WeakCrossingSIVindependence;
14650b57cec5SDimitry Andric     ++WeakCrossingSIVsuccesses;
14660b57cec5SDimitry Andric     return true;
14670b57cec5SDimitry Andric   }
14680b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Distance = " << Distance << "\n");
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   // if 2*Coeff doesn't divide Delta, then the equal direction isn't possible
14710b57cec5SDimitry Andric   APInt Two = APInt(Distance.getBitWidth(), 2, true);
14720b57cec5SDimitry Andric   Remainder = Distance.srem(Two);
14730b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
14740b57cec5SDimitry Andric   if (Remainder != 0) {
14750b57cec5SDimitry Andric     // Equal direction isn't possible
1476bdd1243dSDimitry Andric     Result.DV[Level].Direction &= ~Dependence::DVEntry::EQ;
14770b57cec5SDimitry Andric     ++WeakCrossingSIVsuccesses;
14780b57cec5SDimitry Andric   }
14790b57cec5SDimitry Andric   return false;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric 
14830b57cec5SDimitry Andric // Kirch's algorithm, from
14840b57cec5SDimitry Andric //
14850b57cec5SDimitry Andric //        Optimizing Supercompilers for Supercomputers
14860b57cec5SDimitry Andric //        Michael Wolfe
14870b57cec5SDimitry Andric //        MIT Press, 1989
14880b57cec5SDimitry Andric //
14890b57cec5SDimitry Andric // Program 2.1, page 29.
14900b57cec5SDimitry Andric // Computes the GCD of AM and BM.
14910b57cec5SDimitry Andric // Also finds a solution to the equation ax - by = gcd(a, b).
14920b57cec5SDimitry Andric // Returns true if dependence disproved; i.e., gcd does not divide Delta.
14930b57cec5SDimitry Andric static bool findGCD(unsigned Bits, const APInt &AM, const APInt &BM,
14940b57cec5SDimitry Andric                     const APInt &Delta, APInt &G, APInt &X, APInt &Y) {
14950b57cec5SDimitry Andric   APInt A0(Bits, 1, true), A1(Bits, 0, true);
14960b57cec5SDimitry Andric   APInt B0(Bits, 0, true), B1(Bits, 1, true);
14970b57cec5SDimitry Andric   APInt G0 = AM.abs();
14980b57cec5SDimitry Andric   APInt G1 = BM.abs();
14990b57cec5SDimitry Andric   APInt Q = G0; // these need to be initialized
15000b57cec5SDimitry Andric   APInt R = G0;
15010b57cec5SDimitry Andric   APInt::sdivrem(G0, G1, Q, R);
15020b57cec5SDimitry Andric   while (R != 0) {
15030b57cec5SDimitry Andric     APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
15040b57cec5SDimitry Andric     APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
15050b57cec5SDimitry Andric     G0 = G1; G1 = R;
15060b57cec5SDimitry Andric     APInt::sdivrem(G0, G1, Q, R);
15070b57cec5SDimitry Andric   }
15080b57cec5SDimitry Andric   G = G1;
15090b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    GCD = " << G << "\n");
15100b57cec5SDimitry Andric   X = AM.slt(0) ? -A1 : A1;
15110b57cec5SDimitry Andric   Y = BM.slt(0) ? B1 : -B1;
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric   // make sure gcd divides Delta
15140b57cec5SDimitry Andric   R = Delta.srem(G);
15150b57cec5SDimitry Andric   if (R != 0)
15160b57cec5SDimitry Andric     return true; // gcd doesn't divide Delta, no dependence
15170b57cec5SDimitry Andric   Q = Delta.sdiv(G);
15180b57cec5SDimitry Andric   return false;
15190b57cec5SDimitry Andric }
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric static APInt floorOfQuotient(const APInt &A, const APInt &B) {
15220b57cec5SDimitry Andric   APInt Q = A; // these need to be initialized
15230b57cec5SDimitry Andric   APInt R = A;
15240b57cec5SDimitry Andric   APInt::sdivrem(A, B, Q, R);
15250b57cec5SDimitry Andric   if (R == 0)
15260b57cec5SDimitry Andric     return Q;
15270b57cec5SDimitry Andric   if ((A.sgt(0) && B.sgt(0)) ||
15280b57cec5SDimitry Andric       (A.slt(0) && B.slt(0)))
15290b57cec5SDimitry Andric     return Q;
15300b57cec5SDimitry Andric   else
15310b57cec5SDimitry Andric     return Q - 1;
15320b57cec5SDimitry Andric }
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric static APInt ceilingOfQuotient(const APInt &A, const APInt &B) {
15350b57cec5SDimitry Andric   APInt Q = A; // these need to be initialized
15360b57cec5SDimitry Andric   APInt R = A;
15370b57cec5SDimitry Andric   APInt::sdivrem(A, B, Q, R);
15380b57cec5SDimitry Andric   if (R == 0)
15390b57cec5SDimitry Andric     return Q;
15400b57cec5SDimitry Andric   if ((A.sgt(0) && B.sgt(0)) ||
15410b57cec5SDimitry Andric       (A.slt(0) && B.slt(0)))
15420b57cec5SDimitry Andric     return Q + 1;
15430b57cec5SDimitry Andric   else
15440b57cec5SDimitry Andric     return Q;
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric // exactSIVtest -
15480b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*i],
15490b57cec5SDimitry Andric // where i is an induction variable, c1 and c2 are loop invariant, and a1
15500b57cec5SDimitry Andric // and a2 are constant, we can solve it exactly using an algorithm developed
1551fe6060f1SDimitry Andric // by Banerjee and Wolfe. See Algorithm 6.2.1 (case 2.5) in:
15520b57cec5SDimitry Andric //
1553fe6060f1SDimitry Andric //        Dependence Analysis for Supercomputing
1554fe6060f1SDimitry Andric //        Utpal Banerjee
1555fe6060f1SDimitry Andric //        Kluwer Academic Publishers, 1988
15560b57cec5SDimitry Andric //
15570b57cec5SDimitry Andric // It's slower than the specialized tests (strong SIV, weak-zero SIV, etc),
15580b57cec5SDimitry Andric // so use them if possible. They're also a bit better with symbolics and,
15590b57cec5SDimitry Andric // in the case of the strong SIV test, can compute Distances.
15600b57cec5SDimitry Andric //
15610b57cec5SDimitry Andric // Return true if dependence disproved.
1562fe6060f1SDimitry Andric //
1563fe6060f1SDimitry Andric // This is a modified version of the original Banerjee algorithm. The original
1564fe6060f1SDimitry Andric // only tested whether Dst depends on Src. This algorithm extends that and
1565fe6060f1SDimitry Andric // returns all the dependencies that exist between Dst and Src.
15660b57cec5SDimitry Andric bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
15670b57cec5SDimitry Andric                                   const SCEV *SrcConst, const SCEV *DstConst,
15680b57cec5SDimitry Andric                                   const Loop *CurLoop, unsigned Level,
15690b57cec5SDimitry Andric                                   FullDependence &Result,
15700b57cec5SDimitry Andric                                   Constraint &NewConstraint) const {
15710b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tExact SIV test\n");
15720b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << " = AM\n");
15730b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << " = BM\n");
15740b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
15750b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
15760b57cec5SDimitry Andric   ++ExactSIVapplications;
15770b57cec5SDimitry Andric   assert(0 < Level && Level <= CommonLevels && "Level out of range");
15780b57cec5SDimitry Andric   Level--;
15790b57cec5SDimitry Andric   Result.Consistent = false;
15800b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
15810b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
1582fe6060f1SDimitry Andric   NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta,
1583fe6060f1SDimitry Andric                         CurLoop);
15840b57cec5SDimitry Andric   const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
15850b57cec5SDimitry Andric   const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
15860b57cec5SDimitry Andric   const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
15870b57cec5SDimitry Andric   if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
15880b57cec5SDimitry Andric     return false;
15890b57cec5SDimitry Andric 
15900b57cec5SDimitry Andric   // find gcd
15910b57cec5SDimitry Andric   APInt G, X, Y;
15920b57cec5SDimitry Andric   APInt AM = ConstSrcCoeff->getAPInt();
15930b57cec5SDimitry Andric   APInt BM = ConstDstCoeff->getAPInt();
1594fe6060f1SDimitry Andric   APInt CM = ConstDelta->getAPInt();
15950b57cec5SDimitry Andric   unsigned Bits = AM.getBitWidth();
1596fe6060f1SDimitry Andric   if (findGCD(Bits, AM, BM, CM, G, X, Y)) {
15970b57cec5SDimitry Andric     // gcd doesn't divide Delta, no dependence
15980b57cec5SDimitry Andric     ++ExactSIVindependence;
15990b57cec5SDimitry Andric     ++ExactSIVsuccesses;
16000b57cec5SDimitry Andric     return true;
16010b57cec5SDimitry Andric   }
16020b57cec5SDimitry Andric 
16030b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    X = " << X << ", Y = " << Y << "\n");
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric   // since SCEV construction normalizes, LM = 0
16060b57cec5SDimitry Andric   APInt UM(Bits, 1, true);
1607fe6060f1SDimitry Andric   bool UMValid = false;
16080b57cec5SDimitry Andric   // UM is perhaps unavailable, let's check
16090b57cec5SDimitry Andric   if (const SCEVConstant *CUB =
16100b57cec5SDimitry Andric           collectConstantUpperBound(CurLoop, Delta->getType())) {
16110b57cec5SDimitry Andric     UM = CUB->getAPInt();
16120b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    UM = " << UM << "\n");
1613fe6060f1SDimitry Andric     UMValid = true;
16140b57cec5SDimitry Andric   }
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric   APInt TU(APInt::getSignedMaxValue(Bits));
16170b57cec5SDimitry Andric   APInt TL(APInt::getSignedMinValue(Bits));
1618fe6060f1SDimitry Andric   APInt TC = CM.sdiv(G);
1619fe6060f1SDimitry Andric   APInt TX = X * TC;
1620fe6060f1SDimitry Andric   APInt TY = Y * TC;
1621fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TC = " << TC << "\n");
1622fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TX = " << TX << "\n");
1623fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TY = " << TY << "\n");
16240b57cec5SDimitry Andric 
1625fe6060f1SDimitry Andric   SmallVector<APInt, 2> TLVec, TUVec;
1626fe6060f1SDimitry Andric   APInt TB = BM.sdiv(G);
1627fe6060f1SDimitry Andric   if (TB.sgt(0)) {
1628fe6060f1SDimitry Andric     TLVec.push_back(ceilingOfQuotient(-TX, TB));
1629fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
1630fe6060f1SDimitry Andric     // New bound check - modification to Banerjee's e3 check
1631fe6060f1SDimitry Andric     if (UMValid) {
1632fe6060f1SDimitry Andric       TUVec.push_back(floorOfQuotient(UM - TX, TB));
1633fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
16340b57cec5SDimitry Andric     }
1635fe6060f1SDimitry Andric   } else {
1636fe6060f1SDimitry Andric     TUVec.push_back(floorOfQuotient(-TX, TB));
1637fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
1638fe6060f1SDimitry Andric     // New bound check - modification to Banerjee's e3 check
1639fe6060f1SDimitry Andric     if (UMValid) {
1640fe6060f1SDimitry Andric       TLVec.push_back(ceilingOfQuotient(UM - TX, TB));
1641fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
16420b57cec5SDimitry Andric     }
16430b57cec5SDimitry Andric   }
16440b57cec5SDimitry Andric 
1645fe6060f1SDimitry Andric   APInt TA = AM.sdiv(G);
1646fe6060f1SDimitry Andric   if (TA.sgt(0)) {
1647fe6060f1SDimitry Andric     if (UMValid) {
1648fe6060f1SDimitry Andric       TUVec.push_back(floorOfQuotient(UM - TY, TA));
1649fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
1650fe6060f1SDimitry Andric     }
1651fe6060f1SDimitry Andric     // New bound check - modification to Banerjee's e3 check
1652fe6060f1SDimitry Andric     TLVec.push_back(ceilingOfQuotient(-TY, TA));
1653fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
1654fe6060f1SDimitry Andric   } else {
1655fe6060f1SDimitry Andric     if (UMValid) {
1656fe6060f1SDimitry Andric       TLVec.push_back(ceilingOfQuotient(UM - TY, TA));
1657fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
1658fe6060f1SDimitry Andric     }
1659fe6060f1SDimitry Andric     // New bound check - modification to Banerjee's e3 check
1660fe6060f1SDimitry Andric     TUVec.push_back(floorOfQuotient(-TY, TA));
1661fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
1662fe6060f1SDimitry Andric   }
1663fe6060f1SDimitry Andric 
1664fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TA = " << TA << "\n");
1665fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TB = " << TB << "\n");
1666fe6060f1SDimitry Andric 
1667fe6060f1SDimitry Andric   if (TLVec.empty() || TUVec.empty())
1668fe6060f1SDimitry Andric     return false;
1669fe6060f1SDimitry Andric   TL = APIntOps::smax(TLVec.front(), TLVec.back());
1670fe6060f1SDimitry Andric   TU = APIntOps::smin(TUVec.front(), TUVec.back());
16710b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TL = " << TL << "\n");
16720b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TU = " << TU << "\n");
1673fe6060f1SDimitry Andric 
16740b57cec5SDimitry Andric   if (TL.sgt(TU)) {
16750b57cec5SDimitry Andric     ++ExactSIVindependence;
16760b57cec5SDimitry Andric     ++ExactSIVsuccesses;
16770b57cec5SDimitry Andric     return true;
16780b57cec5SDimitry Andric   }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric   // explore directions
16810b57cec5SDimitry Andric   unsigned NewDirection = Dependence::DVEntry::NONE;
1682fe6060f1SDimitry Andric   APInt LowerDistance, UpperDistance;
1683fe6060f1SDimitry Andric   if (TA.sgt(TB)) {
1684fe6060f1SDimitry Andric     LowerDistance = (TY - TX) + (TA - TB) * TL;
1685fe6060f1SDimitry Andric     UpperDistance = (TY - TX) + (TA - TB) * TU;
1686fe6060f1SDimitry Andric   } else {
1687fe6060f1SDimitry Andric     LowerDistance = (TY - TX) + (TA - TB) * TU;
1688fe6060f1SDimitry Andric     UpperDistance = (TY - TX) + (TA - TB) * TL;
16890b57cec5SDimitry Andric   }
16900b57cec5SDimitry Andric 
1691fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    LowerDistance = " << LowerDistance << "\n");
1692fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    UpperDistance = " << UpperDistance << "\n");
1693fe6060f1SDimitry Andric 
1694fe6060f1SDimitry Andric   APInt Zero(Bits, 0, true);
1695fe6060f1SDimitry Andric   if (LowerDistance.sle(Zero) && UpperDistance.sge(Zero)) {
16960b57cec5SDimitry Andric     NewDirection |= Dependence::DVEntry::EQ;
16970b57cec5SDimitry Andric     ++ExactSIVsuccesses;
16980b57cec5SDimitry Andric   }
1699fe6060f1SDimitry Andric   if (LowerDistance.slt(0)) {
17000b57cec5SDimitry Andric     NewDirection |= Dependence::DVEntry::GT;
17010b57cec5SDimitry Andric     ++ExactSIVsuccesses;
17020b57cec5SDimitry Andric   }
1703fe6060f1SDimitry Andric   if (UpperDistance.sgt(0)) {
1704fe6060f1SDimitry Andric     NewDirection |= Dependence::DVEntry::LT;
1705fe6060f1SDimitry Andric     ++ExactSIVsuccesses;
1706fe6060f1SDimitry Andric   }
17070b57cec5SDimitry Andric 
17080b57cec5SDimitry Andric   // finished
17090b57cec5SDimitry Andric   Result.DV[Level].Direction &= NewDirection;
17100b57cec5SDimitry Andric   if (Result.DV[Level].Direction == Dependence::DVEntry::NONE)
17110b57cec5SDimitry Andric     ++ExactSIVindependence;
1712fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Result = ");
1713fe6060f1SDimitry Andric   LLVM_DEBUG(Result.dump(dbgs()));
17140b57cec5SDimitry Andric   return Result.DV[Level].Direction == Dependence::DVEntry::NONE;
17150b57cec5SDimitry Andric }
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric 
17180b57cec5SDimitry Andric // Return true if the divisor evenly divides the dividend.
17190b57cec5SDimitry Andric static
17200b57cec5SDimitry Andric bool isRemainderZero(const SCEVConstant *Dividend,
17210b57cec5SDimitry Andric                      const SCEVConstant *Divisor) {
17220b57cec5SDimitry Andric   const APInt &ConstDividend = Dividend->getAPInt();
17230b57cec5SDimitry Andric   const APInt &ConstDivisor = Divisor->getAPInt();
17240b57cec5SDimitry Andric   return ConstDividend.srem(ConstDivisor) == 0;
17250b57cec5SDimitry Andric }
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric // weakZeroSrcSIVtest -
17290b57cec5SDimitry Andric // From the paper, Practical Dependence Testing, Section 4.2.2
17300b57cec5SDimitry Andric //
17310b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1] and [c2 + a*i],
17320b57cec5SDimitry Andric // where i is an induction variable, c1 and c2 are loop invariant,
17330b57cec5SDimitry Andric // and a is a constant, we can solve it exactly using the
17340b57cec5SDimitry Andric // Weak-Zero SIV test.
17350b57cec5SDimitry Andric //
17360b57cec5SDimitry Andric // Given
17370b57cec5SDimitry Andric //
17380b57cec5SDimitry Andric //    c1 = c2 + a*i
17390b57cec5SDimitry Andric //
17400b57cec5SDimitry Andric // we get
17410b57cec5SDimitry Andric //
17420b57cec5SDimitry Andric //    (c1 - c2)/a = i
17430b57cec5SDimitry Andric //
17440b57cec5SDimitry Andric // If i is not an integer, there's no dependence.
17450b57cec5SDimitry Andric // If i < 0 or > UB, there's no dependence.
17460b57cec5SDimitry Andric // If i = 0, the direction is >= and peeling the
17470b57cec5SDimitry Andric // 1st iteration will break the dependence.
17480b57cec5SDimitry Andric // If i = UB, the direction is <= and peeling the
17490b57cec5SDimitry Andric // last iteration will break the dependence.
17500b57cec5SDimitry Andric // Otherwise, the direction is *.
17510b57cec5SDimitry Andric //
17520b57cec5SDimitry Andric // Can prove independence. Failing that, we can sometimes refine
17530b57cec5SDimitry Andric // the directions. Can sometimes show that first or last
17540b57cec5SDimitry Andric // iteration carries all the dependences (so worth peeling).
17550b57cec5SDimitry Andric //
17560b57cec5SDimitry Andric // (see also weakZeroDstSIVtest)
17570b57cec5SDimitry Andric //
17580b57cec5SDimitry Andric // Return true if dependence disproved.
17590b57cec5SDimitry Andric bool DependenceInfo::weakZeroSrcSIVtest(const SCEV *DstCoeff,
17600b57cec5SDimitry Andric                                         const SCEV *SrcConst,
17610b57cec5SDimitry Andric                                         const SCEV *DstConst,
17620b57cec5SDimitry Andric                                         const Loop *CurLoop, unsigned Level,
17630b57cec5SDimitry Andric                                         FullDependence &Result,
17640b57cec5SDimitry Andric                                         Constraint &NewConstraint) const {
17650b57cec5SDimitry Andric   // For the WeakSIV test, it's possible the loop isn't common to
17660b57cec5SDimitry Andric   // the Src and Dst loops. If it isn't, then there's no need to
17670b57cec5SDimitry Andric   // record a direction.
17680b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tWeak-Zero (src) SIV test\n");
17690b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << "\n");
17700b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
17710b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
17720b57cec5SDimitry Andric   ++WeakZeroSIVapplications;
17730b57cec5SDimitry Andric   assert(0 < Level && Level <= MaxLevels && "Level out of range");
17740b57cec5SDimitry Andric   Level--;
17750b57cec5SDimitry Andric   Result.Consistent = false;
17760b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
17770b57cec5SDimitry Andric   NewConstraint.setLine(SE->getZero(Delta->getType()), DstCoeff, Delta,
17780b57cec5SDimitry Andric                         CurLoop);
17790b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
17800b57cec5SDimitry Andric   if (isKnownPredicate(CmpInst::ICMP_EQ, SrcConst, DstConst)) {
17810b57cec5SDimitry Andric     if (Level < CommonLevels) {
17820b57cec5SDimitry Andric       Result.DV[Level].Direction &= Dependence::DVEntry::GE;
17830b57cec5SDimitry Andric       Result.DV[Level].PeelFirst = true;
17840b57cec5SDimitry Andric       ++WeakZeroSIVsuccesses;
17850b57cec5SDimitry Andric     }
17860b57cec5SDimitry Andric     return false; // dependences caused by first iteration
17870b57cec5SDimitry Andric   }
17880b57cec5SDimitry Andric   const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
17890b57cec5SDimitry Andric   if (!ConstCoeff)
17900b57cec5SDimitry Andric     return false;
17910b57cec5SDimitry Andric   const SCEV *AbsCoeff =
17920b57cec5SDimitry Andric     SE->isKnownNegative(ConstCoeff) ?
17930b57cec5SDimitry Andric     SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
17940b57cec5SDimitry Andric   const SCEV *NewDelta =
17950b57cec5SDimitry Andric     SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
17960b57cec5SDimitry Andric 
17970b57cec5SDimitry Andric   // check that Delta/SrcCoeff < iteration count
17980b57cec5SDimitry Andric   // really check NewDelta < count*AbsCoeff
17990b57cec5SDimitry Andric   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
18000b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
18010b57cec5SDimitry Andric     const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
18020b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
18030b57cec5SDimitry Andric       ++WeakZeroSIVindependence;
18040b57cec5SDimitry Andric       ++WeakZeroSIVsuccesses;
18050b57cec5SDimitry Andric       return true;
18060b57cec5SDimitry Andric     }
18070b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
18080b57cec5SDimitry Andric       // dependences caused by last iteration
18090b57cec5SDimitry Andric       if (Level < CommonLevels) {
18100b57cec5SDimitry Andric         Result.DV[Level].Direction &= Dependence::DVEntry::LE;
18110b57cec5SDimitry Andric         Result.DV[Level].PeelLast = true;
18120b57cec5SDimitry Andric         ++WeakZeroSIVsuccesses;
18130b57cec5SDimitry Andric       }
18140b57cec5SDimitry Andric       return false;
18150b57cec5SDimitry Andric     }
18160b57cec5SDimitry Andric   }
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric   // check that Delta/SrcCoeff >= 0
18190b57cec5SDimitry Andric   // really check that NewDelta >= 0
18200b57cec5SDimitry Andric   if (SE->isKnownNegative(NewDelta)) {
18210b57cec5SDimitry Andric     // No dependence, newDelta < 0
18220b57cec5SDimitry Andric     ++WeakZeroSIVindependence;
18230b57cec5SDimitry Andric     ++WeakZeroSIVsuccesses;
18240b57cec5SDimitry Andric     return true;
18250b57cec5SDimitry Andric   }
18260b57cec5SDimitry Andric 
18270b57cec5SDimitry Andric   // if SrcCoeff doesn't divide Delta, then no dependence
18280b57cec5SDimitry Andric   if (isa<SCEVConstant>(Delta) &&
18290b57cec5SDimitry Andric       !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
18300b57cec5SDimitry Andric     ++WeakZeroSIVindependence;
18310b57cec5SDimitry Andric     ++WeakZeroSIVsuccesses;
18320b57cec5SDimitry Andric     return true;
18330b57cec5SDimitry Andric   }
18340b57cec5SDimitry Andric   return false;
18350b57cec5SDimitry Andric }
18360b57cec5SDimitry Andric 
18370b57cec5SDimitry Andric 
18380b57cec5SDimitry Andric // weakZeroDstSIVtest -
18390b57cec5SDimitry Andric // From the paper, Practical Dependence Testing, Section 4.2.2
18400b57cec5SDimitry Andric //
18410b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a*i] and [c2],
18420b57cec5SDimitry Andric // where i is an induction variable, c1 and c2 are loop invariant,
18430b57cec5SDimitry Andric // and a is a constant, we can solve it exactly using the
18440b57cec5SDimitry Andric // Weak-Zero SIV test.
18450b57cec5SDimitry Andric //
18460b57cec5SDimitry Andric // Given
18470b57cec5SDimitry Andric //
18480b57cec5SDimitry Andric //    c1 + a*i = c2
18490b57cec5SDimitry Andric //
18500b57cec5SDimitry Andric // we get
18510b57cec5SDimitry Andric //
18520b57cec5SDimitry Andric //    i = (c2 - c1)/a
18530b57cec5SDimitry Andric //
18540b57cec5SDimitry Andric // If i is not an integer, there's no dependence.
18550b57cec5SDimitry Andric // If i < 0 or > UB, there's no dependence.
18560b57cec5SDimitry Andric // If i = 0, the direction is <= and peeling the
18570b57cec5SDimitry Andric // 1st iteration will break the dependence.
18580b57cec5SDimitry Andric // If i = UB, the direction is >= and peeling the
18590b57cec5SDimitry Andric // last iteration will break the dependence.
18600b57cec5SDimitry Andric // Otherwise, the direction is *.
18610b57cec5SDimitry Andric //
18620b57cec5SDimitry Andric // Can prove independence. Failing that, we can sometimes refine
18630b57cec5SDimitry Andric // the directions. Can sometimes show that first or last
18640b57cec5SDimitry Andric // iteration carries all the dependences (so worth peeling).
18650b57cec5SDimitry Andric //
18660b57cec5SDimitry Andric // (see also weakZeroSrcSIVtest)
18670b57cec5SDimitry Andric //
18680b57cec5SDimitry Andric // Return true if dependence disproved.
18690b57cec5SDimitry Andric bool DependenceInfo::weakZeroDstSIVtest(const SCEV *SrcCoeff,
18700b57cec5SDimitry Andric                                         const SCEV *SrcConst,
18710b57cec5SDimitry Andric                                         const SCEV *DstConst,
18720b57cec5SDimitry Andric                                         const Loop *CurLoop, unsigned Level,
18730b57cec5SDimitry Andric                                         FullDependence &Result,
18740b57cec5SDimitry Andric                                         Constraint &NewConstraint) const {
18750b57cec5SDimitry Andric   // For the WeakSIV test, it's possible the loop isn't common to the
18760b57cec5SDimitry Andric   // Src and Dst loops. If it isn't, then there's no need to record a direction.
18770b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tWeak-Zero (dst) SIV test\n");
18780b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << "\n");
18790b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
18800b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
18810b57cec5SDimitry Andric   ++WeakZeroSIVapplications;
18820b57cec5SDimitry Andric   assert(0 < Level && Level <= SrcLevels && "Level out of range");
18830b57cec5SDimitry Andric   Level--;
18840b57cec5SDimitry Andric   Result.Consistent = false;
18850b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
18860b57cec5SDimitry Andric   NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->getType()), Delta,
18870b57cec5SDimitry Andric                         CurLoop);
18880b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
18890b57cec5SDimitry Andric   if (isKnownPredicate(CmpInst::ICMP_EQ, DstConst, SrcConst)) {
18900b57cec5SDimitry Andric     if (Level < CommonLevels) {
18910b57cec5SDimitry Andric       Result.DV[Level].Direction &= Dependence::DVEntry::LE;
18920b57cec5SDimitry Andric       Result.DV[Level].PeelFirst = true;
18930b57cec5SDimitry Andric       ++WeakZeroSIVsuccesses;
18940b57cec5SDimitry Andric     }
18950b57cec5SDimitry Andric     return false; // dependences caused by first iteration
18960b57cec5SDimitry Andric   }
18970b57cec5SDimitry Andric   const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
18980b57cec5SDimitry Andric   if (!ConstCoeff)
18990b57cec5SDimitry Andric     return false;
19000b57cec5SDimitry Andric   const SCEV *AbsCoeff =
19010b57cec5SDimitry Andric     SE->isKnownNegative(ConstCoeff) ?
19020b57cec5SDimitry Andric     SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
19030b57cec5SDimitry Andric   const SCEV *NewDelta =
19040b57cec5SDimitry Andric     SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
19050b57cec5SDimitry Andric 
19060b57cec5SDimitry Andric   // check that Delta/SrcCoeff < iteration count
19070b57cec5SDimitry Andric   // really check NewDelta < count*AbsCoeff
19080b57cec5SDimitry Andric   if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
19090b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
19100b57cec5SDimitry Andric     const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
19110b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
19120b57cec5SDimitry Andric       ++WeakZeroSIVindependence;
19130b57cec5SDimitry Andric       ++WeakZeroSIVsuccesses;
19140b57cec5SDimitry Andric       return true;
19150b57cec5SDimitry Andric     }
19160b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
19170b57cec5SDimitry Andric       // dependences caused by last iteration
19180b57cec5SDimitry Andric       if (Level < CommonLevels) {
19190b57cec5SDimitry Andric         Result.DV[Level].Direction &= Dependence::DVEntry::GE;
19200b57cec5SDimitry Andric         Result.DV[Level].PeelLast = true;
19210b57cec5SDimitry Andric         ++WeakZeroSIVsuccesses;
19220b57cec5SDimitry Andric       }
19230b57cec5SDimitry Andric       return false;
19240b57cec5SDimitry Andric     }
19250b57cec5SDimitry Andric   }
19260b57cec5SDimitry Andric 
19270b57cec5SDimitry Andric   // check that Delta/SrcCoeff >= 0
19280b57cec5SDimitry Andric   // really check that NewDelta >= 0
19290b57cec5SDimitry Andric   if (SE->isKnownNegative(NewDelta)) {
19300b57cec5SDimitry Andric     // No dependence, newDelta < 0
19310b57cec5SDimitry Andric     ++WeakZeroSIVindependence;
19320b57cec5SDimitry Andric     ++WeakZeroSIVsuccesses;
19330b57cec5SDimitry Andric     return true;
19340b57cec5SDimitry Andric   }
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric   // if SrcCoeff doesn't divide Delta, then no dependence
19370b57cec5SDimitry Andric   if (isa<SCEVConstant>(Delta) &&
19380b57cec5SDimitry Andric       !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
19390b57cec5SDimitry Andric     ++WeakZeroSIVindependence;
19400b57cec5SDimitry Andric     ++WeakZeroSIVsuccesses;
19410b57cec5SDimitry Andric     return true;
19420b57cec5SDimitry Andric   }
19430b57cec5SDimitry Andric   return false;
19440b57cec5SDimitry Andric }
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric // exactRDIVtest - Tests the RDIV subscript pair for dependence.
19480b57cec5SDimitry Andric // Things of the form [c1 + a*i] and [c2 + b*j],
19490b57cec5SDimitry Andric // where i and j are induction variable, c1 and c2 are loop invariant,
19500b57cec5SDimitry Andric // and a and b are constants.
19510b57cec5SDimitry Andric // Returns true if any possible dependence is disproved.
19520b57cec5SDimitry Andric // Marks the result as inconsistent.
19530b57cec5SDimitry Andric // Works in some cases that symbolicRDIVtest doesn't, and vice versa.
19540b57cec5SDimitry Andric bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
19550b57cec5SDimitry Andric                                    const SCEV *SrcConst, const SCEV *DstConst,
19560b57cec5SDimitry Andric                                    const Loop *SrcLoop, const Loop *DstLoop,
19570b57cec5SDimitry Andric                                    FullDependence &Result) const {
19580b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tExact RDIV test\n");
19590b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << " = AM\n");
19600b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << " = BM\n");
19610b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
19620b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
19630b57cec5SDimitry Andric   ++ExactRDIVapplications;
19640b57cec5SDimitry Andric   Result.Consistent = false;
19650b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
19660b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
19670b57cec5SDimitry Andric   const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
19680b57cec5SDimitry Andric   const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
19690b57cec5SDimitry Andric   const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
19700b57cec5SDimitry Andric   if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
19710b57cec5SDimitry Andric     return false;
19720b57cec5SDimitry Andric 
19730b57cec5SDimitry Andric   // find gcd
19740b57cec5SDimitry Andric   APInt G, X, Y;
19750b57cec5SDimitry Andric   APInt AM = ConstSrcCoeff->getAPInt();
19760b57cec5SDimitry Andric   APInt BM = ConstDstCoeff->getAPInt();
1977fe6060f1SDimitry Andric   APInt CM = ConstDelta->getAPInt();
19780b57cec5SDimitry Andric   unsigned Bits = AM.getBitWidth();
1979fe6060f1SDimitry Andric   if (findGCD(Bits, AM, BM, CM, G, X, Y)) {
19800b57cec5SDimitry Andric     // gcd doesn't divide Delta, no dependence
19810b57cec5SDimitry Andric     ++ExactRDIVindependence;
19820b57cec5SDimitry Andric     return true;
19830b57cec5SDimitry Andric   }
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    X = " << X << ", Y = " << Y << "\n");
19860b57cec5SDimitry Andric 
19870b57cec5SDimitry Andric   // since SCEV construction seems to normalize, LM = 0
19880b57cec5SDimitry Andric   APInt SrcUM(Bits, 1, true);
19890b57cec5SDimitry Andric   bool SrcUMvalid = false;
19900b57cec5SDimitry Andric   // SrcUM is perhaps unavailable, let's check
19910b57cec5SDimitry Andric   if (const SCEVConstant *UpperBound =
19920b57cec5SDimitry Andric           collectConstantUpperBound(SrcLoop, Delta->getType())) {
19930b57cec5SDimitry Andric     SrcUM = UpperBound->getAPInt();
19940b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    SrcUM = " << SrcUM << "\n");
19950b57cec5SDimitry Andric     SrcUMvalid = true;
19960b57cec5SDimitry Andric   }
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric   APInt DstUM(Bits, 1, true);
19990b57cec5SDimitry Andric   bool DstUMvalid = false;
20000b57cec5SDimitry Andric   // UM is perhaps unavailable, let's check
20010b57cec5SDimitry Andric   if (const SCEVConstant *UpperBound =
20020b57cec5SDimitry Andric           collectConstantUpperBound(DstLoop, Delta->getType())) {
20030b57cec5SDimitry Andric     DstUM = UpperBound->getAPInt();
20040b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    DstUM = " << DstUM << "\n");
20050b57cec5SDimitry Andric     DstUMvalid = true;
20060b57cec5SDimitry Andric   }
20070b57cec5SDimitry Andric 
20080b57cec5SDimitry Andric   APInt TU(APInt::getSignedMaxValue(Bits));
20090b57cec5SDimitry Andric   APInt TL(APInt::getSignedMinValue(Bits));
2010fe6060f1SDimitry Andric   APInt TC = CM.sdiv(G);
2011fe6060f1SDimitry Andric   APInt TX = X * TC;
2012fe6060f1SDimitry Andric   APInt TY = Y * TC;
2013fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TC = " << TC << "\n");
2014fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TX = " << TX << "\n");
2015fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TY = " << TY << "\n");
20160b57cec5SDimitry Andric 
2017fe6060f1SDimitry Andric   SmallVector<APInt, 2> TLVec, TUVec;
2018fe6060f1SDimitry Andric   APInt TB = BM.sdiv(G);
2019fe6060f1SDimitry Andric   if (TB.sgt(0)) {
2020fe6060f1SDimitry Andric     TLVec.push_back(ceilingOfQuotient(-TX, TB));
2021fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
20220b57cec5SDimitry Andric     if (SrcUMvalid) {
2023fe6060f1SDimitry Andric       TUVec.push_back(floorOfQuotient(SrcUM - TX, TB));
2024fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
20250b57cec5SDimitry Andric     }
2026fe6060f1SDimitry Andric   } else {
2027fe6060f1SDimitry Andric     TUVec.push_back(floorOfQuotient(-TX, TB));
2028fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
20290b57cec5SDimitry Andric     if (SrcUMvalid) {
2030fe6060f1SDimitry Andric       TLVec.push_back(ceilingOfQuotient(SrcUM - TX, TB));
2031fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
20320b57cec5SDimitry Andric     }
20330b57cec5SDimitry Andric   }
20340b57cec5SDimitry Andric 
2035fe6060f1SDimitry Andric   APInt TA = AM.sdiv(G);
2036fe6060f1SDimitry Andric   if (TA.sgt(0)) {
2037fe6060f1SDimitry Andric     TLVec.push_back(ceilingOfQuotient(-TY, TA));
2038fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
20390b57cec5SDimitry Andric     if (DstUMvalid) {
2040fe6060f1SDimitry Andric       TUVec.push_back(floorOfQuotient(DstUM - TY, TA));
2041fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
20420b57cec5SDimitry Andric     }
2043fe6060f1SDimitry Andric   } else {
2044fe6060f1SDimitry Andric     TUVec.push_back(floorOfQuotient(-TY, TA));
2045fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Possible TU = " << TUVec.back() << "\n");
20460b57cec5SDimitry Andric     if (DstUMvalid) {
2047fe6060f1SDimitry Andric       TLVec.push_back(ceilingOfQuotient(DstUM - TY, TA));
2048fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    Possible TL = " << TLVec.back() << "\n");
2049fe6060f1SDimitry Andric     }
2050fe6060f1SDimitry Andric   }
2051fe6060f1SDimitry Andric 
2052fe6060f1SDimitry Andric   if (TLVec.empty() || TUVec.empty())
2053fe6060f1SDimitry Andric     return false;
2054fe6060f1SDimitry Andric 
2055fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TA = " << TA << "\n");
2056fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TB = " << TB << "\n");
2057fe6060f1SDimitry Andric 
2058fe6060f1SDimitry Andric   TL = APIntOps::smax(TLVec.front(), TLVec.back());
2059fe6060f1SDimitry Andric   TU = APIntOps::smin(TUVec.front(), TUVec.back());
20600b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TL = " << TL << "\n");
2061fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    TU = " << TU << "\n");
2062fe6060f1SDimitry Andric 
20630b57cec5SDimitry Andric   if (TL.sgt(TU))
20640b57cec5SDimitry Andric     ++ExactRDIVindependence;
20650b57cec5SDimitry Andric   return TL.sgt(TU);
20660b57cec5SDimitry Andric }
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric 
20690b57cec5SDimitry Andric // symbolicRDIVtest -
20700b57cec5SDimitry Andric // In Section 4.5 of the Practical Dependence Testing paper,the authors
20710b57cec5SDimitry Andric // introduce a special case of Banerjee's Inequalities (also called the
20720b57cec5SDimitry Andric // Extreme-Value Test) that can handle some of the SIV and RDIV cases,
20730b57cec5SDimitry Andric // particularly cases with symbolics. Since it's only able to disprove
20740b57cec5SDimitry Andric // dependence (not compute distances or directions), we'll use it as a
20750b57cec5SDimitry Andric // fall back for the other tests.
20760b57cec5SDimitry Andric //
20770b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
20780b57cec5SDimitry Andric // where i and j are induction variables and c1 and c2 are loop invariants,
20790b57cec5SDimitry Andric // we can use the symbolic tests to disprove some dependences, serving as a
20800b57cec5SDimitry Andric // backup for the RDIV test. Note that i and j can be the same variable,
20810b57cec5SDimitry Andric // letting this test serve as a backup for the various SIV tests.
20820b57cec5SDimitry Andric //
20830b57cec5SDimitry Andric // For a dependence to exist, c1 + a1*i must equal c2 + a2*j for some
20840b57cec5SDimitry Andric //  0 <= i <= N1 and some 0 <= j <= N2, where N1 and N2 are the (normalized)
20850b57cec5SDimitry Andric // loop bounds for the i and j loops, respectively. So, ...
20860b57cec5SDimitry Andric //
20870b57cec5SDimitry Andric // c1 + a1*i = c2 + a2*j
20880b57cec5SDimitry Andric // a1*i - a2*j = c2 - c1
20890b57cec5SDimitry Andric //
20900b57cec5SDimitry Andric // To test for a dependence, we compute c2 - c1 and make sure it's in the
20910b57cec5SDimitry Andric // range of the maximum and minimum possible values of a1*i - a2*j.
20920b57cec5SDimitry Andric // Considering the signs of a1 and a2, we have 4 possible cases:
20930b57cec5SDimitry Andric //
20940b57cec5SDimitry Andric // 1) If a1 >= 0 and a2 >= 0, then
20950b57cec5SDimitry Andric //        a1*0 - a2*N2 <= c2 - c1 <= a1*N1 - a2*0
20960b57cec5SDimitry Andric //              -a2*N2 <= c2 - c1 <= a1*N1
20970b57cec5SDimitry Andric //
20980b57cec5SDimitry Andric // 2) If a1 >= 0 and a2 <= 0, then
20990b57cec5SDimitry Andric //        a1*0 - a2*0 <= c2 - c1 <= a1*N1 - a2*N2
21000b57cec5SDimitry Andric //                  0 <= c2 - c1 <= a1*N1 - a2*N2
21010b57cec5SDimitry Andric //
21020b57cec5SDimitry Andric // 3) If a1 <= 0 and a2 >= 0, then
21030b57cec5SDimitry Andric //        a1*N1 - a2*N2 <= c2 - c1 <= a1*0 - a2*0
21040b57cec5SDimitry Andric //        a1*N1 - a2*N2 <= c2 - c1 <= 0
21050b57cec5SDimitry Andric //
21060b57cec5SDimitry Andric // 4) If a1 <= 0 and a2 <= 0, then
21070b57cec5SDimitry Andric //        a1*N1 - a2*0  <= c2 - c1 <= a1*0 - a2*N2
21080b57cec5SDimitry Andric //        a1*N1         <= c2 - c1 <=       -a2*N2
21090b57cec5SDimitry Andric //
21100b57cec5SDimitry Andric // return true if dependence disproved
21110b57cec5SDimitry Andric bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
21120b57cec5SDimitry Andric                                       const SCEV *C1, const SCEV *C2,
21130b57cec5SDimitry Andric                                       const Loop *Loop1,
21140b57cec5SDimitry Andric                                       const Loop *Loop2) const {
21150b57cec5SDimitry Andric   ++SymbolicRDIVapplications;
21160b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\ttry symbolic RDIV test\n");
21170b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    A1 = " << *A1);
21180b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << ", type = " << *A1->getType() << "\n");
21190b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    A2 = " << *A2 << "\n");
21200b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    C1 = " << *C1 << "\n");
21210b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    C2 = " << *C2 << "\n");
21220b57cec5SDimitry Andric   const SCEV *N1 = collectUpperBound(Loop1, A1->getType());
21230b57cec5SDimitry Andric   const SCEV *N2 = collectUpperBound(Loop2, A1->getType());
21240b57cec5SDimitry Andric   LLVM_DEBUG(if (N1) dbgs() << "\t    N1 = " << *N1 << "\n");
21250b57cec5SDimitry Andric   LLVM_DEBUG(if (N2) dbgs() << "\t    N2 = " << *N2 << "\n");
21260b57cec5SDimitry Andric   const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
21270b57cec5SDimitry Andric   const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
21280b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    C2 - C1 = " << *C2_C1 << "\n");
21290b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    C1 - C2 = " << *C1_C2 << "\n");
21300b57cec5SDimitry Andric   if (SE->isKnownNonNegative(A1)) {
21310b57cec5SDimitry Andric     if (SE->isKnownNonNegative(A2)) {
21320b57cec5SDimitry Andric       // A1 >= 0 && A2 >= 0
21330b57cec5SDimitry Andric       if (N1) {
21340b57cec5SDimitry Andric         // make sure that c2 - c1 <= a1*N1
21350b57cec5SDimitry Andric         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
21360b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t    A1*N1 = " << *A1N1 << "\n");
21370b57cec5SDimitry Andric         if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1)) {
21380b57cec5SDimitry Andric           ++SymbolicRDIVindependence;
21390b57cec5SDimitry Andric           return true;
21400b57cec5SDimitry Andric         }
21410b57cec5SDimitry Andric       }
21420b57cec5SDimitry Andric       if (N2) {
21430b57cec5SDimitry Andric         // make sure that -a2*N2 <= c2 - c1, or a2*N2 >= c1 - c2
21440b57cec5SDimitry Andric         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
21450b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t    A2*N2 = " << *A2N2 << "\n");
21460b57cec5SDimitry Andric         if (isKnownPredicate(CmpInst::ICMP_SLT, A2N2, C1_C2)) {
21470b57cec5SDimitry Andric           ++SymbolicRDIVindependence;
21480b57cec5SDimitry Andric           return true;
21490b57cec5SDimitry Andric         }
21500b57cec5SDimitry Andric       }
21510b57cec5SDimitry Andric     }
21520b57cec5SDimitry Andric     else if (SE->isKnownNonPositive(A2)) {
21530b57cec5SDimitry Andric       // a1 >= 0 && a2 <= 0
21540b57cec5SDimitry Andric       if (N1 && N2) {
21550b57cec5SDimitry Andric         // make sure that c2 - c1 <= a1*N1 - a2*N2
21560b57cec5SDimitry Andric         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
21570b57cec5SDimitry Andric         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
21580b57cec5SDimitry Andric         const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
21590b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t    A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
21600b57cec5SDimitry Andric         if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1_A2N2)) {
21610b57cec5SDimitry Andric           ++SymbolicRDIVindependence;
21620b57cec5SDimitry Andric           return true;
21630b57cec5SDimitry Andric         }
21640b57cec5SDimitry Andric       }
21650b57cec5SDimitry Andric       // make sure that 0 <= c2 - c1
21660b57cec5SDimitry Andric       if (SE->isKnownNegative(C2_C1)) {
21670b57cec5SDimitry Andric         ++SymbolicRDIVindependence;
21680b57cec5SDimitry Andric         return true;
21690b57cec5SDimitry Andric       }
21700b57cec5SDimitry Andric     }
21710b57cec5SDimitry Andric   }
21720b57cec5SDimitry Andric   else if (SE->isKnownNonPositive(A1)) {
21730b57cec5SDimitry Andric     if (SE->isKnownNonNegative(A2)) {
21740b57cec5SDimitry Andric       // a1 <= 0 && a2 >= 0
21750b57cec5SDimitry Andric       if (N1 && N2) {
21760b57cec5SDimitry Andric         // make sure that a1*N1 - a2*N2 <= c2 - c1
21770b57cec5SDimitry Andric         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
21780b57cec5SDimitry Andric         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
21790b57cec5SDimitry Andric         const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
21800b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t    A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
21810b57cec5SDimitry Andric         if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1_A2N2, C2_C1)) {
21820b57cec5SDimitry Andric           ++SymbolicRDIVindependence;
21830b57cec5SDimitry Andric           return true;
21840b57cec5SDimitry Andric         }
21850b57cec5SDimitry Andric       }
21860b57cec5SDimitry Andric       // make sure that c2 - c1 <= 0
21870b57cec5SDimitry Andric       if (SE->isKnownPositive(C2_C1)) {
21880b57cec5SDimitry Andric         ++SymbolicRDIVindependence;
21890b57cec5SDimitry Andric         return true;
21900b57cec5SDimitry Andric       }
21910b57cec5SDimitry Andric     }
21920b57cec5SDimitry Andric     else if (SE->isKnownNonPositive(A2)) {
21930b57cec5SDimitry Andric       // a1 <= 0 && a2 <= 0
21940b57cec5SDimitry Andric       if (N1) {
21950b57cec5SDimitry Andric         // make sure that a1*N1 <= c2 - c1
21960b57cec5SDimitry Andric         const SCEV *A1N1 = SE->getMulExpr(A1, N1);
21970b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t    A1*N1 = " << *A1N1 << "\n");
21980b57cec5SDimitry Andric         if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1, C2_C1)) {
21990b57cec5SDimitry Andric           ++SymbolicRDIVindependence;
22000b57cec5SDimitry Andric           return true;
22010b57cec5SDimitry Andric         }
22020b57cec5SDimitry Andric       }
22030b57cec5SDimitry Andric       if (N2) {
22040b57cec5SDimitry Andric         // make sure that c2 - c1 <= -a2*N2, or c1 - c2 >= a2*N2
22050b57cec5SDimitry Andric         const SCEV *A2N2 = SE->getMulExpr(A2, N2);
22060b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\t    A2*N2 = " << *A2N2 << "\n");
22070b57cec5SDimitry Andric         if (isKnownPredicate(CmpInst::ICMP_SLT, C1_C2, A2N2)) {
22080b57cec5SDimitry Andric           ++SymbolicRDIVindependence;
22090b57cec5SDimitry Andric           return true;
22100b57cec5SDimitry Andric         }
22110b57cec5SDimitry Andric       }
22120b57cec5SDimitry Andric     }
22130b57cec5SDimitry Andric   }
22140b57cec5SDimitry Andric   return false;
22150b57cec5SDimitry Andric }
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric 
22180b57cec5SDimitry Andric // testSIV -
22190b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 - a2*i]
22200b57cec5SDimitry Andric // where i is an induction variable, c1 and c2 are loop invariant, and a1 and
22210b57cec5SDimitry Andric // a2 are constant, we attack it with an SIV test. While they can all be
22220b57cec5SDimitry Andric // solved with the Exact SIV test, it's worthwhile to use simpler tests when
22230b57cec5SDimitry Andric // they apply; they're cheaper and sometimes more precise.
22240b57cec5SDimitry Andric //
22250b57cec5SDimitry Andric // Return true if dependence disproved.
22260b57cec5SDimitry Andric bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
22270b57cec5SDimitry Andric                              FullDependence &Result, Constraint &NewConstraint,
22280b57cec5SDimitry Andric                              const SCEV *&SplitIter) const {
22290b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
22300b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
22310b57cec5SDimitry Andric   const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
22320b57cec5SDimitry Andric   const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
22330b57cec5SDimitry Andric   if (SrcAddRec && DstAddRec) {
22340b57cec5SDimitry Andric     const SCEV *SrcConst = SrcAddRec->getStart();
22350b57cec5SDimitry Andric     const SCEV *DstConst = DstAddRec->getStart();
22360b57cec5SDimitry Andric     const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
22370b57cec5SDimitry Andric     const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
22380b57cec5SDimitry Andric     const Loop *CurLoop = SrcAddRec->getLoop();
22390b57cec5SDimitry Andric     assert(CurLoop == DstAddRec->getLoop() &&
22400b57cec5SDimitry Andric            "both loops in SIV should be same");
22410b57cec5SDimitry Andric     Level = mapSrcLoop(CurLoop);
22420b57cec5SDimitry Andric     bool disproven;
22430b57cec5SDimitry Andric     if (SrcCoeff == DstCoeff)
22440b57cec5SDimitry Andric       disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
22450b57cec5SDimitry Andric                                 Level, Result, NewConstraint);
22460b57cec5SDimitry Andric     else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
22470b57cec5SDimitry Andric       disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
22480b57cec5SDimitry Andric                                       Level, Result, NewConstraint, SplitIter);
22490b57cec5SDimitry Andric     else
22500b57cec5SDimitry Andric       disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
22510b57cec5SDimitry Andric                                Level, Result, NewConstraint);
22520b57cec5SDimitry Andric     return disproven ||
22530b57cec5SDimitry Andric       gcdMIVtest(Src, Dst, Result) ||
22540b57cec5SDimitry Andric       symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop, CurLoop);
22550b57cec5SDimitry Andric   }
22560b57cec5SDimitry Andric   if (SrcAddRec) {
22570b57cec5SDimitry Andric     const SCEV *SrcConst = SrcAddRec->getStart();
22580b57cec5SDimitry Andric     const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
22590b57cec5SDimitry Andric     const SCEV *DstConst = Dst;
22600b57cec5SDimitry Andric     const Loop *CurLoop = SrcAddRec->getLoop();
22610b57cec5SDimitry Andric     Level = mapSrcLoop(CurLoop);
22620b57cec5SDimitry Andric     return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
22630b57cec5SDimitry Andric                               Level, Result, NewConstraint) ||
22640b57cec5SDimitry Andric       gcdMIVtest(Src, Dst, Result);
22650b57cec5SDimitry Andric   }
22660b57cec5SDimitry Andric   if (DstAddRec) {
22670b57cec5SDimitry Andric     const SCEV *DstConst = DstAddRec->getStart();
22680b57cec5SDimitry Andric     const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
22690b57cec5SDimitry Andric     const SCEV *SrcConst = Src;
22700b57cec5SDimitry Andric     const Loop *CurLoop = DstAddRec->getLoop();
22710b57cec5SDimitry Andric     Level = mapDstLoop(CurLoop);
22720b57cec5SDimitry Andric     return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst,
22730b57cec5SDimitry Andric                               CurLoop, Level, Result, NewConstraint) ||
22740b57cec5SDimitry Andric       gcdMIVtest(Src, Dst, Result);
22750b57cec5SDimitry Andric   }
22760b57cec5SDimitry Andric   llvm_unreachable("SIV test expected at least one AddRec");
22770b57cec5SDimitry Andric   return false;
22780b57cec5SDimitry Andric }
22790b57cec5SDimitry Andric 
22800b57cec5SDimitry Andric 
22810b57cec5SDimitry Andric // testRDIV -
22820b57cec5SDimitry Andric // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
22830b57cec5SDimitry Andric // where i and j are induction variables, c1 and c2 are loop invariant,
22840b57cec5SDimitry Andric // and a1 and a2 are constant, we can solve it exactly with an easy adaptation
22850b57cec5SDimitry Andric // of the Exact SIV test, the Restricted Double Index Variable (RDIV) test.
22860b57cec5SDimitry Andric // It doesn't make sense to talk about distance or direction in this case,
22870b57cec5SDimitry Andric // so there's no point in making special versions of the Strong SIV test or
22880b57cec5SDimitry Andric // the Weak-crossing SIV test.
22890b57cec5SDimitry Andric //
22900b57cec5SDimitry Andric // With minor algebra, this test can also be used for things like
22910b57cec5SDimitry Andric // [c1 + a1*i + a2*j][c2].
22920b57cec5SDimitry Andric //
22930b57cec5SDimitry Andric // Return true if dependence disproved.
22940b57cec5SDimitry Andric bool DependenceInfo::testRDIV(const SCEV *Src, const SCEV *Dst,
22950b57cec5SDimitry Andric                               FullDependence &Result) const {
22960b57cec5SDimitry Andric   // we have 3 possible situations here:
22970b57cec5SDimitry Andric   //   1) [a*i + b] and [c*j + d]
22980b57cec5SDimitry Andric   //   2) [a*i + c*j + b] and [d]
22990b57cec5SDimitry Andric   //   3) [b] and [a*i + c*j + d]
23000b57cec5SDimitry Andric   // We need to find what we've got and get organized
23010b57cec5SDimitry Andric 
23020b57cec5SDimitry Andric   const SCEV *SrcConst, *DstConst;
23030b57cec5SDimitry Andric   const SCEV *SrcCoeff, *DstCoeff;
23040b57cec5SDimitry Andric   const Loop *SrcLoop, *DstLoop;
23050b57cec5SDimitry Andric 
23060b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
23070b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
23080b57cec5SDimitry Andric   const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
23090b57cec5SDimitry Andric   const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
23100b57cec5SDimitry Andric   if (SrcAddRec && DstAddRec) {
23110b57cec5SDimitry Andric     SrcConst = SrcAddRec->getStart();
23120b57cec5SDimitry Andric     SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
23130b57cec5SDimitry Andric     SrcLoop = SrcAddRec->getLoop();
23140b57cec5SDimitry Andric     DstConst = DstAddRec->getStart();
23150b57cec5SDimitry Andric     DstCoeff = DstAddRec->getStepRecurrence(*SE);
23160b57cec5SDimitry Andric     DstLoop = DstAddRec->getLoop();
23170b57cec5SDimitry Andric   }
23180b57cec5SDimitry Andric   else if (SrcAddRec) {
23190b57cec5SDimitry Andric     if (const SCEVAddRecExpr *tmpAddRec =
23200b57cec5SDimitry Andric         dyn_cast<SCEVAddRecExpr>(SrcAddRec->getStart())) {
23210b57cec5SDimitry Andric       SrcConst = tmpAddRec->getStart();
23220b57cec5SDimitry Andric       SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
23230b57cec5SDimitry Andric       SrcLoop = tmpAddRec->getLoop();
23240b57cec5SDimitry Andric       DstConst = Dst;
23250b57cec5SDimitry Andric       DstCoeff = SE->getNegativeSCEV(SrcAddRec->getStepRecurrence(*SE));
23260b57cec5SDimitry Andric       DstLoop = SrcAddRec->getLoop();
23270b57cec5SDimitry Andric     }
23280b57cec5SDimitry Andric     else
23290b57cec5SDimitry Andric       llvm_unreachable("RDIV reached by surprising SCEVs");
23300b57cec5SDimitry Andric   }
23310b57cec5SDimitry Andric   else if (DstAddRec) {
23320b57cec5SDimitry Andric     if (const SCEVAddRecExpr *tmpAddRec =
23330b57cec5SDimitry Andric         dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
23340b57cec5SDimitry Andric       DstConst = tmpAddRec->getStart();
23350b57cec5SDimitry Andric       DstCoeff = tmpAddRec->getStepRecurrence(*SE);
23360b57cec5SDimitry Andric       DstLoop = tmpAddRec->getLoop();
23370b57cec5SDimitry Andric       SrcConst = Src;
23380b57cec5SDimitry Andric       SrcCoeff = SE->getNegativeSCEV(DstAddRec->getStepRecurrence(*SE));
23390b57cec5SDimitry Andric       SrcLoop = DstAddRec->getLoop();
23400b57cec5SDimitry Andric     }
23410b57cec5SDimitry Andric     else
23420b57cec5SDimitry Andric       llvm_unreachable("RDIV reached by surprising SCEVs");
23430b57cec5SDimitry Andric   }
23440b57cec5SDimitry Andric   else
23450b57cec5SDimitry Andric     llvm_unreachable("RDIV expected at least one AddRec");
23460b57cec5SDimitry Andric   return exactRDIVtest(SrcCoeff, DstCoeff,
23470b57cec5SDimitry Andric                        SrcConst, DstConst,
23480b57cec5SDimitry Andric                        SrcLoop, DstLoop,
23490b57cec5SDimitry Andric                        Result) ||
23500b57cec5SDimitry Andric     gcdMIVtest(Src, Dst, Result) ||
23510b57cec5SDimitry Andric     symbolicRDIVtest(SrcCoeff, DstCoeff,
23520b57cec5SDimitry Andric                      SrcConst, DstConst,
23530b57cec5SDimitry Andric                      SrcLoop, DstLoop);
23540b57cec5SDimitry Andric }
23550b57cec5SDimitry Andric 
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric // Tests the single-subscript MIV pair (Src and Dst) for dependence.
23580b57cec5SDimitry Andric // Return true if dependence disproved.
23590b57cec5SDimitry Andric // Can sometimes refine direction vectors.
23600b57cec5SDimitry Andric bool DependenceInfo::testMIV(const SCEV *Src, const SCEV *Dst,
23610b57cec5SDimitry Andric                              const SmallBitVector &Loops,
23620b57cec5SDimitry Andric                              FullDependence &Result) const {
23630b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
23640b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
23650b57cec5SDimitry Andric   Result.Consistent = false;
23660b57cec5SDimitry Andric   return gcdMIVtest(Src, Dst, Result) ||
23670b57cec5SDimitry Andric     banerjeeMIVtest(Src, Dst, Loops, Result);
23680b57cec5SDimitry Andric }
23690b57cec5SDimitry Andric 
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric // Given a product, e.g., 10*X*Y, returns the first constant operand,
23720b57cec5SDimitry Andric // in this case 10. If there is no constant part, returns NULL.
23730b57cec5SDimitry Andric static
23740b57cec5SDimitry Andric const SCEVConstant *getConstantPart(const SCEV *Expr) {
23750b57cec5SDimitry Andric   if (const auto *Constant = dyn_cast<SCEVConstant>(Expr))
23760b57cec5SDimitry Andric     return Constant;
23770b57cec5SDimitry Andric   else if (const auto *Product = dyn_cast<SCEVMulExpr>(Expr))
23780b57cec5SDimitry Andric     if (const auto *Constant = dyn_cast<SCEVConstant>(Product->getOperand(0)))
23790b57cec5SDimitry Andric       return Constant;
23800b57cec5SDimitry Andric   return nullptr;
23810b57cec5SDimitry Andric }
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric 
23840b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23850b57cec5SDimitry Andric // gcdMIVtest -
23860b57cec5SDimitry Andric // Tests an MIV subscript pair for dependence.
23870b57cec5SDimitry Andric // Returns true if any possible dependence is disproved.
23880b57cec5SDimitry Andric // Marks the result as inconsistent.
23890b57cec5SDimitry Andric // Can sometimes disprove the equal direction for 1 or more loops,
23900b57cec5SDimitry Andric // as discussed in Michael Wolfe's book,
23910b57cec5SDimitry Andric // High Performance Compilers for Parallel Computing, page 235.
23920b57cec5SDimitry Andric //
23930b57cec5SDimitry Andric // We spend some effort (code!) to handle cases like
23940b57cec5SDimitry Andric // [10*i + 5*N*j + 15*M + 6], where i and j are induction variables,
23950b57cec5SDimitry Andric // but M and N are just loop-invariant variables.
23960b57cec5SDimitry Andric // This should help us handle linearized subscripts;
23970b57cec5SDimitry Andric // also makes this test a useful backup to the various SIV tests.
23980b57cec5SDimitry Andric //
23990b57cec5SDimitry Andric // It occurs to me that the presence of loop-invariant variables
24000b57cec5SDimitry Andric // changes the nature of the test from "greatest common divisor"
24010b57cec5SDimitry Andric // to "a common divisor".
24020b57cec5SDimitry Andric bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
24030b57cec5SDimitry Andric                                 FullDependence &Result) const {
24040b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "starting gcd\n");
24050b57cec5SDimitry Andric   ++GCDapplications;
24060b57cec5SDimitry Andric   unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
2407349cc55cSDimitry Andric   APInt RunningGCD = APInt::getZero(BitWidth);
24080b57cec5SDimitry Andric 
24090b57cec5SDimitry Andric   // Examine Src coefficients.
24100b57cec5SDimitry Andric   // Compute running GCD and record source constant.
24110b57cec5SDimitry Andric   // Because we're looking for the constant at the end of the chain,
24120b57cec5SDimitry Andric   // we can't quit the loop just because the GCD == 1.
24130b57cec5SDimitry Andric   const SCEV *Coefficients = Src;
24140b57cec5SDimitry Andric   while (const SCEVAddRecExpr *AddRec =
24150b57cec5SDimitry Andric          dyn_cast<SCEVAddRecExpr>(Coefficients)) {
24160b57cec5SDimitry Andric     const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
24170b57cec5SDimitry Andric     // If the coefficient is the product of a constant and other stuff,
24180b57cec5SDimitry Andric     // we can use the constant in the GCD computation.
24190b57cec5SDimitry Andric     const auto *Constant = getConstantPart(Coeff);
24200b57cec5SDimitry Andric     if (!Constant)
24210b57cec5SDimitry Andric       return false;
24220b57cec5SDimitry Andric     APInt ConstCoeff = Constant->getAPInt();
24230b57cec5SDimitry Andric     RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
24240b57cec5SDimitry Andric     Coefficients = AddRec->getStart();
24250b57cec5SDimitry Andric   }
24260b57cec5SDimitry Andric   const SCEV *SrcConst = Coefficients;
24270b57cec5SDimitry Andric 
24280b57cec5SDimitry Andric   // Examine Dst coefficients.
24290b57cec5SDimitry Andric   // Compute running GCD and record destination constant.
24300b57cec5SDimitry Andric   // Because we're looking for the constant at the end of the chain,
24310b57cec5SDimitry Andric   // we can't quit the loop just because the GCD == 1.
24320b57cec5SDimitry Andric   Coefficients = Dst;
24330b57cec5SDimitry Andric   while (const SCEVAddRecExpr *AddRec =
24340b57cec5SDimitry Andric          dyn_cast<SCEVAddRecExpr>(Coefficients)) {
24350b57cec5SDimitry Andric     const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
24360b57cec5SDimitry Andric     // If the coefficient is the product of a constant and other stuff,
24370b57cec5SDimitry Andric     // we can use the constant in the GCD computation.
24380b57cec5SDimitry Andric     const auto *Constant = getConstantPart(Coeff);
24390b57cec5SDimitry Andric     if (!Constant)
24400b57cec5SDimitry Andric       return false;
24410b57cec5SDimitry Andric     APInt ConstCoeff = Constant->getAPInt();
24420b57cec5SDimitry Andric     RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
24430b57cec5SDimitry Andric     Coefficients = AddRec->getStart();
24440b57cec5SDimitry Andric   }
24450b57cec5SDimitry Andric   const SCEV *DstConst = Coefficients;
24460b57cec5SDimitry Andric 
2447349cc55cSDimitry Andric   APInt ExtraGCD = APInt::getZero(BitWidth);
24480b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
24490b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    Delta = " << *Delta << "\n");
24500b57cec5SDimitry Andric   const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Delta);
24510b57cec5SDimitry Andric   if (const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
24520b57cec5SDimitry Andric     // If Delta is a sum of products, we may be able to make further progress.
24530b57cec5SDimitry Andric     for (unsigned Op = 0, Ops = Sum->getNumOperands(); Op < Ops; Op++) {
24540b57cec5SDimitry Andric       const SCEV *Operand = Sum->getOperand(Op);
24550b57cec5SDimitry Andric       if (isa<SCEVConstant>(Operand)) {
24560b57cec5SDimitry Andric         assert(!Constant && "Surprised to find multiple constants");
24570b57cec5SDimitry Andric         Constant = cast<SCEVConstant>(Operand);
24580b57cec5SDimitry Andric       }
24590b57cec5SDimitry Andric       else if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
24600b57cec5SDimitry Andric         // Search for constant operand to participate in GCD;
24610b57cec5SDimitry Andric         // If none found; return false.
24620b57cec5SDimitry Andric         const SCEVConstant *ConstOp = getConstantPart(Product);
24630b57cec5SDimitry Andric         if (!ConstOp)
24640b57cec5SDimitry Andric           return false;
24650b57cec5SDimitry Andric         APInt ConstOpValue = ConstOp->getAPInt();
24660b57cec5SDimitry Andric         ExtraGCD = APIntOps::GreatestCommonDivisor(ExtraGCD,
24670b57cec5SDimitry Andric                                                    ConstOpValue.abs());
24680b57cec5SDimitry Andric       }
24690b57cec5SDimitry Andric       else
24700b57cec5SDimitry Andric         return false;
24710b57cec5SDimitry Andric     }
24720b57cec5SDimitry Andric   }
24730b57cec5SDimitry Andric   if (!Constant)
24740b57cec5SDimitry Andric     return false;
24750b57cec5SDimitry Andric   APInt ConstDelta = cast<SCEVConstant>(Constant)->getAPInt();
24760b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    ConstDelta = " << ConstDelta << "\n");
24770b57cec5SDimitry Andric   if (ConstDelta == 0)
24780b57cec5SDimitry Andric     return false;
24790b57cec5SDimitry Andric   RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ExtraGCD);
24800b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    RunningGCD = " << RunningGCD << "\n");
24810b57cec5SDimitry Andric   APInt Remainder = ConstDelta.srem(RunningGCD);
24820b57cec5SDimitry Andric   if (Remainder != 0) {
24830b57cec5SDimitry Andric     ++GCDindependence;
24840b57cec5SDimitry Andric     return true;
24850b57cec5SDimitry Andric   }
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric   // Try to disprove equal directions.
24880b57cec5SDimitry Andric   // For example, given a subscript pair [3*i + 2*j] and [i' + 2*j' - 1],
24890b57cec5SDimitry Andric   // the code above can't disprove the dependence because the GCD = 1.
24900b57cec5SDimitry Andric   // So we consider what happen if i = i' and what happens if j = j'.
24910b57cec5SDimitry Andric   // If i = i', we can simplify the subscript to [2*i + 2*j] and [2*j' - 1],
24920b57cec5SDimitry Andric   // which is infeasible, so we can disallow the = direction for the i level.
24930b57cec5SDimitry Andric   // Setting j = j' doesn't help matters, so we end up with a direction vector
24940b57cec5SDimitry Andric   // of [<>, *]
24950b57cec5SDimitry Andric   //
24960b57cec5SDimitry Andric   // Given A[5*i + 10*j*M + 9*M*N] and A[15*i + 20*j*M - 21*N*M + 5],
24970b57cec5SDimitry Andric   // we need to remember that the constant part is 5 and the RunningGCD should
24980b57cec5SDimitry Andric   // be initialized to ExtraGCD = 30.
24990b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    ExtraGCD = " << ExtraGCD << '\n');
25000b57cec5SDimitry Andric 
25010b57cec5SDimitry Andric   bool Improved = false;
25020b57cec5SDimitry Andric   Coefficients = Src;
25030b57cec5SDimitry Andric   while (const SCEVAddRecExpr *AddRec =
25040b57cec5SDimitry Andric          dyn_cast<SCEVAddRecExpr>(Coefficients)) {
25050b57cec5SDimitry Andric     Coefficients = AddRec->getStart();
25060b57cec5SDimitry Andric     const Loop *CurLoop = AddRec->getLoop();
25070b57cec5SDimitry Andric     RunningGCD = ExtraGCD;
25080b57cec5SDimitry Andric     const SCEV *SrcCoeff = AddRec->getStepRecurrence(*SE);
25090b57cec5SDimitry Andric     const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);
25100b57cec5SDimitry Andric     const SCEV *Inner = Src;
25110b57cec5SDimitry Andric     while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
25120b57cec5SDimitry Andric       AddRec = cast<SCEVAddRecExpr>(Inner);
25130b57cec5SDimitry Andric       const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
25140b57cec5SDimitry Andric       if (CurLoop == AddRec->getLoop())
25150b57cec5SDimitry Andric         ; // SrcCoeff == Coeff
25160b57cec5SDimitry Andric       else {
25170b57cec5SDimitry Andric         // If the coefficient is the product of a constant and other stuff,
25180b57cec5SDimitry Andric         // we can use the constant in the GCD computation.
25190b57cec5SDimitry Andric         Constant = getConstantPart(Coeff);
25200b57cec5SDimitry Andric         if (!Constant)
25210b57cec5SDimitry Andric           return false;
25220b57cec5SDimitry Andric         APInt ConstCoeff = Constant->getAPInt();
25230b57cec5SDimitry Andric         RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
25240b57cec5SDimitry Andric       }
25250b57cec5SDimitry Andric       Inner = AddRec->getStart();
25260b57cec5SDimitry Andric     }
25270b57cec5SDimitry Andric     Inner = Dst;
25280b57cec5SDimitry Andric     while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
25290b57cec5SDimitry Andric       AddRec = cast<SCEVAddRecExpr>(Inner);
25300b57cec5SDimitry Andric       const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
25310b57cec5SDimitry Andric       if (CurLoop == AddRec->getLoop())
25320b57cec5SDimitry Andric         DstCoeff = Coeff;
25330b57cec5SDimitry Andric       else {
25340b57cec5SDimitry Andric         // If the coefficient is the product of a constant and other stuff,
25350b57cec5SDimitry Andric         // we can use the constant in the GCD computation.
25360b57cec5SDimitry Andric         Constant = getConstantPart(Coeff);
25370b57cec5SDimitry Andric         if (!Constant)
25380b57cec5SDimitry Andric           return false;
25390b57cec5SDimitry Andric         APInt ConstCoeff = Constant->getAPInt();
25400b57cec5SDimitry Andric         RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
25410b57cec5SDimitry Andric       }
25420b57cec5SDimitry Andric       Inner = AddRec->getStart();
25430b57cec5SDimitry Andric     }
25440b57cec5SDimitry Andric     Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
25450b57cec5SDimitry Andric     // If the coefficient is the product of a constant and other stuff,
25460b57cec5SDimitry Andric     // we can use the constant in the GCD computation.
25470b57cec5SDimitry Andric     Constant = getConstantPart(Delta);
25480b57cec5SDimitry Andric     if (!Constant)
25490b57cec5SDimitry Andric       // The difference of the two coefficients might not be a product
25500b57cec5SDimitry Andric       // or constant, in which case we give up on this direction.
25510b57cec5SDimitry Andric       continue;
25520b57cec5SDimitry Andric     APInt ConstCoeff = Constant->getAPInt();
25530b57cec5SDimitry Andric     RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
25540b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tRunningGCD = " << RunningGCD << "\n");
25550b57cec5SDimitry Andric     if (RunningGCD != 0) {
25560b57cec5SDimitry Andric       Remainder = ConstDelta.srem(RunningGCD);
25570b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\tRemainder = " << Remainder << "\n");
25580b57cec5SDimitry Andric       if (Remainder != 0) {
25590b57cec5SDimitry Andric         unsigned Level = mapSrcLoop(CurLoop);
2560bdd1243dSDimitry Andric         Result.DV[Level - 1].Direction &= ~Dependence::DVEntry::EQ;
25610b57cec5SDimitry Andric         Improved = true;
25620b57cec5SDimitry Andric       }
25630b57cec5SDimitry Andric     }
25640b57cec5SDimitry Andric   }
25650b57cec5SDimitry Andric   if (Improved)
25660b57cec5SDimitry Andric     ++GCDsuccesses;
25670b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "all done\n");
25680b57cec5SDimitry Andric   return false;
25690b57cec5SDimitry Andric }
25700b57cec5SDimitry Andric 
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25730b57cec5SDimitry Andric // banerjeeMIVtest -
25740b57cec5SDimitry Andric // Use Banerjee's Inequalities to test an MIV subscript pair.
25750b57cec5SDimitry Andric // (Wolfe, in the race-car book, calls this the Extreme Value Test.)
25760b57cec5SDimitry Andric // Generally follows the discussion in Section 2.5.2 of
25770b57cec5SDimitry Andric //
25780b57cec5SDimitry Andric //    Optimizing Supercompilers for Supercomputers
25790b57cec5SDimitry Andric //    Michael Wolfe
25800b57cec5SDimitry Andric //
25810b57cec5SDimitry Andric // The inequalities given on page 25 are simplified in that loops are
25820b57cec5SDimitry Andric // normalized so that the lower bound is always 0 and the stride is always 1.
25830b57cec5SDimitry Andric // For example, Wolfe gives
25840b57cec5SDimitry Andric //
25850b57cec5SDimitry Andric //     LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
25860b57cec5SDimitry Andric //
25870b57cec5SDimitry Andric // where A_k is the coefficient of the kth index in the source subscript,
25880b57cec5SDimitry Andric // B_k is the coefficient of the kth index in the destination subscript,
25890b57cec5SDimitry Andric // U_k is the upper bound of the kth index, L_k is the lower bound of the Kth
25900b57cec5SDimitry Andric // index, and N_k is the stride of the kth index. Since all loops are normalized
25910b57cec5SDimitry Andric // by the SCEV package, N_k = 1 and L_k = 0, allowing us to simplify the
25920b57cec5SDimitry Andric // equation to
25930b57cec5SDimitry Andric //
25940b57cec5SDimitry Andric //     LB^<_k = (A^-_k - B_k)^- (U_k - 0 - 1) + (A_k - B_k)0 - B_k 1
25950b57cec5SDimitry Andric //            = (A^-_k - B_k)^- (U_k - 1)  - B_k
25960b57cec5SDimitry Andric //
25970b57cec5SDimitry Andric // Similar simplifications are possible for the other equations.
25980b57cec5SDimitry Andric //
25990b57cec5SDimitry Andric // When we can't determine the number of iterations for a loop,
26000b57cec5SDimitry Andric // we use NULL as an indicator for the worst case, infinity.
26010b57cec5SDimitry Andric // When computing the upper bound, NULL denotes +inf;
26020b57cec5SDimitry Andric // for the lower bound, NULL denotes -inf.
26030b57cec5SDimitry Andric //
26040b57cec5SDimitry Andric // Return true if dependence disproved.
26050b57cec5SDimitry Andric bool DependenceInfo::banerjeeMIVtest(const SCEV *Src, const SCEV *Dst,
26060b57cec5SDimitry Andric                                      const SmallBitVector &Loops,
26070b57cec5SDimitry Andric                                      FullDependence &Result) const {
26080b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "starting Banerjee\n");
26090b57cec5SDimitry Andric   ++BanerjeeApplications;
26100b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    Src = " << *Src << '\n');
26110b57cec5SDimitry Andric   const SCEV *A0;
26120b57cec5SDimitry Andric   CoefficientInfo *A = collectCoeffInfo(Src, true, A0);
26130b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    Dst = " << *Dst << '\n');
26140b57cec5SDimitry Andric   const SCEV *B0;
26150b57cec5SDimitry Andric   CoefficientInfo *B = collectCoeffInfo(Dst, false, B0);
26160b57cec5SDimitry Andric   BoundInfo *Bound = new BoundInfo[MaxLevels + 1];
26170b57cec5SDimitry Andric   const SCEV *Delta = SE->getMinusSCEV(B0, A0);
26180b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tDelta = " << *Delta << '\n');
26190b57cec5SDimitry Andric 
26200b57cec5SDimitry Andric   // Compute bounds for all the * directions.
26210b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tBounds[*]\n");
26220b57cec5SDimitry Andric   for (unsigned K = 1; K <= MaxLevels; ++K) {
26230b57cec5SDimitry Andric     Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
26240b57cec5SDimitry Andric     Bound[K].Direction = Dependence::DVEntry::ALL;
26250b57cec5SDimitry Andric     Bound[K].DirSet = Dependence::DVEntry::NONE;
26260b57cec5SDimitry Andric     findBoundsALL(A, B, Bound, K);
26270b57cec5SDimitry Andric #ifndef NDEBUG
26280b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    " << K << '\t');
26290b57cec5SDimitry Andric     if (Bound[K].Lower[Dependence::DVEntry::ALL])
26300b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << *Bound[K].Lower[Dependence::DVEntry::ALL] << '\t');
26310b57cec5SDimitry Andric     else
26320b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "-inf\t");
26330b57cec5SDimitry Andric     if (Bound[K].Upper[Dependence::DVEntry::ALL])
26340b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << *Bound[K].Upper[Dependence::DVEntry::ALL] << '\n');
26350b57cec5SDimitry Andric     else
26360b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "+inf\n");
26370b57cec5SDimitry Andric #endif
26380b57cec5SDimitry Andric   }
26390b57cec5SDimitry Andric 
26400b57cec5SDimitry Andric   // Test the *, *, *, ... case.
26410b57cec5SDimitry Andric   bool Disproved = false;
26420b57cec5SDimitry Andric   if (testBounds(Dependence::DVEntry::ALL, 0, Bound, Delta)) {
26430b57cec5SDimitry Andric     // Explore the direction vector hierarchy.
26440b57cec5SDimitry Andric     unsigned DepthExpanded = 0;
26450b57cec5SDimitry Andric     unsigned NewDeps = exploreDirections(1, A, B, Bound,
26460b57cec5SDimitry Andric                                          Loops, DepthExpanded, Delta);
26470b57cec5SDimitry Andric     if (NewDeps > 0) {
26480b57cec5SDimitry Andric       bool Improved = false;
26490b57cec5SDimitry Andric       for (unsigned K = 1; K <= CommonLevels; ++K) {
26500b57cec5SDimitry Andric         if (Loops[K]) {
26510b57cec5SDimitry Andric           unsigned Old = Result.DV[K - 1].Direction;
26520b57cec5SDimitry Andric           Result.DV[K - 1].Direction = Old & Bound[K].DirSet;
26530b57cec5SDimitry Andric           Improved |= Old != Result.DV[K - 1].Direction;
26540b57cec5SDimitry Andric           if (!Result.DV[K - 1].Direction) {
26550b57cec5SDimitry Andric             Improved = false;
26560b57cec5SDimitry Andric             Disproved = true;
26570b57cec5SDimitry Andric             break;
26580b57cec5SDimitry Andric           }
26590b57cec5SDimitry Andric         }
26600b57cec5SDimitry Andric       }
26610b57cec5SDimitry Andric       if (Improved)
26620b57cec5SDimitry Andric         ++BanerjeeSuccesses;
26630b57cec5SDimitry Andric     }
26640b57cec5SDimitry Andric     else {
26650b57cec5SDimitry Andric       ++BanerjeeIndependence;
26660b57cec5SDimitry Andric       Disproved = true;
26670b57cec5SDimitry Andric     }
26680b57cec5SDimitry Andric   }
26690b57cec5SDimitry Andric   else {
26700b57cec5SDimitry Andric     ++BanerjeeIndependence;
26710b57cec5SDimitry Andric     Disproved = true;
26720b57cec5SDimitry Andric   }
26730b57cec5SDimitry Andric   delete [] Bound;
26740b57cec5SDimitry Andric   delete [] A;
26750b57cec5SDimitry Andric   delete [] B;
26760b57cec5SDimitry Andric   return Disproved;
26770b57cec5SDimitry Andric }
26780b57cec5SDimitry Andric 
26790b57cec5SDimitry Andric 
26800b57cec5SDimitry Andric // Hierarchically expands the direction vector
26810b57cec5SDimitry Andric // search space, combining the directions of discovered dependences
26820b57cec5SDimitry Andric // in the DirSet field of Bound. Returns the number of distinct
26830b57cec5SDimitry Andric // dependences discovered. If the dependence is disproved,
26840b57cec5SDimitry Andric // it will return 0.
26850b57cec5SDimitry Andric unsigned DependenceInfo::exploreDirections(unsigned Level, CoefficientInfo *A,
26860b57cec5SDimitry Andric                                            CoefficientInfo *B, BoundInfo *Bound,
26870b57cec5SDimitry Andric                                            const SmallBitVector &Loops,
26880b57cec5SDimitry Andric                                            unsigned &DepthExpanded,
26890b57cec5SDimitry Andric                                            const SCEV *Delta) const {
2690349cc55cSDimitry Andric   // This algorithm has worst case complexity of O(3^n), where 'n' is the number
2691349cc55cSDimitry Andric   // of common loop levels. To avoid excessive compile-time, pessimize all the
2692349cc55cSDimitry Andric   // results and immediately return when the number of common levels is beyond
2693349cc55cSDimitry Andric   // the given threshold.
2694349cc55cSDimitry Andric   if (CommonLevels > MIVMaxLevelThreshold) {
2695349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Number of common levels exceeded the threshold. MIV "
2696349cc55cSDimitry Andric                          "direction exploration is terminated.\n");
2697349cc55cSDimitry Andric     for (unsigned K = 1; K <= CommonLevels; ++K)
2698349cc55cSDimitry Andric       if (Loops[K])
2699349cc55cSDimitry Andric         Bound[K].DirSet = Dependence::DVEntry::ALL;
2700349cc55cSDimitry Andric     return 1;
2701349cc55cSDimitry Andric   }
2702349cc55cSDimitry Andric 
27030b57cec5SDimitry Andric   if (Level > CommonLevels) {
27040b57cec5SDimitry Andric     // record result
27050b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t[");
27060b57cec5SDimitry Andric     for (unsigned K = 1; K <= CommonLevels; ++K) {
27070b57cec5SDimitry Andric       if (Loops[K]) {
27080b57cec5SDimitry Andric         Bound[K].DirSet |= Bound[K].Direction;
27090b57cec5SDimitry Andric #ifndef NDEBUG
27100b57cec5SDimitry Andric         switch (Bound[K].Direction) {
27110b57cec5SDimitry Andric         case Dependence::DVEntry::LT:
27120b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << " <");
27130b57cec5SDimitry Andric           break;
27140b57cec5SDimitry Andric         case Dependence::DVEntry::EQ:
27150b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << " =");
27160b57cec5SDimitry Andric           break;
27170b57cec5SDimitry Andric         case Dependence::DVEntry::GT:
27180b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << " >");
27190b57cec5SDimitry Andric           break;
27200b57cec5SDimitry Andric         case Dependence::DVEntry::ALL:
27210b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << " *");
27220b57cec5SDimitry Andric           break;
27230b57cec5SDimitry Andric         default:
27240b57cec5SDimitry Andric           llvm_unreachable("unexpected Bound[K].Direction");
27250b57cec5SDimitry Andric         }
27260b57cec5SDimitry Andric #endif
27270b57cec5SDimitry Andric       }
27280b57cec5SDimitry Andric     }
27290b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " ]\n");
27300b57cec5SDimitry Andric     return 1;
27310b57cec5SDimitry Andric   }
27320b57cec5SDimitry Andric   if (Loops[Level]) {
27330b57cec5SDimitry Andric     if (Level > DepthExpanded) {
27340b57cec5SDimitry Andric       DepthExpanded = Level;
27350b57cec5SDimitry Andric       // compute bounds for <, =, > at current level
27360b57cec5SDimitry Andric       findBoundsLT(A, B, Bound, Level);
27370b57cec5SDimitry Andric       findBoundsGT(A, B, Bound, Level);
27380b57cec5SDimitry Andric       findBoundsEQ(A, B, Bound, Level);
27390b57cec5SDimitry Andric #ifndef NDEBUG
27400b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\tBound for level = " << Level << '\n');
27410b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    <\t");
27420b57cec5SDimitry Andric       if (Bound[Level].Lower[Dependence::DVEntry::LT])
27430b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::LT]
27440b57cec5SDimitry Andric                           << '\t');
27450b57cec5SDimitry Andric       else
27460b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "-inf\t");
27470b57cec5SDimitry Andric       if (Bound[Level].Upper[Dependence::DVEntry::LT])
27480b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::LT]
27490b57cec5SDimitry Andric                           << '\n');
27500b57cec5SDimitry Andric       else
27510b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "+inf\n");
27520b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    =\t");
27530b57cec5SDimitry Andric       if (Bound[Level].Lower[Dependence::DVEntry::EQ])
27540b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::EQ]
27550b57cec5SDimitry Andric                           << '\t');
27560b57cec5SDimitry Andric       else
27570b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "-inf\t");
27580b57cec5SDimitry Andric       if (Bound[Level].Upper[Dependence::DVEntry::EQ])
27590b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::EQ]
27600b57cec5SDimitry Andric                           << '\n');
27610b57cec5SDimitry Andric       else
27620b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "+inf\n");
27630b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\t    >\t");
27640b57cec5SDimitry Andric       if (Bound[Level].Lower[Dependence::DVEntry::GT])
27650b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::GT]
27660b57cec5SDimitry Andric                           << '\t');
27670b57cec5SDimitry Andric       else
27680b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "-inf\t");
27690b57cec5SDimitry Andric       if (Bound[Level].Upper[Dependence::DVEntry::GT])
27700b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::GT]
27710b57cec5SDimitry Andric                           << '\n');
27720b57cec5SDimitry Andric       else
27730b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "+inf\n");
27740b57cec5SDimitry Andric #endif
27750b57cec5SDimitry Andric     }
27760b57cec5SDimitry Andric 
27770b57cec5SDimitry Andric     unsigned NewDeps = 0;
27780b57cec5SDimitry Andric 
27790b57cec5SDimitry Andric     // test bounds for <, *, *, ...
27800b57cec5SDimitry Andric     if (testBounds(Dependence::DVEntry::LT, Level, Bound, Delta))
27810b57cec5SDimitry Andric       NewDeps += exploreDirections(Level + 1, A, B, Bound,
27820b57cec5SDimitry Andric                                    Loops, DepthExpanded, Delta);
27830b57cec5SDimitry Andric 
27840b57cec5SDimitry Andric     // Test bounds for =, *, *, ...
27850b57cec5SDimitry Andric     if (testBounds(Dependence::DVEntry::EQ, Level, Bound, Delta))
27860b57cec5SDimitry Andric       NewDeps += exploreDirections(Level + 1, A, B, Bound,
27870b57cec5SDimitry Andric                                    Loops, DepthExpanded, Delta);
27880b57cec5SDimitry Andric 
27890b57cec5SDimitry Andric     // test bounds for >, *, *, ...
27900b57cec5SDimitry Andric     if (testBounds(Dependence::DVEntry::GT, Level, Bound, Delta))
27910b57cec5SDimitry Andric       NewDeps += exploreDirections(Level + 1, A, B, Bound,
27920b57cec5SDimitry Andric                                    Loops, DepthExpanded, Delta);
27930b57cec5SDimitry Andric 
27940b57cec5SDimitry Andric     Bound[Level].Direction = Dependence::DVEntry::ALL;
27950b57cec5SDimitry Andric     return NewDeps;
27960b57cec5SDimitry Andric   }
27970b57cec5SDimitry Andric   else
27980b57cec5SDimitry Andric     return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded, Delta);
27990b57cec5SDimitry Andric }
28000b57cec5SDimitry Andric 
28010b57cec5SDimitry Andric 
28020b57cec5SDimitry Andric // Returns true iff the current bounds are plausible.
28030b57cec5SDimitry Andric bool DependenceInfo::testBounds(unsigned char DirKind, unsigned Level,
28040b57cec5SDimitry Andric                                 BoundInfo *Bound, const SCEV *Delta) const {
28050b57cec5SDimitry Andric   Bound[Level].Direction = DirKind;
28060b57cec5SDimitry Andric   if (const SCEV *LowerBound = getLowerBound(Bound))
28070b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_SGT, LowerBound, Delta))
28080b57cec5SDimitry Andric       return false;
28090b57cec5SDimitry Andric   if (const SCEV *UpperBound = getUpperBound(Bound))
28100b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, UpperBound))
28110b57cec5SDimitry Andric       return false;
28120b57cec5SDimitry Andric   return true;
28130b57cec5SDimitry Andric }
28140b57cec5SDimitry Andric 
28150b57cec5SDimitry Andric 
28160b57cec5SDimitry Andric // Computes the upper and lower bounds for level K
28170b57cec5SDimitry Andric // using the * direction. Records them in Bound.
28180b57cec5SDimitry Andric // Wolfe gives the equations
28190b57cec5SDimitry Andric //
28200b57cec5SDimitry Andric //    LB^*_k = (A^-_k - B^+_k)(U_k - L_k) + (A_k - B_k)L_k
28210b57cec5SDimitry Andric //    UB^*_k = (A^+_k - B^-_k)(U_k - L_k) + (A_k - B_k)L_k
28220b57cec5SDimitry Andric //
28230b57cec5SDimitry Andric // Since we normalize loops, we can simplify these equations to
28240b57cec5SDimitry Andric //
28250b57cec5SDimitry Andric //    LB^*_k = (A^-_k - B^+_k)U_k
28260b57cec5SDimitry Andric //    UB^*_k = (A^+_k - B^-_k)U_k
28270b57cec5SDimitry Andric //
28280b57cec5SDimitry Andric // We must be careful to handle the case where the upper bound is unknown.
28290b57cec5SDimitry Andric // Note that the lower bound is always <= 0
28300b57cec5SDimitry Andric // and the upper bound is always >= 0.
28310b57cec5SDimitry Andric void DependenceInfo::findBoundsALL(CoefficientInfo *A, CoefficientInfo *B,
28320b57cec5SDimitry Andric                                    BoundInfo *Bound, unsigned K) const {
28330b57cec5SDimitry Andric   Bound[K].Lower[Dependence::DVEntry::ALL] = nullptr; // Default value = -infinity.
28340b57cec5SDimitry Andric   Bound[K].Upper[Dependence::DVEntry::ALL] = nullptr; // Default value = +infinity.
28350b57cec5SDimitry Andric   if (Bound[K].Iterations) {
28360b57cec5SDimitry Andric     Bound[K].Lower[Dependence::DVEntry::ALL] =
28370b57cec5SDimitry Andric       SE->getMulExpr(SE->getMinusSCEV(A[K].NegPart, B[K].PosPart),
28380b57cec5SDimitry Andric                      Bound[K].Iterations);
28390b57cec5SDimitry Andric     Bound[K].Upper[Dependence::DVEntry::ALL] =
28400b57cec5SDimitry Andric       SE->getMulExpr(SE->getMinusSCEV(A[K].PosPart, B[K].NegPart),
28410b57cec5SDimitry Andric                      Bound[K].Iterations);
28420b57cec5SDimitry Andric   }
28430b57cec5SDimitry Andric   else {
28440b57cec5SDimitry Andric     // If the difference is 0, we won't need to know the number of iterations.
28450b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].NegPart, B[K].PosPart))
28460b57cec5SDimitry Andric       Bound[K].Lower[Dependence::DVEntry::ALL] =
28470b57cec5SDimitry Andric           SE->getZero(A[K].Coeff->getType());
28480b57cec5SDimitry Andric     if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].PosPart, B[K].NegPart))
28490b57cec5SDimitry Andric       Bound[K].Upper[Dependence::DVEntry::ALL] =
28500b57cec5SDimitry Andric           SE->getZero(A[K].Coeff->getType());
28510b57cec5SDimitry Andric   }
28520b57cec5SDimitry Andric }
28530b57cec5SDimitry Andric 
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric // Computes the upper and lower bounds for level K
28560b57cec5SDimitry Andric // using the = direction. Records them in Bound.
28570b57cec5SDimitry Andric // Wolfe gives the equations
28580b57cec5SDimitry Andric //
28590b57cec5SDimitry Andric //    LB^=_k = (A_k - B_k)^- (U_k - L_k) + (A_k - B_k)L_k
28600b57cec5SDimitry Andric //    UB^=_k = (A_k - B_k)^+ (U_k - L_k) + (A_k - B_k)L_k
28610b57cec5SDimitry Andric //
28620b57cec5SDimitry Andric // Since we normalize loops, we can simplify these equations to
28630b57cec5SDimitry Andric //
28640b57cec5SDimitry Andric //    LB^=_k = (A_k - B_k)^- U_k
28650b57cec5SDimitry Andric //    UB^=_k = (A_k - B_k)^+ U_k
28660b57cec5SDimitry Andric //
28670b57cec5SDimitry Andric // We must be careful to handle the case where the upper bound is unknown.
28680b57cec5SDimitry Andric // Note that the lower bound is always <= 0
28690b57cec5SDimitry Andric // and the upper bound is always >= 0.
28700b57cec5SDimitry Andric void DependenceInfo::findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B,
28710b57cec5SDimitry Andric                                   BoundInfo *Bound, unsigned K) const {
28720b57cec5SDimitry Andric   Bound[K].Lower[Dependence::DVEntry::EQ] = nullptr; // Default value = -infinity.
28730b57cec5SDimitry Andric   Bound[K].Upper[Dependence::DVEntry::EQ] = nullptr; // Default value = +infinity.
28740b57cec5SDimitry Andric   if (Bound[K].Iterations) {
28750b57cec5SDimitry Andric     const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
28760b57cec5SDimitry Andric     const SCEV *NegativePart = getNegativePart(Delta);
28770b57cec5SDimitry Andric     Bound[K].Lower[Dependence::DVEntry::EQ] =
28780b57cec5SDimitry Andric       SE->getMulExpr(NegativePart, Bound[K].Iterations);
28790b57cec5SDimitry Andric     const SCEV *PositivePart = getPositivePart(Delta);
28800b57cec5SDimitry Andric     Bound[K].Upper[Dependence::DVEntry::EQ] =
28810b57cec5SDimitry Andric       SE->getMulExpr(PositivePart, Bound[K].Iterations);
28820b57cec5SDimitry Andric   }
28830b57cec5SDimitry Andric   else {
28840b57cec5SDimitry Andric     // If the positive/negative part of the difference is 0,
28850b57cec5SDimitry Andric     // we won't need to know the number of iterations.
28860b57cec5SDimitry Andric     const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
28870b57cec5SDimitry Andric     const SCEV *NegativePart = getNegativePart(Delta);
28880b57cec5SDimitry Andric     if (NegativePart->isZero())
28890b57cec5SDimitry Andric       Bound[K].Lower[Dependence::DVEntry::EQ] = NegativePart; // Zero
28900b57cec5SDimitry Andric     const SCEV *PositivePart = getPositivePart(Delta);
28910b57cec5SDimitry Andric     if (PositivePart->isZero())
28920b57cec5SDimitry Andric       Bound[K].Upper[Dependence::DVEntry::EQ] = PositivePart; // Zero
28930b57cec5SDimitry Andric   }
28940b57cec5SDimitry Andric }
28950b57cec5SDimitry Andric 
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric // Computes the upper and lower bounds for level K
28980b57cec5SDimitry Andric // using the < direction. Records them in Bound.
28990b57cec5SDimitry Andric // Wolfe gives the equations
29000b57cec5SDimitry Andric //
29010b57cec5SDimitry Andric //    LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
29020b57cec5SDimitry Andric //    UB^<_k = (A^+_k - B_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
29030b57cec5SDimitry Andric //
29040b57cec5SDimitry Andric // Since we normalize loops, we can simplify these equations to
29050b57cec5SDimitry Andric //
29060b57cec5SDimitry Andric //    LB^<_k = (A^-_k - B_k)^- (U_k - 1) - B_k
29070b57cec5SDimitry Andric //    UB^<_k = (A^+_k - B_k)^+ (U_k - 1) - B_k
29080b57cec5SDimitry Andric //
29090b57cec5SDimitry Andric // We must be careful to handle the case where the upper bound is unknown.
29100b57cec5SDimitry Andric void DependenceInfo::findBoundsLT(CoefficientInfo *A, CoefficientInfo *B,
29110b57cec5SDimitry Andric                                   BoundInfo *Bound, unsigned K) const {
29120b57cec5SDimitry Andric   Bound[K].Lower[Dependence::DVEntry::LT] = nullptr; // Default value = -infinity.
29130b57cec5SDimitry Andric   Bound[K].Upper[Dependence::DVEntry::LT] = nullptr; // Default value = +infinity.
29140b57cec5SDimitry Andric   if (Bound[K].Iterations) {
29150b57cec5SDimitry Andric     const SCEV *Iter_1 = SE->getMinusSCEV(
29160b57cec5SDimitry Andric         Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
29170b57cec5SDimitry Andric     const SCEV *NegPart =
29180b57cec5SDimitry Andric       getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
29190b57cec5SDimitry Andric     Bound[K].Lower[Dependence::DVEntry::LT] =
29200b57cec5SDimitry Andric       SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1), B[K].Coeff);
29210b57cec5SDimitry Andric     const SCEV *PosPart =
29220b57cec5SDimitry Andric       getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
29230b57cec5SDimitry Andric     Bound[K].Upper[Dependence::DVEntry::LT] =
29240b57cec5SDimitry Andric       SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1), B[K].Coeff);
29250b57cec5SDimitry Andric   }
29260b57cec5SDimitry Andric   else {
29270b57cec5SDimitry Andric     // If the positive/negative part of the difference is 0,
29280b57cec5SDimitry Andric     // we won't need to know the number of iterations.
29290b57cec5SDimitry Andric     const SCEV *NegPart =
29300b57cec5SDimitry Andric       getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
29310b57cec5SDimitry Andric     if (NegPart->isZero())
29320b57cec5SDimitry Andric       Bound[K].Lower[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
29330b57cec5SDimitry Andric     const SCEV *PosPart =
29340b57cec5SDimitry Andric       getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
29350b57cec5SDimitry Andric     if (PosPart->isZero())
29360b57cec5SDimitry Andric       Bound[K].Upper[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
29370b57cec5SDimitry Andric   }
29380b57cec5SDimitry Andric }
29390b57cec5SDimitry Andric 
29400b57cec5SDimitry Andric 
29410b57cec5SDimitry Andric // Computes the upper and lower bounds for level K
29420b57cec5SDimitry Andric // using the > direction. Records them in Bound.
29430b57cec5SDimitry Andric // Wolfe gives the equations
29440b57cec5SDimitry Andric //
29450b57cec5SDimitry Andric //    LB^>_k = (A_k - B^+_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
29460b57cec5SDimitry Andric //    UB^>_k = (A_k - B^-_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
29470b57cec5SDimitry Andric //
29480b57cec5SDimitry Andric // Since we normalize loops, we can simplify these equations to
29490b57cec5SDimitry Andric //
29500b57cec5SDimitry Andric //    LB^>_k = (A_k - B^+_k)^- (U_k - 1) + A_k
29510b57cec5SDimitry Andric //    UB^>_k = (A_k - B^-_k)^+ (U_k - 1) + A_k
29520b57cec5SDimitry Andric //
29530b57cec5SDimitry Andric // We must be careful to handle the case where the upper bound is unknown.
29540b57cec5SDimitry Andric void DependenceInfo::findBoundsGT(CoefficientInfo *A, CoefficientInfo *B,
29550b57cec5SDimitry Andric                                   BoundInfo *Bound, unsigned K) const {
29560b57cec5SDimitry Andric   Bound[K].Lower[Dependence::DVEntry::GT] = nullptr; // Default value = -infinity.
29570b57cec5SDimitry Andric   Bound[K].Upper[Dependence::DVEntry::GT] = nullptr; // Default value = +infinity.
29580b57cec5SDimitry Andric   if (Bound[K].Iterations) {
29590b57cec5SDimitry Andric     const SCEV *Iter_1 = SE->getMinusSCEV(
29600b57cec5SDimitry Andric         Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
29610b57cec5SDimitry Andric     const SCEV *NegPart =
29620b57cec5SDimitry Andric       getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
29630b57cec5SDimitry Andric     Bound[K].Lower[Dependence::DVEntry::GT] =
29640b57cec5SDimitry Andric       SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1), A[K].Coeff);
29650b57cec5SDimitry Andric     const SCEV *PosPart =
29660b57cec5SDimitry Andric       getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
29670b57cec5SDimitry Andric     Bound[K].Upper[Dependence::DVEntry::GT] =
29680b57cec5SDimitry Andric       SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1), A[K].Coeff);
29690b57cec5SDimitry Andric   }
29700b57cec5SDimitry Andric   else {
29710b57cec5SDimitry Andric     // If the positive/negative part of the difference is 0,
29720b57cec5SDimitry Andric     // we won't need to know the number of iterations.
29730b57cec5SDimitry Andric     const SCEV *NegPart = getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
29740b57cec5SDimitry Andric     if (NegPart->isZero())
29750b57cec5SDimitry Andric       Bound[K].Lower[Dependence::DVEntry::GT] = A[K].Coeff;
29760b57cec5SDimitry Andric     const SCEV *PosPart = getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
29770b57cec5SDimitry Andric     if (PosPart->isZero())
29780b57cec5SDimitry Andric       Bound[K].Upper[Dependence::DVEntry::GT] = A[K].Coeff;
29790b57cec5SDimitry Andric   }
29800b57cec5SDimitry Andric }
29810b57cec5SDimitry Andric 
29820b57cec5SDimitry Andric 
29830b57cec5SDimitry Andric // X^+ = max(X, 0)
29840b57cec5SDimitry Andric const SCEV *DependenceInfo::getPositivePart(const SCEV *X) const {
29850b57cec5SDimitry Andric   return SE->getSMaxExpr(X, SE->getZero(X->getType()));
29860b57cec5SDimitry Andric }
29870b57cec5SDimitry Andric 
29880b57cec5SDimitry Andric 
29890b57cec5SDimitry Andric // X^- = min(X, 0)
29900b57cec5SDimitry Andric const SCEV *DependenceInfo::getNegativePart(const SCEV *X) const {
29910b57cec5SDimitry Andric   return SE->getSMinExpr(X, SE->getZero(X->getType()));
29920b57cec5SDimitry Andric }
29930b57cec5SDimitry Andric 
29940b57cec5SDimitry Andric 
29950b57cec5SDimitry Andric // Walks through the subscript,
29960b57cec5SDimitry Andric // collecting each coefficient, the associated loop bounds,
29970b57cec5SDimitry Andric // and recording its positive and negative parts for later use.
29980b57cec5SDimitry Andric DependenceInfo::CoefficientInfo *
29990b57cec5SDimitry Andric DependenceInfo::collectCoeffInfo(const SCEV *Subscript, bool SrcFlag,
30000b57cec5SDimitry Andric                                  const SCEV *&Constant) const {
30010b57cec5SDimitry Andric   const SCEV *Zero = SE->getZero(Subscript->getType());
30020b57cec5SDimitry Andric   CoefficientInfo *CI = new CoefficientInfo[MaxLevels + 1];
30030b57cec5SDimitry Andric   for (unsigned K = 1; K <= MaxLevels; ++K) {
30040b57cec5SDimitry Andric     CI[K].Coeff = Zero;
30050b57cec5SDimitry Andric     CI[K].PosPart = Zero;
30060b57cec5SDimitry Andric     CI[K].NegPart = Zero;
30070b57cec5SDimitry Andric     CI[K].Iterations = nullptr;
30080b57cec5SDimitry Andric   }
30090b57cec5SDimitry Andric   while (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
30100b57cec5SDimitry Andric     const Loop *L = AddRec->getLoop();
30110b57cec5SDimitry Andric     unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
30120b57cec5SDimitry Andric     CI[K].Coeff = AddRec->getStepRecurrence(*SE);
30130b57cec5SDimitry Andric     CI[K].PosPart = getPositivePart(CI[K].Coeff);
30140b57cec5SDimitry Andric     CI[K].NegPart = getNegativePart(CI[K].Coeff);
30150b57cec5SDimitry Andric     CI[K].Iterations = collectUpperBound(L, Subscript->getType());
30160b57cec5SDimitry Andric     Subscript = AddRec->getStart();
30170b57cec5SDimitry Andric   }
30180b57cec5SDimitry Andric   Constant = Subscript;
30190b57cec5SDimitry Andric #ifndef NDEBUG
30200b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tCoefficient Info\n");
30210b57cec5SDimitry Andric   for (unsigned K = 1; K <= MaxLevels; ++K) {
30220b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    " << K << "\t" << *CI[K].Coeff);
30230b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tPos Part = ");
30240b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << *CI[K].PosPart);
30250b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tNeg Part = ");
30260b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << *CI[K].NegPart);
30270b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tUpper Bound = ");
30280b57cec5SDimitry Andric     if (CI[K].Iterations)
30290b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << *CI[K].Iterations);
30300b57cec5SDimitry Andric     else
30310b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "+inf");
30320b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << '\n');
30330b57cec5SDimitry Andric   }
30340b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t    Constant = " << *Subscript << '\n');
30350b57cec5SDimitry Andric #endif
30360b57cec5SDimitry Andric   return CI;
30370b57cec5SDimitry Andric }
30380b57cec5SDimitry Andric 
30390b57cec5SDimitry Andric 
30400b57cec5SDimitry Andric // Looks through all the bounds info and
30410b57cec5SDimitry Andric // computes the lower bound given the current direction settings
30420b57cec5SDimitry Andric // at each level. If the lower bound for any level is -inf,
30430b57cec5SDimitry Andric // the result is -inf.
30440b57cec5SDimitry Andric const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound) const {
30450b57cec5SDimitry Andric   const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
30460b57cec5SDimitry Andric   for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
30470b57cec5SDimitry Andric     if (Bound[K].Lower[Bound[K].Direction])
30480b57cec5SDimitry Andric       Sum = SE->getAddExpr(Sum, Bound[K].Lower[Bound[K].Direction]);
30490b57cec5SDimitry Andric     else
30500b57cec5SDimitry Andric       Sum = nullptr;
30510b57cec5SDimitry Andric   }
30520b57cec5SDimitry Andric   return Sum;
30530b57cec5SDimitry Andric }
30540b57cec5SDimitry Andric 
30550b57cec5SDimitry Andric 
30560b57cec5SDimitry Andric // Looks through all the bounds info and
30570b57cec5SDimitry Andric // computes the upper bound given the current direction settings
30580b57cec5SDimitry Andric // at each level. If the upper bound at any level is +inf,
30590b57cec5SDimitry Andric // the result is +inf.
30600b57cec5SDimitry Andric const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound) const {
30610b57cec5SDimitry Andric   const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
30620b57cec5SDimitry Andric   for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
30630b57cec5SDimitry Andric     if (Bound[K].Upper[Bound[K].Direction])
30640b57cec5SDimitry Andric       Sum = SE->getAddExpr(Sum, Bound[K].Upper[Bound[K].Direction]);
30650b57cec5SDimitry Andric     else
30660b57cec5SDimitry Andric       Sum = nullptr;
30670b57cec5SDimitry Andric   }
30680b57cec5SDimitry Andric   return Sum;
30690b57cec5SDimitry Andric }
30700b57cec5SDimitry Andric 
30710b57cec5SDimitry Andric 
30720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
30730b57cec5SDimitry Andric // Constraint manipulation for Delta test.
30740b57cec5SDimitry Andric 
30750b57cec5SDimitry Andric // Given a linear SCEV,
30760b57cec5SDimitry Andric // return the coefficient (the step)
30770b57cec5SDimitry Andric // corresponding to the specified loop.
30780b57cec5SDimitry Andric // If there isn't one, return 0.
30790b57cec5SDimitry Andric // For example, given a*i + b*j + c*k, finding the coefficient
30800b57cec5SDimitry Andric // corresponding to the j loop would yield b.
30810b57cec5SDimitry Andric const SCEV *DependenceInfo::findCoefficient(const SCEV *Expr,
30820b57cec5SDimitry Andric                                             const Loop *TargetLoop) const {
30830b57cec5SDimitry Andric   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
30840b57cec5SDimitry Andric   if (!AddRec)
30850b57cec5SDimitry Andric     return SE->getZero(Expr->getType());
30860b57cec5SDimitry Andric   if (AddRec->getLoop() == TargetLoop)
30870b57cec5SDimitry Andric     return AddRec->getStepRecurrence(*SE);
30880b57cec5SDimitry Andric   return findCoefficient(AddRec->getStart(), TargetLoop);
30890b57cec5SDimitry Andric }
30900b57cec5SDimitry Andric 
30910b57cec5SDimitry Andric 
30920b57cec5SDimitry Andric // Given a linear SCEV,
30930b57cec5SDimitry Andric // return the SCEV given by zeroing out the coefficient
30940b57cec5SDimitry Andric // corresponding to the specified loop.
30950b57cec5SDimitry Andric // For example, given a*i + b*j + c*k, zeroing the coefficient
30960b57cec5SDimitry Andric // corresponding to the j loop would yield a*i + c*k.
30970b57cec5SDimitry Andric const SCEV *DependenceInfo::zeroCoefficient(const SCEV *Expr,
30980b57cec5SDimitry Andric                                             const Loop *TargetLoop) const {
30990b57cec5SDimitry Andric   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
31000b57cec5SDimitry Andric   if (!AddRec)
31010b57cec5SDimitry Andric     return Expr; // ignore
31020b57cec5SDimitry Andric   if (AddRec->getLoop() == TargetLoop)
31030b57cec5SDimitry Andric     return AddRec->getStart();
31040b57cec5SDimitry Andric   return SE->getAddRecExpr(zeroCoefficient(AddRec->getStart(), TargetLoop),
31050b57cec5SDimitry Andric                            AddRec->getStepRecurrence(*SE),
31060b57cec5SDimitry Andric                            AddRec->getLoop(),
31070b57cec5SDimitry Andric                            AddRec->getNoWrapFlags());
31080b57cec5SDimitry Andric }
31090b57cec5SDimitry Andric 
31100b57cec5SDimitry Andric 
31110b57cec5SDimitry Andric // Given a linear SCEV Expr,
31120b57cec5SDimitry Andric // return the SCEV given by adding some Value to the
31130b57cec5SDimitry Andric // coefficient corresponding to the specified TargetLoop.
31140b57cec5SDimitry Andric // For example, given a*i + b*j + c*k, adding 1 to the coefficient
31150b57cec5SDimitry Andric // corresponding to the j loop would yield a*i + (b+1)*j + c*k.
31160b57cec5SDimitry Andric const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
31170b57cec5SDimitry Andric                                              const Loop *TargetLoop,
31180b57cec5SDimitry Andric                                              const SCEV *Value) const {
31190b57cec5SDimitry Andric   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
31200b57cec5SDimitry Andric   if (!AddRec) // create a new addRec
31210b57cec5SDimitry Andric     return SE->getAddRecExpr(Expr,
31220b57cec5SDimitry Andric                              Value,
31230b57cec5SDimitry Andric                              TargetLoop,
31240b57cec5SDimitry Andric                              SCEV::FlagAnyWrap); // Worst case, with no info.
31250b57cec5SDimitry Andric   if (AddRec->getLoop() == TargetLoop) {
31260b57cec5SDimitry Andric     const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
31270b57cec5SDimitry Andric     if (Sum->isZero())
31280b57cec5SDimitry Andric       return AddRec->getStart();
31290b57cec5SDimitry Andric     return SE->getAddRecExpr(AddRec->getStart(),
31300b57cec5SDimitry Andric                              Sum,
31310b57cec5SDimitry Andric                              AddRec->getLoop(),
31320b57cec5SDimitry Andric                              AddRec->getNoWrapFlags());
31330b57cec5SDimitry Andric   }
31340b57cec5SDimitry Andric   if (SE->isLoopInvariant(AddRec, TargetLoop))
31350b57cec5SDimitry Andric     return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
31360b57cec5SDimitry Andric   return SE->getAddRecExpr(
31370b57cec5SDimitry Andric       addToCoefficient(AddRec->getStart(), TargetLoop, Value),
31380b57cec5SDimitry Andric       AddRec->getStepRecurrence(*SE), AddRec->getLoop(),
31390b57cec5SDimitry Andric       AddRec->getNoWrapFlags());
31400b57cec5SDimitry Andric }
31410b57cec5SDimitry Andric 
31420b57cec5SDimitry Andric 
31430b57cec5SDimitry Andric // Review the constraints, looking for opportunities
31440b57cec5SDimitry Andric // to simplify a subscript pair (Src and Dst).
31450b57cec5SDimitry Andric // Return true if some simplification occurs.
31460b57cec5SDimitry Andric // If the simplification isn't exact (that is, if it is conservative
31470b57cec5SDimitry Andric // in terms of dependence), set consistent to false.
31480b57cec5SDimitry Andric // Corresponds to Figure 5 from the paper
31490b57cec5SDimitry Andric //
31500b57cec5SDimitry Andric //            Practical Dependence Testing
31510b57cec5SDimitry Andric //            Goff, Kennedy, Tseng
31520b57cec5SDimitry Andric //            PLDI 1991
31530b57cec5SDimitry Andric bool DependenceInfo::propagate(const SCEV *&Src, const SCEV *&Dst,
31540b57cec5SDimitry Andric                                SmallBitVector &Loops,
31550b57cec5SDimitry Andric                                SmallVectorImpl<Constraint> &Constraints,
31560b57cec5SDimitry Andric                                bool &Consistent) {
31570b57cec5SDimitry Andric   bool Result = false;
31580b57cec5SDimitry Andric   for (unsigned LI : Loops.set_bits()) {
31590b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\t    Constraint[" << LI << "] is");
31600b57cec5SDimitry Andric     LLVM_DEBUG(Constraints[LI].dump(dbgs()));
31610b57cec5SDimitry Andric     if (Constraints[LI].isDistance())
31620b57cec5SDimitry Andric       Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
31630b57cec5SDimitry Andric     else if (Constraints[LI].isLine())
31640b57cec5SDimitry Andric       Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
31650b57cec5SDimitry Andric     else if (Constraints[LI].isPoint())
31660b57cec5SDimitry Andric       Result |= propagatePoint(Src, Dst, Constraints[LI]);
31670b57cec5SDimitry Andric   }
31680b57cec5SDimitry Andric   return Result;
31690b57cec5SDimitry Andric }
31700b57cec5SDimitry Andric 
31710b57cec5SDimitry Andric 
31720b57cec5SDimitry Andric // Attempt to propagate a distance
31730b57cec5SDimitry Andric // constraint into a subscript pair (Src and Dst).
31740b57cec5SDimitry Andric // Return true if some simplification occurs.
31750b57cec5SDimitry Andric // If the simplification isn't exact (that is, if it is conservative
31760b57cec5SDimitry Andric // in terms of dependence), set consistent to false.
31770b57cec5SDimitry Andric bool DependenceInfo::propagateDistance(const SCEV *&Src, const SCEV *&Dst,
31780b57cec5SDimitry Andric                                        Constraint &CurConstraint,
31790b57cec5SDimitry Andric                                        bool &Consistent) {
31800b57cec5SDimitry Andric   const Loop *CurLoop = CurConstraint.getAssociatedLoop();
31810b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
31820b57cec5SDimitry Andric   const SCEV *A_K = findCoefficient(Src, CurLoop);
31830b57cec5SDimitry Andric   if (A_K->isZero())
31840b57cec5SDimitry Andric     return false;
31850b57cec5SDimitry Andric   const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
31860b57cec5SDimitry Andric   Src = SE->getMinusSCEV(Src, DA_K);
31870b57cec5SDimitry Andric   Src = zeroCoefficient(Src, CurLoop);
31880b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
31890b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
31900b57cec5SDimitry Andric   Dst = addToCoefficient(Dst, CurLoop, SE->getNegativeSCEV(A_K));
31910b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
31920b57cec5SDimitry Andric   if (!findCoefficient(Dst, CurLoop)->isZero())
31930b57cec5SDimitry Andric     Consistent = false;
31940b57cec5SDimitry Andric   return true;
31950b57cec5SDimitry Andric }
31960b57cec5SDimitry Andric 
31970b57cec5SDimitry Andric 
31980b57cec5SDimitry Andric // Attempt to propagate a line
31990b57cec5SDimitry Andric // constraint into a subscript pair (Src and Dst).
32000b57cec5SDimitry Andric // Return true if some simplification occurs.
32010b57cec5SDimitry Andric // If the simplification isn't exact (that is, if it is conservative
32020b57cec5SDimitry Andric // in terms of dependence), set consistent to false.
32030b57cec5SDimitry Andric bool DependenceInfo::propagateLine(const SCEV *&Src, const SCEV *&Dst,
32040b57cec5SDimitry Andric                                    Constraint &CurConstraint,
32050b57cec5SDimitry Andric                                    bool &Consistent) {
32060b57cec5SDimitry Andric   const Loop *CurLoop = CurConstraint.getAssociatedLoop();
32070b57cec5SDimitry Andric   const SCEV *A = CurConstraint.getA();
32080b57cec5SDimitry Andric   const SCEV *B = CurConstraint.getB();
32090b57cec5SDimitry Andric   const SCEV *C = CurConstraint.getC();
32100b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tA = " << *A << ", B = " << *B << ", C = " << *C
32110b57cec5SDimitry Andric                     << "\n");
32120b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tSrc = " << *Src << "\n");
32130b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tDst = " << *Dst << "\n");
32140b57cec5SDimitry Andric   if (A->isZero()) {
32150b57cec5SDimitry Andric     const SCEVConstant *Bconst = dyn_cast<SCEVConstant>(B);
32160b57cec5SDimitry Andric     const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
32170b57cec5SDimitry Andric     if (!Bconst || !Cconst) return false;
32180b57cec5SDimitry Andric     APInt Beta = Bconst->getAPInt();
32190b57cec5SDimitry Andric     APInt Charlie = Cconst->getAPInt();
32200b57cec5SDimitry Andric     APInt CdivB = Charlie.sdiv(Beta);
32210b57cec5SDimitry Andric     assert(Charlie.srem(Beta) == 0 && "C should be evenly divisible by B");
32220b57cec5SDimitry Andric     const SCEV *AP_K = findCoefficient(Dst, CurLoop);
32230b57cec5SDimitry Andric     //    Src = SE->getAddExpr(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
32240b57cec5SDimitry Andric     Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
32250b57cec5SDimitry Andric     Dst = zeroCoefficient(Dst, CurLoop);
32260b57cec5SDimitry Andric     if (!findCoefficient(Src, CurLoop)->isZero())
32270b57cec5SDimitry Andric       Consistent = false;
32280b57cec5SDimitry Andric   }
32290b57cec5SDimitry Andric   else if (B->isZero()) {
32300b57cec5SDimitry Andric     const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
32310b57cec5SDimitry Andric     const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
32320b57cec5SDimitry Andric     if (!Aconst || !Cconst) return false;
32330b57cec5SDimitry Andric     APInt Alpha = Aconst->getAPInt();
32340b57cec5SDimitry Andric     APInt Charlie = Cconst->getAPInt();
32350b57cec5SDimitry Andric     APInt CdivA = Charlie.sdiv(Alpha);
32360b57cec5SDimitry Andric     assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
32370b57cec5SDimitry Andric     const SCEV *A_K = findCoefficient(Src, CurLoop);
32380b57cec5SDimitry Andric     Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
32390b57cec5SDimitry Andric     Src = zeroCoefficient(Src, CurLoop);
32400b57cec5SDimitry Andric     if (!findCoefficient(Dst, CurLoop)->isZero())
32410b57cec5SDimitry Andric       Consistent = false;
32420b57cec5SDimitry Andric   }
32430b57cec5SDimitry Andric   else if (isKnownPredicate(CmpInst::ICMP_EQ, A, B)) {
32440b57cec5SDimitry Andric     const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
32450b57cec5SDimitry Andric     const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
32460b57cec5SDimitry Andric     if (!Aconst || !Cconst) return false;
32470b57cec5SDimitry Andric     APInt Alpha = Aconst->getAPInt();
32480b57cec5SDimitry Andric     APInt Charlie = Cconst->getAPInt();
32490b57cec5SDimitry Andric     APInt CdivA = Charlie.sdiv(Alpha);
32500b57cec5SDimitry Andric     assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
32510b57cec5SDimitry Andric     const SCEV *A_K = findCoefficient(Src, CurLoop);
32520b57cec5SDimitry Andric     Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
32530b57cec5SDimitry Andric     Src = zeroCoefficient(Src, CurLoop);
32540b57cec5SDimitry Andric     Dst = addToCoefficient(Dst, CurLoop, A_K);
32550b57cec5SDimitry Andric     if (!findCoefficient(Dst, CurLoop)->isZero())
32560b57cec5SDimitry Andric       Consistent = false;
32570b57cec5SDimitry Andric   }
32580b57cec5SDimitry Andric   else {
32590b57cec5SDimitry Andric     // paper is incorrect here, or perhaps just misleading
32600b57cec5SDimitry Andric     const SCEV *A_K = findCoefficient(Src, CurLoop);
32610b57cec5SDimitry Andric     Src = SE->getMulExpr(Src, A);
32620b57cec5SDimitry Andric     Dst = SE->getMulExpr(Dst, A);
32630b57cec5SDimitry Andric     Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, C));
32640b57cec5SDimitry Andric     Src = zeroCoefficient(Src, CurLoop);
32650b57cec5SDimitry Andric     Dst = addToCoefficient(Dst, CurLoop, SE->getMulExpr(A_K, B));
32660b57cec5SDimitry Andric     if (!findCoefficient(Dst, CurLoop)->isZero())
32670b57cec5SDimitry Andric       Consistent = false;
32680b57cec5SDimitry Andric   }
32690b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tnew Src = " << *Src << "\n");
32700b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tnew Dst = " << *Dst << "\n");
32710b57cec5SDimitry Andric   return true;
32720b57cec5SDimitry Andric }
32730b57cec5SDimitry Andric 
32740b57cec5SDimitry Andric 
32750b57cec5SDimitry Andric // Attempt to propagate a point
32760b57cec5SDimitry Andric // constraint into a subscript pair (Src and Dst).
32770b57cec5SDimitry Andric // Return true if some simplification occurs.
32780b57cec5SDimitry Andric bool DependenceInfo::propagatePoint(const SCEV *&Src, const SCEV *&Dst,
32790b57cec5SDimitry Andric                                     Constraint &CurConstraint) {
32800b57cec5SDimitry Andric   const Loop *CurLoop = CurConstraint.getAssociatedLoop();
32810b57cec5SDimitry Andric   const SCEV *A_K = findCoefficient(Src, CurLoop);
32820b57cec5SDimitry Andric   const SCEV *AP_K = findCoefficient(Dst, CurLoop);
32830b57cec5SDimitry Andric   const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
32840b57cec5SDimitry Andric   const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
32850b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
32860b57cec5SDimitry Andric   Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
32870b57cec5SDimitry Andric   Src = zeroCoefficient(Src, CurLoop);
32880b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
32890b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
32900b57cec5SDimitry Andric   Dst = zeroCoefficient(Dst, CurLoop);
32910b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
32920b57cec5SDimitry Andric   return true;
32930b57cec5SDimitry Andric }
32940b57cec5SDimitry Andric 
32950b57cec5SDimitry Andric 
32960b57cec5SDimitry Andric // Update direction vector entry based on the current constraint.
32970b57cec5SDimitry Andric void DependenceInfo::updateDirection(Dependence::DVEntry &Level,
32980b57cec5SDimitry Andric                                      const Constraint &CurConstraint) const {
32990b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tUpdate direction, constraint =");
33000b57cec5SDimitry Andric   LLVM_DEBUG(CurConstraint.dump(dbgs()));
33010b57cec5SDimitry Andric   if (CurConstraint.isAny())
33020b57cec5SDimitry Andric     ; // use defaults
33030b57cec5SDimitry Andric   else if (CurConstraint.isDistance()) {
33040b57cec5SDimitry Andric     // this one is consistent, the others aren't
33050b57cec5SDimitry Andric     Level.Scalar = false;
33060b57cec5SDimitry Andric     Level.Distance = CurConstraint.getD();
33070b57cec5SDimitry Andric     unsigned NewDirection = Dependence::DVEntry::NONE;
33080b57cec5SDimitry Andric     if (!SE->isKnownNonZero(Level.Distance)) // if may be zero
33090b57cec5SDimitry Andric       NewDirection = Dependence::DVEntry::EQ;
33100b57cec5SDimitry Andric     if (!SE->isKnownNonPositive(Level.Distance)) // if may be positive
33110b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::LT;
33120b57cec5SDimitry Andric     if (!SE->isKnownNonNegative(Level.Distance)) // if may be negative
33130b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::GT;
33140b57cec5SDimitry Andric     Level.Direction &= NewDirection;
33150b57cec5SDimitry Andric   }
33160b57cec5SDimitry Andric   else if (CurConstraint.isLine()) {
33170b57cec5SDimitry Andric     Level.Scalar = false;
33180b57cec5SDimitry Andric     Level.Distance = nullptr;
33190b57cec5SDimitry Andric     // direction should be accurate
33200b57cec5SDimitry Andric   }
33210b57cec5SDimitry Andric   else if (CurConstraint.isPoint()) {
33220b57cec5SDimitry Andric     Level.Scalar = false;
33230b57cec5SDimitry Andric     Level.Distance = nullptr;
33240b57cec5SDimitry Andric     unsigned NewDirection = Dependence::DVEntry::NONE;
33250b57cec5SDimitry Andric     if (!isKnownPredicate(CmpInst::ICMP_NE,
33260b57cec5SDimitry Andric                           CurConstraint.getY(),
33270b57cec5SDimitry Andric                           CurConstraint.getX()))
33280b57cec5SDimitry Andric       // if X may be = Y
33290b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::EQ;
33300b57cec5SDimitry Andric     if (!isKnownPredicate(CmpInst::ICMP_SLE,
33310b57cec5SDimitry Andric                           CurConstraint.getY(),
33320b57cec5SDimitry Andric                           CurConstraint.getX()))
33330b57cec5SDimitry Andric       // if Y may be > X
33340b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::LT;
33350b57cec5SDimitry Andric     if (!isKnownPredicate(CmpInst::ICMP_SGE,
33360b57cec5SDimitry Andric                           CurConstraint.getY(),
33370b57cec5SDimitry Andric                           CurConstraint.getX()))
33380b57cec5SDimitry Andric       // if Y may be < X
33390b57cec5SDimitry Andric       NewDirection |= Dependence::DVEntry::GT;
33400b57cec5SDimitry Andric     Level.Direction &= NewDirection;
33410b57cec5SDimitry Andric   }
33420b57cec5SDimitry Andric   else
33430b57cec5SDimitry Andric     llvm_unreachable("constraint has unexpected kind");
33440b57cec5SDimitry Andric }
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric /// Check if we can delinearize the subscripts. If the SCEVs representing the
33470b57cec5SDimitry Andric /// source and destination array references are recurrences on a nested loop,
33480b57cec5SDimitry Andric /// this function flattens the nested recurrences into separate recurrences
33490b57cec5SDimitry Andric /// for each loop level.
33500b57cec5SDimitry Andric bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
33510b57cec5SDimitry Andric                                     SmallVectorImpl<Subscript> &Pair) {
33520b57cec5SDimitry Andric   assert(isLoadOrStore(Src) && "instruction is not load or store");
33530b57cec5SDimitry Andric   assert(isLoadOrStore(Dst) && "instruction is not load or store");
33540b57cec5SDimitry Andric   Value *SrcPtr = getLoadStorePointerOperand(Src);
33550b57cec5SDimitry Andric   Value *DstPtr = getLoadStorePointerOperand(Dst);
33560b57cec5SDimitry Andric   Loop *SrcLoop = LI->getLoopFor(Src->getParent());
33570b57cec5SDimitry Andric   Loop *DstLoop = LI->getLoopFor(Dst->getParent());
33585ffd83dbSDimitry Andric   const SCEV *SrcAccessFn = SE->getSCEVAtScope(SrcPtr, SrcLoop);
33595ffd83dbSDimitry Andric   const SCEV *DstAccessFn = SE->getSCEVAtScope(DstPtr, DstLoop);
33600b57cec5SDimitry Andric   const SCEVUnknown *SrcBase =
33610b57cec5SDimitry Andric       dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
33620b57cec5SDimitry Andric   const SCEVUnknown *DstBase =
33630b57cec5SDimitry Andric       dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
33640b57cec5SDimitry Andric 
33650b57cec5SDimitry Andric   if (!SrcBase || !DstBase || SrcBase != DstBase)
33660b57cec5SDimitry Andric     return false;
33670b57cec5SDimitry Andric 
33685ffd83dbSDimitry Andric   SmallVector<const SCEV *, 4> SrcSubscripts, DstSubscripts;
33695ffd83dbSDimitry Andric 
33705ffd83dbSDimitry Andric   if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
33715ffd83dbSDimitry Andric                                SrcSubscripts, DstSubscripts) &&
33725ffd83dbSDimitry Andric       !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
33735ffd83dbSDimitry Andric                                     SrcSubscripts, DstSubscripts))
33745ffd83dbSDimitry Andric     return false;
33755ffd83dbSDimitry Andric 
33765ffd83dbSDimitry Andric   int Size = SrcSubscripts.size();
33775ffd83dbSDimitry Andric   LLVM_DEBUG({
33785ffd83dbSDimitry Andric     dbgs() << "\nSrcSubscripts: ";
33795ffd83dbSDimitry Andric     for (int I = 0; I < Size; I++)
33805ffd83dbSDimitry Andric       dbgs() << *SrcSubscripts[I];
33815ffd83dbSDimitry Andric     dbgs() << "\nDstSubscripts: ";
33825ffd83dbSDimitry Andric     for (int I = 0; I < Size; I++)
33835ffd83dbSDimitry Andric       dbgs() << *DstSubscripts[I];
33845ffd83dbSDimitry Andric   });
33855ffd83dbSDimitry Andric 
33865ffd83dbSDimitry Andric   // The delinearization transforms a single-subscript MIV dependence test into
33875ffd83dbSDimitry Andric   // a multi-subscript SIV dependence test that is easier to compute. So we
33885ffd83dbSDimitry Andric   // resize Pair to contain as many pairs of subscripts as the delinearization
33895ffd83dbSDimitry Andric   // has found, and then initialize the pairs following the delinearization.
33905ffd83dbSDimitry Andric   Pair.resize(Size);
33915ffd83dbSDimitry Andric   for (int I = 0; I < Size; ++I) {
33925ffd83dbSDimitry Andric     Pair[I].Src = SrcSubscripts[I];
33935ffd83dbSDimitry Andric     Pair[I].Dst = DstSubscripts[I];
33945ffd83dbSDimitry Andric     unifySubscriptType(&Pair[I]);
33955ffd83dbSDimitry Andric   }
33965ffd83dbSDimitry Andric 
33975ffd83dbSDimitry Andric   return true;
33985ffd83dbSDimitry Andric }
33995ffd83dbSDimitry Andric 
340081ad6265SDimitry Andric /// Try to delinearize \p SrcAccessFn and \p DstAccessFn if the underlying
340181ad6265SDimitry Andric /// arrays accessed are fixed-size arrays. Return true if delinearization was
340281ad6265SDimitry Andric /// successful.
34035ffd83dbSDimitry Andric bool DependenceInfo::tryDelinearizeFixedSize(
34045ffd83dbSDimitry Andric     Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
34055ffd83dbSDimitry Andric     const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
34065ffd83dbSDimitry Andric     SmallVectorImpl<const SCEV *> &DstSubscripts) {
340781ad6265SDimitry Andric   LLVM_DEBUG({
34085ffd83dbSDimitry Andric     const SCEVUnknown *SrcBase =
34095ffd83dbSDimitry Andric         dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
34105ffd83dbSDimitry Andric     const SCEVUnknown *DstBase =
34115ffd83dbSDimitry Andric         dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
34125ffd83dbSDimitry Andric     assert(SrcBase && DstBase && SrcBase == DstBase &&
34135ffd83dbSDimitry Andric            "expected src and dst scev unknowns to be equal");
341481ad6265SDimitry Andric     });
34155ffd83dbSDimitry Andric 
341681ad6265SDimitry Andric   SmallVector<int, 4> SrcSizes;
341781ad6265SDimitry Andric   SmallVector<int, 4> DstSizes;
341881ad6265SDimitry Andric   if (!tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts,
341981ad6265SDimitry Andric                                    SrcSizes) ||
342081ad6265SDimitry Andric       !tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts,
342181ad6265SDimitry Andric                                    DstSizes))
34225ffd83dbSDimitry Andric     return false;
34235ffd83dbSDimitry Andric 
34245ffd83dbSDimitry Andric   // Check that the two size arrays are non-empty and equal in length and
34255ffd83dbSDimitry Andric   // value.
342681ad6265SDimitry Andric   if (SrcSizes.size() != DstSizes.size() ||
34275ffd83dbSDimitry Andric       !std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.begin())) {
34285ffd83dbSDimitry Andric     SrcSubscripts.clear();
34295ffd83dbSDimitry Andric     DstSubscripts.clear();
34305ffd83dbSDimitry Andric     return false;
34315ffd83dbSDimitry Andric   }
34325ffd83dbSDimitry Andric 
34335ffd83dbSDimitry Andric   assert(SrcSubscripts.size() == DstSubscripts.size() &&
343481ad6265SDimitry Andric          "Expected equal number of entries in the list of SrcSubscripts and "
343581ad6265SDimitry Andric          "DstSubscripts.");
343681ad6265SDimitry Andric 
343781ad6265SDimitry Andric   Value *SrcPtr = getLoadStorePointerOperand(Src);
343881ad6265SDimitry Andric   Value *DstPtr = getLoadStorePointerOperand(Dst);
3439fe6060f1SDimitry Andric 
3440fe6060f1SDimitry Andric   // In general we cannot safely assume that the subscripts recovered from GEPs
3441fe6060f1SDimitry Andric   // are in the range of values defined for their corresponding array
3442fe6060f1SDimitry Andric   // dimensions. For example some C language usage/interpretation make it
3443fe6060f1SDimitry Andric   // impossible to verify this at compile-time. As such we can only delinearize
3444fe6060f1SDimitry Andric   // iff the subscripts are positive and are less than the range of the
3445fe6060f1SDimitry Andric   // dimension.
3446fe6060f1SDimitry Andric   if (!DisableDelinearizationChecks) {
3447*0fca6ea1SDimitry Andric     auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
3448fe6060f1SDimitry Andric                                  SmallVectorImpl<const SCEV *> &Subscripts,
3449fe6060f1SDimitry Andric                                  Value *Ptr) {
3450fe6060f1SDimitry Andric       size_t SSize = Subscripts.size();
3451fe6060f1SDimitry Andric       for (size_t I = 1; I < SSize; ++I) {
3452fe6060f1SDimitry Andric         const SCEV *S = Subscripts[I];
3453fe6060f1SDimitry Andric         if (!isKnownNonNegative(S, Ptr))
3454fe6060f1SDimitry Andric           return false;
3455fe6060f1SDimitry Andric         if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
3456fe6060f1SDimitry Andric           const SCEV *Range = SE->getConstant(
3457fe6060f1SDimitry Andric               ConstantInt::get(SType, DimensionSizes[I - 1], false));
3458fe6060f1SDimitry Andric           if (!isKnownLessThan(S, Range))
3459fe6060f1SDimitry Andric             return false;
3460fe6060f1SDimitry Andric         }
3461fe6060f1SDimitry Andric       }
3462fe6060f1SDimitry Andric       return true;
3463fe6060f1SDimitry Andric     };
3464fe6060f1SDimitry Andric 
3465*0fca6ea1SDimitry Andric     if (!AllIndicesInRange(SrcSizes, SrcSubscripts, SrcPtr) ||
3466*0fca6ea1SDimitry Andric         !AllIndicesInRange(DstSizes, DstSubscripts, DstPtr)) {
3467fe6060f1SDimitry Andric       SrcSubscripts.clear();
3468fe6060f1SDimitry Andric       DstSubscripts.clear();
3469fe6060f1SDimitry Andric       return false;
3470fe6060f1SDimitry Andric     }
3471fe6060f1SDimitry Andric   }
34725ffd83dbSDimitry Andric   LLVM_DEBUG({
34735ffd83dbSDimitry Andric     dbgs() << "Delinearized subscripts of fixed-size array\n"
347481ad6265SDimitry Andric            << "SrcGEP:" << *SrcPtr << "\n"
347581ad6265SDimitry Andric            << "DstGEP:" << *DstPtr << "\n";
34765ffd83dbSDimitry Andric   });
34775ffd83dbSDimitry Andric   return true;
34785ffd83dbSDimitry Andric }
34795ffd83dbSDimitry Andric 
34805ffd83dbSDimitry Andric bool DependenceInfo::tryDelinearizeParametricSize(
34815ffd83dbSDimitry Andric     Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
34825ffd83dbSDimitry Andric     const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
34835ffd83dbSDimitry Andric     SmallVectorImpl<const SCEV *> &DstSubscripts) {
34845ffd83dbSDimitry Andric 
34855ffd83dbSDimitry Andric   Value *SrcPtr = getLoadStorePointerOperand(Src);
34865ffd83dbSDimitry Andric   Value *DstPtr = getLoadStorePointerOperand(Dst);
34875ffd83dbSDimitry Andric   const SCEVUnknown *SrcBase =
34885ffd83dbSDimitry Andric       dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
34895ffd83dbSDimitry Andric   const SCEVUnknown *DstBase =
34905ffd83dbSDimitry Andric       dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
34915ffd83dbSDimitry Andric   assert(SrcBase && DstBase && SrcBase == DstBase &&
34925ffd83dbSDimitry Andric          "expected src and dst scev unknowns to be equal");
34935ffd83dbSDimitry Andric 
34940b57cec5SDimitry Andric   const SCEV *ElementSize = SE->getElementSize(Src);
34950b57cec5SDimitry Andric   if (ElementSize != SE->getElementSize(Dst))
34960b57cec5SDimitry Andric     return false;
34970b57cec5SDimitry Andric 
34980b57cec5SDimitry Andric   const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
34990b57cec5SDimitry Andric   const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);
35000b57cec5SDimitry Andric 
35010b57cec5SDimitry Andric   const SCEVAddRecExpr *SrcAR = dyn_cast<SCEVAddRecExpr>(SrcSCEV);
35020b57cec5SDimitry Andric   const SCEVAddRecExpr *DstAR = dyn_cast<SCEVAddRecExpr>(DstSCEV);
35030b57cec5SDimitry Andric   if (!SrcAR || !DstAR || !SrcAR->isAffine() || !DstAR->isAffine())
35040b57cec5SDimitry Andric     return false;
35050b57cec5SDimitry Andric 
35060b57cec5SDimitry Andric   // First step: collect parametric terms in both array references.
35070b57cec5SDimitry Andric   SmallVector<const SCEV *, 4> Terms;
3508349cc55cSDimitry Andric   collectParametricTerms(*SE, SrcAR, Terms);
3509349cc55cSDimitry Andric   collectParametricTerms(*SE, DstAR, Terms);
35100b57cec5SDimitry Andric 
35110b57cec5SDimitry Andric   // Second step: find subscript sizes.
35120b57cec5SDimitry Andric   SmallVector<const SCEV *, 4> Sizes;
3513349cc55cSDimitry Andric   findArrayDimensions(*SE, Terms, Sizes, ElementSize);
35140b57cec5SDimitry Andric 
35150b57cec5SDimitry Andric   // Third step: compute the access functions for each subscript.
3516349cc55cSDimitry Andric   computeAccessFunctions(*SE, SrcAR, SrcSubscripts, Sizes);
3517349cc55cSDimitry Andric   computeAccessFunctions(*SE, DstAR, DstSubscripts, Sizes);
35180b57cec5SDimitry Andric 
35190b57cec5SDimitry Andric   // Fail when there is only a subscript: that's a linearized access function.
35200b57cec5SDimitry Andric   if (SrcSubscripts.size() < 2 || DstSubscripts.size() < 2 ||
35210b57cec5SDimitry Andric       SrcSubscripts.size() != DstSubscripts.size())
35220b57cec5SDimitry Andric     return false;
35230b57cec5SDimitry Andric 
35245ffd83dbSDimitry Andric   size_t Size = SrcSubscripts.size();
35250b57cec5SDimitry Andric 
35260b57cec5SDimitry Andric   // Statically check that the array bounds are in-range. The first subscript we
35270b57cec5SDimitry Andric   // don't have a size for and it cannot overflow into another subscript, so is
35280b57cec5SDimitry Andric   // always safe. The others need to be 0 <= subscript[i] < bound, for both src
35290b57cec5SDimitry Andric   // and dst.
35300b57cec5SDimitry Andric   // FIXME: It may be better to record these sizes and add them as constraints
35310b57cec5SDimitry Andric   // to the dependency checks.
35320b57cec5SDimitry Andric   if (!DisableDelinearizationChecks)
35335ffd83dbSDimitry Andric     for (size_t I = 1; I < Size; ++I) {
35345ffd83dbSDimitry Andric       if (!isKnownNonNegative(SrcSubscripts[I], SrcPtr))
35350b57cec5SDimitry Andric         return false;
35360b57cec5SDimitry Andric 
35375ffd83dbSDimitry Andric       if (!isKnownLessThan(SrcSubscripts[I], Sizes[I - 1]))
35380b57cec5SDimitry Andric         return false;
35390b57cec5SDimitry Andric 
35405ffd83dbSDimitry Andric       if (!isKnownNonNegative(DstSubscripts[I], DstPtr))
35410b57cec5SDimitry Andric         return false;
35420b57cec5SDimitry Andric 
35435ffd83dbSDimitry Andric       if (!isKnownLessThan(DstSubscripts[I], Sizes[I - 1]))
35440b57cec5SDimitry Andric         return false;
35450b57cec5SDimitry Andric     }
35460b57cec5SDimitry Andric 
35470b57cec5SDimitry Andric   return true;
35480b57cec5SDimitry Andric }
35490b57cec5SDimitry Andric 
35500b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
35510b57cec5SDimitry Andric 
35520b57cec5SDimitry Andric #ifndef NDEBUG
35530b57cec5SDimitry Andric // For debugging purposes, dump a small bit vector to dbgs().
35540b57cec5SDimitry Andric static void dumpSmallBitVector(SmallBitVector &BV) {
35550b57cec5SDimitry Andric   dbgs() << "{";
35560b57cec5SDimitry Andric   for (unsigned VI : BV.set_bits()) {
35570b57cec5SDimitry Andric     dbgs() << VI;
35580b57cec5SDimitry Andric     if (BV.find_next(VI) >= 0)
35590b57cec5SDimitry Andric       dbgs() << ' ';
35600b57cec5SDimitry Andric   }
35610b57cec5SDimitry Andric   dbgs() << "}\n";
35620b57cec5SDimitry Andric }
35630b57cec5SDimitry Andric #endif
35640b57cec5SDimitry Andric 
35650b57cec5SDimitry Andric bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
35660b57cec5SDimitry Andric                                 FunctionAnalysisManager::Invalidator &Inv) {
35670b57cec5SDimitry Andric   // Check if the analysis itself has been invalidated.
35680b57cec5SDimitry Andric   auto PAC = PA.getChecker<DependenceAnalysis>();
35690b57cec5SDimitry Andric   if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>())
35700b57cec5SDimitry Andric     return true;
35710b57cec5SDimitry Andric 
35720b57cec5SDimitry Andric   // Check transitive dependencies.
35730b57cec5SDimitry Andric   return Inv.invalidate<AAManager>(F, PA) ||
35740b57cec5SDimitry Andric          Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
35750b57cec5SDimitry Andric          Inv.invalidate<LoopAnalysis>(F, PA);
35760b57cec5SDimitry Andric }
35770b57cec5SDimitry Andric 
35780b57cec5SDimitry Andric // depends -
35790b57cec5SDimitry Andric // Returns NULL if there is no dependence.
35800b57cec5SDimitry Andric // Otherwise, return a Dependence with as many details as possible.
35810b57cec5SDimitry Andric // Corresponds to Section 3.1 in the paper
35820b57cec5SDimitry Andric //
35830b57cec5SDimitry Andric //            Practical Dependence Testing
35840b57cec5SDimitry Andric //            Goff, Kennedy, Tseng
35850b57cec5SDimitry Andric //            PLDI 1991
35860b57cec5SDimitry Andric //
35870b57cec5SDimitry Andric // Care is required to keep the routine below, getSplitIteration(),
35880b57cec5SDimitry Andric // up to date with respect to this routine.
35890b57cec5SDimitry Andric std::unique_ptr<Dependence>
35900b57cec5SDimitry Andric DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35910b57cec5SDimitry Andric                         bool PossiblyLoopIndependent) {
35920b57cec5SDimitry Andric   if (Src == Dst)
35930b57cec5SDimitry Andric     PossiblyLoopIndependent = false;
35940b57cec5SDimitry Andric 
3595480093f4SDimitry Andric   if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
35960b57cec5SDimitry Andric     // if both instructions don't reference memory, there's no dependence
35970b57cec5SDimitry Andric     return nullptr;
35980b57cec5SDimitry Andric 
35990b57cec5SDimitry Andric   if (!isLoadOrStore(Src) || !isLoadOrStore(Dst)) {
36000b57cec5SDimitry Andric     // can only analyze simple loads and stores, i.e., no calls, invokes, etc.
36010b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "can only handle simple loads and stores\n");
36028bcb0991SDimitry Andric     return std::make_unique<Dependence>(Src, Dst);
36030b57cec5SDimitry Andric   }
36040b57cec5SDimitry Andric 
36050b57cec5SDimitry Andric   assert(isLoadOrStore(Src) && "instruction is not load or store");
36060b57cec5SDimitry Andric   assert(isLoadOrStore(Dst) && "instruction is not load or store");
36070b57cec5SDimitry Andric   Value *SrcPtr = getLoadStorePointerOperand(Src);
36080b57cec5SDimitry Andric   Value *DstPtr = getLoadStorePointerOperand(Dst);
36090b57cec5SDimitry Andric 
3610*0fca6ea1SDimitry Andric   switch (underlyingObjectsAlias(AA, F->getDataLayout(),
36110b57cec5SDimitry Andric                                  MemoryLocation::get(Dst),
36120b57cec5SDimitry Andric                                  MemoryLocation::get(Src))) {
3613fe6060f1SDimitry Andric   case AliasResult::MayAlias:
3614fe6060f1SDimitry Andric   case AliasResult::PartialAlias:
36150b57cec5SDimitry Andric     // cannot analyse objects if we don't understand their aliasing.
36160b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "can't analyze may or partial alias\n");
36178bcb0991SDimitry Andric     return std::make_unique<Dependence>(Src, Dst);
3618fe6060f1SDimitry Andric   case AliasResult::NoAlias:
36190b57cec5SDimitry Andric     // If the objects noalias, they are distinct, accesses are independent.
36200b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "no alias\n");
36210b57cec5SDimitry Andric     return nullptr;
3622fe6060f1SDimitry Andric   case AliasResult::MustAlias:
36230b57cec5SDimitry Andric     break; // The underlying objects alias; test accesses for dependence.
36240b57cec5SDimitry Andric   }
36250b57cec5SDimitry Andric 
36260b57cec5SDimitry Andric   // establish loop nesting levels
36270b57cec5SDimitry Andric   establishNestingLevels(Src, Dst);
36280b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    common nesting levels = " << CommonLevels << "\n");
36290b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    maximum nesting levels = " << MaxLevels << "\n");
36300b57cec5SDimitry Andric 
36310b57cec5SDimitry Andric   FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
36320b57cec5SDimitry Andric   ++TotalArrayPairs;
36330b57cec5SDimitry Andric 
36340b57cec5SDimitry Andric   unsigned Pairs = 1;
36350b57cec5SDimitry Andric   SmallVector<Subscript, 2> Pair(Pairs);
36360b57cec5SDimitry Andric   const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
36370b57cec5SDimitry Andric   const SCEV *DstSCEV = SE->getSCEV(DstPtr);
36380b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    SrcSCEV = " << *SrcSCEV << "\n");
36390b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    DstSCEV = " << *DstSCEV << "\n");
3640fe6060f1SDimitry Andric   if (SE->getPointerBase(SrcSCEV) != SE->getPointerBase(DstSCEV)) {
3641fe6060f1SDimitry Andric     // If two pointers have different bases, trying to analyze indexes won't
3642fe6060f1SDimitry Andric     // work; we can't compare them to each other. This can happen, for example,
3643fe6060f1SDimitry Andric     // if one is produced by an LCSSA PHI node.
3644fe6060f1SDimitry Andric     //
3645fe6060f1SDimitry Andric     // We check this upfront so we don't crash in cases where getMinusSCEV()
3646fe6060f1SDimitry Andric     // returns a SCEVCouldNotCompute.
3647fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "can't analyze SCEV with different pointer base\n");
3648fe6060f1SDimitry Andric     return std::make_unique<Dependence>(Src, Dst);
3649fe6060f1SDimitry Andric   }
36500b57cec5SDimitry Andric   Pair[0].Src = SrcSCEV;
36510b57cec5SDimitry Andric   Pair[0].Dst = DstSCEV;
36520b57cec5SDimitry Andric 
36530b57cec5SDimitry Andric   if (Delinearize) {
36540b57cec5SDimitry Andric     if (tryDelinearize(Src, Dst, Pair)) {
36550b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "    delinearized\n");
36560b57cec5SDimitry Andric       Pairs = Pair.size();
36570b57cec5SDimitry Andric     }
36580b57cec5SDimitry Andric   }
36590b57cec5SDimitry Andric 
36600b57cec5SDimitry Andric   for (unsigned P = 0; P < Pairs; ++P) {
36610b57cec5SDimitry Andric     Pair[P].Loops.resize(MaxLevels + 1);
36620b57cec5SDimitry Andric     Pair[P].GroupLoops.resize(MaxLevels + 1);
36630b57cec5SDimitry Andric     Pair[P].Group.resize(Pairs);
36640b57cec5SDimitry Andric     removeMatchingExtensions(&Pair[P]);
36650b57cec5SDimitry Andric     Pair[P].Classification =
36660b57cec5SDimitry Andric       classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
36670b57cec5SDimitry Andric                    Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
36680b57cec5SDimitry Andric                    Pair[P].Loops);
36690b57cec5SDimitry Andric     Pair[P].GroupLoops = Pair[P].Loops;
36700b57cec5SDimitry Andric     Pair[P].Group.set(P);
36710b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "    subscript " << P << "\n");
36720b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tsrc = " << *Pair[P].Src << "\n");
36730b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tdst = " << *Pair[P].Dst << "\n");
36740b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tclass = " << Pair[P].Classification << "\n");
36750b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tloops = ");
36760b57cec5SDimitry Andric     LLVM_DEBUG(dumpSmallBitVector(Pair[P].Loops));
36770b57cec5SDimitry Andric   }
36780b57cec5SDimitry Andric 
36790b57cec5SDimitry Andric   SmallBitVector Separable(Pairs);
36800b57cec5SDimitry Andric   SmallBitVector Coupled(Pairs);
36810b57cec5SDimitry Andric 
36820b57cec5SDimitry Andric   // Partition subscripts into separable and minimally-coupled groups
36830b57cec5SDimitry Andric   // Algorithm in paper is algorithmically better;
36840b57cec5SDimitry Andric   // this may be faster in practice. Check someday.
36850b57cec5SDimitry Andric   //
36860b57cec5SDimitry Andric   // Here's an example of how it works. Consider this code:
36870b57cec5SDimitry Andric   //
36880b57cec5SDimitry Andric   //   for (i = ...) {
36890b57cec5SDimitry Andric   //     for (j = ...) {
36900b57cec5SDimitry Andric   //       for (k = ...) {
36910b57cec5SDimitry Andric   //         for (l = ...) {
36920b57cec5SDimitry Andric   //           for (m = ...) {
36930b57cec5SDimitry Andric   //             A[i][j][k][m] = ...;
36940b57cec5SDimitry Andric   //             ... = A[0][j][l][i + j];
36950b57cec5SDimitry Andric   //           }
36960b57cec5SDimitry Andric   //         }
36970b57cec5SDimitry Andric   //       }
36980b57cec5SDimitry Andric   //     }
36990b57cec5SDimitry Andric   //   }
37000b57cec5SDimitry Andric   //
37010b57cec5SDimitry Andric   // There are 4 subscripts here:
37020b57cec5SDimitry Andric   //    0 [i] and [0]
37030b57cec5SDimitry Andric   //    1 [j] and [j]
37040b57cec5SDimitry Andric   //    2 [k] and [l]
37050b57cec5SDimitry Andric   //    3 [m] and [i + j]
37060b57cec5SDimitry Andric   //
37070b57cec5SDimitry Andric   // We've already classified each subscript pair as ZIV, SIV, etc.,
37080b57cec5SDimitry Andric   // and collected all the loops mentioned by pair P in Pair[P].Loops.
37090b57cec5SDimitry Andric   // In addition, we've initialized Pair[P].GroupLoops to Pair[P].Loops
37100b57cec5SDimitry Andric   // and set Pair[P].Group = {P}.
37110b57cec5SDimitry Andric   //
37120b57cec5SDimitry Andric   //      Src Dst    Classification Loops  GroupLoops Group
37130b57cec5SDimitry Andric   //    0 [i] [0]         SIV       {1}      {1}        {0}
37140b57cec5SDimitry Andric   //    1 [j] [j]         SIV       {2}      {2}        {1}
37150b57cec5SDimitry Andric   //    2 [k] [l]         RDIV      {3,4}    {3,4}      {2}
37160b57cec5SDimitry Andric   //    3 [m] [i + j]     MIV       {1,2,5}  {1,2,5}    {3}
37170b57cec5SDimitry Andric   //
37180b57cec5SDimitry Andric   // For each subscript SI 0 .. 3, we consider each remaining subscript, SJ.
37190b57cec5SDimitry Andric   // So, 0 is compared against 1, 2, and 3; 1 is compared against 2 and 3, etc.
37200b57cec5SDimitry Andric   //
37210b57cec5SDimitry Andric   // We begin by comparing 0 and 1. The intersection of the GroupLoops is empty.
37220b57cec5SDimitry Andric   // Next, 0 and 2. Again, the intersection of their GroupLoops is empty.
37230b57cec5SDimitry Andric   // Next 0 and 3. The intersection of their GroupLoop = {1}, not empty,
37240b57cec5SDimitry Andric   // so Pair[3].Group = {0,3} and Done = false (that is, 0 will not be added
37250b57cec5SDimitry Andric   // to either Separable or Coupled).
37260b57cec5SDimitry Andric   //
37270b57cec5SDimitry Andric   // Next, we consider 1 and 2. The intersection of the GroupLoops is empty.
37280b57cec5SDimitry Andric   // Next, 1 and 3. The intersection of their GroupLoops = {2}, not empty,
37290b57cec5SDimitry Andric   // so Pair[3].Group = {0, 1, 3} and Done = false.
37300b57cec5SDimitry Andric   //
37310b57cec5SDimitry Andric   // Next, we compare 2 against 3. The intersection of the GroupLoops is empty.
37320b57cec5SDimitry Andric   // Since Done remains true, we add 2 to the set of Separable pairs.
37330b57cec5SDimitry Andric   //
37340b57cec5SDimitry Andric   // Finally, we consider 3. There's nothing to compare it with,
37350b57cec5SDimitry Andric   // so Done remains true and we add it to the Coupled set.
37360b57cec5SDimitry Andric   // Pair[3].Group = {0, 1, 3} and GroupLoops = {1, 2, 5}.
37370b57cec5SDimitry Andric   //
37380b57cec5SDimitry Andric   // In the end, we've got 1 separable subscript and 1 coupled group.
37390b57cec5SDimitry Andric   for (unsigned SI = 0; SI < Pairs; ++SI) {
37400b57cec5SDimitry Andric     if (Pair[SI].Classification == Subscript::NonLinear) {
37410b57cec5SDimitry Andric       // ignore these, but collect loops for later
37420b57cec5SDimitry Andric       ++NonlinearSubscriptPairs;
37430b57cec5SDimitry Andric       collectCommonLoops(Pair[SI].Src,
37440b57cec5SDimitry Andric                          LI->getLoopFor(Src->getParent()),
37450b57cec5SDimitry Andric                          Pair[SI].Loops);
37460b57cec5SDimitry Andric       collectCommonLoops(Pair[SI].Dst,
37470b57cec5SDimitry Andric                          LI->getLoopFor(Dst->getParent()),
37480b57cec5SDimitry Andric                          Pair[SI].Loops);
37490b57cec5SDimitry Andric       Result.Consistent = false;
37500b57cec5SDimitry Andric     } else if (Pair[SI].Classification == Subscript::ZIV) {
37510b57cec5SDimitry Andric       // always separable
37520b57cec5SDimitry Andric       Separable.set(SI);
37530b57cec5SDimitry Andric     }
37540b57cec5SDimitry Andric     else {
37550b57cec5SDimitry Andric       // SIV, RDIV, or MIV, so check for coupled group
37560b57cec5SDimitry Andric       bool Done = true;
37570b57cec5SDimitry Andric       for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
37580b57cec5SDimitry Andric         SmallBitVector Intersection = Pair[SI].GroupLoops;
37590b57cec5SDimitry Andric         Intersection &= Pair[SJ].GroupLoops;
37600b57cec5SDimitry Andric         if (Intersection.any()) {
37610b57cec5SDimitry Andric           // accumulate set of all the loops in group
37620b57cec5SDimitry Andric           Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
37630b57cec5SDimitry Andric           // accumulate set of all subscripts in group
37640b57cec5SDimitry Andric           Pair[SJ].Group |= Pair[SI].Group;
37650b57cec5SDimitry Andric           Done = false;
37660b57cec5SDimitry Andric         }
37670b57cec5SDimitry Andric       }
37680b57cec5SDimitry Andric       if (Done) {
37690b57cec5SDimitry Andric         if (Pair[SI].Group.count() == 1) {
37700b57cec5SDimitry Andric           Separable.set(SI);
37710b57cec5SDimitry Andric           ++SeparableSubscriptPairs;
37720b57cec5SDimitry Andric         }
37730b57cec5SDimitry Andric         else {
37740b57cec5SDimitry Andric           Coupled.set(SI);
37750b57cec5SDimitry Andric           ++CoupledSubscriptPairs;
37760b57cec5SDimitry Andric         }
37770b57cec5SDimitry Andric       }
37780b57cec5SDimitry Andric     }
37790b57cec5SDimitry Andric   }
37800b57cec5SDimitry Andric 
37810b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    Separable = ");
37820b57cec5SDimitry Andric   LLVM_DEBUG(dumpSmallBitVector(Separable));
37830b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    Coupled = ");
37840b57cec5SDimitry Andric   LLVM_DEBUG(dumpSmallBitVector(Coupled));
37850b57cec5SDimitry Andric 
37860b57cec5SDimitry Andric   Constraint NewConstraint;
37870b57cec5SDimitry Andric   NewConstraint.setAny(SE);
37880b57cec5SDimitry Andric 
37890b57cec5SDimitry Andric   // test separable subscripts
37900b57cec5SDimitry Andric   for (unsigned SI : Separable.set_bits()) {
37910b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "testing subscript " << SI);
37920b57cec5SDimitry Andric     switch (Pair[SI].Classification) {
37930b57cec5SDimitry Andric     case Subscript::ZIV:
37940b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << ", ZIV\n");
37950b57cec5SDimitry Andric       if (testZIV(Pair[SI].Src, Pair[SI].Dst, Result))
37960b57cec5SDimitry Andric         return nullptr;
37970b57cec5SDimitry Andric       break;
37980b57cec5SDimitry Andric     case Subscript::SIV: {
37990b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << ", SIV\n");
38000b57cec5SDimitry Andric       unsigned Level;
38010b57cec5SDimitry Andric       const SCEV *SplitIter = nullptr;
38020b57cec5SDimitry Andric       if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
38030b57cec5SDimitry Andric                   SplitIter))
38040b57cec5SDimitry Andric         return nullptr;
38050b57cec5SDimitry Andric       break;
38060b57cec5SDimitry Andric     }
38070b57cec5SDimitry Andric     case Subscript::RDIV:
38080b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << ", RDIV\n");
38090b57cec5SDimitry Andric       if (testRDIV(Pair[SI].Src, Pair[SI].Dst, Result))
38100b57cec5SDimitry Andric         return nullptr;
38110b57cec5SDimitry Andric       break;
38120b57cec5SDimitry Andric     case Subscript::MIV:
38130b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << ", MIV\n");
38140b57cec5SDimitry Andric       if (testMIV(Pair[SI].Src, Pair[SI].Dst, Pair[SI].Loops, Result))
38150b57cec5SDimitry Andric         return nullptr;
38160b57cec5SDimitry Andric       break;
38170b57cec5SDimitry Andric     default:
38180b57cec5SDimitry Andric       llvm_unreachable("subscript has unexpected classification");
38190b57cec5SDimitry Andric     }
38200b57cec5SDimitry Andric   }
38210b57cec5SDimitry Andric 
38220b57cec5SDimitry Andric   if (Coupled.count()) {
38230b57cec5SDimitry Andric     // test coupled subscript groups
38240b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "starting on coupled subscripts\n");
38250b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "MaxLevels + 1 = " << MaxLevels + 1 << "\n");
38260b57cec5SDimitry Andric     SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
38270b57cec5SDimitry Andric     for (unsigned II = 0; II <= MaxLevels; ++II)
38280b57cec5SDimitry Andric       Constraints[II].setAny(SE);
38290b57cec5SDimitry Andric     for (unsigned SI : Coupled.set_bits()) {
38300b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "testing subscript group " << SI << " { ");
38310b57cec5SDimitry Andric       SmallBitVector Group(Pair[SI].Group);
38320b57cec5SDimitry Andric       SmallBitVector Sivs(Pairs);
38330b57cec5SDimitry Andric       SmallBitVector Mivs(Pairs);
38340b57cec5SDimitry Andric       SmallBitVector ConstrainedLevels(MaxLevels + 1);
38350b57cec5SDimitry Andric       SmallVector<Subscript *, 4> PairsInGroup;
38360b57cec5SDimitry Andric       for (unsigned SJ : Group.set_bits()) {
38370b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << SJ << " ");
38380b57cec5SDimitry Andric         if (Pair[SJ].Classification == Subscript::SIV)
38390b57cec5SDimitry Andric           Sivs.set(SJ);
38400b57cec5SDimitry Andric         else
38410b57cec5SDimitry Andric           Mivs.set(SJ);
38420b57cec5SDimitry Andric         PairsInGroup.push_back(&Pair[SJ]);
38430b57cec5SDimitry Andric       }
38440b57cec5SDimitry Andric       unifySubscriptType(PairsInGroup);
38450b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "}\n");
38460b57cec5SDimitry Andric       while (Sivs.any()) {
38470b57cec5SDimitry Andric         bool Changed = false;
38480b57cec5SDimitry Andric         for (unsigned SJ : Sivs.set_bits()) {
38490b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "testing subscript " << SJ << ", SIV\n");
38500b57cec5SDimitry Andric           // SJ is an SIV subscript that's part of the current coupled group
38510b57cec5SDimitry Andric           unsigned Level;
38520b57cec5SDimitry Andric           const SCEV *SplitIter = nullptr;
38530b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "SIV\n");
38540b57cec5SDimitry Andric           if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
38550b57cec5SDimitry Andric                       SplitIter))
38560b57cec5SDimitry Andric             return nullptr;
38570b57cec5SDimitry Andric           ConstrainedLevels.set(Level);
38580b57cec5SDimitry Andric           if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
38590b57cec5SDimitry Andric             if (Constraints[Level].isEmpty()) {
38600b57cec5SDimitry Andric               ++DeltaIndependence;
38610b57cec5SDimitry Andric               return nullptr;
38620b57cec5SDimitry Andric             }
38630b57cec5SDimitry Andric             Changed = true;
38640b57cec5SDimitry Andric           }
38650b57cec5SDimitry Andric           Sivs.reset(SJ);
38660b57cec5SDimitry Andric         }
38670b57cec5SDimitry Andric         if (Changed) {
38680b57cec5SDimitry Andric           // propagate, possibly creating new SIVs and ZIVs
38690b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "    propagating\n");
38700b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "\tMivs = ");
38710b57cec5SDimitry Andric           LLVM_DEBUG(dumpSmallBitVector(Mivs));
38720b57cec5SDimitry Andric           for (unsigned SJ : Mivs.set_bits()) {
38730b57cec5SDimitry Andric             // SJ is an MIV subscript that's part of the current coupled group
38740b57cec5SDimitry Andric             LLVM_DEBUG(dbgs() << "\tSJ = " << SJ << "\n");
38750b57cec5SDimitry Andric             if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
38760b57cec5SDimitry Andric                           Constraints, Result.Consistent)) {
38770b57cec5SDimitry Andric               LLVM_DEBUG(dbgs() << "\t    Changed\n");
38780b57cec5SDimitry Andric               ++DeltaPropagations;
38790b57cec5SDimitry Andric               Pair[SJ].Classification =
38800b57cec5SDimitry Andric                 classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
38810b57cec5SDimitry Andric                              Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
38820b57cec5SDimitry Andric                              Pair[SJ].Loops);
38830b57cec5SDimitry Andric               switch (Pair[SJ].Classification) {
38840b57cec5SDimitry Andric               case Subscript::ZIV:
38850b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "ZIV\n");
38860b57cec5SDimitry Andric                 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
38870b57cec5SDimitry Andric                   return nullptr;
38880b57cec5SDimitry Andric                 Mivs.reset(SJ);
38890b57cec5SDimitry Andric                 break;
38900b57cec5SDimitry Andric               case Subscript::SIV:
38910b57cec5SDimitry Andric                 Sivs.set(SJ);
38920b57cec5SDimitry Andric                 Mivs.reset(SJ);
38930b57cec5SDimitry Andric                 break;
38940b57cec5SDimitry Andric               case Subscript::RDIV:
38950b57cec5SDimitry Andric               case Subscript::MIV:
38960b57cec5SDimitry Andric                 break;
38970b57cec5SDimitry Andric               default:
38980b57cec5SDimitry Andric                 llvm_unreachable("bad subscript classification");
38990b57cec5SDimitry Andric               }
39000b57cec5SDimitry Andric             }
39010b57cec5SDimitry Andric           }
39020b57cec5SDimitry Andric         }
39030b57cec5SDimitry Andric       }
39040b57cec5SDimitry Andric 
39050b57cec5SDimitry Andric       // test & propagate remaining RDIVs
39060b57cec5SDimitry Andric       for (unsigned SJ : Mivs.set_bits()) {
39070b57cec5SDimitry Andric         if (Pair[SJ].Classification == Subscript::RDIV) {
39080b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "RDIV test\n");
39090b57cec5SDimitry Andric           if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
39100b57cec5SDimitry Andric             return nullptr;
39110b57cec5SDimitry Andric           // I don't yet understand how to propagate RDIV results
39120b57cec5SDimitry Andric           Mivs.reset(SJ);
39130b57cec5SDimitry Andric         }
39140b57cec5SDimitry Andric       }
39150b57cec5SDimitry Andric 
39160b57cec5SDimitry Andric       // test remaining MIVs
39170b57cec5SDimitry Andric       // This code is temporary.
39180b57cec5SDimitry Andric       // Better to somehow test all remaining subscripts simultaneously.
39190b57cec5SDimitry Andric       for (unsigned SJ : Mivs.set_bits()) {
39200b57cec5SDimitry Andric         if (Pair[SJ].Classification == Subscript::MIV) {
39210b57cec5SDimitry Andric           LLVM_DEBUG(dbgs() << "MIV test\n");
39220b57cec5SDimitry Andric           if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
39230b57cec5SDimitry Andric             return nullptr;
39240b57cec5SDimitry Andric         }
39250b57cec5SDimitry Andric         else
39260b57cec5SDimitry Andric           llvm_unreachable("expected only MIV subscripts at this point");
39270b57cec5SDimitry Andric       }
39280b57cec5SDimitry Andric 
39290b57cec5SDimitry Andric       // update Result.DV from constraint vector
39300b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "    updating\n");
39310b57cec5SDimitry Andric       for (unsigned SJ : ConstrainedLevels.set_bits()) {
39320b57cec5SDimitry Andric         if (SJ > CommonLevels)
39330b57cec5SDimitry Andric           break;
39340b57cec5SDimitry Andric         updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
39350b57cec5SDimitry Andric         if (Result.DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
39360b57cec5SDimitry Andric           return nullptr;
39370b57cec5SDimitry Andric       }
39380b57cec5SDimitry Andric     }
39390b57cec5SDimitry Andric   }
39400b57cec5SDimitry Andric 
39410b57cec5SDimitry Andric   // Make sure the Scalar flags are set correctly.
39420b57cec5SDimitry Andric   SmallBitVector CompleteLoops(MaxLevels + 1);
39430b57cec5SDimitry Andric   for (unsigned SI = 0; SI < Pairs; ++SI)
39440b57cec5SDimitry Andric     CompleteLoops |= Pair[SI].Loops;
39450b57cec5SDimitry Andric   for (unsigned II = 1; II <= CommonLevels; ++II)
39460b57cec5SDimitry Andric     if (CompleteLoops[II])
39470b57cec5SDimitry Andric       Result.DV[II - 1].Scalar = false;
39480b57cec5SDimitry Andric 
39490b57cec5SDimitry Andric   if (PossiblyLoopIndependent) {
39500b57cec5SDimitry Andric     // Make sure the LoopIndependent flag is set correctly.
39510b57cec5SDimitry Andric     // All directions must include equal, otherwise no
39520b57cec5SDimitry Andric     // loop-independent dependence is possible.
39530b57cec5SDimitry Andric     for (unsigned II = 1; II <= CommonLevels; ++II) {
39540b57cec5SDimitry Andric       if (!(Result.getDirection(II) & Dependence::DVEntry::EQ)) {
39550b57cec5SDimitry Andric         Result.LoopIndependent = false;
39560b57cec5SDimitry Andric         break;
39570b57cec5SDimitry Andric       }
39580b57cec5SDimitry Andric     }
39590b57cec5SDimitry Andric   }
39600b57cec5SDimitry Andric   else {
39610b57cec5SDimitry Andric     // On the other hand, if all directions are equal and there's no
39620b57cec5SDimitry Andric     // loop-independent dependence possible, then no dependence exists.
39630b57cec5SDimitry Andric     bool AllEqual = true;
39640b57cec5SDimitry Andric     for (unsigned II = 1; II <= CommonLevels; ++II) {
39650b57cec5SDimitry Andric       if (Result.getDirection(II) != Dependence::DVEntry::EQ) {
39660b57cec5SDimitry Andric         AllEqual = false;
39670b57cec5SDimitry Andric         break;
39680b57cec5SDimitry Andric       }
39690b57cec5SDimitry Andric     }
39700b57cec5SDimitry Andric     if (AllEqual)
39710b57cec5SDimitry Andric       return nullptr;
39720b57cec5SDimitry Andric   }
39730b57cec5SDimitry Andric 
39748bcb0991SDimitry Andric   return std::make_unique<FullDependence>(std::move(Result));
39750b57cec5SDimitry Andric }
39760b57cec5SDimitry Andric 
39770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
39780b57cec5SDimitry Andric // getSplitIteration -
39790b57cec5SDimitry Andric // Rather than spend rarely-used space recording the splitting iteration
39800b57cec5SDimitry Andric // during the Weak-Crossing SIV test, we re-compute it on demand.
39810b57cec5SDimitry Andric // The re-computation is basically a repeat of the entire dependence test,
39820b57cec5SDimitry Andric // though simplified since we know that the dependence exists.
39830b57cec5SDimitry Andric // It's tedious, since we must go through all propagations, etc.
39840b57cec5SDimitry Andric //
39850b57cec5SDimitry Andric // Care is required to keep this code up to date with respect to the routine
39860b57cec5SDimitry Andric // above, depends().
39870b57cec5SDimitry Andric //
39880b57cec5SDimitry Andric // Generally, the dependence analyzer will be used to build
39890b57cec5SDimitry Andric // a dependence graph for a function (basically a map from instructions
39900b57cec5SDimitry Andric // to dependences). Looking for cycles in the graph shows us loops
39910b57cec5SDimitry Andric // that cannot be trivially vectorized/parallelized.
39920b57cec5SDimitry Andric //
39930b57cec5SDimitry Andric // We can try to improve the situation by examining all the dependences
39940b57cec5SDimitry Andric // that make up the cycle, looking for ones we can break.
39950b57cec5SDimitry Andric // Sometimes, peeling the first or last iteration of a loop will break
39960b57cec5SDimitry Andric // dependences, and we've got flags for those possibilities.
39970b57cec5SDimitry Andric // Sometimes, splitting a loop at some other iteration will do the trick,
39980b57cec5SDimitry Andric // and we've got a flag for that case. Rather than waste the space to
39990b57cec5SDimitry Andric // record the exact iteration (since we rarely know), we provide
40000b57cec5SDimitry Andric // a method that calculates the iteration. It's a drag that it must work
40010b57cec5SDimitry Andric // from scratch, but wonderful in that it's possible.
40020b57cec5SDimitry Andric //
40030b57cec5SDimitry Andric // Here's an example:
40040b57cec5SDimitry Andric //
40050b57cec5SDimitry Andric //    for (i = 0; i < 10; i++)
40060b57cec5SDimitry Andric //        A[i] = ...
40070b57cec5SDimitry Andric //        ... = A[11 - i]
40080b57cec5SDimitry Andric //
40090b57cec5SDimitry Andric // There's a loop-carried flow dependence from the store to the load,
40100b57cec5SDimitry Andric // found by the weak-crossing SIV test. The dependence will have a flag,
40110b57cec5SDimitry Andric // indicating that the dependence can be broken by splitting the loop.
40120b57cec5SDimitry Andric // Calling getSplitIteration will return 5.
40130b57cec5SDimitry Andric // Splitting the loop breaks the dependence, like so:
40140b57cec5SDimitry Andric //
40150b57cec5SDimitry Andric //    for (i = 0; i <= 5; i++)
40160b57cec5SDimitry Andric //        A[i] = ...
40170b57cec5SDimitry Andric //        ... = A[11 - i]
40180b57cec5SDimitry Andric //    for (i = 6; i < 10; i++)
40190b57cec5SDimitry Andric //        A[i] = ...
40200b57cec5SDimitry Andric //        ... = A[11 - i]
40210b57cec5SDimitry Andric //
40220b57cec5SDimitry Andric // breaks the dependence and allows us to vectorize/parallelize
40230b57cec5SDimitry Andric // both loops.
40240b57cec5SDimitry Andric const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
40250b57cec5SDimitry Andric                                               unsigned SplitLevel) {
40260b57cec5SDimitry Andric   assert(Dep.isSplitable(SplitLevel) &&
40270b57cec5SDimitry Andric          "Dep should be splitable at SplitLevel");
40280b57cec5SDimitry Andric   Instruction *Src = Dep.getSrc();
40290b57cec5SDimitry Andric   Instruction *Dst = Dep.getDst();
40300b57cec5SDimitry Andric   assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
40310b57cec5SDimitry Andric   assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
40320b57cec5SDimitry Andric   assert(isLoadOrStore(Src));
40330b57cec5SDimitry Andric   assert(isLoadOrStore(Dst));
40340b57cec5SDimitry Andric   Value *SrcPtr = getLoadStorePointerOperand(Src);
40350b57cec5SDimitry Andric   Value *DstPtr = getLoadStorePointerOperand(Dst);
4036fe6060f1SDimitry Andric   assert(underlyingObjectsAlias(
4037*0fca6ea1SDimitry Andric              AA, F->getDataLayout(), MemoryLocation::get(Dst),
4038fe6060f1SDimitry Andric              MemoryLocation::get(Src)) == AliasResult::MustAlias);
40390b57cec5SDimitry Andric 
40400b57cec5SDimitry Andric   // establish loop nesting levels
40410b57cec5SDimitry Andric   establishNestingLevels(Src, Dst);
40420b57cec5SDimitry Andric 
40430b57cec5SDimitry Andric   FullDependence Result(Src, Dst, false, CommonLevels);
40440b57cec5SDimitry Andric 
40450b57cec5SDimitry Andric   unsigned Pairs = 1;
40460b57cec5SDimitry Andric   SmallVector<Subscript, 2> Pair(Pairs);
40470b57cec5SDimitry Andric   const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
40480b57cec5SDimitry Andric   const SCEV *DstSCEV = SE->getSCEV(DstPtr);
40490b57cec5SDimitry Andric   Pair[0].Src = SrcSCEV;
40500b57cec5SDimitry Andric   Pair[0].Dst = DstSCEV;
40510b57cec5SDimitry Andric 
40520b57cec5SDimitry Andric   if (Delinearize) {
40530b57cec5SDimitry Andric     if (tryDelinearize(Src, Dst, Pair)) {
40540b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "    delinearized\n");
40550b57cec5SDimitry Andric       Pairs = Pair.size();
40560b57cec5SDimitry Andric     }
40570b57cec5SDimitry Andric   }
40580b57cec5SDimitry Andric 
40590b57cec5SDimitry Andric   for (unsigned P = 0; P < Pairs; ++P) {
40600b57cec5SDimitry Andric     Pair[P].Loops.resize(MaxLevels + 1);
40610b57cec5SDimitry Andric     Pair[P].GroupLoops.resize(MaxLevels + 1);
40620b57cec5SDimitry Andric     Pair[P].Group.resize(Pairs);
40630b57cec5SDimitry Andric     removeMatchingExtensions(&Pair[P]);
40640b57cec5SDimitry Andric     Pair[P].Classification =
40650b57cec5SDimitry Andric       classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
40660b57cec5SDimitry Andric                    Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
40670b57cec5SDimitry Andric                    Pair[P].Loops);
40680b57cec5SDimitry Andric     Pair[P].GroupLoops = Pair[P].Loops;
40690b57cec5SDimitry Andric     Pair[P].Group.set(P);
40700b57cec5SDimitry Andric   }
40710b57cec5SDimitry Andric 
40720b57cec5SDimitry Andric   SmallBitVector Separable(Pairs);
40730b57cec5SDimitry Andric   SmallBitVector Coupled(Pairs);
40740b57cec5SDimitry Andric 
40750b57cec5SDimitry Andric   // partition subscripts into separable and minimally-coupled groups
40760b57cec5SDimitry Andric   for (unsigned SI = 0; SI < Pairs; ++SI) {
40770b57cec5SDimitry Andric     if (Pair[SI].Classification == Subscript::NonLinear) {
40780b57cec5SDimitry Andric       // ignore these, but collect loops for later
40790b57cec5SDimitry Andric       collectCommonLoops(Pair[SI].Src,
40800b57cec5SDimitry Andric                          LI->getLoopFor(Src->getParent()),
40810b57cec5SDimitry Andric                          Pair[SI].Loops);
40820b57cec5SDimitry Andric       collectCommonLoops(Pair[SI].Dst,
40830b57cec5SDimitry Andric                          LI->getLoopFor(Dst->getParent()),
40840b57cec5SDimitry Andric                          Pair[SI].Loops);
40850b57cec5SDimitry Andric       Result.Consistent = false;
40860b57cec5SDimitry Andric     }
40870b57cec5SDimitry Andric     else if (Pair[SI].Classification == Subscript::ZIV)
40880b57cec5SDimitry Andric       Separable.set(SI);
40890b57cec5SDimitry Andric     else {
40900b57cec5SDimitry Andric       // SIV, RDIV, or MIV, so check for coupled group
40910b57cec5SDimitry Andric       bool Done = true;
40920b57cec5SDimitry Andric       for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
40930b57cec5SDimitry Andric         SmallBitVector Intersection = Pair[SI].GroupLoops;
40940b57cec5SDimitry Andric         Intersection &= Pair[SJ].GroupLoops;
40950b57cec5SDimitry Andric         if (Intersection.any()) {
40960b57cec5SDimitry Andric           // accumulate set of all the loops in group
40970b57cec5SDimitry Andric           Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
40980b57cec5SDimitry Andric           // accumulate set of all subscripts in group
40990b57cec5SDimitry Andric           Pair[SJ].Group |= Pair[SI].Group;
41000b57cec5SDimitry Andric           Done = false;
41010b57cec5SDimitry Andric         }
41020b57cec5SDimitry Andric       }
41030b57cec5SDimitry Andric       if (Done) {
41040b57cec5SDimitry Andric         if (Pair[SI].Group.count() == 1)
41050b57cec5SDimitry Andric           Separable.set(SI);
41060b57cec5SDimitry Andric         else
41070b57cec5SDimitry Andric           Coupled.set(SI);
41080b57cec5SDimitry Andric       }
41090b57cec5SDimitry Andric     }
41100b57cec5SDimitry Andric   }
41110b57cec5SDimitry Andric 
41120b57cec5SDimitry Andric   Constraint NewConstraint;
41130b57cec5SDimitry Andric   NewConstraint.setAny(SE);
41140b57cec5SDimitry Andric 
41150b57cec5SDimitry Andric   // test separable subscripts
41160b57cec5SDimitry Andric   for (unsigned SI : Separable.set_bits()) {
41170b57cec5SDimitry Andric     switch (Pair[SI].Classification) {
41180b57cec5SDimitry Andric     case Subscript::SIV: {
41190b57cec5SDimitry Andric       unsigned Level;
41200b57cec5SDimitry Andric       const SCEV *SplitIter = nullptr;
41210b57cec5SDimitry Andric       (void) testSIV(Pair[SI].Src, Pair[SI].Dst, Level,
41220b57cec5SDimitry Andric                      Result, NewConstraint, SplitIter);
41230b57cec5SDimitry Andric       if (Level == SplitLevel) {
41240b57cec5SDimitry Andric         assert(SplitIter != nullptr);
41250b57cec5SDimitry Andric         return SplitIter;
41260b57cec5SDimitry Andric       }
41270b57cec5SDimitry Andric       break;
41280b57cec5SDimitry Andric     }
41290b57cec5SDimitry Andric     case Subscript::ZIV:
41300b57cec5SDimitry Andric     case Subscript::RDIV:
41310b57cec5SDimitry Andric     case Subscript::MIV:
41320b57cec5SDimitry Andric       break;
41330b57cec5SDimitry Andric     default:
41340b57cec5SDimitry Andric       llvm_unreachable("subscript has unexpected classification");
41350b57cec5SDimitry Andric     }
41360b57cec5SDimitry Andric   }
41370b57cec5SDimitry Andric 
41380b57cec5SDimitry Andric   if (Coupled.count()) {
41390b57cec5SDimitry Andric     // test coupled subscript groups
41400b57cec5SDimitry Andric     SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
41410b57cec5SDimitry Andric     for (unsigned II = 0; II <= MaxLevels; ++II)
41420b57cec5SDimitry Andric       Constraints[II].setAny(SE);
41430b57cec5SDimitry Andric     for (unsigned SI : Coupled.set_bits()) {
41440b57cec5SDimitry Andric       SmallBitVector Group(Pair[SI].Group);
41450b57cec5SDimitry Andric       SmallBitVector Sivs(Pairs);
41460b57cec5SDimitry Andric       SmallBitVector Mivs(Pairs);
41470b57cec5SDimitry Andric       SmallBitVector ConstrainedLevels(MaxLevels + 1);
41480b57cec5SDimitry Andric       for (unsigned SJ : Group.set_bits()) {
41490b57cec5SDimitry Andric         if (Pair[SJ].Classification == Subscript::SIV)
41500b57cec5SDimitry Andric           Sivs.set(SJ);
41510b57cec5SDimitry Andric         else
41520b57cec5SDimitry Andric           Mivs.set(SJ);
41530b57cec5SDimitry Andric       }
41540b57cec5SDimitry Andric       while (Sivs.any()) {
41550b57cec5SDimitry Andric         bool Changed = false;
41560b57cec5SDimitry Andric         for (unsigned SJ : Sivs.set_bits()) {
41570b57cec5SDimitry Andric           // SJ is an SIV subscript that's part of the current coupled group
41580b57cec5SDimitry Andric           unsigned Level;
41590b57cec5SDimitry Andric           const SCEV *SplitIter = nullptr;
41600b57cec5SDimitry Andric           (void) testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
41610b57cec5SDimitry Andric                          Result, NewConstraint, SplitIter);
41620b57cec5SDimitry Andric           if (Level == SplitLevel && SplitIter)
41630b57cec5SDimitry Andric             return SplitIter;
41640b57cec5SDimitry Andric           ConstrainedLevels.set(Level);
41650b57cec5SDimitry Andric           if (intersectConstraints(&Constraints[Level], &NewConstraint))
41660b57cec5SDimitry Andric             Changed = true;
41670b57cec5SDimitry Andric           Sivs.reset(SJ);
41680b57cec5SDimitry Andric         }
41690b57cec5SDimitry Andric         if (Changed) {
41700b57cec5SDimitry Andric           // propagate, possibly creating new SIVs and ZIVs
41710b57cec5SDimitry Andric           for (unsigned SJ : Mivs.set_bits()) {
41720b57cec5SDimitry Andric             // SJ is an MIV subscript that's part of the current coupled group
41730b57cec5SDimitry Andric             if (propagate(Pair[SJ].Src, Pair[SJ].Dst,
41740b57cec5SDimitry Andric                           Pair[SJ].Loops, Constraints, Result.Consistent)) {
41750b57cec5SDimitry Andric               Pair[SJ].Classification =
41760b57cec5SDimitry Andric                 classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
41770b57cec5SDimitry Andric                              Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
41780b57cec5SDimitry Andric                              Pair[SJ].Loops);
41790b57cec5SDimitry Andric               switch (Pair[SJ].Classification) {
41800b57cec5SDimitry Andric               case Subscript::ZIV:
41810b57cec5SDimitry Andric                 Mivs.reset(SJ);
41820b57cec5SDimitry Andric                 break;
41830b57cec5SDimitry Andric               case Subscript::SIV:
41840b57cec5SDimitry Andric                 Sivs.set(SJ);
41850b57cec5SDimitry Andric                 Mivs.reset(SJ);
41860b57cec5SDimitry Andric                 break;
41870b57cec5SDimitry Andric               case Subscript::RDIV:
41880b57cec5SDimitry Andric               case Subscript::MIV:
41890b57cec5SDimitry Andric                 break;
41900b57cec5SDimitry Andric               default:
41910b57cec5SDimitry Andric                 llvm_unreachable("bad subscript classification");
41920b57cec5SDimitry Andric               }
41930b57cec5SDimitry Andric             }
41940b57cec5SDimitry Andric           }
41950b57cec5SDimitry Andric         }
41960b57cec5SDimitry Andric       }
41970b57cec5SDimitry Andric     }
41980b57cec5SDimitry Andric   }
41990b57cec5SDimitry Andric   llvm_unreachable("somehow reached end of routine");
42000b57cec5SDimitry Andric   return nullptr;
42010b57cec5SDimitry Andric }
4202