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