159b61b9eSSebastian Pop //===-- DependenceAnalysis.cpp - DA Implementation --------------*- C++ -*-===//
259b61b9eSSebastian Pop //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
659b61b9eSSebastian Pop //
759b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
859b61b9eSSebastian Pop //
959b61b9eSSebastian Pop // DependenceAnalysis is an LLVM pass that analyses dependences between memory
1059b61b9eSSebastian Pop // accesses. Currently, it is an (incomplete) implementation of the approach
1159b61b9eSSebastian Pop // described in
1259b61b9eSSebastian Pop //
1359b61b9eSSebastian Pop // Practical Dependence Testing
1459b61b9eSSebastian Pop // Goff, Kennedy, Tseng
1559b61b9eSSebastian Pop // PLDI 1991
1659b61b9eSSebastian Pop //
1759b61b9eSSebastian Pop // There's a single entry point that analyzes the dependence between a pair
1859b61b9eSSebastian Pop // of memory references in a function, returning either NULL, for no dependence,
1959b61b9eSSebastian Pop // or a more-or-less detailed description of the dependence between them.
2059b61b9eSSebastian Pop //
2159b61b9eSSebastian Pop // Currently, the implementation cannot propagate constraints between
2259b61b9eSSebastian Pop // coupled RDIV subscripts and lacks a multi-subscript MIV test.
2359b61b9eSSebastian Pop // Both of these are conservative weaknesses;
2459b61b9eSSebastian Pop // that is, not a source of correctness problems.
2559b61b9eSSebastian Pop //
26bf6e1c26SSebastian Pop // Since Clang linearizes some array subscripts, the dependence
277ee14724SSebastian Pop // analysis is using SCEV->delinearize to recover the representation of multiple
287ee14724SSebastian Pop // subscripts, and thus avoid the more expensive and less precise MIV tests. The
297ee14724SSebastian Pop // delinearization is controlled by the flag -da-delinearize.
3059b61b9eSSebastian Pop //
3159b61b9eSSebastian Pop // We should pay some careful attention to the possibility of integer overflow
3259b61b9eSSebastian Pop // in the implementation of the various tests. This could happen with Add,
3359b61b9eSSebastian Pop // Subtract, or Multiply, with both APInt's and SCEV's.
3459b61b9eSSebastian Pop //
3559b61b9eSSebastian Pop // Some non-linear subscript pairs can be handled by the GCD test
3659b61b9eSSebastian Pop // (and perhaps other tests).
3759b61b9eSSebastian Pop // Should explore how often these things occur.
3859b61b9eSSebastian Pop //
3959b61b9eSSebastian Pop // Finally, it seems like certain test cases expose weaknesses in the SCEV
4059b61b9eSSebastian Pop // simplification, especially in the handling of sign and zero extensions.
4159b61b9eSSebastian Pop // It could be useful to spend time exploring these.
4259b61b9eSSebastian Pop //
4359b61b9eSSebastian Pop // Please note that this is work in progress and the interface is subject to
4459b61b9eSSebastian Pop // change.
4559b61b9eSSebastian Pop //
4659b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
4759b61b9eSSebastian Pop // //
4859b61b9eSSebastian Pop // In memory of Ken Kennedy, 1945 - 2007 //
4959b61b9eSSebastian Pop // //
5059b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
5159b61b9eSSebastian Pop
5259b61b9eSSebastian Pop #include "llvm/Analysis/DependenceAnalysis.h"
5359b61b9eSSebastian Pop #include "llvm/ADT/Statistic.h"
5471a3512dSBenjamin Kramer #include "llvm/Analysis/AliasAnalysis.h"
55585c594dSPhilip Reames #include "llvm/Analysis/Delinearization.h"
5671a3512dSBenjamin Kramer #include "llvm/Analysis/LoopInfo.h"
5771a3512dSBenjamin Kramer #include "llvm/Analysis/ScalarEvolution.h"
5871a3512dSBenjamin Kramer #include "llvm/Analysis/ScalarEvolutionExpressions.h"
59ed0881b2SChandler Carruth #include "llvm/Analysis/ValueTracking.h"
608394857fSChandler Carruth #include "llvm/IR/InstIterator.h"
61a28d91d8SMehdi Amini #include "llvm/IR/Module.h"
6205da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
63c62c679cSSebastian Pop #include "llvm/Support/CommandLine.h"
6459b61b9eSSebastian Pop #include "llvm/Support/Debug.h"
6559b61b9eSSebastian Pop #include "llvm/Support/ErrorHandling.h"
6671a3512dSBenjamin Kramer #include "llvm/Support/raw_ostream.h"
6759b61b9eSSebastian Pop
6859b61b9eSSebastian Pop using namespace llvm;
6959b61b9eSSebastian Pop
70f1221bd0SChandler Carruth #define DEBUG_TYPE "da"
71f1221bd0SChandler Carruth
7259b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
7359b61b9eSSebastian Pop // statistics
7459b61b9eSSebastian Pop
7559b61b9eSSebastian Pop STATISTIC(TotalArrayPairs, "Array pairs tested");
7659b61b9eSSebastian Pop STATISTIC(SeparableSubscriptPairs, "Separable subscript pairs");
7759b61b9eSSebastian Pop STATISTIC(CoupledSubscriptPairs, "Coupled subscript pairs");
7859b61b9eSSebastian Pop STATISTIC(NonlinearSubscriptPairs, "Nonlinear subscript pairs");
7959b61b9eSSebastian Pop STATISTIC(ZIVapplications, "ZIV applications");
8059b61b9eSSebastian Pop STATISTIC(ZIVindependence, "ZIV independence");
8159b61b9eSSebastian Pop STATISTIC(StrongSIVapplications, "Strong SIV applications");
8259b61b9eSSebastian Pop STATISTIC(StrongSIVsuccesses, "Strong SIV successes");
8359b61b9eSSebastian Pop STATISTIC(StrongSIVindependence, "Strong SIV independence");
8459b61b9eSSebastian Pop STATISTIC(WeakCrossingSIVapplications, "Weak-Crossing SIV applications");
8559b61b9eSSebastian Pop STATISTIC(WeakCrossingSIVsuccesses, "Weak-Crossing SIV successes");
8659b61b9eSSebastian Pop STATISTIC(WeakCrossingSIVindependence, "Weak-Crossing SIV independence");
8759b61b9eSSebastian Pop STATISTIC(ExactSIVapplications, "Exact SIV applications");
8859b61b9eSSebastian Pop STATISTIC(ExactSIVsuccesses, "Exact SIV successes");
8959b61b9eSSebastian Pop STATISTIC(ExactSIVindependence, "Exact SIV independence");
9059b61b9eSSebastian Pop STATISTIC(WeakZeroSIVapplications, "Weak-Zero SIV applications");
9159b61b9eSSebastian Pop STATISTIC(WeakZeroSIVsuccesses, "Weak-Zero SIV successes");
9259b61b9eSSebastian Pop STATISTIC(WeakZeroSIVindependence, "Weak-Zero SIV independence");
9359b61b9eSSebastian Pop STATISTIC(ExactRDIVapplications, "Exact RDIV applications");
9459b61b9eSSebastian Pop STATISTIC(ExactRDIVindependence, "Exact RDIV independence");
9559b61b9eSSebastian Pop STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
9659b61b9eSSebastian Pop STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
9759b61b9eSSebastian Pop STATISTIC(DeltaApplications, "Delta applications");
9859b61b9eSSebastian Pop STATISTIC(DeltaSuccesses, "Delta successes");
9959b61b9eSSebastian Pop STATISTIC(DeltaIndependence, "Delta independence");
10059b61b9eSSebastian Pop STATISTIC(DeltaPropagations, "Delta propagations");
10159b61b9eSSebastian Pop STATISTIC(GCDapplications, "GCD applications");
10259b61b9eSSebastian Pop STATISTIC(GCDsuccesses, "GCD successes");
10359b61b9eSSebastian Pop STATISTIC(GCDindependence, "GCD independence");
10459b61b9eSSebastian Pop STATISTIC(BanerjeeApplications, "Banerjee applications");
10559b61b9eSSebastian Pop STATISTIC(BanerjeeIndependence, "Banerjee independence");
10659b61b9eSSebastian Pop STATISTIC(BanerjeeSuccesses, "Banerjee successes");
10759b61b9eSSebastian Pop
108c62c679cSSebastian Pop static cl::opt<bool>
109557efc9aSFangrui Song Delinearize("da-delinearize", cl::init(true), cl::Hidden,
110c62c679cSSebastian Pop cl::desc("Try to delinearize array references."));
11103e8369aSWhitney Tsang static cl::opt<bool> DisableDelinearizationChecks(
112d86a206fSFangrui Song "da-disable-delinearization-checks", cl::Hidden,
11303e8369aSWhitney Tsang cl::desc(
11403e8369aSWhitney Tsang "Disable checks that try to statically verify validity of "
11503e8369aSWhitney Tsang "delinearized subscripts. Enabling this option may result in incorrect "
11603e8369aSWhitney Tsang "dependence vectors for languages that allow the subscript of one "
11703e8369aSWhitney Tsang "dimension to underflow or overflow into another dimension."));
118c62c679cSSebastian Pop
1190e08891eSBardia Mahjour static cl::opt<unsigned> MIVMaxLevelThreshold(
120557efc9aSFangrui Song "da-miv-max-level-threshold", cl::init(7), cl::Hidden,
1210e08891eSBardia Mahjour cl::desc("Maximum depth allowed for the recursive algorithm used to "
1220e08891eSBardia Mahjour "explore MIV direction vectors."));
1230e08891eSBardia Mahjour
12459b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
12559b61b9eSSebastian Pop // basics
12659b61b9eSSebastian Pop
12749c22190SChandler Carruth DependenceAnalysis::Result
run(Function & F,FunctionAnalysisManager & FAM)12849c22190SChandler Carruth DependenceAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
12949c22190SChandler Carruth auto &AA = FAM.getResult<AAManager>(F);
13049c22190SChandler Carruth auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
13149c22190SChandler Carruth auto &LI = FAM.getResult<LoopAnalysis>(F);
13249c22190SChandler Carruth return DependenceInfo(&F, &AA, &SE, &LI);
13349c22190SChandler Carruth }
13449c22190SChandler Carruth
135dab4eae2SChandler Carruth AnalysisKey DependenceAnalysis::Key;
13649c22190SChandler Carruth
13749c22190SChandler Carruth INITIALIZE_PASS_BEGIN(DependenceAnalysisWrapperPass, "da",
13859b61b9eSSebastian Pop "Dependence Analysis", true, true)
1394f8f307cSChandler Carruth INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
1402f1fd165SChandler Carruth INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
1417b560d40SChandler Carruth INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
14249c22190SChandler Carruth INITIALIZE_PASS_END(DependenceAnalysisWrapperPass, "da", "Dependence Analysis",
14349c22190SChandler Carruth true, true)
14459b61b9eSSebastian Pop
14549c22190SChandler Carruth char DependenceAnalysisWrapperPass::ID = 0;
14659b61b9eSSebastian Pop
DependenceAnalysisWrapperPass()14705da2fe5SReid Kleckner DependenceAnalysisWrapperPass::DependenceAnalysisWrapperPass()
14805da2fe5SReid Kleckner : FunctionPass(ID) {
14905da2fe5SReid Kleckner initializeDependenceAnalysisWrapperPassPass(*PassRegistry::getPassRegistry());
15005da2fe5SReid Kleckner }
15105da2fe5SReid Kleckner
createDependenceAnalysisWrapperPass()15249c22190SChandler Carruth FunctionPass *llvm::createDependenceAnalysisWrapperPass() {
15349c22190SChandler Carruth return new DependenceAnalysisWrapperPass();
15459b61b9eSSebastian Pop }
15559b61b9eSSebastian Pop
runOnFunction(Function & F)15649c22190SChandler Carruth bool DependenceAnalysisWrapperPass::runOnFunction(Function &F) {
15749c22190SChandler Carruth auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
15849c22190SChandler Carruth auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
15949c22190SChandler Carruth auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
16049c22190SChandler Carruth info.reset(new DependenceInfo(&F, &AA, &SE, &LI));
16159b61b9eSSebastian Pop return false;
16259b61b9eSSebastian Pop }
16359b61b9eSSebastian Pop
getDI() const16449c22190SChandler Carruth DependenceInfo &DependenceAnalysisWrapperPass::getDI() const { return *info; }
16559b61b9eSSebastian Pop
releaseMemory()16649c22190SChandler Carruth void DependenceAnalysisWrapperPass::releaseMemory() { info.reset(); }
16759b61b9eSSebastian Pop
getAnalysisUsage(AnalysisUsage & AU) const16849c22190SChandler Carruth void DependenceAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
16959b61b9eSSebastian Pop AU.setPreservesAll();
1707b560d40SChandler Carruth AU.addRequiredTransitive<AAResultsWrapperPass>();
1712f1fd165SChandler Carruth AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
1724f8f307cSChandler Carruth AU.addRequiredTransitive<LoopInfoWrapperPass>();
17359b61b9eSSebastian Pop }
17459b61b9eSSebastian Pop
17559b61b9eSSebastian Pop // Used to test the dependence analyzer.
176916d37a2SBardia Mahjour // Looks through the function, noting instructions that may access memory.
1773eb15630SBenjamin Kramer // Calls depends() on every possible pair and prints out the result.
17859b61b9eSSebastian Pop // Ignores all other instructions.
dumpExampleDependence(raw_ostream & OS,DependenceInfo * DA)17949c22190SChandler Carruth static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA) {
18049c22190SChandler Carruth auto *F = DA->getFunction();
18149c22190SChandler Carruth for (inst_iterator SrcI = inst_begin(F), SrcE = inst_end(F); SrcI != SrcE;
18249c22190SChandler Carruth ++SrcI) {
183916d37a2SBardia Mahjour if (SrcI->mayReadOrWriteMemory()) {
18459b61b9eSSebastian Pop for (inst_iterator DstI = SrcI, DstE = inst_end(F);
18559b61b9eSSebastian Pop DstI != DstE; ++DstI) {
186916d37a2SBardia Mahjour if (DstI->mayReadOrWriteMemory()) {
187916d37a2SBardia Mahjour OS << "Src:" << *SrcI << " --> Dst:" << *DstI << "\n";
18859b61b9eSSebastian Pop OS << " da analyze - ";
1892cae60e7SDylan Noblesmith if (auto D = DA->depends(&*SrcI, &*DstI, true)) {
19059b61b9eSSebastian Pop D->dump(OS);
19159b61b9eSSebastian Pop for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
19259b61b9eSSebastian Pop if (D->isSplitable(Level)) {
19359b61b9eSSebastian Pop OS << " da analyze - split level = " << Level;
194d96ce66cSDylan Noblesmith OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
19559b61b9eSSebastian Pop OS << "!\n";
19659b61b9eSSebastian Pop }
19759b61b9eSSebastian Pop }
19859b61b9eSSebastian Pop }
19959b61b9eSSebastian Pop else
20059b61b9eSSebastian Pop OS << "none!\n";
20159b61b9eSSebastian Pop }
20259b61b9eSSebastian Pop }
20359b61b9eSSebastian Pop }
20459b61b9eSSebastian Pop }
20559b61b9eSSebastian Pop }
20659b61b9eSSebastian Pop
print(raw_ostream & OS,const Module *) const20749c22190SChandler Carruth void DependenceAnalysisWrapperPass::print(raw_ostream &OS,
20849c22190SChandler Carruth const Module *) const {
20949c22190SChandler Carruth dumpExampleDependence(OS, info.get());
21059b61b9eSSebastian Pop }
21159b61b9eSSebastian Pop
212efb5ad1cSPhilip Pfaffe PreservedAnalyses
run(Function & F,FunctionAnalysisManager & FAM)213efb5ad1cSPhilip Pfaffe DependenceAnalysisPrinterPass::run(Function &F, FunctionAnalysisManager &FAM) {
214efb5ad1cSPhilip Pfaffe OS << "'Dependence Analysis' for function '" << F.getName() << "':\n";
215efb5ad1cSPhilip Pfaffe dumpExampleDependence(OS, &FAM.getResult<DependenceAnalysis>(F));
216efb5ad1cSPhilip Pfaffe return PreservedAnalyses::all();
217efb5ad1cSPhilip Pfaffe }
218efb5ad1cSPhilip Pfaffe
21959b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
22059b61b9eSSebastian Pop // Dependence methods
22159b61b9eSSebastian Pop
22259b61b9eSSebastian Pop // Returns true if this is an input dependence.
isInput() const22359b61b9eSSebastian Pop bool Dependence::isInput() const {
22459b61b9eSSebastian Pop return Src->mayReadFromMemory() && Dst->mayReadFromMemory();
22559b61b9eSSebastian Pop }
22659b61b9eSSebastian Pop
22759b61b9eSSebastian Pop
22859b61b9eSSebastian Pop // Returns true if this is an output dependence.
isOutput() const22959b61b9eSSebastian Pop bool Dependence::isOutput() const {
23059b61b9eSSebastian Pop return Src->mayWriteToMemory() && Dst->mayWriteToMemory();
23159b61b9eSSebastian Pop }
23259b61b9eSSebastian Pop
23359b61b9eSSebastian Pop
23459b61b9eSSebastian Pop // Returns true if this is an flow (aka true) dependence.
isFlow() const23559b61b9eSSebastian Pop bool Dependence::isFlow() const {
23659b61b9eSSebastian Pop return Src->mayWriteToMemory() && Dst->mayReadFromMemory();
23759b61b9eSSebastian Pop }
23859b61b9eSSebastian Pop
23959b61b9eSSebastian Pop
24059b61b9eSSebastian Pop // Returns true if this is an anti dependence.
isAnti() const24159b61b9eSSebastian Pop bool Dependence::isAnti() const {
24259b61b9eSSebastian Pop return Src->mayReadFromMemory() && Dst->mayWriteToMemory();
24359b61b9eSSebastian Pop }
24459b61b9eSSebastian Pop
24559b61b9eSSebastian Pop
24659b61b9eSSebastian Pop // Returns true if a particular level is scalar; that is,
24759b61b9eSSebastian Pop // if no subscript in the source or destination mention the induction
24859b61b9eSSebastian Pop // variable associated with the loop at this level.
24959b61b9eSSebastian Pop // Leave this out of line, so it will serve as a virtual method anchor
isScalar(unsigned level) const25059b61b9eSSebastian Pop bool Dependence::isScalar(unsigned level) const {
25159b61b9eSSebastian Pop return false;
25259b61b9eSSebastian Pop }
25359b61b9eSSebastian Pop
25459b61b9eSSebastian Pop
25559b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
25659b61b9eSSebastian Pop // FullDependence methods
25759b61b9eSSebastian Pop
FullDependence(Instruction * Source,Instruction * Destination,bool PossiblyLoopIndependent,unsigned CommonLevels)258478559a5SNAKAMURA Takumi FullDependence::FullDependence(Instruction *Source, Instruction *Destination,
25959b61b9eSSebastian Pop bool PossiblyLoopIndependent,
260478559a5SNAKAMURA Takumi unsigned CommonLevels)
261478559a5SNAKAMURA Takumi : Dependence(Source, Destination), Levels(CommonLevels),
262e110d641SNAKAMURA Takumi LoopIndependent(PossiblyLoopIndependent) {
263e110d641SNAKAMURA Takumi Consistent = true;
26447039dcfSDavid Blaikie if (CommonLevels)
2650eaee545SJonas Devlieghere DV = std::make_unique<DVEntry[]>(CommonLevels);
266e110d641SNAKAMURA Takumi }
26759b61b9eSSebastian Pop
26859b61b9eSSebastian Pop // The rest are simple getters that hide the implementation.
26959b61b9eSSebastian Pop
27059b61b9eSSebastian Pop // getDirection - Returns the direction associated with a particular level.
getDirection(unsigned Level) const27159b61b9eSSebastian Pop unsigned FullDependence::getDirection(unsigned Level) const {
27259b61b9eSSebastian Pop assert(0 < Level && Level <= Levels && "Level out of range");
27359b61b9eSSebastian Pop return DV[Level - 1].Direction;
27459b61b9eSSebastian Pop }
27559b61b9eSSebastian Pop
27659b61b9eSSebastian Pop
27759b61b9eSSebastian Pop // Returns the distance (or NULL) associated with a particular level.
getDistance(unsigned Level) const27859b61b9eSSebastian Pop const SCEV *FullDependence::getDistance(unsigned Level) const {
27959b61b9eSSebastian Pop assert(0 < Level && Level <= Levels && "Level out of range");
28059b61b9eSSebastian Pop return DV[Level - 1].Distance;
28159b61b9eSSebastian Pop }
28259b61b9eSSebastian Pop
28359b61b9eSSebastian Pop
28459b61b9eSSebastian Pop // Returns true if a particular level is scalar; that is,
28559b61b9eSSebastian Pop // if no subscript in the source or destination mention the induction
28659b61b9eSSebastian Pop // variable associated with the loop at this level.
isScalar(unsigned Level) const28759b61b9eSSebastian Pop bool FullDependence::isScalar(unsigned Level) const {
28859b61b9eSSebastian Pop assert(0 < Level && Level <= Levels && "Level out of range");
28959b61b9eSSebastian Pop return DV[Level - 1].Scalar;
29059b61b9eSSebastian Pop }
29159b61b9eSSebastian Pop
29259b61b9eSSebastian Pop
29359b61b9eSSebastian Pop // Returns true if peeling the first iteration from this loop
29459b61b9eSSebastian Pop // will break this dependence.
isPeelFirst(unsigned Level) const29559b61b9eSSebastian Pop bool FullDependence::isPeelFirst(unsigned Level) const {
29659b61b9eSSebastian Pop assert(0 < Level && Level <= Levels && "Level out of range");
29759b61b9eSSebastian Pop return DV[Level - 1].PeelFirst;
29859b61b9eSSebastian Pop }
29959b61b9eSSebastian Pop
30059b61b9eSSebastian Pop
30159b61b9eSSebastian Pop // Returns true if peeling the last iteration from this loop
30259b61b9eSSebastian Pop // will break this dependence.
isPeelLast(unsigned Level) const30359b61b9eSSebastian Pop bool FullDependence::isPeelLast(unsigned Level) const {
30459b61b9eSSebastian Pop assert(0 < Level && Level <= Levels && "Level out of range");
30559b61b9eSSebastian Pop return DV[Level - 1].PeelLast;
30659b61b9eSSebastian Pop }
30759b61b9eSSebastian Pop
30859b61b9eSSebastian Pop
30959b61b9eSSebastian Pop // Returns true if splitting this loop will break the dependence.
isSplitable(unsigned Level) const31059b61b9eSSebastian Pop bool FullDependence::isSplitable(unsigned Level) const {
31159b61b9eSSebastian Pop assert(0 < Level && Level <= Levels && "Level out of range");
31259b61b9eSSebastian Pop return DV[Level - 1].Splitable;
31359b61b9eSSebastian Pop }
31459b61b9eSSebastian Pop
31559b61b9eSSebastian Pop
31659b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
31749c22190SChandler Carruth // DependenceInfo::Constraint methods
31859b61b9eSSebastian Pop
31959b61b9eSSebastian Pop // If constraint is a point <X, Y>, returns X.
32059b61b9eSSebastian Pop // Otherwise assert.
getX() const32149c22190SChandler Carruth const SCEV *DependenceInfo::Constraint::getX() const {
32259b61b9eSSebastian Pop assert(Kind == Point && "Kind should be Point");
32359b61b9eSSebastian Pop return A;
32459b61b9eSSebastian Pop }
32559b61b9eSSebastian Pop
32659b61b9eSSebastian Pop
32759b61b9eSSebastian Pop // If constraint is a point <X, Y>, returns Y.
32859b61b9eSSebastian Pop // Otherwise assert.
getY() const32949c22190SChandler Carruth const SCEV *DependenceInfo::Constraint::getY() const {
33059b61b9eSSebastian Pop assert(Kind == Point && "Kind should be Point");
33159b61b9eSSebastian Pop return B;
33259b61b9eSSebastian Pop }
33359b61b9eSSebastian Pop
33459b61b9eSSebastian Pop
33559b61b9eSSebastian Pop // If constraint is a line AX + BY = C, returns A.
33659b61b9eSSebastian Pop // Otherwise assert.
getA() const33749c22190SChandler Carruth const SCEV *DependenceInfo::Constraint::getA() const {
33859b61b9eSSebastian Pop assert((Kind == Line || Kind == Distance) &&
33959b61b9eSSebastian Pop "Kind should be Line (or Distance)");
34059b61b9eSSebastian Pop return A;
34159b61b9eSSebastian Pop }
34259b61b9eSSebastian Pop
34359b61b9eSSebastian Pop
34459b61b9eSSebastian Pop // If constraint is a line AX + BY = C, returns B.
34559b61b9eSSebastian Pop // Otherwise assert.
getB() const34649c22190SChandler Carruth const SCEV *DependenceInfo::Constraint::getB() const {
34759b61b9eSSebastian Pop assert((Kind == Line || Kind == Distance) &&
34859b61b9eSSebastian Pop "Kind should be Line (or Distance)");
34959b61b9eSSebastian Pop return B;
35059b61b9eSSebastian Pop }
35159b61b9eSSebastian Pop
35259b61b9eSSebastian Pop
35359b61b9eSSebastian Pop // If constraint is a line AX + BY = C, returns C.
35459b61b9eSSebastian Pop // Otherwise assert.
getC() const35549c22190SChandler Carruth const SCEV *DependenceInfo::Constraint::getC() const {
35659b61b9eSSebastian Pop assert((Kind == Line || Kind == Distance) &&
35759b61b9eSSebastian Pop "Kind should be Line (or Distance)");
35859b61b9eSSebastian Pop return C;
35959b61b9eSSebastian Pop }
36059b61b9eSSebastian Pop
36159b61b9eSSebastian Pop
36259b61b9eSSebastian Pop // If constraint is a distance, returns D.
36359b61b9eSSebastian Pop // Otherwise assert.
getD() const36449c22190SChandler Carruth const SCEV *DependenceInfo::Constraint::getD() const {
36559b61b9eSSebastian Pop assert(Kind == Distance && "Kind should be Distance");
36659b61b9eSSebastian Pop return SE->getNegativeSCEV(C);
36759b61b9eSSebastian Pop }
36859b61b9eSSebastian Pop
36959b61b9eSSebastian Pop
37059b61b9eSSebastian Pop // Returns the loop associated with this constraint.
getAssociatedLoop() const37149c22190SChandler Carruth const Loop *DependenceInfo::Constraint::getAssociatedLoop() const {
37259b61b9eSSebastian Pop assert((Kind == Distance || Kind == Line || Kind == Point) &&
37359b61b9eSSebastian Pop "Kind should be Distance, Line, or Point");
37459b61b9eSSebastian Pop return AssociatedLoop;
37559b61b9eSSebastian Pop }
37659b61b9eSSebastian Pop
setPoint(const SCEV * X,const SCEV * Y,const Loop * CurLoop)37749c22190SChandler Carruth void DependenceInfo::Constraint::setPoint(const SCEV *X, const SCEV *Y,
37859b61b9eSSebastian Pop const Loop *CurLoop) {
37959b61b9eSSebastian Pop Kind = Point;
38059b61b9eSSebastian Pop A = X;
38159b61b9eSSebastian Pop B = Y;
38259b61b9eSSebastian Pop AssociatedLoop = CurLoop;
38359b61b9eSSebastian Pop }
38459b61b9eSSebastian Pop
setLine(const SCEV * AA,const SCEV * BB,const SCEV * CC,const Loop * CurLoop)38549c22190SChandler Carruth void DependenceInfo::Constraint::setLine(const SCEV *AA, const SCEV *BB,
38649c22190SChandler Carruth const SCEV *CC, const Loop *CurLoop) {
38759b61b9eSSebastian Pop Kind = Line;
38859b61b9eSSebastian Pop A = AA;
38959b61b9eSSebastian Pop B = BB;
39059b61b9eSSebastian Pop C = CC;
39159b61b9eSSebastian Pop AssociatedLoop = CurLoop;
39259b61b9eSSebastian Pop }
39359b61b9eSSebastian Pop
setDistance(const SCEV * D,const Loop * CurLoop)39449c22190SChandler Carruth void DependenceInfo::Constraint::setDistance(const SCEV *D,
39559b61b9eSSebastian Pop const Loop *CurLoop) {
39659b61b9eSSebastian Pop Kind = Distance;
3972aacc0ecSSanjoy Das A = SE->getOne(D->getType());
39859b61b9eSSebastian Pop B = SE->getNegativeSCEV(A);
39959b61b9eSSebastian Pop C = SE->getNegativeSCEV(D);
40059b61b9eSSebastian Pop AssociatedLoop = CurLoop;
40159b61b9eSSebastian Pop }
40259b61b9eSSebastian Pop
setEmpty()40349c22190SChandler Carruth void DependenceInfo::Constraint::setEmpty() { Kind = Empty; }
40459b61b9eSSebastian Pop
setAny(ScalarEvolution * NewSE)40549c22190SChandler Carruth void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
40659b61b9eSSebastian Pop SE = NewSE;
40759b61b9eSSebastian Pop Kind = Any;
40859b61b9eSSebastian Pop }
40959b61b9eSSebastian Pop
410615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
41159b61b9eSSebastian Pop // For debugging purposes. Dumps the constraint out to OS.
dump(raw_ostream & OS) const4128c209aa8SMatthias Braun LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS) const {
41359b61b9eSSebastian Pop if (isEmpty())
41459b61b9eSSebastian Pop OS << " Empty\n";
41559b61b9eSSebastian Pop else if (isAny())
41659b61b9eSSebastian Pop OS << " Any\n";
41759b61b9eSSebastian Pop else if (isPoint())
41859b61b9eSSebastian Pop OS << " Point is <" << *getX() << ", " << *getY() << ">\n";
41959b61b9eSSebastian Pop else if (isDistance())
42059b61b9eSSebastian Pop OS << " Distance is " << *getD() <<
42159b61b9eSSebastian Pop " (" << *getA() << "*X + " << *getB() << "*Y = " << *getC() << ")\n";
42259b61b9eSSebastian Pop else if (isLine())
42359b61b9eSSebastian Pop OS << " Line is " << *getA() << "*X + " <<
42459b61b9eSSebastian Pop *getB() << "*Y = " << *getC() << "\n";
42559b61b9eSSebastian Pop else
42659b61b9eSSebastian Pop llvm_unreachable("unknown constraint type in Constraint::dump");
42759b61b9eSSebastian Pop }
4288c209aa8SMatthias Braun #endif
42959b61b9eSSebastian Pop
43059b61b9eSSebastian Pop
43159b61b9eSSebastian Pop // Updates X with the intersection
43259b61b9eSSebastian Pop // of the Constraints X and Y. Returns true if X has changed.
43359b61b9eSSebastian Pop // Corresponds to Figure 4 from the paper
43459b61b9eSSebastian Pop //
43559b61b9eSSebastian Pop // Practical Dependence Testing
43659b61b9eSSebastian Pop // Goff, Kennedy, Tseng
43759b61b9eSSebastian Pop // PLDI 1991
intersectConstraints(Constraint * X,const Constraint * Y)43849c22190SChandler Carruth bool DependenceInfo::intersectConstraints(Constraint *X, const Constraint *Y) {
43959b61b9eSSebastian Pop ++DeltaApplications;
440d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tintersect constraints\n");
441d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t X ="; X->dump(dbgs()));
442d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Y ="; Y->dump(dbgs()));
44359b61b9eSSebastian Pop assert(!Y->isPoint() && "Y must not be a Point");
44459b61b9eSSebastian Pop if (X->isAny()) {
44559b61b9eSSebastian Pop if (Y->isAny())
44659b61b9eSSebastian Pop return false;
44759b61b9eSSebastian Pop *X = *Y;
44859b61b9eSSebastian Pop return true;
44959b61b9eSSebastian Pop }
45059b61b9eSSebastian Pop if (X->isEmpty())
45159b61b9eSSebastian Pop return false;
45259b61b9eSSebastian Pop if (Y->isEmpty()) {
45359b61b9eSSebastian Pop X->setEmpty();
45459b61b9eSSebastian Pop return true;
45559b61b9eSSebastian Pop }
45659b61b9eSSebastian Pop
45759b61b9eSSebastian Pop if (X->isDistance() && Y->isDistance()) {
458d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t intersect 2 distances\n");
45959b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, X->getD(), Y->getD()))
46059b61b9eSSebastian Pop return false;
46159b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_NE, X->getD(), Y->getD())) {
46259b61b9eSSebastian Pop X->setEmpty();
46359b61b9eSSebastian Pop ++DeltaSuccesses;
46459b61b9eSSebastian Pop return true;
46559b61b9eSSebastian Pop }
46659b61b9eSSebastian Pop // Hmmm, interesting situation.
46759b61b9eSSebastian Pop // I guess if either is constant, keep it and ignore the other.
46859b61b9eSSebastian Pop if (isa<SCEVConstant>(Y->getD())) {
46959b61b9eSSebastian Pop *X = *Y;
47059b61b9eSSebastian Pop return true;
47159b61b9eSSebastian Pop }
47259b61b9eSSebastian Pop return false;
47359b61b9eSSebastian Pop }
47459b61b9eSSebastian Pop
47559b61b9eSSebastian Pop // At this point, the pseudo-code in Figure 4 of the paper
47659b61b9eSSebastian Pop // checks if (X->isPoint() && Y->isPoint()).
47759b61b9eSSebastian Pop // This case can't occur in our implementation,
47859b61b9eSSebastian Pop // since a Point can only arise as the result of intersecting
47959b61b9eSSebastian Pop // two Line constraints, and the right-hand value, Y, is never
48059b61b9eSSebastian Pop // the result of an intersection.
48159b61b9eSSebastian Pop assert(!(X->isPoint() && Y->isPoint()) &&
48259b61b9eSSebastian Pop "We shouldn't ever see X->isPoint() && Y->isPoint()");
48359b61b9eSSebastian Pop
48459b61b9eSSebastian Pop if (X->isLine() && Y->isLine()) {
485d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t intersect 2 lines\n");
48659b61b9eSSebastian Pop const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
48759b61b9eSSebastian Pop const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
48859b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2)) {
48959b61b9eSSebastian Pop // slopes are equal, so lines are parallel
490d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tsame slope\n");
49159b61b9eSSebastian Pop Prod1 = SE->getMulExpr(X->getC(), Y->getB());
49259b61b9eSSebastian Pop Prod2 = SE->getMulExpr(X->getB(), Y->getC());
49359b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2))
49459b61b9eSSebastian Pop return false;
49559b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
49659b61b9eSSebastian Pop X->setEmpty();
49759b61b9eSSebastian Pop ++DeltaSuccesses;
49859b61b9eSSebastian Pop return true;
49959b61b9eSSebastian Pop }
50059b61b9eSSebastian Pop return false;
50159b61b9eSSebastian Pop }
50259b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
50359b61b9eSSebastian Pop // slopes differ, so lines intersect
504d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tdifferent slopes\n");
50559b61b9eSSebastian Pop const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
50659b61b9eSSebastian Pop const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
50759b61b9eSSebastian Pop const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
50859b61b9eSSebastian Pop const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->getA());
50959b61b9eSSebastian Pop const SCEV *A1B2 = SE->getMulExpr(X->getA(), Y->getB());
51059b61b9eSSebastian Pop const SCEV *A2B1 = SE->getMulExpr(Y->getA(), X->getB());
51159b61b9eSSebastian Pop const SCEVConstant *C1A2_C2A1 =
51259b61b9eSSebastian Pop dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1A2, C2A1));
51359b61b9eSSebastian Pop const SCEVConstant *C1B2_C2B1 =
51459b61b9eSSebastian Pop dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1B2, C2B1));
51559b61b9eSSebastian Pop const SCEVConstant *A1B2_A2B1 =
51659b61b9eSSebastian Pop dyn_cast<SCEVConstant>(SE->getMinusSCEV(A1B2, A2B1));
51759b61b9eSSebastian Pop const SCEVConstant *A2B1_A1B2 =
51859b61b9eSSebastian Pop dyn_cast<SCEVConstant>(SE->getMinusSCEV(A2B1, A1B2));
51959b61b9eSSebastian Pop if (!C1B2_C2B1 || !C1A2_C2A1 ||
52059b61b9eSSebastian Pop !A1B2_A2B1 || !A2B1_A1B2)
52159b61b9eSSebastian Pop return false;
5220de2feceSSanjoy Das APInt Xtop = C1B2_C2B1->getAPInt();
5230de2feceSSanjoy Das APInt Xbot = A1B2_A2B1->getAPInt();
5240de2feceSSanjoy Das APInt Ytop = C1A2_C2A1->getAPInt();
5250de2feceSSanjoy Das APInt Ybot = A2B1_A1B2->getAPInt();
526d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tXtop = " << Xtop << "\n");
527d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tXbot = " << Xbot << "\n");
528d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tYtop = " << Ytop << "\n");
529d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tYbot = " << Ybot << "\n");
53059b61b9eSSebastian Pop APInt Xq = Xtop; // these need to be initialized, even
53159b61b9eSSebastian Pop APInt Xr = Xtop; // though they're just going to be overwritten
53259b61b9eSSebastian Pop APInt::sdivrem(Xtop, Xbot, Xq, Xr);
53359b61b9eSSebastian Pop APInt Yq = Ytop;
534340c780dSJakub Staszak APInt Yr = Ytop;
53559b61b9eSSebastian Pop APInt::sdivrem(Ytop, Ybot, Yq, Yr);
53659b61b9eSSebastian Pop if (Xr != 0 || Yr != 0) {
53759b61b9eSSebastian Pop X->setEmpty();
53859b61b9eSSebastian Pop ++DeltaSuccesses;
53959b61b9eSSebastian Pop return true;
54059b61b9eSSebastian Pop }
541d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tX = " << Xq << ", Y = " << Yq << "\n");
54259b61b9eSSebastian Pop if (Xq.slt(0) || Yq.slt(0)) {
54359b61b9eSSebastian Pop X->setEmpty();
54459b61b9eSSebastian Pop ++DeltaSuccesses;
54559b61b9eSSebastian Pop return true;
54659b61b9eSSebastian Pop }
54759b61b9eSSebastian Pop if (const SCEVConstant *CUB =
54859b61b9eSSebastian Pop collectConstantUpperBound(X->getAssociatedLoop(), Prod1->getType())) {
54946e38f36SBenjamin Kramer const APInt &UpperBound = CUB->getAPInt();
550d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tupper bound = " << UpperBound << "\n");
55159b61b9eSSebastian Pop if (Xq.sgt(UpperBound) || Yq.sgt(UpperBound)) {
55259b61b9eSSebastian Pop X->setEmpty();
55359b61b9eSSebastian Pop ++DeltaSuccesses;
55459b61b9eSSebastian Pop return true;
55559b61b9eSSebastian Pop }
55659b61b9eSSebastian Pop }
55759b61b9eSSebastian Pop X->setPoint(SE->getConstant(Xq),
55859b61b9eSSebastian Pop SE->getConstant(Yq),
55959b61b9eSSebastian Pop X->getAssociatedLoop());
56059b61b9eSSebastian Pop ++DeltaSuccesses;
56159b61b9eSSebastian Pop return true;
56259b61b9eSSebastian Pop }
56359b61b9eSSebastian Pop return false;
56459b61b9eSSebastian Pop }
56559b61b9eSSebastian Pop
56659b61b9eSSebastian Pop // if (X->isLine() && Y->isPoint()) This case can't occur.
56759b61b9eSSebastian Pop assert(!(X->isLine() && Y->isPoint()) && "This case should never occur");
56859b61b9eSSebastian Pop
56959b61b9eSSebastian Pop if (X->isPoint() && Y->isLine()) {
570d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t intersect Point and Line\n");
57159b61b9eSSebastian Pop const SCEV *A1X1 = SE->getMulExpr(Y->getA(), X->getX());
57259b61b9eSSebastian Pop const SCEV *B1Y1 = SE->getMulExpr(Y->getB(), X->getY());
57359b61b9eSSebastian Pop const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
57459b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, Sum, Y->getC()))
57559b61b9eSSebastian Pop return false;
57659b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_NE, Sum, Y->getC())) {
57759b61b9eSSebastian Pop X->setEmpty();
57859b61b9eSSebastian Pop ++DeltaSuccesses;
57959b61b9eSSebastian Pop return true;
58059b61b9eSSebastian Pop }
58159b61b9eSSebastian Pop return false;
58259b61b9eSSebastian Pop }
58359b61b9eSSebastian Pop
58459b61b9eSSebastian Pop llvm_unreachable("shouldn't reach the end of Constraint intersection");
58559b61b9eSSebastian Pop return false;
58659b61b9eSSebastian Pop }
58759b61b9eSSebastian Pop
58859b61b9eSSebastian Pop
58959b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
59049c22190SChandler Carruth // DependenceInfo methods
59159b61b9eSSebastian Pop
59259b61b9eSSebastian Pop // For debugging purposes. Dumps a dependence to OS.
dump(raw_ostream & OS) const59359b61b9eSSebastian Pop void Dependence::dump(raw_ostream &OS) const {
59459b61b9eSSebastian Pop bool Splitable = false;
59559b61b9eSSebastian Pop if (isConfused())
59659b61b9eSSebastian Pop OS << "confused";
59759b61b9eSSebastian Pop else {
59859b61b9eSSebastian Pop if (isConsistent())
59959b61b9eSSebastian Pop OS << "consistent ";
60059b61b9eSSebastian Pop if (isFlow())
60159b61b9eSSebastian Pop OS << "flow";
60259b61b9eSSebastian Pop else if (isOutput())
60359b61b9eSSebastian Pop OS << "output";
60459b61b9eSSebastian Pop else if (isAnti())
60559b61b9eSSebastian Pop OS << "anti";
60659b61b9eSSebastian Pop else if (isInput())
60759b61b9eSSebastian Pop OS << "input";
60859b61b9eSSebastian Pop unsigned Levels = getLevels();
60959b61b9eSSebastian Pop OS << " [";
61059b61b9eSSebastian Pop for (unsigned II = 1; II <= Levels; ++II) {
61159b61b9eSSebastian Pop if (isSplitable(II))
61259b61b9eSSebastian Pop Splitable = true;
61359b61b9eSSebastian Pop if (isPeelFirst(II))
61459b61b9eSSebastian Pop OS << 'p';
61559b61b9eSSebastian Pop const SCEV *Distance = getDistance(II);
61659b61b9eSSebastian Pop if (Distance)
61759b61b9eSSebastian Pop OS << *Distance;
61859b61b9eSSebastian Pop else if (isScalar(II))
61959b61b9eSSebastian Pop OS << "S";
62059b61b9eSSebastian Pop else {
62159b61b9eSSebastian Pop unsigned Direction = getDirection(II);
62259b61b9eSSebastian Pop if (Direction == DVEntry::ALL)
62359b61b9eSSebastian Pop OS << "*";
62459b61b9eSSebastian Pop else {
62559b61b9eSSebastian Pop if (Direction & DVEntry::LT)
62659b61b9eSSebastian Pop OS << "<";
62759b61b9eSSebastian Pop if (Direction & DVEntry::EQ)
62859b61b9eSSebastian Pop OS << "=";
62959b61b9eSSebastian Pop if (Direction & DVEntry::GT)
63059b61b9eSSebastian Pop OS << ">";
63159b61b9eSSebastian Pop }
63259b61b9eSSebastian Pop }
63359b61b9eSSebastian Pop if (isPeelLast(II))
63459b61b9eSSebastian Pop OS << 'p';
63559b61b9eSSebastian Pop if (II < Levels)
63659b61b9eSSebastian Pop OS << " ";
63759b61b9eSSebastian Pop }
63859b61b9eSSebastian Pop if (isLoopIndependent())
63959b61b9eSSebastian Pop OS << "|<";
64059b61b9eSSebastian Pop OS << "]";
64159b61b9eSSebastian Pop if (Splitable)
64259b61b9eSSebastian Pop OS << " splitable";
64359b61b9eSSebastian Pop }
64459b61b9eSSebastian Pop OS << "!\n";
64559b61b9eSSebastian Pop }
64659b61b9eSSebastian Pop
6475ef933b0SDavid Green // Returns NoAlias/MayAliass/MustAlias for two memory locations based upon their
6485ef933b0SDavid Green // underlaying objects. If LocA and LocB are known to not alias (for any reason:
6495ef933b0SDavid Green // tbaa, non-overlapping regions etc), then it is known there is no dependecy.
6505ef933b0SDavid Green // Otherwise the underlying objects are checked to see if they point to
6515ef933b0SDavid Green // different identifiable objects.
underlyingObjectsAlias(AAResults * AA,const DataLayout & DL,const MemoryLocation & LocA,const MemoryLocation & LocB)6523642d388SSimon Pilgrim static AliasResult underlyingObjectsAlias(AAResults *AA,
6535ef933b0SDavid Green const DataLayout &DL,
6545ef933b0SDavid Green const MemoryLocation &LocA,
6555ef933b0SDavid Green const MemoryLocation &LocB) {
6565ef933b0SDavid Green // Check the original locations (minus size) for noalias, which can happen for
6575ef933b0SDavid Green // tbaa, incompatible underlying object locations, etc.
6584df8efceSNikita Popov MemoryLocation LocAS =
6594df8efceSNikita Popov MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
6604df8efceSNikita Popov MemoryLocation LocBS =
6614df8efceSNikita Popov MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
662d0660797Sdfukalov if (AA->isNoAlias(LocAS, LocBS))
663d0660797Sdfukalov return AliasResult::NoAlias;
6645ef933b0SDavid Green
6655ef933b0SDavid Green // Check the underlying objects are the same
666b0eb40caSVitaly Buka const Value *AObj = getUnderlyingObject(LocA.Ptr);
667b0eb40caSVitaly Buka const Value *BObj = getUnderlyingObject(LocB.Ptr);
6685ef933b0SDavid Green
6695ef933b0SDavid Green // If the underlying objects are the same, they must alias
6705ef933b0SDavid Green if (AObj == BObj)
671d0660797Sdfukalov return AliasResult::MustAlias;
6725ef933b0SDavid Green
6735ef933b0SDavid Green // We may have hit the recursion limit for underlying objects, or have
6745ef933b0SDavid Green // underlying objects where we don't know they will alias.
6755ef933b0SDavid Green if (!isIdentifiedObject(AObj) || !isIdentifiedObject(BObj))
676d0660797Sdfukalov return AliasResult::MayAlias;
6775ef933b0SDavid Green
6785ef933b0SDavid Green // Otherwise we know the objects are different and both identified objects so
6795ef933b0SDavid Green // must not alias.
680d0660797Sdfukalov return AliasResult::NoAlias;
68159b61b9eSSebastian Pop }
68259b61b9eSSebastian Pop
68359b61b9eSSebastian Pop
68459b61b9eSSebastian Pop // Returns true if the load or store can be analyzed. Atomic and volatile
68559b61b9eSSebastian Pop // operations have properties which this analysis does not understand.
68659b61b9eSSebastian Pop static
isLoadOrStore(const Instruction * I)68759b61b9eSSebastian Pop bool isLoadOrStore(const Instruction *I) {
68859b61b9eSSebastian Pop if (const LoadInst *LI = dyn_cast<LoadInst>(I))
68959b61b9eSSebastian Pop return LI->isUnordered();
69059b61b9eSSebastian Pop else if (const StoreInst *SI = dyn_cast<StoreInst>(I))
69159b61b9eSSebastian Pop return SI->isUnordered();
69259b61b9eSSebastian Pop return false;
69359b61b9eSSebastian Pop }
69459b61b9eSSebastian Pop
69559b61b9eSSebastian Pop
69659b61b9eSSebastian Pop // Examines the loop nesting of the Src and Dst
69759b61b9eSSebastian Pop // instructions and establishes their shared loops. Sets the variables
69859b61b9eSSebastian Pop // CommonLevels, SrcLevels, and MaxLevels.
69959b61b9eSSebastian Pop // The source and destination instructions needn't be contained in the same
70059b61b9eSSebastian Pop // loop. The routine establishNestingLevels finds the level of most deeply
70159b61b9eSSebastian Pop // nested loop that contains them both, CommonLevels. An instruction that's
70259b61b9eSSebastian Pop // not contained in a loop is at level = 0. MaxLevels is equal to the level
70359b61b9eSSebastian Pop // of the source plus the level of the destination, minus CommonLevels.
70459b61b9eSSebastian Pop // This lets us allocate vectors MaxLevels in length, with room for every
70559b61b9eSSebastian Pop // distinct loop referenced in both the source and destination subscripts.
70659b61b9eSSebastian Pop // The variable SrcLevels is the nesting depth of the source instruction.
70759b61b9eSSebastian Pop // It's used to help calculate distinct loops referenced by the destination.
70859b61b9eSSebastian Pop // Here's the map from loops to levels:
70959b61b9eSSebastian Pop // 0 - unused
71059b61b9eSSebastian Pop // 1 - outermost common loop
71159b61b9eSSebastian Pop // ... - other common loops
71259b61b9eSSebastian Pop // CommonLevels - innermost common loop
71359b61b9eSSebastian Pop // ... - loops containing Src but not Dst
71459b61b9eSSebastian Pop // SrcLevels - innermost loop containing Src but not Dst
71559b61b9eSSebastian Pop // ... - loops containing Dst but not Src
71659b61b9eSSebastian Pop // MaxLevels - innermost loops containing Dst but not Src
71759b61b9eSSebastian Pop // Consider the follow code fragment:
71859b61b9eSSebastian Pop // for (a = ...) {
71959b61b9eSSebastian Pop // for (b = ...) {
72059b61b9eSSebastian Pop // for (c = ...) {
72159b61b9eSSebastian Pop // for (d = ...) {
72259b61b9eSSebastian Pop // A[] = ...;
72359b61b9eSSebastian Pop // }
72459b61b9eSSebastian Pop // }
72559b61b9eSSebastian Pop // for (e = ...) {
72659b61b9eSSebastian Pop // for (f = ...) {
72759b61b9eSSebastian Pop // for (g = ...) {
72859b61b9eSSebastian Pop // ... = A[];
72959b61b9eSSebastian Pop // }
73059b61b9eSSebastian Pop // }
73159b61b9eSSebastian Pop // }
73259b61b9eSSebastian Pop // }
73359b61b9eSSebastian Pop // }
73459b61b9eSSebastian Pop // If we're looking at the possibility of a dependence between the store
73559b61b9eSSebastian Pop // to A (the Src) and the load from A (the Dst), we'll note that they
73659b61b9eSSebastian Pop // have 2 loops in common, so CommonLevels will equal 2 and the direction
73759b61b9eSSebastian Pop // vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
73859b61b9eSSebastian Pop // A map from loop names to loop numbers would look like
73959b61b9eSSebastian Pop // a - 1
74059b61b9eSSebastian Pop // b - 2 = CommonLevels
74159b61b9eSSebastian Pop // c - 3
74259b61b9eSSebastian Pop // d - 4 = SrcLevels
74359b61b9eSSebastian Pop // e - 5
74459b61b9eSSebastian Pop // f - 6
74559b61b9eSSebastian Pop // g - 7 = MaxLevels
establishNestingLevels(const Instruction * Src,const Instruction * Dst)74649c22190SChandler Carruth void DependenceInfo::establishNestingLevels(const Instruction *Src,
74759b61b9eSSebastian Pop const Instruction *Dst) {
74859b61b9eSSebastian Pop const BasicBlock *SrcBlock = Src->getParent();
74959b61b9eSSebastian Pop const BasicBlock *DstBlock = Dst->getParent();
75059b61b9eSSebastian Pop unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
75159b61b9eSSebastian Pop unsigned DstLevel = LI->getLoopDepth(DstBlock);
75259b61b9eSSebastian Pop const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
75359b61b9eSSebastian Pop const Loop *DstLoop = LI->getLoopFor(DstBlock);
75459b61b9eSSebastian Pop SrcLevels = SrcLevel;
75559b61b9eSSebastian Pop MaxLevels = SrcLevel + DstLevel;
75659b61b9eSSebastian Pop while (SrcLevel > DstLevel) {
75759b61b9eSSebastian Pop SrcLoop = SrcLoop->getParentLoop();
75859b61b9eSSebastian Pop SrcLevel--;
75959b61b9eSSebastian Pop }
76059b61b9eSSebastian Pop while (DstLevel > SrcLevel) {
76159b61b9eSSebastian Pop DstLoop = DstLoop->getParentLoop();
76259b61b9eSSebastian Pop DstLevel--;
76359b61b9eSSebastian Pop }
76459b61b9eSSebastian Pop while (SrcLoop != DstLoop) {
76559b61b9eSSebastian Pop SrcLoop = SrcLoop->getParentLoop();
76659b61b9eSSebastian Pop DstLoop = DstLoop->getParentLoop();
76759b61b9eSSebastian Pop SrcLevel--;
76859b61b9eSSebastian Pop }
76959b61b9eSSebastian Pop CommonLevels = SrcLevel;
77059b61b9eSSebastian Pop MaxLevels -= CommonLevels;
77159b61b9eSSebastian Pop }
77259b61b9eSSebastian Pop
77359b61b9eSSebastian Pop
77459b61b9eSSebastian Pop // Given one of the loops containing the source, return
77559b61b9eSSebastian Pop // its level index in our numbering scheme.
mapSrcLoop(const Loop * SrcLoop) const77649c22190SChandler Carruth unsigned DependenceInfo::mapSrcLoop(const Loop *SrcLoop) const {
77759b61b9eSSebastian Pop return SrcLoop->getLoopDepth();
77859b61b9eSSebastian Pop }
77959b61b9eSSebastian Pop
78059b61b9eSSebastian Pop
78159b61b9eSSebastian Pop // Given one of the loops containing the destination,
78259b61b9eSSebastian Pop // return its level index in our numbering scheme.
mapDstLoop(const Loop * DstLoop) const78349c22190SChandler Carruth unsigned DependenceInfo::mapDstLoop(const Loop *DstLoop) const {
78459b61b9eSSebastian Pop unsigned D = DstLoop->getLoopDepth();
78559b61b9eSSebastian Pop if (D > CommonLevels)
786c9677f6dSBardia Mahjour // This tries to make sure that we assign unique numbers to src and dst when
787c9677f6dSBardia Mahjour // the memory accesses reside in different loops that have the same depth.
78859b61b9eSSebastian Pop return D - CommonLevels + SrcLevels;
78959b61b9eSSebastian Pop else
79059b61b9eSSebastian Pop return D;
79159b61b9eSSebastian Pop }
79259b61b9eSSebastian Pop
79359b61b9eSSebastian Pop
79459b61b9eSSebastian Pop // Returns true if Expression is loop invariant in LoopNest.
isLoopInvariant(const SCEV * Expression,const Loop * LoopNest) const79549c22190SChandler Carruth bool DependenceInfo::isLoopInvariant(const SCEV *Expression,
79659b61b9eSSebastian Pop const Loop *LoopNest) const {
797c9677f6dSBardia Mahjour // Unlike ScalarEvolution::isLoopInvariant() we consider an access outside of
798c9677f6dSBardia Mahjour // any loop as invariant, because we only consier expression evaluation at a
799c9677f6dSBardia Mahjour // specific position (where the array access takes place), and not across the
800c9677f6dSBardia Mahjour // entire function.
80159b61b9eSSebastian Pop if (!LoopNest)
80259b61b9eSSebastian Pop return true;
803c9677f6dSBardia Mahjour
804c9677f6dSBardia Mahjour // If the expression is invariant in the outermost loop of the loop nest, it
805c9677f6dSBardia Mahjour // is invariant anywhere in the loop nest.
806d77f9448SNikita Popov return SE->isLoopInvariant(Expression, LoopNest->getOutermostLoop());
80759b61b9eSSebastian Pop }
80859b61b9eSSebastian Pop
80959b61b9eSSebastian Pop
81059b61b9eSSebastian Pop
81159b61b9eSSebastian Pop // Finds the set of loops from the LoopNest that
81259b61b9eSSebastian Pop // have a level <= CommonLevels and are referred to by the SCEV Expression.
collectCommonLoops(const SCEV * Expression,const Loop * LoopNest,SmallBitVector & Loops) const81349c22190SChandler Carruth void DependenceInfo::collectCommonLoops(const SCEV *Expression,
81459b61b9eSSebastian Pop const Loop *LoopNest,
81559b61b9eSSebastian Pop SmallBitVector &Loops) const {
81659b61b9eSSebastian Pop while (LoopNest) {
81759b61b9eSSebastian Pop unsigned Level = LoopNest->getLoopDepth();
81859b61b9eSSebastian Pop if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
81959b61b9eSSebastian Pop Loops.set(Level);
82059b61b9eSSebastian Pop LoopNest = LoopNest->getParentLoop();
82159b61b9eSSebastian Pop }
82259b61b9eSSebastian Pop }
82359b61b9eSSebastian Pop
unifySubscriptType(ArrayRef<Subscript * > Pairs)82449c22190SChandler Carruth void DependenceInfo::unifySubscriptType(ArrayRef<Subscript *> Pairs) {
825a84feb17SJingyue Wu
826a84feb17SJingyue Wu unsigned widestWidthSeen = 0;
827a84feb17SJingyue Wu Type *widestType;
828a84feb17SJingyue Wu
829a84feb17SJingyue Wu // Go through each pair and find the widest bit to which we need
830a84feb17SJingyue Wu // to extend all of them.
831aa209150SBenjamin Kramer for (Subscript *Pair : Pairs) {
832aa209150SBenjamin Kramer const SCEV *Src = Pair->Src;
833aa209150SBenjamin Kramer const SCEV *Dst = Pair->Dst;
8340fa125a7SJingyue Wu IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
8350fa125a7SJingyue Wu IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
8360fa125a7SJingyue Wu if (SrcTy == nullptr || DstTy == nullptr) {
8370fa125a7SJingyue Wu assert(SrcTy == DstTy && "This function only unify integer types and "
8380fa125a7SJingyue Wu "expect Src and Dst share the same type "
8390fa125a7SJingyue Wu "otherwise.");
840a84feb17SJingyue Wu continue;
8410fa125a7SJingyue Wu }
842a84feb17SJingyue Wu if (SrcTy->getBitWidth() > widestWidthSeen) {
843a84feb17SJingyue Wu widestWidthSeen = SrcTy->getBitWidth();
844a84feb17SJingyue Wu widestType = SrcTy;
845a84feb17SJingyue Wu }
846a84feb17SJingyue Wu if (DstTy->getBitWidth() > widestWidthSeen) {
847a84feb17SJingyue Wu widestWidthSeen = DstTy->getBitWidth();
848a84feb17SJingyue Wu widestType = DstTy;
849a84feb17SJingyue Wu }
850a84feb17SJingyue Wu }
851a84feb17SJingyue Wu
852a84feb17SJingyue Wu
853a84feb17SJingyue Wu assert(widestWidthSeen > 0);
854a84feb17SJingyue Wu
855a84feb17SJingyue Wu // Now extend each pair to the widest seen.
856aa209150SBenjamin Kramer for (Subscript *Pair : Pairs) {
857aa209150SBenjamin Kramer const SCEV *Src = Pair->Src;
858aa209150SBenjamin Kramer const SCEV *Dst = Pair->Dst;
859a84feb17SJingyue Wu IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
860a84feb17SJingyue Wu IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
861a84feb17SJingyue Wu if (SrcTy == nullptr || DstTy == nullptr) {
862a84feb17SJingyue Wu assert(SrcTy == DstTy && "This function only unify integer types and "
863a84feb17SJingyue Wu "expect Src and Dst share the same type "
864a84feb17SJingyue Wu "otherwise.");
865a84feb17SJingyue Wu continue;
866a84feb17SJingyue Wu }
867a84feb17SJingyue Wu if (SrcTy->getBitWidth() < widestWidthSeen)
868a84feb17SJingyue Wu // Sign-extend Src to widestType
869aa209150SBenjamin Kramer Pair->Src = SE->getSignExtendExpr(Src, widestType);
870a84feb17SJingyue Wu if (DstTy->getBitWidth() < widestWidthSeen) {
871a84feb17SJingyue Wu // Sign-extend Dst to widestType
872aa209150SBenjamin Kramer Pair->Dst = SE->getSignExtendExpr(Dst, widestType);
873a84feb17SJingyue Wu }
8740fa125a7SJingyue Wu }
8750fa125a7SJingyue Wu }
87659b61b9eSSebastian Pop
87759b61b9eSSebastian Pop // removeMatchingExtensions - Examines a subscript pair.
87859b61b9eSSebastian Pop // If the source and destination are identically sign (or zero)
87959b61b9eSSebastian Pop // extended, it strips off the extension in an effect to simplify
88059b61b9eSSebastian Pop // the actual analysis.
removeMatchingExtensions(Subscript * Pair)88149c22190SChandler Carruth void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
88259b61b9eSSebastian Pop const SCEV *Src = Pair->Src;
88359b61b9eSSebastian Pop const SCEV *Dst = Pair->Dst;
88459b61b9eSSebastian Pop if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
88559b61b9eSSebastian Pop (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
886d083d55cSRoman Lebedev const SCEVIntegralCastExpr *SrcCast = cast<SCEVIntegralCastExpr>(Src);
887d083d55cSRoman Lebedev const SCEVIntegralCastExpr *DstCast = cast<SCEVIntegralCastExpr>(Dst);
8880fa125a7SJingyue Wu const SCEV *SrcCastOp = SrcCast->getOperand();
8890fa125a7SJingyue Wu const SCEV *DstCastOp = DstCast->getOperand();
8900fa125a7SJingyue Wu if (SrcCastOp->getType() == DstCastOp->getType()) {
8910fa125a7SJingyue Wu Pair->Src = SrcCastOp;
8920fa125a7SJingyue Wu Pair->Dst = DstCastOp;
89359b61b9eSSebastian Pop }
89459b61b9eSSebastian Pop }
89559b61b9eSSebastian Pop }
89659b61b9eSSebastian Pop
897c9677f6dSBardia Mahjour // Examine the scev and return true iff it's affine.
8982abda668SDanilo Carvalho Grael // Collect any loops mentioned in the set of "Loops".
checkSubscript(const SCEV * Expr,const Loop * LoopNest,SmallBitVector & Loops,bool IsSrc)8992abda668SDanilo Carvalho Grael bool DependenceInfo::checkSubscript(const SCEV *Expr, const Loop *LoopNest,
9002abda668SDanilo Carvalho Grael SmallBitVector &Loops, bool IsSrc) {
9012abda668SDanilo Carvalho Grael const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
9022abda668SDanilo Carvalho Grael if (!AddRec)
9032abda668SDanilo Carvalho Grael return isLoopInvariant(Expr, LoopNest);
904c9677f6dSBardia Mahjour
905c9677f6dSBardia Mahjour // The AddRec must depend on one of the containing loops. Otherwise,
906c9677f6dSBardia Mahjour // mapSrcLoop and mapDstLoop return indices outside the intended range. This
907c9677f6dSBardia Mahjour // can happen when a subscript in one loop references an IV from a sibling
908c9677f6dSBardia Mahjour // loop that could not be replaced with a concrete exit value by
909c9677f6dSBardia Mahjour // getSCEVAtScope.
910c9677f6dSBardia Mahjour const Loop *L = LoopNest;
911c9677f6dSBardia Mahjour while (L && AddRec->getLoop() != L)
912c9677f6dSBardia Mahjour L = L->getParentLoop();
913c9677f6dSBardia Mahjour if (!L)
914c9677f6dSBardia Mahjour return false;
915c9677f6dSBardia Mahjour
9162abda668SDanilo Carvalho Grael const SCEV *Start = AddRec->getStart();
9172abda668SDanilo Carvalho Grael const SCEV *Step = AddRec->getStepRecurrence(*SE);
9182abda668SDanilo Carvalho Grael const SCEV *UB = SE->getBackedgeTakenCount(AddRec->getLoop());
9192abda668SDanilo Carvalho Grael if (!isa<SCEVCouldNotCompute>(UB)) {
9202abda668SDanilo Carvalho Grael if (SE->getTypeSizeInBits(Start->getType()) <
9212abda668SDanilo Carvalho Grael SE->getTypeSizeInBits(UB->getType())) {
9222abda668SDanilo Carvalho Grael if (!AddRec->getNoWrapFlags())
9232abda668SDanilo Carvalho Grael return false;
9242abda668SDanilo Carvalho Grael }
9252abda668SDanilo Carvalho Grael }
9262abda668SDanilo Carvalho Grael if (!isLoopInvariant(Step, LoopNest))
9272abda668SDanilo Carvalho Grael return false;
9282abda668SDanilo Carvalho Grael if (IsSrc)
9292abda668SDanilo Carvalho Grael Loops.set(mapSrcLoop(AddRec->getLoop()));
9302abda668SDanilo Carvalho Grael else
9312abda668SDanilo Carvalho Grael Loops.set(mapDstLoop(AddRec->getLoop()));
9322abda668SDanilo Carvalho Grael return checkSubscript(Start, LoopNest, Loops, IsSrc);
9332abda668SDanilo Carvalho Grael }
93459b61b9eSSebastian Pop
93559b61b9eSSebastian Pop // Examine the scev and return true iff it's linear.
93659b61b9eSSebastian Pop // Collect any loops mentioned in the set of "Loops".
checkSrcSubscript(const SCEV * Src,const Loop * LoopNest,SmallBitVector & Loops)93749c22190SChandler Carruth bool DependenceInfo::checkSrcSubscript(const SCEV *Src, const Loop *LoopNest,
93859b61b9eSSebastian Pop SmallBitVector &Loops) {
9392abda668SDanilo Carvalho Grael return checkSubscript(Src, LoopNest, Loops, true);
940c0661aeaSJames Molloy }
94159b61b9eSSebastian Pop
94259b61b9eSSebastian Pop // Examine the scev and return true iff it's linear.
94359b61b9eSSebastian Pop // Collect any loops mentioned in the set of "Loops".
checkDstSubscript(const SCEV * Dst,const Loop * LoopNest,SmallBitVector & Loops)94449c22190SChandler Carruth bool DependenceInfo::checkDstSubscript(const SCEV *Dst, const Loop *LoopNest,
94559b61b9eSSebastian Pop SmallBitVector &Loops) {
9462abda668SDanilo Carvalho Grael return checkSubscript(Dst, LoopNest, Loops, false);
94759b61b9eSSebastian Pop }
94859b61b9eSSebastian Pop
94959b61b9eSSebastian Pop
95059b61b9eSSebastian Pop // Examines the subscript pair (the Src and Dst SCEVs)
95159b61b9eSSebastian Pop // and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
95259b61b9eSSebastian Pop // Collects the associated loops in a set.
95349c22190SChandler Carruth DependenceInfo::Subscript::ClassificationKind
classifyPair(const SCEV * Src,const Loop * SrcLoopNest,const SCEV * Dst,const Loop * DstLoopNest,SmallBitVector & Loops)95449c22190SChandler Carruth DependenceInfo::classifyPair(const SCEV *Src, const Loop *SrcLoopNest,
95559b61b9eSSebastian Pop const SCEV *Dst, const Loop *DstLoopNest,
95659b61b9eSSebastian Pop SmallBitVector &Loops) {
95759b61b9eSSebastian Pop SmallBitVector SrcLoops(MaxLevels + 1);
95859b61b9eSSebastian Pop SmallBitVector DstLoops(MaxLevels + 1);
95959b61b9eSSebastian Pop if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
96059b61b9eSSebastian Pop return Subscript::NonLinear;
96159b61b9eSSebastian Pop if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
96259b61b9eSSebastian Pop return Subscript::NonLinear;
96359b61b9eSSebastian Pop Loops = SrcLoops;
96459b61b9eSSebastian Pop Loops |= DstLoops;
96559b61b9eSSebastian Pop unsigned N = Loops.count();
96659b61b9eSSebastian Pop if (N == 0)
96759b61b9eSSebastian Pop return Subscript::ZIV;
96859b61b9eSSebastian Pop if (N == 1)
96959b61b9eSSebastian Pop return Subscript::SIV;
97059b61b9eSSebastian Pop if (N == 2 && (SrcLoops.count() == 0 ||
97159b61b9eSSebastian Pop DstLoops.count() == 0 ||
97259b61b9eSSebastian Pop (SrcLoops.count() == 1 && DstLoops.count() == 1)))
97359b61b9eSSebastian Pop return Subscript::RDIV;
97459b61b9eSSebastian Pop return Subscript::MIV;
97559b61b9eSSebastian Pop }
97659b61b9eSSebastian Pop
97759b61b9eSSebastian Pop
97859b61b9eSSebastian Pop // A wrapper around SCEV::isKnownPredicate.
97959b61b9eSSebastian Pop // Looks for cases where we're interested in comparing for equality.
98059b61b9eSSebastian Pop // If both X and Y have been identically sign or zero extended,
98159b61b9eSSebastian Pop // it strips off the (confusing) extensions before invoking
98259b61b9eSSebastian Pop // SCEV::isKnownPredicate. Perhaps, someday, the ScalarEvolution package
98359b61b9eSSebastian Pop // will be similarly updated.
98459b61b9eSSebastian Pop //
98559b61b9eSSebastian Pop // If SCEV::isKnownPredicate can't prove the predicate,
98659b61b9eSSebastian Pop // we try simple subtraction, which seems to help in some cases
98759b61b9eSSebastian Pop // involving symbolics.
isKnownPredicate(ICmpInst::Predicate Pred,const SCEV * X,const SCEV * Y) const98849c22190SChandler Carruth bool DependenceInfo::isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *X,
98959b61b9eSSebastian Pop const SCEV *Y) const {
99059b61b9eSSebastian Pop if (Pred == CmpInst::ICMP_EQ ||
99159b61b9eSSebastian Pop Pred == CmpInst::ICMP_NE) {
99259b61b9eSSebastian Pop if ((isa<SCEVSignExtendExpr>(X) &&
99359b61b9eSSebastian Pop isa<SCEVSignExtendExpr>(Y)) ||
99459b61b9eSSebastian Pop (isa<SCEVZeroExtendExpr>(X) &&
99559b61b9eSSebastian Pop isa<SCEVZeroExtendExpr>(Y))) {
996d083d55cSRoman Lebedev const SCEVIntegralCastExpr *CX = cast<SCEVIntegralCastExpr>(X);
997d083d55cSRoman Lebedev const SCEVIntegralCastExpr *CY = cast<SCEVIntegralCastExpr>(Y);
99859b61b9eSSebastian Pop const SCEV *Xop = CX->getOperand();
99959b61b9eSSebastian Pop const SCEV *Yop = CY->getOperand();
100059b61b9eSSebastian Pop if (Xop->getType() == Yop->getType()) {
100159b61b9eSSebastian Pop X = Xop;
100259b61b9eSSebastian Pop Y = Yop;
100359b61b9eSSebastian Pop }
100459b61b9eSSebastian Pop }
100559b61b9eSSebastian Pop }
100659b61b9eSSebastian Pop if (SE->isKnownPredicate(Pred, X, Y))
100759b61b9eSSebastian Pop return true;
100859b61b9eSSebastian Pop // If SE->isKnownPredicate can't prove the condition,
100959b61b9eSSebastian Pop // we try the brute-force approach of subtracting
101059b61b9eSSebastian Pop // and testing the difference.
101159b61b9eSSebastian Pop // By testing with SE->isKnownPredicate first, we avoid
101259b61b9eSSebastian Pop // the possibility of overflow when the arguments are constants.
101359b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(X, Y);
101459b61b9eSSebastian Pop switch (Pred) {
101559b61b9eSSebastian Pop case CmpInst::ICMP_EQ:
101659b61b9eSSebastian Pop return Delta->isZero();
101759b61b9eSSebastian Pop case CmpInst::ICMP_NE:
101859b61b9eSSebastian Pop return SE->isKnownNonZero(Delta);
101959b61b9eSSebastian Pop case CmpInst::ICMP_SGE:
102059b61b9eSSebastian Pop return SE->isKnownNonNegative(Delta);
102159b61b9eSSebastian Pop case CmpInst::ICMP_SLE:
102259b61b9eSSebastian Pop return SE->isKnownNonPositive(Delta);
102359b61b9eSSebastian Pop case CmpInst::ICMP_SGT:
102459b61b9eSSebastian Pop return SE->isKnownPositive(Delta);
102559b61b9eSSebastian Pop case CmpInst::ICMP_SLT:
102659b61b9eSSebastian Pop return SE->isKnownNegative(Delta);
102759b61b9eSSebastian Pop default:
102859b61b9eSSebastian Pop llvm_unreachable("unexpected predicate in isKnownPredicate");
102959b61b9eSSebastian Pop }
103059b61b9eSSebastian Pop }
103159b61b9eSSebastian Pop
1032d143c65dSDavid Green /// Compare to see if S is less than Size, using isKnownNegative(S - max(Size, 1))
1033d143c65dSDavid Green /// with some extra checking if S is an AddRec and we can prove less-than using
1034d143c65dSDavid Green /// the loop bounds.
isKnownLessThan(const SCEV * S,const SCEV * Size) const1035d143c65dSDavid Green bool DependenceInfo::isKnownLessThan(const SCEV *S, const SCEV *Size) const {
1036d143c65dSDavid Green // First unify to the same type
1037d143c65dSDavid Green auto *SType = dyn_cast<IntegerType>(S->getType());
1038d143c65dSDavid Green auto *SizeType = dyn_cast<IntegerType>(Size->getType());
1039d143c65dSDavid Green if (!SType || !SizeType)
1040d143c65dSDavid Green return false;
1041d143c65dSDavid Green Type *MaxType =
1042d143c65dSDavid Green (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
1043d143c65dSDavid Green S = SE->getTruncateOrZeroExtend(S, MaxType);
1044d143c65dSDavid Green Size = SE->getTruncateOrZeroExtend(Size, MaxType);
1045d143c65dSDavid Green
1046d143c65dSDavid Green // Special check for addrecs using BE taken count
1047d143c65dSDavid Green const SCEV *Bound = SE->getMinusSCEV(S, Size);
1048d143c65dSDavid Green if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Bound)) {
1049d143c65dSDavid Green if (AddRec->isAffine()) {
1050d143c65dSDavid Green const SCEV *BECount = SE->getBackedgeTakenCount(AddRec->getLoop());
1051d143c65dSDavid Green if (!isa<SCEVCouldNotCompute>(BECount)) {
1052d143c65dSDavid Green const SCEV *Limit = AddRec->evaluateAtIteration(BECount, *SE);
1053d143c65dSDavid Green if (SE->isKnownNegative(Limit))
1054d143c65dSDavid Green return true;
1055d143c65dSDavid Green }
1056d143c65dSDavid Green }
1057d143c65dSDavid Green }
1058d143c65dSDavid Green
1059d143c65dSDavid Green // Check using normal isKnownNegative
1060d143c65dSDavid Green const SCEV *LimitedBound =
1061d143c65dSDavid Green SE->getMinusSCEV(S, SE->getSMaxExpr(Size, SE->getOne(Size->getType())));
1062d143c65dSDavid Green return SE->isKnownNegative(LimitedBound);
1063d143c65dSDavid Green }
106459b61b9eSSebastian Pop
isKnownNonNegative(const SCEV * S,const Value * Ptr) const106586994923SDavid Green bool DependenceInfo::isKnownNonNegative(const SCEV *S, const Value *Ptr) const {
106686994923SDavid Green bool Inbounds = false;
106786994923SDavid Green if (auto *SrcGEP = dyn_cast<GetElementPtrInst>(Ptr))
106886994923SDavid Green Inbounds = SrcGEP->isInBounds();
106986994923SDavid Green if (Inbounds) {
107086994923SDavid Green if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
107186994923SDavid Green if (AddRec->isAffine()) {
107286994923SDavid Green // We know S is for Ptr, the operand on a load/store, so doesn't wrap.
107386994923SDavid Green // If both parts are NonNegative, the end result will be NonNegative
107486994923SDavid Green if (SE->isKnownNonNegative(AddRec->getStart()) &&
107586994923SDavid Green SE->isKnownNonNegative(AddRec->getOperand(1)))
107686994923SDavid Green return true;
107786994923SDavid Green }
107886994923SDavid Green }
107986994923SDavid Green }
108086994923SDavid Green
108186994923SDavid Green return SE->isKnownNonNegative(S);
108286994923SDavid Green }
108386994923SDavid Green
108459b61b9eSSebastian Pop // All subscripts are all the same type.
108559b61b9eSSebastian Pop // Loop bound may be smaller (e.g., a char).
108659b61b9eSSebastian Pop // Should zero extend loop bound, since it's always >= 0.
1087c0661aeaSJames Molloy // This routine collects upper bound and extends or truncates if needed.
1088c0661aeaSJames Molloy // Truncating is safe when subscripts are known not to wrap. Cases without
1089c0661aeaSJames Molloy // nowrap flags should have been rejected earlier.
109059b61b9eSSebastian Pop // Return null if no bound available.
collectUpperBound(const Loop * L,Type * T) const109149c22190SChandler Carruth const SCEV *DependenceInfo::collectUpperBound(const Loop *L, Type *T) const {
109259b61b9eSSebastian Pop if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
109359b61b9eSSebastian Pop const SCEV *UB = SE->getBackedgeTakenCount(L);
1094c0661aeaSJames Molloy return SE->getTruncateOrZeroExtend(UB, T);
109559b61b9eSSebastian Pop }
10969f008867SCraig Topper return nullptr;
109759b61b9eSSebastian Pop }
109859b61b9eSSebastian Pop
109959b61b9eSSebastian Pop
110059b61b9eSSebastian Pop // Calls collectUpperBound(), then attempts to cast it to SCEVConstant.
110159b61b9eSSebastian Pop // If the cast fails, returns NULL.
collectConstantUpperBound(const Loop * L,Type * T) const110249c22190SChandler Carruth const SCEVConstant *DependenceInfo::collectConstantUpperBound(const Loop *L,
110349c22190SChandler Carruth Type *T) const {
110459b61b9eSSebastian Pop if (const SCEV *UB = collectUpperBound(L, T))
110559b61b9eSSebastian Pop return dyn_cast<SCEVConstant>(UB);
11069f008867SCraig Topper return nullptr;
110759b61b9eSSebastian Pop }
110859b61b9eSSebastian Pop
110959b61b9eSSebastian Pop
111059b61b9eSSebastian Pop // testZIV -
111159b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1] and [c2],
111259b61b9eSSebastian Pop // where c1 and c2 are both loop invariant, we attack it using
111359b61b9eSSebastian Pop // the ZIV test. Basically, we test by comparing the two values,
111459b61b9eSSebastian Pop // but there are actually three possible results:
111559b61b9eSSebastian Pop // 1) the values are equal, so there's a dependence
111659b61b9eSSebastian Pop // 2) the values are different, so there's no dependence
111759b61b9eSSebastian Pop // 3) the values might be equal, so we have to assume a dependence.
111859b61b9eSSebastian Pop //
111959b61b9eSSebastian Pop // Return true if dependence disproved.
testZIV(const SCEV * Src,const SCEV * Dst,FullDependence & Result) const112049c22190SChandler Carruth bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
112159b61b9eSSebastian Pop FullDependence &Result) const {
1122d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " src = " << *Src << "\n");
1123d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " dst = " << *Dst << "\n");
112459b61b9eSSebastian Pop ++ZIVapplications;
112559b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, Src, Dst)) {
1126d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " provably dependent\n");
112759b61b9eSSebastian Pop return false; // provably dependent
112859b61b9eSSebastian Pop }
112959b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_NE, Src, Dst)) {
1130d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " provably independent\n");
113159b61b9eSSebastian Pop ++ZIVindependence;
113259b61b9eSSebastian Pop return true; // provably independent
113359b61b9eSSebastian Pop }
1134d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " possibly dependent\n");
113559b61b9eSSebastian Pop Result.Consistent = false;
113659b61b9eSSebastian Pop return false; // possibly dependent
113759b61b9eSSebastian Pop }
113859b61b9eSSebastian Pop
113959b61b9eSSebastian Pop
114059b61b9eSSebastian Pop // strongSIVtest -
114159b61b9eSSebastian Pop // From the paper, Practical Dependence Testing, Section 4.2.1
114259b61b9eSSebastian Pop //
114359b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a*i] and [c2 + a*i],
114459b61b9eSSebastian Pop // where i is an induction variable, c1 and c2 are loop invariant,
114559b61b9eSSebastian Pop // and a is a constant, we can solve it exactly using the Strong SIV test.
114659b61b9eSSebastian Pop //
114759b61b9eSSebastian Pop // Can prove independence. Failing that, can compute distance (and direction).
114859b61b9eSSebastian Pop // In the presence of symbolic terms, we can sometimes make progress.
114959b61b9eSSebastian Pop //
115059b61b9eSSebastian Pop // If there's a dependence,
115159b61b9eSSebastian Pop //
115259b61b9eSSebastian Pop // c1 + a*i = c2 + a*i'
115359b61b9eSSebastian Pop //
115459b61b9eSSebastian Pop // The dependence distance is
115559b61b9eSSebastian Pop //
115659b61b9eSSebastian Pop // d = i' - i = (c1 - c2)/a
115759b61b9eSSebastian Pop //
115859b61b9eSSebastian Pop // A dependence only exists if d is an integer and abs(d) <= U, where U is the
115959b61b9eSSebastian Pop // loop's upper bound. If a dependence exists, the dependence direction is
116059b61b9eSSebastian Pop // defined as
116159b61b9eSSebastian Pop //
116259b61b9eSSebastian Pop // { < if d > 0
116359b61b9eSSebastian Pop // direction = { = if d = 0
116459b61b9eSSebastian Pop // { > if d < 0
116559b61b9eSSebastian Pop //
116659b61b9eSSebastian Pop // Return true if dependence disproved.
strongSIVtest(const SCEV * Coeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const116749c22190SChandler Carruth bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
116849c22190SChandler Carruth const SCEV *DstConst, const Loop *CurLoop,
116949c22190SChandler Carruth unsigned Level, FullDependence &Result,
117059b61b9eSSebastian Pop Constraint &NewConstraint) const {
1171d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tStrong SIV test\n");
1172d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Coeff = " << *Coeff);
1173d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", " << *Coeff->getType() << "\n");
1174d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst);
1175d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", " << *SrcConst->getType() << "\n");
1176d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst);
1177d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", " << *DstConst->getType() << "\n");
117859b61b9eSSebastian Pop ++StrongSIVapplications;
117959b61b9eSSebastian Pop assert(0 < Level && Level <= CommonLevels && "level out of range");
118059b61b9eSSebastian Pop Level--;
118159b61b9eSSebastian Pop
118259b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1183d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta);
1184d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", " << *Delta->getType() << "\n");
118559b61b9eSSebastian Pop
118659b61b9eSSebastian Pop // check that |Delta| < iteration count
118759b61b9eSSebastian Pop if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1188d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound);
1189d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", " << *UpperBound->getType() << "\n");
119059b61b9eSSebastian Pop const SCEV *AbsDelta =
119159b61b9eSSebastian Pop SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
119259b61b9eSSebastian Pop const SCEV *AbsCoeff =
119359b61b9eSSebastian Pop SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
119459b61b9eSSebastian Pop const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
119559b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product)) {
119659b61b9eSSebastian Pop // Distance greater than trip count - no dependence
119759b61b9eSSebastian Pop ++StrongSIVindependence;
119859b61b9eSSebastian Pop ++StrongSIVsuccesses;
119959b61b9eSSebastian Pop return true;
120059b61b9eSSebastian Pop }
120159b61b9eSSebastian Pop }
120259b61b9eSSebastian Pop
120359b61b9eSSebastian Pop // Can we compute distance?
120459b61b9eSSebastian Pop if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
12050de2feceSSanjoy Das APInt ConstDelta = cast<SCEVConstant>(Delta)->getAPInt();
12060de2feceSSanjoy Das APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getAPInt();
120759b61b9eSSebastian Pop APInt Distance = ConstDelta; // these need to be initialized
120859b61b9eSSebastian Pop APInt Remainder = ConstDelta;
120959b61b9eSSebastian Pop APInt::sdivrem(ConstDelta, ConstCoeff, Distance, Remainder);
1210d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Distance = " << Distance << "\n");
1211d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Remainder = " << Remainder << "\n");
121259b61b9eSSebastian Pop // Make sure Coeff divides Delta exactly
121359b61b9eSSebastian Pop if (Remainder != 0) {
121459b61b9eSSebastian Pop // Coeff doesn't divide Distance, no dependence
121559b61b9eSSebastian Pop ++StrongSIVindependence;
121659b61b9eSSebastian Pop ++StrongSIVsuccesses;
121759b61b9eSSebastian Pop return true;
121859b61b9eSSebastian Pop }
121959b61b9eSSebastian Pop Result.DV[Level].Distance = SE->getConstant(Distance);
122059b61b9eSSebastian Pop NewConstraint.setDistance(SE->getConstant(Distance), CurLoop);
122159b61b9eSSebastian Pop if (Distance.sgt(0))
122259b61b9eSSebastian Pop Result.DV[Level].Direction &= Dependence::DVEntry::LT;
122359b61b9eSSebastian Pop else if (Distance.slt(0))
122459b61b9eSSebastian Pop Result.DV[Level].Direction &= Dependence::DVEntry::GT;
122559b61b9eSSebastian Pop else
122659b61b9eSSebastian Pop Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
122759b61b9eSSebastian Pop ++StrongSIVsuccesses;
122859b61b9eSSebastian Pop }
122959b61b9eSSebastian Pop else if (Delta->isZero()) {
123059b61b9eSSebastian Pop // since 0/X == 0
123159b61b9eSSebastian Pop Result.DV[Level].Distance = Delta;
123259b61b9eSSebastian Pop NewConstraint.setDistance(Delta, CurLoop);
123359b61b9eSSebastian Pop Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
123459b61b9eSSebastian Pop ++StrongSIVsuccesses;
123559b61b9eSSebastian Pop }
123659b61b9eSSebastian Pop else {
123759b61b9eSSebastian Pop if (Coeff->isOne()) {
1238d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Distance = " << *Delta << "\n");
123959b61b9eSSebastian Pop Result.DV[Level].Distance = Delta; // since X/1 == X
124059b61b9eSSebastian Pop NewConstraint.setDistance(Delta, CurLoop);
124159b61b9eSSebastian Pop }
124259b61b9eSSebastian Pop else {
124359b61b9eSSebastian Pop Result.Consistent = false;
124459b61b9eSSebastian Pop NewConstraint.setLine(Coeff,
124559b61b9eSSebastian Pop SE->getNegativeSCEV(Coeff),
124659b61b9eSSebastian Pop SE->getNegativeSCEV(Delta), CurLoop);
124759b61b9eSSebastian Pop }
124859b61b9eSSebastian Pop
124959b61b9eSSebastian Pop // maybe we can get a useful direction
125059b61b9eSSebastian Pop bool DeltaMaybeZero = !SE->isKnownNonZero(Delta);
125159b61b9eSSebastian Pop bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
125259b61b9eSSebastian Pop bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
125359b61b9eSSebastian Pop bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
125459b61b9eSSebastian Pop bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
125559b61b9eSSebastian Pop // The double negatives above are confusing.
125659b61b9eSSebastian Pop // It helps to read !SE->isKnownNonZero(Delta)
125759b61b9eSSebastian Pop // as "Delta might be Zero"
125859b61b9eSSebastian Pop unsigned NewDirection = Dependence::DVEntry::NONE;
125959b61b9eSSebastian Pop if ((DeltaMaybePositive && CoeffMaybePositive) ||
126059b61b9eSSebastian Pop (DeltaMaybeNegative && CoeffMaybeNegative))
126159b61b9eSSebastian Pop NewDirection = Dependence::DVEntry::LT;
126259b61b9eSSebastian Pop if (DeltaMaybeZero)
126359b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::EQ;
126459b61b9eSSebastian Pop if ((DeltaMaybeNegative && CoeffMaybePositive) ||
126559b61b9eSSebastian Pop (DeltaMaybePositive && CoeffMaybeNegative))
126659b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::GT;
126759b61b9eSSebastian Pop if (NewDirection < Result.DV[Level].Direction)
126859b61b9eSSebastian Pop ++StrongSIVsuccesses;
126959b61b9eSSebastian Pop Result.DV[Level].Direction &= NewDirection;
127059b61b9eSSebastian Pop }
127159b61b9eSSebastian Pop return false;
127259b61b9eSSebastian Pop }
127359b61b9eSSebastian Pop
127459b61b9eSSebastian Pop
127559b61b9eSSebastian Pop // weakCrossingSIVtest -
127659b61b9eSSebastian Pop // From the paper, Practical Dependence Testing, Section 4.2.2
127759b61b9eSSebastian Pop //
127859b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a*i] and [c2 - a*i],
127959b61b9eSSebastian Pop // where i is an induction variable, c1 and c2 are loop invariant,
128059b61b9eSSebastian Pop // and a is a constant, we can solve it exactly using the
128159b61b9eSSebastian Pop // Weak-Crossing SIV test.
128259b61b9eSSebastian Pop //
128359b61b9eSSebastian Pop // Given c1 + a*i = c2 - a*i', we can look for the intersection of
128459b61b9eSSebastian Pop // the two lines, where i = i', yielding
128559b61b9eSSebastian Pop //
128659b61b9eSSebastian Pop // c1 + a*i = c2 - a*i
128759b61b9eSSebastian Pop // 2a*i = c2 - c1
128859b61b9eSSebastian Pop // i = (c2 - c1)/2a
128959b61b9eSSebastian Pop //
129059b61b9eSSebastian Pop // If i < 0, there is no dependence.
129159b61b9eSSebastian Pop // If i > upperbound, there is no dependence.
129259b61b9eSSebastian Pop // If i = 0 (i.e., if c1 = c2), there's a dependence with distance = 0.
129359b61b9eSSebastian Pop // If i = upperbound, there's a dependence with distance = 0.
129459b61b9eSSebastian Pop // If i is integral, there's a dependence (all directions).
129559b61b9eSSebastian Pop // If the non-integer part = 1/2, there's a dependence (<> directions).
129659b61b9eSSebastian Pop // Otherwise, there's no dependence.
129759b61b9eSSebastian Pop //
129859b61b9eSSebastian Pop // Can prove independence. Failing that,
129959b61b9eSSebastian Pop // can sometimes refine the directions.
130059b61b9eSSebastian Pop // Can determine iteration for splitting.
130159b61b9eSSebastian Pop //
130259b61b9eSSebastian Pop // Return true if dependence disproved.
weakCrossingSIVtest(const SCEV * Coeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint,const SCEV * & SplitIter) const130349c22190SChandler Carruth bool DependenceInfo::weakCrossingSIVtest(
130449c22190SChandler Carruth const SCEV *Coeff, const SCEV *SrcConst, const SCEV *DstConst,
130549c22190SChandler Carruth const Loop *CurLoop, unsigned Level, FullDependence &Result,
130649c22190SChandler Carruth Constraint &NewConstraint, const SCEV *&SplitIter) const {
1307d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tWeak-Crossing SIV test\n");
1308d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Coeff = " << *Coeff << "\n");
1309d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n");
1310d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst << "\n");
131159b61b9eSSebastian Pop ++WeakCrossingSIVapplications;
131259b61b9eSSebastian Pop assert(0 < Level && Level <= CommonLevels && "Level out of range");
131359b61b9eSSebastian Pop Level--;
131459b61b9eSSebastian Pop Result.Consistent = false;
131559b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1316d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n");
131759b61b9eSSebastian Pop NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
131859b61b9eSSebastian Pop if (Delta->isZero()) {
1319e9623261SSebastian Pop Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::LT);
1320e9623261SSebastian Pop Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::GT);
132159b61b9eSSebastian Pop ++WeakCrossingSIVsuccesses;
132259b61b9eSSebastian Pop if (!Result.DV[Level].Direction) {
132359b61b9eSSebastian Pop ++WeakCrossingSIVindependence;
132459b61b9eSSebastian Pop return true;
132559b61b9eSSebastian Pop }
132659b61b9eSSebastian Pop Result.DV[Level].Distance = Delta; // = 0
132759b61b9eSSebastian Pop return false;
132859b61b9eSSebastian Pop }
132959b61b9eSSebastian Pop const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(Coeff);
133059b61b9eSSebastian Pop if (!ConstCoeff)
133159b61b9eSSebastian Pop return false;
133259b61b9eSSebastian Pop
133359b61b9eSSebastian Pop Result.DV[Level].Splitable = true;
133459b61b9eSSebastian Pop if (SE->isKnownNegative(ConstCoeff)) {
133559b61b9eSSebastian Pop ConstCoeff = dyn_cast<SCEVConstant>(SE->getNegativeSCEV(ConstCoeff));
133659b61b9eSSebastian Pop assert(ConstCoeff &&
133759b61b9eSSebastian Pop "dynamic cast of negative of ConstCoeff should yield constant");
133859b61b9eSSebastian Pop Delta = SE->getNegativeSCEV(Delta);
133959b61b9eSSebastian Pop }
134059b61b9eSSebastian Pop assert(SE->isKnownPositive(ConstCoeff) && "ConstCoeff should be positive");
134159b61b9eSSebastian Pop
134249c22190SChandler Carruth // compute SplitIter for use by DependenceInfo::getSplitIteration()
13432aacc0ecSSanjoy Das SplitIter = SE->getUDivExpr(
13442aacc0ecSSanjoy Das SE->getSMaxExpr(SE->getZero(Delta->getType()), Delta),
13452aacc0ecSSanjoy Das SE->getMulExpr(SE->getConstant(Delta->getType(), 2), ConstCoeff));
1346d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Split iter = " << *SplitIter << "\n");
134759b61b9eSSebastian Pop
134859b61b9eSSebastian Pop const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
134959b61b9eSSebastian Pop if (!ConstDelta)
135059b61b9eSSebastian Pop return false;
135159b61b9eSSebastian Pop
135259b61b9eSSebastian Pop // We're certain that ConstCoeff > 0; therefore,
135359b61b9eSSebastian Pop // if Delta < 0, then no dependence.
1354d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n");
1355d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t ConstCoeff = " << *ConstCoeff << "\n");
135659b61b9eSSebastian Pop if (SE->isKnownNegative(Delta)) {
135759b61b9eSSebastian Pop // No dependence, Delta < 0
135859b61b9eSSebastian Pop ++WeakCrossingSIVindependence;
135959b61b9eSSebastian Pop ++WeakCrossingSIVsuccesses;
136059b61b9eSSebastian Pop return true;
136159b61b9eSSebastian Pop }
136259b61b9eSSebastian Pop
136359b61b9eSSebastian Pop // We're certain that Delta > 0 and ConstCoeff > 0.
136459b61b9eSSebastian Pop // Check Delta/(2*ConstCoeff) against upper loop bound
136559b61b9eSSebastian Pop if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1366d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound << "\n");
136759b61b9eSSebastian Pop const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
136859b61b9eSSebastian Pop const SCEV *ML = SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound),
136959b61b9eSSebastian Pop ConstantTwo);
1370d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t ML = " << *ML << "\n");
137159b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, ML)) {
137259b61b9eSSebastian Pop // Delta too big, no dependence
137359b61b9eSSebastian Pop ++WeakCrossingSIVindependence;
137459b61b9eSSebastian Pop ++WeakCrossingSIVsuccesses;
137559b61b9eSSebastian Pop return true;
137659b61b9eSSebastian Pop }
137759b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, Delta, ML)) {
137859b61b9eSSebastian Pop // i = i' = UB
1379e9623261SSebastian Pop Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::LT);
1380e9623261SSebastian Pop Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::GT);
138159b61b9eSSebastian Pop ++WeakCrossingSIVsuccesses;
138259b61b9eSSebastian Pop if (!Result.DV[Level].Direction) {
138359b61b9eSSebastian Pop ++WeakCrossingSIVindependence;
138459b61b9eSSebastian Pop return true;
138559b61b9eSSebastian Pop }
138659b61b9eSSebastian Pop Result.DV[Level].Splitable = false;
13872aacc0ecSSanjoy Das Result.DV[Level].Distance = SE->getZero(Delta->getType());
138859b61b9eSSebastian Pop return false;
138959b61b9eSSebastian Pop }
139059b61b9eSSebastian Pop }
139159b61b9eSSebastian Pop
139259b61b9eSSebastian Pop // check that Coeff divides Delta
13930de2feceSSanjoy Das APInt APDelta = ConstDelta->getAPInt();
13940de2feceSSanjoy Das APInt APCoeff = ConstCoeff->getAPInt();
139559b61b9eSSebastian Pop APInt Distance = APDelta; // these need to be initialzed
139659b61b9eSSebastian Pop APInt Remainder = APDelta;
139759b61b9eSSebastian Pop APInt::sdivrem(APDelta, APCoeff, Distance, Remainder);
1398d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Remainder = " << Remainder << "\n");
139959b61b9eSSebastian Pop if (Remainder != 0) {
140059b61b9eSSebastian Pop // Coeff doesn't divide Delta, no dependence
140159b61b9eSSebastian Pop ++WeakCrossingSIVindependence;
140259b61b9eSSebastian Pop ++WeakCrossingSIVsuccesses;
140359b61b9eSSebastian Pop return true;
140459b61b9eSSebastian Pop }
1405d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Distance = " << Distance << "\n");
140659b61b9eSSebastian Pop
140759b61b9eSSebastian Pop // if 2*Coeff doesn't divide Delta, then the equal direction isn't possible
140859b61b9eSSebastian Pop APInt Two = APInt(Distance.getBitWidth(), 2, true);
140959b61b9eSSebastian Pop Remainder = Distance.srem(Two);
1410d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Remainder = " << Remainder << "\n");
141159b61b9eSSebastian Pop if (Remainder != 0) {
141259b61b9eSSebastian Pop // Equal direction isn't possible
1413e9623261SSebastian Pop Result.DV[Level].Direction &= unsigned(~Dependence::DVEntry::EQ);
141459b61b9eSSebastian Pop ++WeakCrossingSIVsuccesses;
141559b61b9eSSebastian Pop }
141659b61b9eSSebastian Pop return false;
141759b61b9eSSebastian Pop }
141859b61b9eSSebastian Pop
141959b61b9eSSebastian Pop
142059b61b9eSSebastian Pop // Kirch's algorithm, from
142159b61b9eSSebastian Pop //
142259b61b9eSSebastian Pop // Optimizing Supercompilers for Supercomputers
142359b61b9eSSebastian Pop // Michael Wolfe
142459b61b9eSSebastian Pop // MIT Press, 1989
142559b61b9eSSebastian Pop //
142659b61b9eSSebastian Pop // Program 2.1, page 29.
142759b61b9eSSebastian Pop // Computes the GCD of AM and BM.
14289deac1b7SMingjie Xing // Also finds a solution to the equation ax - by = gcd(a, b).
14299deac1b7SMingjie Xing // Returns true if dependence disproved; i.e., gcd does not divide Delta.
findGCD(unsigned Bits,const APInt & AM,const APInt & BM,const APInt & Delta,APInt & G,APInt & X,APInt & Y)1430c321e534SBenjamin Kramer static bool findGCD(unsigned Bits, const APInt &AM, const APInt &BM,
1431c321e534SBenjamin Kramer const APInt &Delta, APInt &G, APInt &X, APInt &Y) {
143259b61b9eSSebastian Pop APInt A0(Bits, 1, true), A1(Bits, 0, true);
143359b61b9eSSebastian Pop APInt B0(Bits, 0, true), B1(Bits, 1, true);
143459b61b9eSSebastian Pop APInt G0 = AM.abs();
143559b61b9eSSebastian Pop APInt G1 = BM.abs();
143659b61b9eSSebastian Pop APInt Q = G0; // these need to be initialized
143759b61b9eSSebastian Pop APInt R = G0;
143859b61b9eSSebastian Pop APInt::sdivrem(G0, G1, Q, R);
143959b61b9eSSebastian Pop while (R != 0) {
144059b61b9eSSebastian Pop APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
144159b61b9eSSebastian Pop APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
144259b61b9eSSebastian Pop G0 = G1; G1 = R;
144359b61b9eSSebastian Pop APInt::sdivrem(G0, G1, Q, R);
144459b61b9eSSebastian Pop }
144559b61b9eSSebastian Pop G = G1;
1446d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t GCD = " << G << "\n");
144759b61b9eSSebastian Pop X = AM.slt(0) ? -A1 : A1;
144859b61b9eSSebastian Pop Y = BM.slt(0) ? B1 : -B1;
144959b61b9eSSebastian Pop
145059b61b9eSSebastian Pop // make sure gcd divides Delta
145159b61b9eSSebastian Pop R = Delta.srem(G);
145259b61b9eSSebastian Pop if (R != 0)
145359b61b9eSSebastian Pop return true; // gcd doesn't divide Delta, no dependence
145459b61b9eSSebastian Pop Q = Delta.sdiv(G);
145559b61b9eSSebastian Pop return false;
145659b61b9eSSebastian Pop }
145759b61b9eSSebastian Pop
floorOfQuotient(const APInt & A,const APInt & B)1458c321e534SBenjamin Kramer static APInt floorOfQuotient(const APInt &A, const APInt &B) {
145959b61b9eSSebastian Pop APInt Q = A; // these need to be initialized
146059b61b9eSSebastian Pop APInt R = A;
146159b61b9eSSebastian Pop APInt::sdivrem(A, B, Q, R);
146259b61b9eSSebastian Pop if (R == 0)
146359b61b9eSSebastian Pop return Q;
146459b61b9eSSebastian Pop if ((A.sgt(0) && B.sgt(0)) ||
146559b61b9eSSebastian Pop (A.slt(0) && B.slt(0)))
146659b61b9eSSebastian Pop return Q;
146759b61b9eSSebastian Pop else
146859b61b9eSSebastian Pop return Q - 1;
146959b61b9eSSebastian Pop }
147059b61b9eSSebastian Pop
ceilingOfQuotient(const APInt & A,const APInt & B)1471c321e534SBenjamin Kramer static APInt ceilingOfQuotient(const APInt &A, const APInt &B) {
147259b61b9eSSebastian Pop APInt Q = A; // these need to be initialized
147359b61b9eSSebastian Pop APInt R = A;
147459b61b9eSSebastian Pop APInt::sdivrem(A, B, Q, R);
147559b61b9eSSebastian Pop if (R == 0)
147659b61b9eSSebastian Pop return Q;
147759b61b9eSSebastian Pop if ((A.sgt(0) && B.sgt(0)) ||
147859b61b9eSSebastian Pop (A.slt(0) && B.slt(0)))
147959b61b9eSSebastian Pop return Q + 1;
148059b61b9eSSebastian Pop else
148159b61b9eSSebastian Pop return Q;
148259b61b9eSSebastian Pop }
148359b61b9eSSebastian Pop
148459b61b9eSSebastian Pop // exactSIVtest -
148559b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*i],
148659b61b9eSSebastian Pop // where i is an induction variable, c1 and c2 are loop invariant, and a1
148759b61b9eSSebastian Pop // and a2 are constant, we can solve it exactly using an algorithm developed
14880a82d885SAndy Kaylor // by Banerjee and Wolfe. See Algorithm 6.2.1 (case 2.5) in:
148959b61b9eSSebastian Pop //
14900a82d885SAndy Kaylor // Dependence Analysis for Supercomputing
14910a82d885SAndy Kaylor // Utpal Banerjee
14920a82d885SAndy Kaylor // Kluwer Academic Publishers, 1988
149359b61b9eSSebastian Pop //
149459b61b9eSSebastian Pop // It's slower than the specialized tests (strong SIV, weak-zero SIV, etc),
149559b61b9eSSebastian Pop // so use them if possible. They're also a bit better with symbolics and,
149659b61b9eSSebastian Pop // in the case of the strong SIV test, can compute Distances.
149759b61b9eSSebastian Pop //
149859b61b9eSSebastian Pop // Return true if dependence disproved.
14990a82d885SAndy Kaylor //
15000a82d885SAndy Kaylor // This is a modified version of the original Banerjee algorithm. The original
15010a82d885SAndy Kaylor // only tested whether Dst depends on Src. This algorithm extends that and
15020a82d885SAndy Kaylor // returns all the dependencies that exist between Dst and Src.
exactSIVtest(const SCEV * SrcCoeff,const SCEV * DstCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const150349c22190SChandler Carruth bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
150449c22190SChandler Carruth const SCEV *SrcConst, const SCEV *DstConst,
150549c22190SChandler Carruth const Loop *CurLoop, unsigned Level,
150659b61b9eSSebastian Pop FullDependence &Result,
150759b61b9eSSebastian Pop Constraint &NewConstraint) const {
1508d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tExact SIV test\n");
1509d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcCoeff = " << *SrcCoeff << " = AM\n");
1510d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstCoeff = " << *DstCoeff << " = BM\n");
1511d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n");
1512d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst << "\n");
151359b61b9eSSebastian Pop ++ExactSIVapplications;
151459b61b9eSSebastian Pop assert(0 < Level && Level <= CommonLevels && "Level out of range");
151559b61b9eSSebastian Pop Level--;
151659b61b9eSSebastian Pop Result.Consistent = false;
151759b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1518d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n");
15190a82d885SAndy Kaylor NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta,
15200a82d885SAndy Kaylor CurLoop);
152159b61b9eSSebastian Pop const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
152259b61b9eSSebastian Pop const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
152359b61b9eSSebastian Pop const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
152459b61b9eSSebastian Pop if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
152559b61b9eSSebastian Pop return false;
152659b61b9eSSebastian Pop
152759b61b9eSSebastian Pop // find gcd
152859b61b9eSSebastian Pop APInt G, X, Y;
15290de2feceSSanjoy Das APInt AM = ConstSrcCoeff->getAPInt();
15300de2feceSSanjoy Das APInt BM = ConstDstCoeff->getAPInt();
15310a82d885SAndy Kaylor APInt CM = ConstDelta->getAPInt();
153259b61b9eSSebastian Pop unsigned Bits = AM.getBitWidth();
15330a82d885SAndy Kaylor if (findGCD(Bits, AM, BM, CM, G, X, Y)) {
153459b61b9eSSebastian Pop // gcd doesn't divide Delta, no dependence
153559b61b9eSSebastian Pop ++ExactSIVindependence;
153659b61b9eSSebastian Pop ++ExactSIVsuccesses;
153759b61b9eSSebastian Pop return true;
153859b61b9eSSebastian Pop }
153959b61b9eSSebastian Pop
1540d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t X = " << X << ", Y = " << Y << "\n");
154159b61b9eSSebastian Pop
154259b61b9eSSebastian Pop // since SCEV construction normalizes, LM = 0
154359b61b9eSSebastian Pop APInt UM(Bits, 1, true);
15440a82d885SAndy Kaylor bool UMValid = false;
154559b61b9eSSebastian Pop // UM is perhaps unavailable, let's check
154659b61b9eSSebastian Pop if (const SCEVConstant *CUB =
154759b61b9eSSebastian Pop collectConstantUpperBound(CurLoop, Delta->getType())) {
15480de2feceSSanjoy Das UM = CUB->getAPInt();
1549d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t UM = " << UM << "\n");
15500a82d885SAndy Kaylor UMValid = true;
155159b61b9eSSebastian Pop }
155259b61b9eSSebastian Pop
155359b61b9eSSebastian Pop APInt TU(APInt::getSignedMaxValue(Bits));
155459b61b9eSSebastian Pop APInt TL(APInt::getSignedMinValue(Bits));
15550a82d885SAndy Kaylor APInt TC = CM.sdiv(G);
15560a82d885SAndy Kaylor APInt TX = X * TC;
15570a82d885SAndy Kaylor APInt TY = Y * TC;
15580a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TC = " << TC << "\n");
15590a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TX = " << TX << "\n");
15600a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TY = " << TY << "\n");
156159b61b9eSSebastian Pop
15620a82d885SAndy Kaylor SmallVector<APInt, 2> TLVec, TUVec;
15630a82d885SAndy Kaylor APInt TB = BM.sdiv(G);
15640a82d885SAndy Kaylor if (TB.sgt(0)) {
15650a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(-TX, TB));
15660a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
15670a82d885SAndy Kaylor // New bound check - modification to Banerjee's e3 check
15680a82d885SAndy Kaylor if (UMValid) {
15690a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(UM - TX, TB));
15700a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
157159b61b9eSSebastian Pop }
15720a82d885SAndy Kaylor } else {
15730a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(-TX, TB));
15740a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
15750a82d885SAndy Kaylor // New bound check - modification to Banerjee's e3 check
15760a82d885SAndy Kaylor if (UMValid) {
15770a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(UM - TX, TB));
15780a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
157959b61b9eSSebastian Pop }
158059b61b9eSSebastian Pop }
158159b61b9eSSebastian Pop
15820a82d885SAndy Kaylor APInt TA = AM.sdiv(G);
15830a82d885SAndy Kaylor if (TA.sgt(0)) {
15840a82d885SAndy Kaylor if (UMValid) {
15850a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(UM - TY, TA));
15860a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
15870a82d885SAndy Kaylor }
15880a82d885SAndy Kaylor // New bound check - modification to Banerjee's e3 check
15890a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(-TY, TA));
15900a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
15910a82d885SAndy Kaylor } else {
15920a82d885SAndy Kaylor if (UMValid) {
15930a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(UM - TY, TA));
15940a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
15950a82d885SAndy Kaylor }
15960a82d885SAndy Kaylor // New bound check - modification to Banerjee's e3 check
15970a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(-TY, TA));
15980a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
15990a82d885SAndy Kaylor }
16000a82d885SAndy Kaylor
16010a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TA = " << TA << "\n");
16020a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TB = " << TB << "\n");
16030a82d885SAndy Kaylor
16040a82d885SAndy Kaylor if (TLVec.empty() || TUVec.empty())
16050a82d885SAndy Kaylor return false;
16060a82d885SAndy Kaylor TL = APIntOps::smax(TLVec.front(), TLVec.back());
16070a82d885SAndy Kaylor TU = APIntOps::smin(TUVec.front(), TUVec.back());
1608d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
1609d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
16100a82d885SAndy Kaylor
161159b61b9eSSebastian Pop if (TL.sgt(TU)) {
161259b61b9eSSebastian Pop ++ExactSIVindependence;
161359b61b9eSSebastian Pop ++ExactSIVsuccesses;
161459b61b9eSSebastian Pop return true;
161559b61b9eSSebastian Pop }
161659b61b9eSSebastian Pop
161759b61b9eSSebastian Pop // explore directions
161859b61b9eSSebastian Pop unsigned NewDirection = Dependence::DVEntry::NONE;
16190a82d885SAndy Kaylor APInt LowerDistance, UpperDistance;
16200a82d885SAndy Kaylor if (TA.sgt(TB)) {
16210a82d885SAndy Kaylor LowerDistance = (TY - TX) + (TA - TB) * TL;
16220a82d885SAndy Kaylor UpperDistance = (TY - TX) + (TA - TB) * TU;
16230a82d885SAndy Kaylor } else {
16240a82d885SAndy Kaylor LowerDistance = (TY - TX) + (TA - TB) * TU;
16250a82d885SAndy Kaylor UpperDistance = (TY - TX) + (TA - TB) * TL;
162659b61b9eSSebastian Pop }
162759b61b9eSSebastian Pop
16280a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t LowerDistance = " << LowerDistance << "\n");
16290a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t UpperDistance = " << UpperDistance << "\n");
16300a82d885SAndy Kaylor
16310a82d885SAndy Kaylor APInt Zero(Bits, 0, true);
16320a82d885SAndy Kaylor if (LowerDistance.sle(Zero) && UpperDistance.sge(Zero)) {
163359b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::EQ;
163459b61b9eSSebastian Pop ++ExactSIVsuccesses;
163559b61b9eSSebastian Pop }
16360a82d885SAndy Kaylor if (LowerDistance.slt(0)) {
163759b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::GT;
163859b61b9eSSebastian Pop ++ExactSIVsuccesses;
163959b61b9eSSebastian Pop }
16400a82d885SAndy Kaylor if (UpperDistance.sgt(0)) {
16410a82d885SAndy Kaylor NewDirection |= Dependence::DVEntry::LT;
16420a82d885SAndy Kaylor ++ExactSIVsuccesses;
16430a82d885SAndy Kaylor }
164459b61b9eSSebastian Pop
164559b61b9eSSebastian Pop // finished
164659b61b9eSSebastian Pop Result.DV[Level].Direction &= NewDirection;
164759b61b9eSSebastian Pop if (Result.DV[Level].Direction == Dependence::DVEntry::NONE)
164859b61b9eSSebastian Pop ++ExactSIVindependence;
16490a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Result = ");
16500a82d885SAndy Kaylor LLVM_DEBUG(Result.dump(dbgs()));
165159b61b9eSSebastian Pop return Result.DV[Level].Direction == Dependence::DVEntry::NONE;
165259b61b9eSSebastian Pop }
165359b61b9eSSebastian Pop
165459b61b9eSSebastian Pop
165559b61b9eSSebastian Pop // Return true if the divisor evenly divides the dividend.
165659b61b9eSSebastian Pop static
isRemainderZero(const SCEVConstant * Dividend,const SCEVConstant * Divisor)165759b61b9eSSebastian Pop bool isRemainderZero(const SCEVConstant *Dividend,
165859b61b9eSSebastian Pop const SCEVConstant *Divisor) {
165946e38f36SBenjamin Kramer const APInt &ConstDividend = Dividend->getAPInt();
166046e38f36SBenjamin Kramer const APInt &ConstDivisor = Divisor->getAPInt();
166159b61b9eSSebastian Pop return ConstDividend.srem(ConstDivisor) == 0;
166259b61b9eSSebastian Pop }
166359b61b9eSSebastian Pop
166459b61b9eSSebastian Pop
166559b61b9eSSebastian Pop // weakZeroSrcSIVtest -
166659b61b9eSSebastian Pop // From the paper, Practical Dependence Testing, Section 4.2.2
166759b61b9eSSebastian Pop //
166859b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1] and [c2 + a*i],
166959b61b9eSSebastian Pop // where i is an induction variable, c1 and c2 are loop invariant,
167059b61b9eSSebastian Pop // and a is a constant, we can solve it exactly using the
167159b61b9eSSebastian Pop // Weak-Zero SIV test.
167259b61b9eSSebastian Pop //
167359b61b9eSSebastian Pop // Given
167459b61b9eSSebastian Pop //
167559b61b9eSSebastian Pop // c1 = c2 + a*i
167659b61b9eSSebastian Pop //
167759b61b9eSSebastian Pop // we get
167859b61b9eSSebastian Pop //
167959b61b9eSSebastian Pop // (c1 - c2)/a = i
168059b61b9eSSebastian Pop //
168159b61b9eSSebastian Pop // If i is not an integer, there's no dependence.
168259b61b9eSSebastian Pop // If i < 0 or > UB, there's no dependence.
16832911b3a0SDavid Green // If i = 0, the direction is >= and peeling the
168459b61b9eSSebastian Pop // 1st iteration will break the dependence.
16852911b3a0SDavid Green // If i = UB, the direction is <= and peeling the
168659b61b9eSSebastian Pop // last iteration will break the dependence.
168759b61b9eSSebastian Pop // Otherwise, the direction is *.
168859b61b9eSSebastian Pop //
168959b61b9eSSebastian Pop // Can prove independence. Failing that, we can sometimes refine
169059b61b9eSSebastian Pop // the directions. Can sometimes show that first or last
169159b61b9eSSebastian Pop // iteration carries all the dependences (so worth peeling).
169259b61b9eSSebastian Pop //
169359b61b9eSSebastian Pop // (see also weakZeroDstSIVtest)
169459b61b9eSSebastian Pop //
169559b61b9eSSebastian Pop // Return true if dependence disproved.
weakZeroSrcSIVtest(const SCEV * DstCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const169649c22190SChandler Carruth bool DependenceInfo::weakZeroSrcSIVtest(const SCEV *DstCoeff,
169759b61b9eSSebastian Pop const SCEV *SrcConst,
169859b61b9eSSebastian Pop const SCEV *DstConst,
169949c22190SChandler Carruth const Loop *CurLoop, unsigned Level,
170059b61b9eSSebastian Pop FullDependence &Result,
170159b61b9eSSebastian Pop Constraint &NewConstraint) const {
170259b61b9eSSebastian Pop // For the WeakSIV test, it's possible the loop isn't common to
170359b61b9eSSebastian Pop // the Src and Dst loops. If it isn't, then there's no need to
170459b61b9eSSebastian Pop // record a direction.
1705d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tWeak-Zero (src) SIV test\n");
1706d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstCoeff = " << *DstCoeff << "\n");
1707d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n");
1708d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst << "\n");
170959b61b9eSSebastian Pop ++WeakZeroSIVapplications;
171059b61b9eSSebastian Pop assert(0 < Level && Level <= MaxLevels && "Level out of range");
171159b61b9eSSebastian Pop Level--;
171259b61b9eSSebastian Pop Result.Consistent = false;
171359b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
17142aacc0ecSSanjoy Das NewConstraint.setLine(SE->getZero(Delta->getType()), DstCoeff, Delta,
17152aacc0ecSSanjoy Das CurLoop);
1716d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n");
171759b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, SrcConst, DstConst)) {
171859b61b9eSSebastian Pop if (Level < CommonLevels) {
17192911b3a0SDavid Green Result.DV[Level].Direction &= Dependence::DVEntry::GE;
172059b61b9eSSebastian Pop Result.DV[Level].PeelFirst = true;
172159b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
172259b61b9eSSebastian Pop }
172359b61b9eSSebastian Pop return false; // dependences caused by first iteration
172459b61b9eSSebastian Pop }
172559b61b9eSSebastian Pop const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
172659b61b9eSSebastian Pop if (!ConstCoeff)
172759b61b9eSSebastian Pop return false;
172859b61b9eSSebastian Pop const SCEV *AbsCoeff =
172959b61b9eSSebastian Pop SE->isKnownNegative(ConstCoeff) ?
173059b61b9eSSebastian Pop SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
173159b61b9eSSebastian Pop const SCEV *NewDelta =
173259b61b9eSSebastian Pop SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
173359b61b9eSSebastian Pop
173459b61b9eSSebastian Pop // check that Delta/SrcCoeff < iteration count
173559b61b9eSSebastian Pop // really check NewDelta < count*AbsCoeff
173659b61b9eSSebastian Pop if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1737d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound << "\n");
173859b61b9eSSebastian Pop const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
173959b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
174059b61b9eSSebastian Pop ++WeakZeroSIVindependence;
174159b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
174259b61b9eSSebastian Pop return true;
174359b61b9eSSebastian Pop }
174459b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
174559b61b9eSSebastian Pop // dependences caused by last iteration
174659b61b9eSSebastian Pop if (Level < CommonLevels) {
17472911b3a0SDavid Green Result.DV[Level].Direction &= Dependence::DVEntry::LE;
174859b61b9eSSebastian Pop Result.DV[Level].PeelLast = true;
174959b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
175059b61b9eSSebastian Pop }
175159b61b9eSSebastian Pop return false;
175259b61b9eSSebastian Pop }
175359b61b9eSSebastian Pop }
175459b61b9eSSebastian Pop
175559b61b9eSSebastian Pop // check that Delta/SrcCoeff >= 0
175659b61b9eSSebastian Pop // really check that NewDelta >= 0
175759b61b9eSSebastian Pop if (SE->isKnownNegative(NewDelta)) {
175859b61b9eSSebastian Pop // No dependence, newDelta < 0
175959b61b9eSSebastian Pop ++WeakZeroSIVindependence;
176059b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
176159b61b9eSSebastian Pop return true;
176259b61b9eSSebastian Pop }
176359b61b9eSSebastian Pop
176459b61b9eSSebastian Pop // if SrcCoeff doesn't divide Delta, then no dependence
176559b61b9eSSebastian Pop if (isa<SCEVConstant>(Delta) &&
176659b61b9eSSebastian Pop !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
176759b61b9eSSebastian Pop ++WeakZeroSIVindependence;
176859b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
176959b61b9eSSebastian Pop return true;
177059b61b9eSSebastian Pop }
177159b61b9eSSebastian Pop return false;
177259b61b9eSSebastian Pop }
177359b61b9eSSebastian Pop
177459b61b9eSSebastian Pop
177559b61b9eSSebastian Pop // weakZeroDstSIVtest -
177659b61b9eSSebastian Pop // From the paper, Practical Dependence Testing, Section 4.2.2
177759b61b9eSSebastian Pop //
177859b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a*i] and [c2],
177959b61b9eSSebastian Pop // where i is an induction variable, c1 and c2 are loop invariant,
178059b61b9eSSebastian Pop // and a is a constant, we can solve it exactly using the
178159b61b9eSSebastian Pop // Weak-Zero SIV test.
178259b61b9eSSebastian Pop //
178359b61b9eSSebastian Pop // Given
178459b61b9eSSebastian Pop //
178559b61b9eSSebastian Pop // c1 + a*i = c2
178659b61b9eSSebastian Pop //
178759b61b9eSSebastian Pop // we get
178859b61b9eSSebastian Pop //
178959b61b9eSSebastian Pop // i = (c2 - c1)/a
179059b61b9eSSebastian Pop //
179159b61b9eSSebastian Pop // If i is not an integer, there's no dependence.
179259b61b9eSSebastian Pop // If i < 0 or > UB, there's no dependence.
179359b61b9eSSebastian Pop // If i = 0, the direction is <= and peeling the
179459b61b9eSSebastian Pop // 1st iteration will break the dependence.
179559b61b9eSSebastian Pop // If i = UB, the direction is >= and peeling the
179659b61b9eSSebastian Pop // last iteration will break the dependence.
179759b61b9eSSebastian Pop // Otherwise, the direction is *.
179859b61b9eSSebastian Pop //
179959b61b9eSSebastian Pop // Can prove independence. Failing that, we can sometimes refine
180059b61b9eSSebastian Pop // the directions. Can sometimes show that first or last
180159b61b9eSSebastian Pop // iteration carries all the dependences (so worth peeling).
180259b61b9eSSebastian Pop //
180359b61b9eSSebastian Pop // (see also weakZeroSrcSIVtest)
180459b61b9eSSebastian Pop //
180559b61b9eSSebastian Pop // Return true if dependence disproved.
weakZeroDstSIVtest(const SCEV * SrcCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * CurLoop,unsigned Level,FullDependence & Result,Constraint & NewConstraint) const180649c22190SChandler Carruth bool DependenceInfo::weakZeroDstSIVtest(const SCEV *SrcCoeff,
180759b61b9eSSebastian Pop const SCEV *SrcConst,
180859b61b9eSSebastian Pop const SCEV *DstConst,
180949c22190SChandler Carruth const Loop *CurLoop, unsigned Level,
181059b61b9eSSebastian Pop FullDependence &Result,
181159b61b9eSSebastian Pop Constraint &NewConstraint) const {
181259b61b9eSSebastian Pop // For the WeakSIV test, it's possible the loop isn't common to the
181359b61b9eSSebastian Pop // Src and Dst loops. If it isn't, then there's no need to record a direction.
1814d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tWeak-Zero (dst) SIV test\n");
1815d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcCoeff = " << *SrcCoeff << "\n");
1816d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n");
1817d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst << "\n");
181859b61b9eSSebastian Pop ++WeakZeroSIVapplications;
181959b61b9eSSebastian Pop assert(0 < Level && Level <= SrcLevels && "Level out of range");
182059b61b9eSSebastian Pop Level--;
182159b61b9eSSebastian Pop Result.Consistent = false;
182259b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
18232aacc0ecSSanjoy Das NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->getType()), Delta,
18242aacc0ecSSanjoy Das CurLoop);
1825d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n");
182659b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, DstConst, SrcConst)) {
182759b61b9eSSebastian Pop if (Level < CommonLevels) {
182859b61b9eSSebastian Pop Result.DV[Level].Direction &= Dependence::DVEntry::LE;
182959b61b9eSSebastian Pop Result.DV[Level].PeelFirst = true;
183059b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
183159b61b9eSSebastian Pop }
183259b61b9eSSebastian Pop return false; // dependences caused by first iteration
183359b61b9eSSebastian Pop }
183459b61b9eSSebastian Pop const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
183559b61b9eSSebastian Pop if (!ConstCoeff)
183659b61b9eSSebastian Pop return false;
183759b61b9eSSebastian Pop const SCEV *AbsCoeff =
183859b61b9eSSebastian Pop SE->isKnownNegative(ConstCoeff) ?
183959b61b9eSSebastian Pop SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
184059b61b9eSSebastian Pop const SCEV *NewDelta =
184159b61b9eSSebastian Pop SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
184259b61b9eSSebastian Pop
184359b61b9eSSebastian Pop // check that Delta/SrcCoeff < iteration count
184459b61b9eSSebastian Pop // really check NewDelta < count*AbsCoeff
184559b61b9eSSebastian Pop if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
1846d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound << "\n");
184759b61b9eSSebastian Pop const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
184859b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
184959b61b9eSSebastian Pop ++WeakZeroSIVindependence;
185059b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
185159b61b9eSSebastian Pop return true;
185259b61b9eSSebastian Pop }
185359b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
185459b61b9eSSebastian Pop // dependences caused by last iteration
185559b61b9eSSebastian Pop if (Level < CommonLevels) {
185659b61b9eSSebastian Pop Result.DV[Level].Direction &= Dependence::DVEntry::GE;
185759b61b9eSSebastian Pop Result.DV[Level].PeelLast = true;
185859b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
185959b61b9eSSebastian Pop }
186059b61b9eSSebastian Pop return false;
186159b61b9eSSebastian Pop }
186259b61b9eSSebastian Pop }
186359b61b9eSSebastian Pop
186459b61b9eSSebastian Pop // check that Delta/SrcCoeff >= 0
186559b61b9eSSebastian Pop // really check that NewDelta >= 0
186659b61b9eSSebastian Pop if (SE->isKnownNegative(NewDelta)) {
186759b61b9eSSebastian Pop // No dependence, newDelta < 0
186859b61b9eSSebastian Pop ++WeakZeroSIVindependence;
186959b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
187059b61b9eSSebastian Pop return true;
187159b61b9eSSebastian Pop }
187259b61b9eSSebastian Pop
187359b61b9eSSebastian Pop // if SrcCoeff doesn't divide Delta, then no dependence
187459b61b9eSSebastian Pop if (isa<SCEVConstant>(Delta) &&
187559b61b9eSSebastian Pop !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
187659b61b9eSSebastian Pop ++WeakZeroSIVindependence;
187759b61b9eSSebastian Pop ++WeakZeroSIVsuccesses;
187859b61b9eSSebastian Pop return true;
187959b61b9eSSebastian Pop }
188059b61b9eSSebastian Pop return false;
188159b61b9eSSebastian Pop }
188259b61b9eSSebastian Pop
188359b61b9eSSebastian Pop
188459b61b9eSSebastian Pop // exactRDIVtest - Tests the RDIV subscript pair for dependence.
188559b61b9eSSebastian Pop // Things of the form [c1 + a*i] and [c2 + b*j],
188659b61b9eSSebastian Pop // where i and j are induction variable, c1 and c2 are loop invariant,
188759b61b9eSSebastian Pop // and a and b are constants.
188859b61b9eSSebastian Pop // Returns true if any possible dependence is disproved.
1889c914ab6eSBenjamin Kramer // Marks the result as inconsistent.
189059b61b9eSSebastian Pop // Works in some cases that symbolicRDIVtest doesn't, and vice versa.
exactRDIVtest(const SCEV * SrcCoeff,const SCEV * DstCoeff,const SCEV * SrcConst,const SCEV * DstConst,const Loop * SrcLoop,const Loop * DstLoop,FullDependence & Result) const189149c22190SChandler Carruth bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
189249c22190SChandler Carruth const SCEV *SrcConst, const SCEV *DstConst,
189349c22190SChandler Carruth const Loop *SrcLoop, const Loop *DstLoop,
189459b61b9eSSebastian Pop FullDependence &Result) const {
1895d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tExact RDIV test\n");
1896d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcCoeff = " << *SrcCoeff << " = AM\n");
1897d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstCoeff = " << *DstCoeff << " = BM\n");
1898d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n");
1899d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst << "\n");
190059b61b9eSSebastian Pop ++ExactRDIVapplications;
190159b61b9eSSebastian Pop Result.Consistent = false;
190259b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1903d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n");
190459b61b9eSSebastian Pop const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
190559b61b9eSSebastian Pop const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
190659b61b9eSSebastian Pop const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
190759b61b9eSSebastian Pop if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
190859b61b9eSSebastian Pop return false;
190959b61b9eSSebastian Pop
191059b61b9eSSebastian Pop // find gcd
191159b61b9eSSebastian Pop APInt G, X, Y;
19120de2feceSSanjoy Das APInt AM = ConstSrcCoeff->getAPInt();
19130de2feceSSanjoy Das APInt BM = ConstDstCoeff->getAPInt();
19140a82d885SAndy Kaylor APInt CM = ConstDelta->getAPInt();
191559b61b9eSSebastian Pop unsigned Bits = AM.getBitWidth();
19160a82d885SAndy Kaylor if (findGCD(Bits, AM, BM, CM, G, X, Y)) {
191759b61b9eSSebastian Pop // gcd doesn't divide Delta, no dependence
191859b61b9eSSebastian Pop ++ExactRDIVindependence;
191959b61b9eSSebastian Pop return true;
192059b61b9eSSebastian Pop }
192159b61b9eSSebastian Pop
1922d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t X = " << X << ", Y = " << Y << "\n");
192359b61b9eSSebastian Pop
192459b61b9eSSebastian Pop // since SCEV construction seems to normalize, LM = 0
192559b61b9eSSebastian Pop APInt SrcUM(Bits, 1, true);
192659b61b9eSSebastian Pop bool SrcUMvalid = false;
192759b61b9eSSebastian Pop // SrcUM is perhaps unavailable, let's check
192859b61b9eSSebastian Pop if (const SCEVConstant *UpperBound =
192959b61b9eSSebastian Pop collectConstantUpperBound(SrcLoop, Delta->getType())) {
19300de2feceSSanjoy Das SrcUM = UpperBound->getAPInt();
1931d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t SrcUM = " << SrcUM << "\n");
193259b61b9eSSebastian Pop SrcUMvalid = true;
193359b61b9eSSebastian Pop }
193459b61b9eSSebastian Pop
193559b61b9eSSebastian Pop APInt DstUM(Bits, 1, true);
193659b61b9eSSebastian Pop bool DstUMvalid = false;
193759b61b9eSSebastian Pop // UM is perhaps unavailable, let's check
193859b61b9eSSebastian Pop if (const SCEVConstant *UpperBound =
193959b61b9eSSebastian Pop collectConstantUpperBound(DstLoop, Delta->getType())) {
19400de2feceSSanjoy Das DstUM = UpperBound->getAPInt();
1941d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t DstUM = " << DstUM << "\n");
194259b61b9eSSebastian Pop DstUMvalid = true;
194359b61b9eSSebastian Pop }
194459b61b9eSSebastian Pop
194559b61b9eSSebastian Pop APInt TU(APInt::getSignedMaxValue(Bits));
194659b61b9eSSebastian Pop APInt TL(APInt::getSignedMinValue(Bits));
19470a82d885SAndy Kaylor APInt TC = CM.sdiv(G);
19480a82d885SAndy Kaylor APInt TX = X * TC;
19490a82d885SAndy Kaylor APInt TY = Y * TC;
19500a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TC = " << TC << "\n");
19510a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TX = " << TX << "\n");
19520a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TY = " << TY << "\n");
195359b61b9eSSebastian Pop
19540a82d885SAndy Kaylor SmallVector<APInt, 2> TLVec, TUVec;
19550a82d885SAndy Kaylor APInt TB = BM.sdiv(G);
19560a82d885SAndy Kaylor if (TB.sgt(0)) {
19570a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(-TX, TB));
19580a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
195959b61b9eSSebastian Pop if (SrcUMvalid) {
19600a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(SrcUM - TX, TB));
19610a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
196259b61b9eSSebastian Pop }
19630a82d885SAndy Kaylor } else {
19640a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(-TX, TB));
19650a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
196659b61b9eSSebastian Pop if (SrcUMvalid) {
19670a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(SrcUM - TX, TB));
19680a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
196959b61b9eSSebastian Pop }
197059b61b9eSSebastian Pop }
197159b61b9eSSebastian Pop
19720a82d885SAndy Kaylor APInt TA = AM.sdiv(G);
19730a82d885SAndy Kaylor if (TA.sgt(0)) {
19740a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(-TY, TA));
19750a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
197659b61b9eSSebastian Pop if (DstUMvalid) {
19770a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(DstUM - TY, TA));
19780a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
197959b61b9eSSebastian Pop }
19800a82d885SAndy Kaylor } else {
19810a82d885SAndy Kaylor TUVec.push_back(floorOfQuotient(-TY, TA));
19820a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TU = " << TUVec.back() << "\n");
198359b61b9eSSebastian Pop if (DstUMvalid) {
19840a82d885SAndy Kaylor TLVec.push_back(ceilingOfQuotient(DstUM - TY, TA));
19850a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t Possible TL = " << TLVec.back() << "\n");
19860a82d885SAndy Kaylor }
19870a82d885SAndy Kaylor }
19880a82d885SAndy Kaylor
19890a82d885SAndy Kaylor if (TLVec.empty() || TUVec.empty())
19900a82d885SAndy Kaylor return false;
19910a82d885SAndy Kaylor
19920a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TA = " << TA << "\n");
19930a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TB = " << TB << "\n");
19940a82d885SAndy Kaylor
19950a82d885SAndy Kaylor TL = APIntOps::smax(TLVec.front(), TLVec.back());
19960a82d885SAndy Kaylor TU = APIntOps::smin(TUVec.front(), TUVec.back());
1997d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t TL = " << TL << "\n");
19980a82d885SAndy Kaylor LLVM_DEBUG(dbgs() << "\t TU = " << TU << "\n");
19990a82d885SAndy Kaylor
200059b61b9eSSebastian Pop if (TL.sgt(TU))
200159b61b9eSSebastian Pop ++ExactRDIVindependence;
200259b61b9eSSebastian Pop return TL.sgt(TU);
200359b61b9eSSebastian Pop }
200459b61b9eSSebastian Pop
200559b61b9eSSebastian Pop
200659b61b9eSSebastian Pop // symbolicRDIVtest -
200759b61b9eSSebastian Pop // In Section 4.5 of the Practical Dependence Testing paper,the authors
200859b61b9eSSebastian Pop // introduce a special case of Banerjee's Inequalities (also called the
200959b61b9eSSebastian Pop // Extreme-Value Test) that can handle some of the SIV and RDIV cases,
201059b61b9eSSebastian Pop // particularly cases with symbolics. Since it's only able to disprove
201159b61b9eSSebastian Pop // dependence (not compute distances or directions), we'll use it as a
201259b61b9eSSebastian Pop // fall back for the other tests.
201359b61b9eSSebastian Pop //
201459b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
201559b61b9eSSebastian Pop // where i and j are induction variables and c1 and c2 are loop invariants,
201659b61b9eSSebastian Pop // we can use the symbolic tests to disprove some dependences, serving as a
201759b61b9eSSebastian Pop // backup for the RDIV test. Note that i and j can be the same variable,
201859b61b9eSSebastian Pop // letting this test serve as a backup for the various SIV tests.
201959b61b9eSSebastian Pop //
202059b61b9eSSebastian Pop // For a dependence to exist, c1 + a1*i must equal c2 + a2*j for some
202159b61b9eSSebastian Pop // 0 <= i <= N1 and some 0 <= j <= N2, where N1 and N2 are the (normalized)
202259b61b9eSSebastian Pop // loop bounds for the i and j loops, respectively. So, ...
202359b61b9eSSebastian Pop //
202459b61b9eSSebastian Pop // c1 + a1*i = c2 + a2*j
202559b61b9eSSebastian Pop // a1*i - a2*j = c2 - c1
202659b61b9eSSebastian Pop //
202759b61b9eSSebastian Pop // To test for a dependence, we compute c2 - c1 and make sure it's in the
202859b61b9eSSebastian Pop // range of the maximum and minimum possible values of a1*i - a2*j.
202959b61b9eSSebastian Pop // Considering the signs of a1 and a2, we have 4 possible cases:
203059b61b9eSSebastian Pop //
203159b61b9eSSebastian Pop // 1) If a1 >= 0 and a2 >= 0, then
203259b61b9eSSebastian Pop // a1*0 - a2*N2 <= c2 - c1 <= a1*N1 - a2*0
203359b61b9eSSebastian Pop // -a2*N2 <= c2 - c1 <= a1*N1
203459b61b9eSSebastian Pop //
203559b61b9eSSebastian Pop // 2) If a1 >= 0 and a2 <= 0, then
203659b61b9eSSebastian Pop // a1*0 - a2*0 <= c2 - c1 <= a1*N1 - a2*N2
203759b61b9eSSebastian Pop // 0 <= c2 - c1 <= a1*N1 - a2*N2
203859b61b9eSSebastian Pop //
203959b61b9eSSebastian Pop // 3) If a1 <= 0 and a2 >= 0, then
204059b61b9eSSebastian Pop // a1*N1 - a2*N2 <= c2 - c1 <= a1*0 - a2*0
204159b61b9eSSebastian Pop // a1*N1 - a2*N2 <= c2 - c1 <= 0
204259b61b9eSSebastian Pop //
204359b61b9eSSebastian Pop // 4) If a1 <= 0 and a2 <= 0, then
204459b61b9eSSebastian Pop // a1*N1 - a2*0 <= c2 - c1 <= a1*0 - a2*N2
204559b61b9eSSebastian Pop // a1*N1 <= c2 - c1 <= -a2*N2
204659b61b9eSSebastian Pop //
204759b61b9eSSebastian Pop // return true if dependence disproved
symbolicRDIVtest(const SCEV * A1,const SCEV * A2,const SCEV * C1,const SCEV * C2,const Loop * Loop1,const Loop * Loop2) const204849c22190SChandler Carruth bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
204949c22190SChandler Carruth const SCEV *C1, const SCEV *C2,
205059b61b9eSSebastian Pop const Loop *Loop1,
205159b61b9eSSebastian Pop const Loop *Loop2) const {
205259b61b9eSSebastian Pop ++SymbolicRDIVapplications;
2053d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\ttry symbolic RDIV test\n");
2054d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A1 = " << *A1);
2055d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", type = " << *A1->getType() << "\n");
2056d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A2 = " << *A2 << "\n");
2057d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t C1 = " << *C1 << "\n");
2058d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t C2 = " << *C2 << "\n");
205959b61b9eSSebastian Pop const SCEV *N1 = collectUpperBound(Loop1, A1->getType());
206059b61b9eSSebastian Pop const SCEV *N2 = collectUpperBound(Loop2, A1->getType());
2061d34e60caSNicola Zaghen LLVM_DEBUG(if (N1) dbgs() << "\t N1 = " << *N1 << "\n");
2062d34e60caSNicola Zaghen LLVM_DEBUG(if (N2) dbgs() << "\t N2 = " << *N2 << "\n");
206359b61b9eSSebastian Pop const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
206459b61b9eSSebastian Pop const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
2065d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t C2 - C1 = " << *C2_C1 << "\n");
2066d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t C1 - C2 = " << *C1_C2 << "\n");
206759b61b9eSSebastian Pop if (SE->isKnownNonNegative(A1)) {
206859b61b9eSSebastian Pop if (SE->isKnownNonNegative(A2)) {
206959b61b9eSSebastian Pop // A1 >= 0 && A2 >= 0
207059b61b9eSSebastian Pop if (N1) {
207159b61b9eSSebastian Pop // make sure that c2 - c1 <= a1*N1
207259b61b9eSSebastian Pop const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2073d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A1*N1 = " << *A1N1 << "\n");
207459b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1)) {
207559b61b9eSSebastian Pop ++SymbolicRDIVindependence;
207659b61b9eSSebastian Pop return true;
207759b61b9eSSebastian Pop }
207859b61b9eSSebastian Pop }
207959b61b9eSSebastian Pop if (N2) {
208059b61b9eSSebastian Pop // make sure that -a2*N2 <= c2 - c1, or a2*N2 >= c1 - c2
208159b61b9eSSebastian Pop const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2082d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A2*N2 = " << *A2N2 << "\n");
208359b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SLT, A2N2, C1_C2)) {
208459b61b9eSSebastian Pop ++SymbolicRDIVindependence;
208559b61b9eSSebastian Pop return true;
208659b61b9eSSebastian Pop }
208759b61b9eSSebastian Pop }
208859b61b9eSSebastian Pop }
208959b61b9eSSebastian Pop else if (SE->isKnownNonPositive(A2)) {
209059b61b9eSSebastian Pop // a1 >= 0 && a2 <= 0
209159b61b9eSSebastian Pop if (N1 && N2) {
209259b61b9eSSebastian Pop // make sure that c2 - c1 <= a1*N1 - a2*N2
209359b61b9eSSebastian Pop const SCEV *A1N1 = SE->getMulExpr(A1, N1);
209459b61b9eSSebastian Pop const SCEV *A2N2 = SE->getMulExpr(A2, N2);
209559b61b9eSSebastian Pop const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2096d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
209759b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1_A2N2)) {
209859b61b9eSSebastian Pop ++SymbolicRDIVindependence;
209959b61b9eSSebastian Pop return true;
210059b61b9eSSebastian Pop }
210159b61b9eSSebastian Pop }
210259b61b9eSSebastian Pop // make sure that 0 <= c2 - c1
210359b61b9eSSebastian Pop if (SE->isKnownNegative(C2_C1)) {
210459b61b9eSSebastian Pop ++SymbolicRDIVindependence;
210559b61b9eSSebastian Pop return true;
210659b61b9eSSebastian Pop }
210759b61b9eSSebastian Pop }
210859b61b9eSSebastian Pop }
210959b61b9eSSebastian Pop else if (SE->isKnownNonPositive(A1)) {
211059b61b9eSSebastian Pop if (SE->isKnownNonNegative(A2)) {
211159b61b9eSSebastian Pop // a1 <= 0 && a2 >= 0
211259b61b9eSSebastian Pop if (N1 && N2) {
211359b61b9eSSebastian Pop // make sure that a1*N1 - a2*N2 <= c2 - c1
211459b61b9eSSebastian Pop const SCEV *A1N1 = SE->getMulExpr(A1, N1);
211559b61b9eSSebastian Pop const SCEV *A2N2 = SE->getMulExpr(A2, N2);
211659b61b9eSSebastian Pop const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2117d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
211859b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1_A2N2, C2_C1)) {
211959b61b9eSSebastian Pop ++SymbolicRDIVindependence;
212059b61b9eSSebastian Pop return true;
212159b61b9eSSebastian Pop }
212259b61b9eSSebastian Pop }
212359b61b9eSSebastian Pop // make sure that c2 - c1 <= 0
212459b61b9eSSebastian Pop if (SE->isKnownPositive(C2_C1)) {
212559b61b9eSSebastian Pop ++SymbolicRDIVindependence;
212659b61b9eSSebastian Pop return true;
212759b61b9eSSebastian Pop }
212859b61b9eSSebastian Pop }
212959b61b9eSSebastian Pop else if (SE->isKnownNonPositive(A2)) {
213059b61b9eSSebastian Pop // a1 <= 0 && a2 <= 0
213159b61b9eSSebastian Pop if (N1) {
213259b61b9eSSebastian Pop // make sure that a1*N1 <= c2 - c1
213359b61b9eSSebastian Pop const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2134d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A1*N1 = " << *A1N1 << "\n");
213559b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1, C2_C1)) {
213659b61b9eSSebastian Pop ++SymbolicRDIVindependence;
213759b61b9eSSebastian Pop return true;
213859b61b9eSSebastian Pop }
213959b61b9eSSebastian Pop }
214059b61b9eSSebastian Pop if (N2) {
214159b61b9eSSebastian Pop // make sure that c2 - c1 <= -a2*N2, or c1 - c2 >= a2*N2
214259b61b9eSSebastian Pop const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2143d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t A2*N2 = " << *A2N2 << "\n");
214459b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SLT, C1_C2, A2N2)) {
214559b61b9eSSebastian Pop ++SymbolicRDIVindependence;
214659b61b9eSSebastian Pop return true;
214759b61b9eSSebastian Pop }
214859b61b9eSSebastian Pop }
214959b61b9eSSebastian Pop }
215059b61b9eSSebastian Pop }
215159b61b9eSSebastian Pop return false;
215259b61b9eSSebastian Pop }
215359b61b9eSSebastian Pop
215459b61b9eSSebastian Pop
215559b61b9eSSebastian Pop // testSIV -
215659b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 - a2*i]
215759b61b9eSSebastian Pop // where i is an induction variable, c1 and c2 are loop invariant, and a1 and
215859b61b9eSSebastian Pop // a2 are constant, we attack it with an SIV test. While they can all be
215959b61b9eSSebastian Pop // solved with the Exact SIV test, it's worthwhile to use simpler tests when
216059b61b9eSSebastian Pop // they apply; they're cheaper and sometimes more precise.
216159b61b9eSSebastian Pop //
216259b61b9eSSebastian Pop // Return true if dependence disproved.
testSIV(const SCEV * Src,const SCEV * Dst,unsigned & Level,FullDependence & Result,Constraint & NewConstraint,const SCEV * & SplitIter) const216349c22190SChandler Carruth bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
216449c22190SChandler Carruth FullDependence &Result, Constraint &NewConstraint,
216559b61b9eSSebastian Pop const SCEV *&SplitIter) const {
2166d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " src = " << *Src << "\n");
2167d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " dst = " << *Dst << "\n");
216859b61b9eSSebastian Pop const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
216959b61b9eSSebastian Pop const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
217059b61b9eSSebastian Pop if (SrcAddRec && DstAddRec) {
217159b61b9eSSebastian Pop const SCEV *SrcConst = SrcAddRec->getStart();
217259b61b9eSSebastian Pop const SCEV *DstConst = DstAddRec->getStart();
217359b61b9eSSebastian Pop const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
217459b61b9eSSebastian Pop const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
217559b61b9eSSebastian Pop const Loop *CurLoop = SrcAddRec->getLoop();
217659b61b9eSSebastian Pop assert(CurLoop == DstAddRec->getLoop() &&
217759b61b9eSSebastian Pop "both loops in SIV should be same");
217859b61b9eSSebastian Pop Level = mapSrcLoop(CurLoop);
217959b61b9eSSebastian Pop bool disproven;
218059b61b9eSSebastian Pop if (SrcCoeff == DstCoeff)
218159b61b9eSSebastian Pop disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
218259b61b9eSSebastian Pop Level, Result, NewConstraint);
218359b61b9eSSebastian Pop else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
218459b61b9eSSebastian Pop disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
218559b61b9eSSebastian Pop Level, Result, NewConstraint, SplitIter);
218659b61b9eSSebastian Pop else
218759b61b9eSSebastian Pop disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
218859b61b9eSSebastian Pop Level, Result, NewConstraint);
218959b61b9eSSebastian Pop return disproven ||
219059b61b9eSSebastian Pop gcdMIVtest(Src, Dst, Result) ||
219159b61b9eSSebastian Pop symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop, CurLoop);
219259b61b9eSSebastian Pop }
219359b61b9eSSebastian Pop if (SrcAddRec) {
219459b61b9eSSebastian Pop const SCEV *SrcConst = SrcAddRec->getStart();
219559b61b9eSSebastian Pop const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
219659b61b9eSSebastian Pop const SCEV *DstConst = Dst;
219759b61b9eSSebastian Pop const Loop *CurLoop = SrcAddRec->getLoop();
219859b61b9eSSebastian Pop Level = mapSrcLoop(CurLoop);
219959b61b9eSSebastian Pop return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
220059b61b9eSSebastian Pop Level, Result, NewConstraint) ||
220159b61b9eSSebastian Pop gcdMIVtest(Src, Dst, Result);
220259b61b9eSSebastian Pop }
220359b61b9eSSebastian Pop if (DstAddRec) {
220459b61b9eSSebastian Pop const SCEV *DstConst = DstAddRec->getStart();
220559b61b9eSSebastian Pop const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
220659b61b9eSSebastian Pop const SCEV *SrcConst = Src;
220759b61b9eSSebastian Pop const Loop *CurLoop = DstAddRec->getLoop();
220859b61b9eSSebastian Pop Level = mapDstLoop(CurLoop);
220959b61b9eSSebastian Pop return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst,
221059b61b9eSSebastian Pop CurLoop, Level, Result, NewConstraint) ||
221159b61b9eSSebastian Pop gcdMIVtest(Src, Dst, Result);
221259b61b9eSSebastian Pop }
221359b61b9eSSebastian Pop llvm_unreachable("SIV test expected at least one AddRec");
221459b61b9eSSebastian Pop return false;
221559b61b9eSSebastian Pop }
221659b61b9eSSebastian Pop
221759b61b9eSSebastian Pop
221859b61b9eSSebastian Pop // testRDIV -
221959b61b9eSSebastian Pop // When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
222059b61b9eSSebastian Pop // where i and j are induction variables, c1 and c2 are loop invariant,
222159b61b9eSSebastian Pop // and a1 and a2 are constant, we can solve it exactly with an easy adaptation
222259b61b9eSSebastian Pop // of the Exact SIV test, the Restricted Double Index Variable (RDIV) test.
222359b61b9eSSebastian Pop // It doesn't make sense to talk about distance or direction in this case,
222459b61b9eSSebastian Pop // so there's no point in making special versions of the Strong SIV test or
222559b61b9eSSebastian Pop // the Weak-crossing SIV test.
222659b61b9eSSebastian Pop //
222759b61b9eSSebastian Pop // With minor algebra, this test can also be used for things like
222859b61b9eSSebastian Pop // [c1 + a1*i + a2*j][c2].
222959b61b9eSSebastian Pop //
223059b61b9eSSebastian Pop // Return true if dependence disproved.
testRDIV(const SCEV * Src,const SCEV * Dst,FullDependence & Result) const223149c22190SChandler Carruth bool DependenceInfo::testRDIV(const SCEV *Src, const SCEV *Dst,
223259b61b9eSSebastian Pop FullDependence &Result) const {
223359b61b9eSSebastian Pop // we have 3 possible situations here:
223459b61b9eSSebastian Pop // 1) [a*i + b] and [c*j + d]
223559b61b9eSSebastian Pop // 2) [a*i + c*j + b] and [d]
223659b61b9eSSebastian Pop // 3) [b] and [a*i + c*j + d]
223759b61b9eSSebastian Pop // We need to find what we've got and get organized
223859b61b9eSSebastian Pop
223959b61b9eSSebastian Pop const SCEV *SrcConst, *DstConst;
224059b61b9eSSebastian Pop const SCEV *SrcCoeff, *DstCoeff;
224159b61b9eSSebastian Pop const Loop *SrcLoop, *DstLoop;
224259b61b9eSSebastian Pop
2243d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " src = " << *Src << "\n");
2244d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " dst = " << *Dst << "\n");
224559b61b9eSSebastian Pop const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
224659b61b9eSSebastian Pop const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
224759b61b9eSSebastian Pop if (SrcAddRec && DstAddRec) {
224859b61b9eSSebastian Pop SrcConst = SrcAddRec->getStart();
224959b61b9eSSebastian Pop SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
225059b61b9eSSebastian Pop SrcLoop = SrcAddRec->getLoop();
225159b61b9eSSebastian Pop DstConst = DstAddRec->getStart();
225259b61b9eSSebastian Pop DstCoeff = DstAddRec->getStepRecurrence(*SE);
225359b61b9eSSebastian Pop DstLoop = DstAddRec->getLoop();
225459b61b9eSSebastian Pop }
225559b61b9eSSebastian Pop else if (SrcAddRec) {
225659b61b9eSSebastian Pop if (const SCEVAddRecExpr *tmpAddRec =
225759b61b9eSSebastian Pop dyn_cast<SCEVAddRecExpr>(SrcAddRec->getStart())) {
225859b61b9eSSebastian Pop SrcConst = tmpAddRec->getStart();
225959b61b9eSSebastian Pop SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
226059b61b9eSSebastian Pop SrcLoop = tmpAddRec->getLoop();
226159b61b9eSSebastian Pop DstConst = Dst;
226259b61b9eSSebastian Pop DstCoeff = SE->getNegativeSCEV(SrcAddRec->getStepRecurrence(*SE));
226359b61b9eSSebastian Pop DstLoop = SrcAddRec->getLoop();
226459b61b9eSSebastian Pop }
226559b61b9eSSebastian Pop else
226659b61b9eSSebastian Pop llvm_unreachable("RDIV reached by surprising SCEVs");
226759b61b9eSSebastian Pop }
226859b61b9eSSebastian Pop else if (DstAddRec) {
226959b61b9eSSebastian Pop if (const SCEVAddRecExpr *tmpAddRec =
227059b61b9eSSebastian Pop dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
227159b61b9eSSebastian Pop DstConst = tmpAddRec->getStart();
227259b61b9eSSebastian Pop DstCoeff = tmpAddRec->getStepRecurrence(*SE);
227359b61b9eSSebastian Pop DstLoop = tmpAddRec->getLoop();
227459b61b9eSSebastian Pop SrcConst = Src;
227559b61b9eSSebastian Pop SrcCoeff = SE->getNegativeSCEV(DstAddRec->getStepRecurrence(*SE));
227659b61b9eSSebastian Pop SrcLoop = DstAddRec->getLoop();
227759b61b9eSSebastian Pop }
227859b61b9eSSebastian Pop else
227959b61b9eSSebastian Pop llvm_unreachable("RDIV reached by surprising SCEVs");
228059b61b9eSSebastian Pop }
228159b61b9eSSebastian Pop else
228259b61b9eSSebastian Pop llvm_unreachable("RDIV expected at least one AddRec");
228359b61b9eSSebastian Pop return exactRDIVtest(SrcCoeff, DstCoeff,
228459b61b9eSSebastian Pop SrcConst, DstConst,
228559b61b9eSSebastian Pop SrcLoop, DstLoop,
228659b61b9eSSebastian Pop Result) ||
228759b61b9eSSebastian Pop gcdMIVtest(Src, Dst, Result) ||
228859b61b9eSSebastian Pop symbolicRDIVtest(SrcCoeff, DstCoeff,
228959b61b9eSSebastian Pop SrcConst, DstConst,
229059b61b9eSSebastian Pop SrcLoop, DstLoop);
229159b61b9eSSebastian Pop }
229259b61b9eSSebastian Pop
229359b61b9eSSebastian Pop
229459b61b9eSSebastian Pop // Tests the single-subscript MIV pair (Src and Dst) for dependence.
229559b61b9eSSebastian Pop // Return true if dependence disproved.
229659b61b9eSSebastian Pop // Can sometimes refine direction vectors.
testMIV(const SCEV * Src,const SCEV * Dst,const SmallBitVector & Loops,FullDependence & Result) const229749c22190SChandler Carruth bool DependenceInfo::testMIV(const SCEV *Src, const SCEV *Dst,
229859b61b9eSSebastian Pop const SmallBitVector &Loops,
229959b61b9eSSebastian Pop FullDependence &Result) const {
2300d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " src = " << *Src << "\n");
2301d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " dst = " << *Dst << "\n");
230259b61b9eSSebastian Pop Result.Consistent = false;
230359b61b9eSSebastian Pop return gcdMIVtest(Src, Dst, Result) ||
230459b61b9eSSebastian Pop banerjeeMIVtest(Src, Dst, Loops, Result);
230559b61b9eSSebastian Pop }
230659b61b9eSSebastian Pop
230759b61b9eSSebastian Pop
230859b61b9eSSebastian Pop // Given a product, e.g., 10*X*Y, returns the first constant operand,
230959b61b9eSSebastian Pop // in this case 10. If there is no constant part, returns NULL.
231059b61b9eSSebastian Pop static
getConstantPart(const SCEV * Expr)2311be2da82cSBrendon Cahoon const SCEVConstant *getConstantPart(const SCEV *Expr) {
2312be2da82cSBrendon Cahoon if (const auto *Constant = dyn_cast<SCEVConstant>(Expr))
231359b61b9eSSebastian Pop return Constant;
2314be2da82cSBrendon Cahoon else if (const auto *Product = dyn_cast<SCEVMulExpr>(Expr))
2315be2da82cSBrendon Cahoon if (const auto *Constant = dyn_cast<SCEVConstant>(Product->getOperand(0)))
2316be2da82cSBrendon Cahoon return Constant;
23179f008867SCraig Topper return nullptr;
231859b61b9eSSebastian Pop }
231959b61b9eSSebastian Pop
232059b61b9eSSebastian Pop
232159b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
232259b61b9eSSebastian Pop // gcdMIVtest -
232359b61b9eSSebastian Pop // Tests an MIV subscript pair for dependence.
232459b61b9eSSebastian Pop // Returns true if any possible dependence is disproved.
2325c914ab6eSBenjamin Kramer // Marks the result as inconsistent.
232659b61b9eSSebastian Pop // Can sometimes disprove the equal direction for 1 or more loops,
232759b61b9eSSebastian Pop // as discussed in Michael Wolfe's book,
232859b61b9eSSebastian Pop // High Performance Compilers for Parallel Computing, page 235.
232959b61b9eSSebastian Pop //
233059b61b9eSSebastian Pop // We spend some effort (code!) to handle cases like
233159b61b9eSSebastian Pop // [10*i + 5*N*j + 15*M + 6], where i and j are induction variables,
233259b61b9eSSebastian Pop // but M and N are just loop-invariant variables.
233359b61b9eSSebastian Pop // This should help us handle linearized subscripts;
233459b61b9eSSebastian Pop // also makes this test a useful backup to the various SIV tests.
233559b61b9eSSebastian Pop //
233659b61b9eSSebastian Pop // It occurs to me that the presence of loop-invariant variables
233759b61b9eSSebastian Pop // changes the nature of the test from "greatest common divisor"
23384eb7ee56SPreston Briggs // to "a common divisor".
gcdMIVtest(const SCEV * Src,const SCEV * Dst,FullDependence & Result) const233949c22190SChandler Carruth bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
234059b61b9eSSebastian Pop FullDependence &Result) const {
2341d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "starting gcd\n");
234259b61b9eSSebastian Pop ++GCDapplications;
23433ad39493SPreston Briggs unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
2344735f4671SChris Lattner APInt RunningGCD = APInt::getZero(BitWidth);
234559b61b9eSSebastian Pop
234659b61b9eSSebastian Pop // Examine Src coefficients.
234759b61b9eSSebastian Pop // Compute running GCD and record source constant.
234859b61b9eSSebastian Pop // Because we're looking for the constant at the end of the chain,
234959b61b9eSSebastian Pop // we can't quit the loop just because the GCD == 1.
235059b61b9eSSebastian Pop const SCEV *Coefficients = Src;
235159b61b9eSSebastian Pop while (const SCEVAddRecExpr *AddRec =
235259b61b9eSSebastian Pop dyn_cast<SCEVAddRecExpr>(Coefficients)) {
235359b61b9eSSebastian Pop const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
235459b61b9eSSebastian Pop // If the coefficient is the product of a constant and other stuff,
235559b61b9eSSebastian Pop // we can use the constant in the GCD computation.
2356be2da82cSBrendon Cahoon const auto *Constant = getConstantPart(Coeff);
235759b61b9eSSebastian Pop if (!Constant)
235859b61b9eSSebastian Pop return false;
23590de2feceSSanjoy Das APInt ConstCoeff = Constant->getAPInt();
236059b61b9eSSebastian Pop RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
236159b61b9eSSebastian Pop Coefficients = AddRec->getStart();
236259b61b9eSSebastian Pop }
236359b61b9eSSebastian Pop const SCEV *SrcConst = Coefficients;
236459b61b9eSSebastian Pop
236559b61b9eSSebastian Pop // Examine Dst coefficients.
236659b61b9eSSebastian Pop // Compute running GCD and record destination constant.
236759b61b9eSSebastian Pop // Because we're looking for the constant at the end of the chain,
236859b61b9eSSebastian Pop // we can't quit the loop just because the GCD == 1.
236959b61b9eSSebastian Pop Coefficients = Dst;
237059b61b9eSSebastian Pop while (const SCEVAddRecExpr *AddRec =
237159b61b9eSSebastian Pop dyn_cast<SCEVAddRecExpr>(Coefficients)) {
237259b61b9eSSebastian Pop const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
237359b61b9eSSebastian Pop // If the coefficient is the product of a constant and other stuff,
237459b61b9eSSebastian Pop // we can use the constant in the GCD computation.
2375be2da82cSBrendon Cahoon const auto *Constant = getConstantPart(Coeff);
237659b61b9eSSebastian Pop if (!Constant)
237759b61b9eSSebastian Pop return false;
23780de2feceSSanjoy Das APInt ConstCoeff = Constant->getAPInt();
237959b61b9eSSebastian Pop RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
238059b61b9eSSebastian Pop Coefficients = AddRec->getStart();
238159b61b9eSSebastian Pop }
238259b61b9eSSebastian Pop const SCEV *DstConst = Coefficients;
238359b61b9eSSebastian Pop
2384735f4671SChris Lattner APInt ExtraGCD = APInt::getZero(BitWidth);
238559b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2386d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Delta = " << *Delta << "\n");
238759b61b9eSSebastian Pop const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Delta);
238859b61b9eSSebastian Pop if (const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
238959b61b9eSSebastian Pop // If Delta is a sum of products, we may be able to make further progress.
239059b61b9eSSebastian Pop for (unsigned Op = 0, Ops = Sum->getNumOperands(); Op < Ops; Op++) {
239159b61b9eSSebastian Pop const SCEV *Operand = Sum->getOperand(Op);
239259b61b9eSSebastian Pop if (isa<SCEVConstant>(Operand)) {
239359b61b9eSSebastian Pop assert(!Constant && "Surprised to find multiple constants");
239459b61b9eSSebastian Pop Constant = cast<SCEVConstant>(Operand);
239559b61b9eSSebastian Pop }
239624c643b6SBenjamin Kramer else if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
239759b61b9eSSebastian Pop // Search for constant operand to participate in GCD;
239859b61b9eSSebastian Pop // If none found; return false.
239924c643b6SBenjamin Kramer const SCEVConstant *ConstOp = getConstantPart(Product);
240024c643b6SBenjamin Kramer if (!ConstOp)
240124c643b6SBenjamin Kramer return false;
24020de2feceSSanjoy Das APInt ConstOpValue = ConstOp->getAPInt();
240359b61b9eSSebastian Pop ExtraGCD = APIntOps::GreatestCommonDivisor(ExtraGCD,
240459b61b9eSSebastian Pop ConstOpValue.abs());
240559b61b9eSSebastian Pop }
240659b61b9eSSebastian Pop else
240759b61b9eSSebastian Pop return false;
240859b61b9eSSebastian Pop }
240959b61b9eSSebastian Pop }
241059b61b9eSSebastian Pop if (!Constant)
241159b61b9eSSebastian Pop return false;
24120de2feceSSanjoy Das APInt ConstDelta = cast<SCEVConstant>(Constant)->getAPInt();
2413d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " ConstDelta = " << ConstDelta << "\n");
241459b61b9eSSebastian Pop if (ConstDelta == 0)
241559b61b9eSSebastian Pop return false;
241659b61b9eSSebastian Pop RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ExtraGCD);
2417d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " RunningGCD = " << RunningGCD << "\n");
241859b61b9eSSebastian Pop APInt Remainder = ConstDelta.srem(RunningGCD);
241959b61b9eSSebastian Pop if (Remainder != 0) {
242059b61b9eSSebastian Pop ++GCDindependence;
242159b61b9eSSebastian Pop return true;
242259b61b9eSSebastian Pop }
242359b61b9eSSebastian Pop
242459b61b9eSSebastian Pop // Try to disprove equal directions.
242559b61b9eSSebastian Pop // For example, given a subscript pair [3*i + 2*j] and [i' + 2*j' - 1],
242659b61b9eSSebastian Pop // the code above can't disprove the dependence because the GCD = 1.
242759b61b9eSSebastian Pop // So we consider what happen if i = i' and what happens if j = j'.
242859b61b9eSSebastian Pop // If i = i', we can simplify the subscript to [2*i + 2*j] and [2*j' - 1],
242959b61b9eSSebastian Pop // which is infeasible, so we can disallow the = direction for the i level.
243059b61b9eSSebastian Pop // Setting j = j' doesn't help matters, so we end up with a direction vector
243159b61b9eSSebastian Pop // of [<>, *]
243259b61b9eSSebastian Pop //
243359b61b9eSSebastian Pop // Given A[5*i + 10*j*M + 9*M*N] and A[15*i + 20*j*M - 21*N*M + 5],
243459b61b9eSSebastian Pop // we need to remember that the constant part is 5 and the RunningGCD should
243559b61b9eSSebastian Pop // be initialized to ExtraGCD = 30.
2436d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " ExtraGCD = " << ExtraGCD << '\n');
243759b61b9eSSebastian Pop
243859b61b9eSSebastian Pop bool Improved = false;
243959b61b9eSSebastian Pop Coefficients = Src;
244059b61b9eSSebastian Pop while (const SCEVAddRecExpr *AddRec =
244159b61b9eSSebastian Pop dyn_cast<SCEVAddRecExpr>(Coefficients)) {
244259b61b9eSSebastian Pop Coefficients = AddRec->getStart();
244359b61b9eSSebastian Pop const Loop *CurLoop = AddRec->getLoop();
244459b61b9eSSebastian Pop RunningGCD = ExtraGCD;
244559b61b9eSSebastian Pop const SCEV *SrcCoeff = AddRec->getStepRecurrence(*SE);
244659b61b9eSSebastian Pop const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);
244759b61b9eSSebastian Pop const SCEV *Inner = Src;
244859b61b9eSSebastian Pop while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
244959b61b9eSSebastian Pop AddRec = cast<SCEVAddRecExpr>(Inner);
245059b61b9eSSebastian Pop const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
245159b61b9eSSebastian Pop if (CurLoop == AddRec->getLoop())
245259b61b9eSSebastian Pop ; // SrcCoeff == Coeff
245359b61b9eSSebastian Pop else {
245459b61b9eSSebastian Pop // If the coefficient is the product of a constant and other stuff,
245559b61b9eSSebastian Pop // we can use the constant in the GCD computation.
2456be2da82cSBrendon Cahoon Constant = getConstantPart(Coeff);
245786f783e3SBrendon Cahoon if (!Constant)
245886f783e3SBrendon Cahoon return false;
24590de2feceSSanjoy Das APInt ConstCoeff = Constant->getAPInt();
246059b61b9eSSebastian Pop RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
246159b61b9eSSebastian Pop }
246259b61b9eSSebastian Pop Inner = AddRec->getStart();
246359b61b9eSSebastian Pop }
246459b61b9eSSebastian Pop Inner = Dst;
246559b61b9eSSebastian Pop while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
246659b61b9eSSebastian Pop AddRec = cast<SCEVAddRecExpr>(Inner);
246759b61b9eSSebastian Pop const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
246859b61b9eSSebastian Pop if (CurLoop == AddRec->getLoop())
246959b61b9eSSebastian Pop DstCoeff = Coeff;
247059b61b9eSSebastian Pop else {
247159b61b9eSSebastian Pop // If the coefficient is the product of a constant and other stuff,
247259b61b9eSSebastian Pop // we can use the constant in the GCD computation.
2473be2da82cSBrendon Cahoon Constant = getConstantPart(Coeff);
247486f783e3SBrendon Cahoon if (!Constant)
247586f783e3SBrendon Cahoon return false;
24760de2feceSSanjoy Das APInt ConstCoeff = Constant->getAPInt();
247759b61b9eSSebastian Pop RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
247859b61b9eSSebastian Pop }
247959b61b9eSSebastian Pop Inner = AddRec->getStart();
248059b61b9eSSebastian Pop }
248159b61b9eSSebastian Pop Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
248259b61b9eSSebastian Pop // If the coefficient is the product of a constant and other stuff,
248359b61b9eSSebastian Pop // we can use the constant in the GCD computation.
2484be2da82cSBrendon Cahoon Constant = getConstantPart(Delta);
2485be2da82cSBrendon Cahoon if (!Constant)
248659b61b9eSSebastian Pop // The difference of the two coefficients might not be a product
248759b61b9eSSebastian Pop // or constant, in which case we give up on this direction.
248859b61b9eSSebastian Pop continue;
24890de2feceSSanjoy Das APInt ConstCoeff = Constant->getAPInt();
249059b61b9eSSebastian Pop RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff.abs());
2491d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tRunningGCD = " << RunningGCD << "\n");
249259b61b9eSSebastian Pop if (RunningGCD != 0) {
249359b61b9eSSebastian Pop Remainder = ConstDelta.srem(RunningGCD);
2494d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tRemainder = " << Remainder << "\n");
249559b61b9eSSebastian Pop if (Remainder != 0) {
249659b61b9eSSebastian Pop unsigned Level = mapSrcLoop(CurLoop);
2497e9623261SSebastian Pop Result.DV[Level - 1].Direction &= unsigned(~Dependence::DVEntry::EQ);
249859b61b9eSSebastian Pop Improved = true;
249959b61b9eSSebastian Pop }
250059b61b9eSSebastian Pop }
250159b61b9eSSebastian Pop }
250259b61b9eSSebastian Pop if (Improved)
250359b61b9eSSebastian Pop ++GCDsuccesses;
2504d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "all done\n");
250559b61b9eSSebastian Pop return false;
250659b61b9eSSebastian Pop }
250759b61b9eSSebastian Pop
250859b61b9eSSebastian Pop
250959b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
251059b61b9eSSebastian Pop // banerjeeMIVtest -
251159b61b9eSSebastian Pop // Use Banerjee's Inequalities to test an MIV subscript pair.
251259b61b9eSSebastian Pop // (Wolfe, in the race-car book, calls this the Extreme Value Test.)
251359b61b9eSSebastian Pop // Generally follows the discussion in Section 2.5.2 of
251459b61b9eSSebastian Pop //
251559b61b9eSSebastian Pop // Optimizing Supercompilers for Supercomputers
251659b61b9eSSebastian Pop // Michael Wolfe
251759b61b9eSSebastian Pop //
251859b61b9eSSebastian Pop // The inequalities given on page 25 are simplified in that loops are
251959b61b9eSSebastian Pop // normalized so that the lower bound is always 0 and the stride is always 1.
252059b61b9eSSebastian Pop // For example, Wolfe gives
252159b61b9eSSebastian Pop //
252259b61b9eSSebastian Pop // LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
252359b61b9eSSebastian Pop //
252459b61b9eSSebastian Pop // where A_k is the coefficient of the kth index in the source subscript,
252559b61b9eSSebastian Pop // B_k is the coefficient of the kth index in the destination subscript,
252659b61b9eSSebastian Pop // U_k is the upper bound of the kth index, L_k is the lower bound of the Kth
252759b61b9eSSebastian Pop // index, and N_k is the stride of the kth index. Since all loops are normalized
252859b61b9eSSebastian Pop // by the SCEV package, N_k = 1 and L_k = 0, allowing us to simplify the
252959b61b9eSSebastian Pop // equation to
253059b61b9eSSebastian Pop //
253159b61b9eSSebastian Pop // LB^<_k = (A^-_k - B_k)^- (U_k - 0 - 1) + (A_k - B_k)0 - B_k 1
253259b61b9eSSebastian Pop // = (A^-_k - B_k)^- (U_k - 1) - B_k
253359b61b9eSSebastian Pop //
253459b61b9eSSebastian Pop // Similar simplifications are possible for the other equations.
253559b61b9eSSebastian Pop //
253659b61b9eSSebastian Pop // When we can't determine the number of iterations for a loop,
253759b61b9eSSebastian Pop // we use NULL as an indicator for the worst case, infinity.
253859b61b9eSSebastian Pop // When computing the upper bound, NULL denotes +inf;
253959b61b9eSSebastian Pop // for the lower bound, NULL denotes -inf.
254059b61b9eSSebastian Pop //
254159b61b9eSSebastian Pop // Return true if dependence disproved.
banerjeeMIVtest(const SCEV * Src,const SCEV * Dst,const SmallBitVector & Loops,FullDependence & Result) const254249c22190SChandler Carruth bool DependenceInfo::banerjeeMIVtest(const SCEV *Src, const SCEV *Dst,
254359b61b9eSSebastian Pop const SmallBitVector &Loops,
254459b61b9eSSebastian Pop FullDependence &Result) const {
2545d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "starting Banerjee\n");
254659b61b9eSSebastian Pop ++BanerjeeApplications;
2547d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Src = " << *Src << '\n');
254859b61b9eSSebastian Pop const SCEV *A0;
25494ffafefdSDylan Noblesmith CoefficientInfo *A = collectCoeffInfo(Src, true, A0);
2550d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Dst = " << *Dst << '\n');
255159b61b9eSSebastian Pop const SCEV *B0;
25524ffafefdSDylan Noblesmith CoefficientInfo *B = collectCoeffInfo(Dst, false, B0);
25534ffafefdSDylan Noblesmith BoundInfo *Bound = new BoundInfo[MaxLevels + 1];
255459b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(B0, A0);
2555d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tDelta = " << *Delta << '\n');
255659b61b9eSSebastian Pop
255759b61b9eSSebastian Pop // Compute bounds for all the * directions.
2558d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tBounds[*]\n");
255959b61b9eSSebastian Pop for (unsigned K = 1; K <= MaxLevels; ++K) {
256059b61b9eSSebastian Pop Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
256159b61b9eSSebastian Pop Bound[K].Direction = Dependence::DVEntry::ALL;
256259b61b9eSSebastian Pop Bound[K].DirSet = Dependence::DVEntry::NONE;
256359b61b9eSSebastian Pop findBoundsALL(A, B, Bound, K);
256459b61b9eSSebastian Pop #ifndef NDEBUG
2565d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t " << K << '\t');
256659b61b9eSSebastian Pop if (Bound[K].Lower[Dependence::DVEntry::ALL])
2567d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[K].Lower[Dependence::DVEntry::ALL] << '\t');
256859b61b9eSSebastian Pop else
2569d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "-inf\t");
257059b61b9eSSebastian Pop if (Bound[K].Upper[Dependence::DVEntry::ALL])
2571d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[K].Upper[Dependence::DVEntry::ALL] << '\n');
257259b61b9eSSebastian Pop else
2573d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "+inf\n");
257459b61b9eSSebastian Pop #endif
257559b61b9eSSebastian Pop }
257659b61b9eSSebastian Pop
257759b61b9eSSebastian Pop // Test the *, *, *, ... case.
257859b61b9eSSebastian Pop bool Disproved = false;
257959b61b9eSSebastian Pop if (testBounds(Dependence::DVEntry::ALL, 0, Bound, Delta)) {
258059b61b9eSSebastian Pop // Explore the direction vector hierarchy.
258159b61b9eSSebastian Pop unsigned DepthExpanded = 0;
258259b61b9eSSebastian Pop unsigned NewDeps = exploreDirections(1, A, B, Bound,
258359b61b9eSSebastian Pop Loops, DepthExpanded, Delta);
258459b61b9eSSebastian Pop if (NewDeps > 0) {
258559b61b9eSSebastian Pop bool Improved = false;
258659b61b9eSSebastian Pop for (unsigned K = 1; K <= CommonLevels; ++K) {
258759b61b9eSSebastian Pop if (Loops[K]) {
258859b61b9eSSebastian Pop unsigned Old = Result.DV[K - 1].Direction;
258959b61b9eSSebastian Pop Result.DV[K - 1].Direction = Old & Bound[K].DirSet;
259059b61b9eSSebastian Pop Improved |= Old != Result.DV[K - 1].Direction;
259159b61b9eSSebastian Pop if (!Result.DV[K - 1].Direction) {
259259b61b9eSSebastian Pop Improved = false;
259359b61b9eSSebastian Pop Disproved = true;
259459b61b9eSSebastian Pop break;
259559b61b9eSSebastian Pop }
259659b61b9eSSebastian Pop }
259759b61b9eSSebastian Pop }
259859b61b9eSSebastian Pop if (Improved)
259959b61b9eSSebastian Pop ++BanerjeeSuccesses;
260059b61b9eSSebastian Pop }
260159b61b9eSSebastian Pop else {
260259b61b9eSSebastian Pop ++BanerjeeIndependence;
260359b61b9eSSebastian Pop Disproved = true;
260459b61b9eSSebastian Pop }
260559b61b9eSSebastian Pop }
260659b61b9eSSebastian Pop else {
260759b61b9eSSebastian Pop ++BanerjeeIndependence;
260859b61b9eSSebastian Pop Disproved = true;
260959b61b9eSSebastian Pop }
26104ffafefdSDylan Noblesmith delete [] Bound;
26114ffafefdSDylan Noblesmith delete [] A;
26124ffafefdSDylan Noblesmith delete [] B;
261359b61b9eSSebastian Pop return Disproved;
261459b61b9eSSebastian Pop }
261559b61b9eSSebastian Pop
261659b61b9eSSebastian Pop
261759b61b9eSSebastian Pop // Hierarchically expands the direction vector
261859b61b9eSSebastian Pop // search space, combining the directions of discovered dependences
261959b61b9eSSebastian Pop // in the DirSet field of Bound. Returns the number of distinct
262059b61b9eSSebastian Pop // dependences discovered. If the dependence is disproved,
262159b61b9eSSebastian Pop // it will return 0.
exploreDirections(unsigned Level,CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,const SmallBitVector & Loops,unsigned & DepthExpanded,const SCEV * Delta) const262249c22190SChandler Carruth unsigned DependenceInfo::exploreDirections(unsigned Level, CoefficientInfo *A,
262349c22190SChandler Carruth CoefficientInfo *B, BoundInfo *Bound,
262459b61b9eSSebastian Pop const SmallBitVector &Loops,
262559b61b9eSSebastian Pop unsigned &DepthExpanded,
262659b61b9eSSebastian Pop const SCEV *Delta) const {
26270e08891eSBardia Mahjour // This algorithm has worst case complexity of O(3^n), where 'n' is the number
26280e08891eSBardia Mahjour // of common loop levels. To avoid excessive compile-time, pessimize all the
26290e08891eSBardia Mahjour // results and immediately return when the number of common levels is beyond
26300e08891eSBardia Mahjour // the given threshold.
26310e08891eSBardia Mahjour if (CommonLevels > MIVMaxLevelThreshold) {
26320e08891eSBardia Mahjour LLVM_DEBUG(dbgs() << "Number of common levels exceeded the threshold. MIV "
26330e08891eSBardia Mahjour "direction exploration is terminated.\n");
26340e08891eSBardia Mahjour for (unsigned K = 1; K <= CommonLevels; ++K)
26350e08891eSBardia Mahjour if (Loops[K])
26360e08891eSBardia Mahjour Bound[K].DirSet = Dependence::DVEntry::ALL;
26370e08891eSBardia Mahjour return 1;
26380e08891eSBardia Mahjour }
26390e08891eSBardia Mahjour
264059b61b9eSSebastian Pop if (Level > CommonLevels) {
264159b61b9eSSebastian Pop // record result
2642d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t[");
264359b61b9eSSebastian Pop for (unsigned K = 1; K <= CommonLevels; ++K) {
264459b61b9eSSebastian Pop if (Loops[K]) {
264559b61b9eSSebastian Pop Bound[K].DirSet |= Bound[K].Direction;
264659b61b9eSSebastian Pop #ifndef NDEBUG
264759b61b9eSSebastian Pop switch (Bound[K].Direction) {
264859b61b9eSSebastian Pop case Dependence::DVEntry::LT:
2649d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " <");
265059b61b9eSSebastian Pop break;
265159b61b9eSSebastian Pop case Dependence::DVEntry::EQ:
2652d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " =");
265359b61b9eSSebastian Pop break;
265459b61b9eSSebastian Pop case Dependence::DVEntry::GT:
2655d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " >");
265659b61b9eSSebastian Pop break;
265759b61b9eSSebastian Pop case Dependence::DVEntry::ALL:
2658d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " *");
265959b61b9eSSebastian Pop break;
266059b61b9eSSebastian Pop default:
266159b61b9eSSebastian Pop llvm_unreachable("unexpected Bound[K].Direction");
266259b61b9eSSebastian Pop }
266359b61b9eSSebastian Pop #endif
266459b61b9eSSebastian Pop }
266559b61b9eSSebastian Pop }
2666d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " ]\n");
266759b61b9eSSebastian Pop return 1;
266859b61b9eSSebastian Pop }
266959b61b9eSSebastian Pop if (Loops[Level]) {
267059b61b9eSSebastian Pop if (Level > DepthExpanded) {
267159b61b9eSSebastian Pop DepthExpanded = Level;
267259b61b9eSSebastian Pop // compute bounds for <, =, > at current level
267359b61b9eSSebastian Pop findBoundsLT(A, B, Bound, Level);
267459b61b9eSSebastian Pop findBoundsGT(A, B, Bound, Level);
267559b61b9eSSebastian Pop findBoundsEQ(A, B, Bound, Level);
267659b61b9eSSebastian Pop #ifndef NDEBUG
2677d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tBound for level = " << Level << '\n');
2678d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t <\t");
267959b61b9eSSebastian Pop if (Bound[Level].Lower[Dependence::DVEntry::LT])
2680d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::LT]
2681d34e60caSNicola Zaghen << '\t');
268259b61b9eSSebastian Pop else
2683d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "-inf\t");
268459b61b9eSSebastian Pop if (Bound[Level].Upper[Dependence::DVEntry::LT])
2685d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::LT]
2686d34e60caSNicola Zaghen << '\n');
268759b61b9eSSebastian Pop else
2688d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "+inf\n");
2689d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t =\t");
269059b61b9eSSebastian Pop if (Bound[Level].Lower[Dependence::DVEntry::EQ])
2691d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::EQ]
2692d34e60caSNicola Zaghen << '\t');
269359b61b9eSSebastian Pop else
2694d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "-inf\t");
269559b61b9eSSebastian Pop if (Bound[Level].Upper[Dependence::DVEntry::EQ])
2696d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::EQ]
2697d34e60caSNicola Zaghen << '\n');
269859b61b9eSSebastian Pop else
2699d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "+inf\n");
2700d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t >\t");
270159b61b9eSSebastian Pop if (Bound[Level].Lower[Dependence::DVEntry::GT])
2702d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::GT]
2703d34e60caSNicola Zaghen << '\t');
270459b61b9eSSebastian Pop else
2705d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "-inf\t");
270659b61b9eSSebastian Pop if (Bound[Level].Upper[Dependence::DVEntry::GT])
2707d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::GT]
2708d34e60caSNicola Zaghen << '\n');
270959b61b9eSSebastian Pop else
2710d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "+inf\n");
271159b61b9eSSebastian Pop #endif
271259b61b9eSSebastian Pop }
271359b61b9eSSebastian Pop
271459b61b9eSSebastian Pop unsigned NewDeps = 0;
271559b61b9eSSebastian Pop
271659b61b9eSSebastian Pop // test bounds for <, *, *, ...
271759b61b9eSSebastian Pop if (testBounds(Dependence::DVEntry::LT, Level, Bound, Delta))
271859b61b9eSSebastian Pop NewDeps += exploreDirections(Level + 1, A, B, Bound,
271959b61b9eSSebastian Pop Loops, DepthExpanded, Delta);
272059b61b9eSSebastian Pop
272159b61b9eSSebastian Pop // Test bounds for =, *, *, ...
272259b61b9eSSebastian Pop if (testBounds(Dependence::DVEntry::EQ, Level, Bound, Delta))
272359b61b9eSSebastian Pop NewDeps += exploreDirections(Level + 1, A, B, Bound,
272459b61b9eSSebastian Pop Loops, DepthExpanded, Delta);
272559b61b9eSSebastian Pop
272659b61b9eSSebastian Pop // test bounds for >, *, *, ...
272759b61b9eSSebastian Pop if (testBounds(Dependence::DVEntry::GT, Level, Bound, Delta))
272859b61b9eSSebastian Pop NewDeps += exploreDirections(Level + 1, A, B, Bound,
272959b61b9eSSebastian Pop Loops, DepthExpanded, Delta);
273059b61b9eSSebastian Pop
273159b61b9eSSebastian Pop Bound[Level].Direction = Dependence::DVEntry::ALL;
273259b61b9eSSebastian Pop return NewDeps;
273359b61b9eSSebastian Pop }
273459b61b9eSSebastian Pop else
273559b61b9eSSebastian Pop return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded, Delta);
273659b61b9eSSebastian Pop }
273759b61b9eSSebastian Pop
273859b61b9eSSebastian Pop
273959b61b9eSSebastian Pop // Returns true iff the current bounds are plausible.
testBounds(unsigned char DirKind,unsigned Level,BoundInfo * Bound,const SCEV * Delta) const274049c22190SChandler Carruth bool DependenceInfo::testBounds(unsigned char DirKind, unsigned Level,
274149c22190SChandler Carruth BoundInfo *Bound, const SCEV *Delta) const {
274259b61b9eSSebastian Pop Bound[Level].Direction = DirKind;
274359b61b9eSSebastian Pop if (const SCEV *LowerBound = getLowerBound(Bound))
274459b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, LowerBound, Delta))
274559b61b9eSSebastian Pop return false;
274659b61b9eSSebastian Pop if (const SCEV *UpperBound = getUpperBound(Bound))
274759b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, UpperBound))
274859b61b9eSSebastian Pop return false;
274959b61b9eSSebastian Pop return true;
275059b61b9eSSebastian Pop }
275159b61b9eSSebastian Pop
275259b61b9eSSebastian Pop
275359b61b9eSSebastian Pop // Computes the upper and lower bounds for level K
275459b61b9eSSebastian Pop // using the * direction. Records them in Bound.
275559b61b9eSSebastian Pop // Wolfe gives the equations
275659b61b9eSSebastian Pop //
275759b61b9eSSebastian Pop // LB^*_k = (A^-_k - B^+_k)(U_k - L_k) + (A_k - B_k)L_k
275859b61b9eSSebastian Pop // UB^*_k = (A^+_k - B^-_k)(U_k - L_k) + (A_k - B_k)L_k
275959b61b9eSSebastian Pop //
276059b61b9eSSebastian Pop // Since we normalize loops, we can simplify these equations to
276159b61b9eSSebastian Pop //
276259b61b9eSSebastian Pop // LB^*_k = (A^-_k - B^+_k)U_k
276359b61b9eSSebastian Pop // UB^*_k = (A^+_k - B^-_k)U_k
276459b61b9eSSebastian Pop //
276559b61b9eSSebastian Pop // We must be careful to handle the case where the upper bound is unknown.
276659b61b9eSSebastian Pop // Note that the lower bound is always <= 0
276759b61b9eSSebastian Pop // and the upper bound is always >= 0.
findBoundsALL(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const276849c22190SChandler Carruth void DependenceInfo::findBoundsALL(CoefficientInfo *A, CoefficientInfo *B,
276949c22190SChandler Carruth BoundInfo *Bound, unsigned K) const {
27709f008867SCraig Topper Bound[K].Lower[Dependence::DVEntry::ALL] = nullptr; // Default value = -infinity.
27719f008867SCraig Topper Bound[K].Upper[Dependence::DVEntry::ALL] = nullptr; // Default value = +infinity.
277259b61b9eSSebastian Pop if (Bound[K].Iterations) {
277359b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::ALL] =
277459b61b9eSSebastian Pop SE->getMulExpr(SE->getMinusSCEV(A[K].NegPart, B[K].PosPart),
277559b61b9eSSebastian Pop Bound[K].Iterations);
277659b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::ALL] =
277759b61b9eSSebastian Pop SE->getMulExpr(SE->getMinusSCEV(A[K].PosPart, B[K].NegPart),
277859b61b9eSSebastian Pop Bound[K].Iterations);
277959b61b9eSSebastian Pop }
278059b61b9eSSebastian Pop else {
278159b61b9eSSebastian Pop // If the difference is 0, we won't need to know the number of iterations.
278259b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].NegPart, B[K].PosPart))
278359b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::ALL] =
27842aacc0ecSSanjoy Das SE->getZero(A[K].Coeff->getType());
278559b61b9eSSebastian Pop if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].PosPart, B[K].NegPart))
278659b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::ALL] =
27872aacc0ecSSanjoy Das SE->getZero(A[K].Coeff->getType());
278859b61b9eSSebastian Pop }
278959b61b9eSSebastian Pop }
279059b61b9eSSebastian Pop
279159b61b9eSSebastian Pop
279259b61b9eSSebastian Pop // Computes the upper and lower bounds for level K
279359b61b9eSSebastian Pop // using the = direction. Records them in Bound.
279459b61b9eSSebastian Pop // Wolfe gives the equations
279559b61b9eSSebastian Pop //
279659b61b9eSSebastian Pop // LB^=_k = (A_k - B_k)^- (U_k - L_k) + (A_k - B_k)L_k
279759b61b9eSSebastian Pop // UB^=_k = (A_k - B_k)^+ (U_k - L_k) + (A_k - B_k)L_k
279859b61b9eSSebastian Pop //
279959b61b9eSSebastian Pop // Since we normalize loops, we can simplify these equations to
280059b61b9eSSebastian Pop //
280159b61b9eSSebastian Pop // LB^=_k = (A_k - B_k)^- U_k
280259b61b9eSSebastian Pop // UB^=_k = (A_k - B_k)^+ U_k
280359b61b9eSSebastian Pop //
280459b61b9eSSebastian Pop // We must be careful to handle the case where the upper bound is unknown.
280559b61b9eSSebastian Pop // Note that the lower bound is always <= 0
280659b61b9eSSebastian Pop // and the upper bound is always >= 0.
findBoundsEQ(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const280749c22190SChandler Carruth void DependenceInfo::findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B,
280849c22190SChandler Carruth BoundInfo *Bound, unsigned K) const {
28099f008867SCraig Topper Bound[K].Lower[Dependence::DVEntry::EQ] = nullptr; // Default value = -infinity.
28109f008867SCraig Topper Bound[K].Upper[Dependence::DVEntry::EQ] = nullptr; // Default value = +infinity.
281159b61b9eSSebastian Pop if (Bound[K].Iterations) {
281259b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
281359b61b9eSSebastian Pop const SCEV *NegativePart = getNegativePart(Delta);
281459b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::EQ] =
281559b61b9eSSebastian Pop SE->getMulExpr(NegativePart, Bound[K].Iterations);
281659b61b9eSSebastian Pop const SCEV *PositivePart = getPositivePart(Delta);
281759b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::EQ] =
281859b61b9eSSebastian Pop SE->getMulExpr(PositivePart, Bound[K].Iterations);
281959b61b9eSSebastian Pop }
282059b61b9eSSebastian Pop else {
282159b61b9eSSebastian Pop // If the positive/negative part of the difference is 0,
282259b61b9eSSebastian Pop // we won't need to know the number of iterations.
282359b61b9eSSebastian Pop const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
282459b61b9eSSebastian Pop const SCEV *NegativePart = getNegativePart(Delta);
282559b61b9eSSebastian Pop if (NegativePart->isZero())
282659b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::EQ] = NegativePart; // Zero
282759b61b9eSSebastian Pop const SCEV *PositivePart = getPositivePart(Delta);
282859b61b9eSSebastian Pop if (PositivePart->isZero())
282959b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::EQ] = PositivePart; // Zero
283059b61b9eSSebastian Pop }
283159b61b9eSSebastian Pop }
283259b61b9eSSebastian Pop
283359b61b9eSSebastian Pop
283459b61b9eSSebastian Pop // Computes the upper and lower bounds for level K
283559b61b9eSSebastian Pop // using the < direction. Records them in Bound.
283659b61b9eSSebastian Pop // Wolfe gives the equations
283759b61b9eSSebastian Pop //
283859b61b9eSSebastian Pop // LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
283959b61b9eSSebastian Pop // UB^<_k = (A^+_k - B_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
284059b61b9eSSebastian Pop //
284159b61b9eSSebastian Pop // Since we normalize loops, we can simplify these equations to
284259b61b9eSSebastian Pop //
284359b61b9eSSebastian Pop // LB^<_k = (A^-_k - B_k)^- (U_k - 1) - B_k
284459b61b9eSSebastian Pop // UB^<_k = (A^+_k - B_k)^+ (U_k - 1) - B_k
284559b61b9eSSebastian Pop //
284659b61b9eSSebastian Pop // We must be careful to handle the case where the upper bound is unknown.
findBoundsLT(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const284749c22190SChandler Carruth void DependenceInfo::findBoundsLT(CoefficientInfo *A, CoefficientInfo *B,
284849c22190SChandler Carruth BoundInfo *Bound, unsigned K) const {
28499f008867SCraig Topper Bound[K].Lower[Dependence::DVEntry::LT] = nullptr; // Default value = -infinity.
28509f008867SCraig Topper Bound[K].Upper[Dependence::DVEntry::LT] = nullptr; // Default value = +infinity.
285159b61b9eSSebastian Pop if (Bound[K].Iterations) {
28522aacc0ecSSanjoy Das const SCEV *Iter_1 = SE->getMinusSCEV(
28532aacc0ecSSanjoy Das Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
285459b61b9eSSebastian Pop const SCEV *NegPart =
285559b61b9eSSebastian Pop getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
285659b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::LT] =
285759b61b9eSSebastian Pop SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1), B[K].Coeff);
285859b61b9eSSebastian Pop const SCEV *PosPart =
285959b61b9eSSebastian Pop getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
286059b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::LT] =
286159b61b9eSSebastian Pop SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1), B[K].Coeff);
286259b61b9eSSebastian Pop }
286359b61b9eSSebastian Pop else {
286459b61b9eSSebastian Pop // If the positive/negative part of the difference is 0,
286559b61b9eSSebastian Pop // we won't need to know the number of iterations.
286659b61b9eSSebastian Pop const SCEV *NegPart =
286759b61b9eSSebastian Pop getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
286859b61b9eSSebastian Pop if (NegPart->isZero())
286959b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
287059b61b9eSSebastian Pop const SCEV *PosPart =
287159b61b9eSSebastian Pop getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
287259b61b9eSSebastian Pop if (PosPart->isZero())
287359b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
287459b61b9eSSebastian Pop }
287559b61b9eSSebastian Pop }
287659b61b9eSSebastian Pop
287759b61b9eSSebastian Pop
287859b61b9eSSebastian Pop // Computes the upper and lower bounds for level K
287959b61b9eSSebastian Pop // using the > direction. Records them in Bound.
288059b61b9eSSebastian Pop // Wolfe gives the equations
288159b61b9eSSebastian Pop //
288259b61b9eSSebastian Pop // LB^>_k = (A_k - B^+_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
288359b61b9eSSebastian Pop // UB^>_k = (A_k - B^-_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
288459b61b9eSSebastian Pop //
288559b61b9eSSebastian Pop // Since we normalize loops, we can simplify these equations to
288659b61b9eSSebastian Pop //
288759b61b9eSSebastian Pop // LB^>_k = (A_k - B^+_k)^- (U_k - 1) + A_k
288859b61b9eSSebastian Pop // UB^>_k = (A_k - B^-_k)^+ (U_k - 1) + A_k
288959b61b9eSSebastian Pop //
289059b61b9eSSebastian Pop // We must be careful to handle the case where the upper bound is unknown.
findBoundsGT(CoefficientInfo * A,CoefficientInfo * B,BoundInfo * Bound,unsigned K) const289149c22190SChandler Carruth void DependenceInfo::findBoundsGT(CoefficientInfo *A, CoefficientInfo *B,
289249c22190SChandler Carruth BoundInfo *Bound, unsigned K) const {
28939f008867SCraig Topper Bound[K].Lower[Dependence::DVEntry::GT] = nullptr; // Default value = -infinity.
28949f008867SCraig Topper Bound[K].Upper[Dependence::DVEntry::GT] = nullptr; // Default value = +infinity.
289559b61b9eSSebastian Pop if (Bound[K].Iterations) {
28962aacc0ecSSanjoy Das const SCEV *Iter_1 = SE->getMinusSCEV(
28972aacc0ecSSanjoy Das Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
289859b61b9eSSebastian Pop const SCEV *NegPart =
289959b61b9eSSebastian Pop getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
290059b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::GT] =
290159b61b9eSSebastian Pop SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1), A[K].Coeff);
290259b61b9eSSebastian Pop const SCEV *PosPart =
290359b61b9eSSebastian Pop getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
290459b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::GT] =
290559b61b9eSSebastian Pop SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1), A[K].Coeff);
290659b61b9eSSebastian Pop }
290759b61b9eSSebastian Pop else {
290859b61b9eSSebastian Pop // If the positive/negative part of the difference is 0,
290959b61b9eSSebastian Pop // we won't need to know the number of iterations.
291059b61b9eSSebastian Pop const SCEV *NegPart = getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
291159b61b9eSSebastian Pop if (NegPart->isZero())
291259b61b9eSSebastian Pop Bound[K].Lower[Dependence::DVEntry::GT] = A[K].Coeff;
291359b61b9eSSebastian Pop const SCEV *PosPart = getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
291459b61b9eSSebastian Pop if (PosPart->isZero())
291559b61b9eSSebastian Pop Bound[K].Upper[Dependence::DVEntry::GT] = A[K].Coeff;
291659b61b9eSSebastian Pop }
291759b61b9eSSebastian Pop }
291859b61b9eSSebastian Pop
291959b61b9eSSebastian Pop
292059b61b9eSSebastian Pop // X^+ = max(X, 0)
getPositivePart(const SCEV * X) const292149c22190SChandler Carruth const SCEV *DependenceInfo::getPositivePart(const SCEV *X) const {
29222aacc0ecSSanjoy Das return SE->getSMaxExpr(X, SE->getZero(X->getType()));
292359b61b9eSSebastian Pop }
292459b61b9eSSebastian Pop
292559b61b9eSSebastian Pop
292659b61b9eSSebastian Pop // X^- = min(X, 0)
getNegativePart(const SCEV * X) const292749c22190SChandler Carruth const SCEV *DependenceInfo::getNegativePart(const SCEV *X) const {
29282aacc0ecSSanjoy Das return SE->getSMinExpr(X, SE->getZero(X->getType()));
292959b61b9eSSebastian Pop }
293059b61b9eSSebastian Pop
293159b61b9eSSebastian Pop
293259b61b9eSSebastian Pop // Walks through the subscript,
293359b61b9eSSebastian Pop // collecting each coefficient, the associated loop bounds,
293459b61b9eSSebastian Pop // and recording its positive and negative parts for later use.
293549c22190SChandler Carruth DependenceInfo::CoefficientInfo *
collectCoeffInfo(const SCEV * Subscript,bool SrcFlag,const SCEV * & Constant) const293649c22190SChandler Carruth DependenceInfo::collectCoeffInfo(const SCEV *Subscript, bool SrcFlag,
293759b61b9eSSebastian Pop const SCEV *&Constant) const {
29382aacc0ecSSanjoy Das const SCEV *Zero = SE->getZero(Subscript->getType());
29394ffafefdSDylan Noblesmith CoefficientInfo *CI = new CoefficientInfo[MaxLevels + 1];
294059b61b9eSSebastian Pop for (unsigned K = 1; K <= MaxLevels; ++K) {
294159b61b9eSSebastian Pop CI[K].Coeff = Zero;
294259b61b9eSSebastian Pop CI[K].PosPart = Zero;
294359b61b9eSSebastian Pop CI[K].NegPart = Zero;
29449f008867SCraig Topper CI[K].Iterations = nullptr;
294559b61b9eSSebastian Pop }
294659b61b9eSSebastian Pop while (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
294759b61b9eSSebastian Pop const Loop *L = AddRec->getLoop();
294859b61b9eSSebastian Pop unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
294959b61b9eSSebastian Pop CI[K].Coeff = AddRec->getStepRecurrence(*SE);
295059b61b9eSSebastian Pop CI[K].PosPart = getPositivePart(CI[K].Coeff);
295159b61b9eSSebastian Pop CI[K].NegPart = getNegativePart(CI[K].Coeff);
295259b61b9eSSebastian Pop CI[K].Iterations = collectUpperBound(L, Subscript->getType());
295359b61b9eSSebastian Pop Subscript = AddRec->getStart();
295459b61b9eSSebastian Pop }
295559b61b9eSSebastian Pop Constant = Subscript;
295659b61b9eSSebastian Pop #ifndef NDEBUG
2957d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tCoefficient Info\n");
295859b61b9eSSebastian Pop for (unsigned K = 1; K <= MaxLevels; ++K) {
2959d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t " << K << "\t" << *CI[K].Coeff);
2960d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tPos Part = ");
2961d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *CI[K].PosPart);
2962d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tNeg Part = ");
2963d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *CI[K].NegPart);
2964d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tUpper Bound = ");
296559b61b9eSSebastian Pop if (CI[K].Iterations)
2966d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << *CI[K].Iterations);
296759b61b9eSSebastian Pop else
2968d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "+inf");
2969d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << '\n');
297059b61b9eSSebastian Pop }
2971d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Constant = " << *Subscript << '\n');
297259b61b9eSSebastian Pop #endif
297359b61b9eSSebastian Pop return CI;
297459b61b9eSSebastian Pop }
297559b61b9eSSebastian Pop
297659b61b9eSSebastian Pop
297759b61b9eSSebastian Pop // Looks through all the bounds info and
297859b61b9eSSebastian Pop // computes the lower bound given the current direction settings
297959b61b9eSSebastian Pop // at each level. If the lower bound for any level is -inf,
298059b61b9eSSebastian Pop // the result is -inf.
getLowerBound(BoundInfo * Bound) const298149c22190SChandler Carruth const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound) const {
298259b61b9eSSebastian Pop const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
298359b61b9eSSebastian Pop for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
298459b61b9eSSebastian Pop if (Bound[K].Lower[Bound[K].Direction])
298559b61b9eSSebastian Pop Sum = SE->getAddExpr(Sum, Bound[K].Lower[Bound[K].Direction]);
298659b61b9eSSebastian Pop else
29879f008867SCraig Topper Sum = nullptr;
298859b61b9eSSebastian Pop }
298959b61b9eSSebastian Pop return Sum;
299059b61b9eSSebastian Pop }
299159b61b9eSSebastian Pop
299259b61b9eSSebastian Pop
299359b61b9eSSebastian Pop // Looks through all the bounds info and
299459b61b9eSSebastian Pop // computes the upper bound given the current direction settings
299559b61b9eSSebastian Pop // at each level. If the upper bound at any level is +inf,
299659b61b9eSSebastian Pop // the result is +inf.
getUpperBound(BoundInfo * Bound) const299749c22190SChandler Carruth const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound) const {
299859b61b9eSSebastian Pop const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
299959b61b9eSSebastian Pop for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
300059b61b9eSSebastian Pop if (Bound[K].Upper[Bound[K].Direction])
300159b61b9eSSebastian Pop Sum = SE->getAddExpr(Sum, Bound[K].Upper[Bound[K].Direction]);
300259b61b9eSSebastian Pop else
30039f008867SCraig Topper Sum = nullptr;
300459b61b9eSSebastian Pop }
300559b61b9eSSebastian Pop return Sum;
300659b61b9eSSebastian Pop }
300759b61b9eSSebastian Pop
300859b61b9eSSebastian Pop
300959b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
301059b61b9eSSebastian Pop // Constraint manipulation for Delta test.
301159b61b9eSSebastian Pop
301259b61b9eSSebastian Pop // Given a linear SCEV,
301359b61b9eSSebastian Pop // return the coefficient (the step)
301459b61b9eSSebastian Pop // corresponding to the specified loop.
301559b61b9eSSebastian Pop // If there isn't one, return 0.
3016a84feb17SJingyue Wu // For example, given a*i + b*j + c*k, finding the coefficient
301759b61b9eSSebastian Pop // corresponding to the j loop would yield b.
findCoefficient(const SCEV * Expr,const Loop * TargetLoop) const301849c22190SChandler Carruth const SCEV *DependenceInfo::findCoefficient(const SCEV *Expr,
301959b61b9eSSebastian Pop const Loop *TargetLoop) const {
302059b61b9eSSebastian Pop const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
302159b61b9eSSebastian Pop if (!AddRec)
30222aacc0ecSSanjoy Das return SE->getZero(Expr->getType());
302359b61b9eSSebastian Pop if (AddRec->getLoop() == TargetLoop)
302459b61b9eSSebastian Pop return AddRec->getStepRecurrence(*SE);
302559b61b9eSSebastian Pop return findCoefficient(AddRec->getStart(), TargetLoop);
302659b61b9eSSebastian Pop }
302759b61b9eSSebastian Pop
302859b61b9eSSebastian Pop
302959b61b9eSSebastian Pop // Given a linear SCEV,
303059b61b9eSSebastian Pop // return the SCEV given by zeroing out the coefficient
303159b61b9eSSebastian Pop // corresponding to the specified loop.
303259b61b9eSSebastian Pop // For example, given a*i + b*j + c*k, zeroing the coefficient
303359b61b9eSSebastian Pop // corresponding to the j loop would yield a*i + c*k.
zeroCoefficient(const SCEV * Expr,const Loop * TargetLoop) const303449c22190SChandler Carruth const SCEV *DependenceInfo::zeroCoefficient(const SCEV *Expr,
303559b61b9eSSebastian Pop const Loop *TargetLoop) const {
303659b61b9eSSebastian Pop const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
303759b61b9eSSebastian Pop if (!AddRec)
303859b61b9eSSebastian Pop return Expr; // ignore
303959b61b9eSSebastian Pop if (AddRec->getLoop() == TargetLoop)
304059b61b9eSSebastian Pop return AddRec->getStart();
304159b61b9eSSebastian Pop return SE->getAddRecExpr(zeroCoefficient(AddRec->getStart(), TargetLoop),
304259b61b9eSSebastian Pop AddRec->getStepRecurrence(*SE),
304359b61b9eSSebastian Pop AddRec->getLoop(),
304459b61b9eSSebastian Pop AddRec->getNoWrapFlags());
304559b61b9eSSebastian Pop }
304659b61b9eSSebastian Pop
304759b61b9eSSebastian Pop
304859b61b9eSSebastian Pop // Given a linear SCEV Expr,
304959b61b9eSSebastian Pop // return the SCEV given by adding some Value to the
305059b61b9eSSebastian Pop // coefficient corresponding to the specified TargetLoop.
305159b61b9eSSebastian Pop // For example, given a*i + b*j + c*k, adding 1 to the coefficient
305259b61b9eSSebastian Pop // corresponding to the j loop would yield a*i + (b+1)*j + c*k.
addToCoefficient(const SCEV * Expr,const Loop * TargetLoop,const SCEV * Value) const305349c22190SChandler Carruth const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
305459b61b9eSSebastian Pop const Loop *TargetLoop,
305559b61b9eSSebastian Pop const SCEV *Value) const {
305659b61b9eSSebastian Pop const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
305759b61b9eSSebastian Pop if (!AddRec) // create a new addRec
305859b61b9eSSebastian Pop return SE->getAddRecExpr(Expr,
305959b61b9eSSebastian Pop Value,
306059b61b9eSSebastian Pop TargetLoop,
306159b61b9eSSebastian Pop SCEV::FlagAnyWrap); // Worst case, with no info.
306259b61b9eSSebastian Pop if (AddRec->getLoop() == TargetLoop) {
306359b61b9eSSebastian Pop const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
306459b61b9eSSebastian Pop if (Sum->isZero())
306559b61b9eSSebastian Pop return AddRec->getStart();
306659b61b9eSSebastian Pop return SE->getAddRecExpr(AddRec->getStart(),
306759b61b9eSSebastian Pop Sum,
306859b61b9eSSebastian Pop AddRec->getLoop(),
306959b61b9eSSebastian Pop AddRec->getNoWrapFlags());
307059b61b9eSSebastian Pop }
30716c286b60SPreston Briggs if (SE->isLoopInvariant(AddRec, TargetLoop))
3072d0e13af2SNAKAMURA Takumi return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
3073d0e13af2SNAKAMURA Takumi return SE->getAddRecExpr(
3074d0e13af2SNAKAMURA Takumi addToCoefficient(AddRec->getStart(), TargetLoop, Value),
3075d0e13af2SNAKAMURA Takumi AddRec->getStepRecurrence(*SE), AddRec->getLoop(),
307659b61b9eSSebastian Pop AddRec->getNoWrapFlags());
307759b61b9eSSebastian Pop }
307859b61b9eSSebastian Pop
307959b61b9eSSebastian Pop
308059b61b9eSSebastian Pop // Review the constraints, looking for opportunities
308159b61b9eSSebastian Pop // to simplify a subscript pair (Src and Dst).
308259b61b9eSSebastian Pop // Return true if some simplification occurs.
308359b61b9eSSebastian Pop // If the simplification isn't exact (that is, if it is conservative
308459b61b9eSSebastian Pop // in terms of dependence), set consistent to false.
308559b61b9eSSebastian Pop // Corresponds to Figure 5 from the paper
308659b61b9eSSebastian Pop //
308759b61b9eSSebastian Pop // Practical Dependence Testing
308859b61b9eSSebastian Pop // Goff, Kennedy, Tseng
308959b61b9eSSebastian Pop // PLDI 1991
propagate(const SCEV * & Src,const SCEV * & Dst,SmallBitVector & Loops,SmallVectorImpl<Constraint> & Constraints,bool & Consistent)309049c22190SChandler Carruth bool DependenceInfo::propagate(const SCEV *&Src, const SCEV *&Dst,
309159b61b9eSSebastian Pop SmallBitVector &Loops,
3092b94011fdSCraig Topper SmallVectorImpl<Constraint> &Constraints,
309359b61b9eSSebastian Pop bool &Consistent) {
309459b61b9eSSebastian Pop bool Result = false;
3095b52e0366SFrancis Visoiu Mistrih for (unsigned LI : Loops.set_bits()) {
3096d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Constraint[" << LI << "] is");
3097d34e60caSNicola Zaghen LLVM_DEBUG(Constraints[LI].dump(dbgs()));
309859b61b9eSSebastian Pop if (Constraints[LI].isDistance())
309959b61b9eSSebastian Pop Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
310059b61b9eSSebastian Pop else if (Constraints[LI].isLine())
310159b61b9eSSebastian Pop Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
310259b61b9eSSebastian Pop else if (Constraints[LI].isPoint())
310359b61b9eSSebastian Pop Result |= propagatePoint(Src, Dst, Constraints[LI]);
310459b61b9eSSebastian Pop }
310559b61b9eSSebastian Pop return Result;
310659b61b9eSSebastian Pop }
310759b61b9eSSebastian Pop
310859b61b9eSSebastian Pop
310959b61b9eSSebastian Pop // Attempt to propagate a distance
311059b61b9eSSebastian Pop // constraint into a subscript pair (Src and Dst).
311159b61b9eSSebastian Pop // Return true if some simplification occurs.
311259b61b9eSSebastian Pop // If the simplification isn't exact (that is, if it is conservative
311359b61b9eSSebastian Pop // in terms of dependence), set consistent to false.
propagateDistance(const SCEV * & Src,const SCEV * & Dst,Constraint & CurConstraint,bool & Consistent)311449c22190SChandler Carruth bool DependenceInfo::propagateDistance(const SCEV *&Src, const SCEV *&Dst,
311559b61b9eSSebastian Pop Constraint &CurConstraint,
311659b61b9eSSebastian Pop bool &Consistent) {
311759b61b9eSSebastian Pop const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3118d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
311959b61b9eSSebastian Pop const SCEV *A_K = findCoefficient(Src, CurLoop);
312059b61b9eSSebastian Pop if (A_K->isZero())
312159b61b9eSSebastian Pop return false;
312259b61b9eSSebastian Pop const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
312359b61b9eSSebastian Pop Src = SE->getMinusSCEV(Src, DA_K);
312459b61b9eSSebastian Pop Src = zeroCoefficient(Src, CurLoop);
3125d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
3126d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
312759b61b9eSSebastian Pop Dst = addToCoefficient(Dst, CurLoop, SE->getNegativeSCEV(A_K));
3128d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
312959b61b9eSSebastian Pop if (!findCoefficient(Dst, CurLoop)->isZero())
313059b61b9eSSebastian Pop Consistent = false;
313159b61b9eSSebastian Pop return true;
313259b61b9eSSebastian Pop }
313359b61b9eSSebastian Pop
313459b61b9eSSebastian Pop
313559b61b9eSSebastian Pop // Attempt to propagate a line
313659b61b9eSSebastian Pop // constraint into a subscript pair (Src and Dst).
313759b61b9eSSebastian Pop // Return true if some simplification occurs.
313859b61b9eSSebastian Pop // If the simplification isn't exact (that is, if it is conservative
313959b61b9eSSebastian Pop // in terms of dependence), set consistent to false.
propagateLine(const SCEV * & Src,const SCEV * & Dst,Constraint & CurConstraint,bool & Consistent)314049c22190SChandler Carruth bool DependenceInfo::propagateLine(const SCEV *&Src, const SCEV *&Dst,
314159b61b9eSSebastian Pop Constraint &CurConstraint,
314259b61b9eSSebastian Pop bool &Consistent) {
314359b61b9eSSebastian Pop const Loop *CurLoop = CurConstraint.getAssociatedLoop();
314459b61b9eSSebastian Pop const SCEV *A = CurConstraint.getA();
314559b61b9eSSebastian Pop const SCEV *B = CurConstraint.getB();
314659b61b9eSSebastian Pop const SCEV *C = CurConstraint.getC();
3147d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tA = " << *A << ", B = " << *B << ", C = " << *C
3148d34e60caSNicola Zaghen << "\n");
3149d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tSrc = " << *Src << "\n");
3150d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tDst = " << *Dst << "\n");
315159b61b9eSSebastian Pop if (A->isZero()) {
315259b61b9eSSebastian Pop const SCEVConstant *Bconst = dyn_cast<SCEVConstant>(B);
315359b61b9eSSebastian Pop const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
315459b61b9eSSebastian Pop if (!Bconst || !Cconst) return false;
31550de2feceSSanjoy Das APInt Beta = Bconst->getAPInt();
31560de2feceSSanjoy Das APInt Charlie = Cconst->getAPInt();
315759b61b9eSSebastian Pop APInt CdivB = Charlie.sdiv(Beta);
315859b61b9eSSebastian Pop assert(Charlie.srem(Beta) == 0 && "C should be evenly divisible by B");
315959b61b9eSSebastian Pop const SCEV *AP_K = findCoefficient(Dst, CurLoop);
316059b61b9eSSebastian Pop // Src = SE->getAddExpr(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
316159b61b9eSSebastian Pop Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
316259b61b9eSSebastian Pop Dst = zeroCoefficient(Dst, CurLoop);
316359b61b9eSSebastian Pop if (!findCoefficient(Src, CurLoop)->isZero())
316459b61b9eSSebastian Pop Consistent = false;
316559b61b9eSSebastian Pop }
316659b61b9eSSebastian Pop else if (B->isZero()) {
316759b61b9eSSebastian Pop const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
316859b61b9eSSebastian Pop const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
316959b61b9eSSebastian Pop if (!Aconst || !Cconst) return false;
31700de2feceSSanjoy Das APInt Alpha = Aconst->getAPInt();
31710de2feceSSanjoy Das APInt Charlie = Cconst->getAPInt();
317259b61b9eSSebastian Pop APInt CdivA = Charlie.sdiv(Alpha);
317359b61b9eSSebastian Pop assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
317459b61b9eSSebastian Pop const SCEV *A_K = findCoefficient(Src, CurLoop);
317559b61b9eSSebastian Pop Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
317659b61b9eSSebastian Pop Src = zeroCoefficient(Src, CurLoop);
317759b61b9eSSebastian Pop if (!findCoefficient(Dst, CurLoop)->isZero())
317859b61b9eSSebastian Pop Consistent = false;
317959b61b9eSSebastian Pop }
318059b61b9eSSebastian Pop else if (isKnownPredicate(CmpInst::ICMP_EQ, A, B)) {
318159b61b9eSSebastian Pop const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
318259b61b9eSSebastian Pop const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
318359b61b9eSSebastian Pop if (!Aconst || !Cconst) return false;
31840de2feceSSanjoy Das APInt Alpha = Aconst->getAPInt();
31850de2feceSSanjoy Das APInt Charlie = Cconst->getAPInt();
318659b61b9eSSebastian Pop APInt CdivA = Charlie.sdiv(Alpha);
318759b61b9eSSebastian Pop assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
318859b61b9eSSebastian Pop const SCEV *A_K = findCoefficient(Src, CurLoop);
318959b61b9eSSebastian Pop Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
319059b61b9eSSebastian Pop Src = zeroCoefficient(Src, CurLoop);
319159b61b9eSSebastian Pop Dst = addToCoefficient(Dst, CurLoop, A_K);
319259b61b9eSSebastian Pop if (!findCoefficient(Dst, CurLoop)->isZero())
319359b61b9eSSebastian Pop Consistent = false;
319459b61b9eSSebastian Pop }
319559b61b9eSSebastian Pop else {
319659b61b9eSSebastian Pop // paper is incorrect here, or perhaps just misleading
319759b61b9eSSebastian Pop const SCEV *A_K = findCoefficient(Src, CurLoop);
319859b61b9eSSebastian Pop Src = SE->getMulExpr(Src, A);
319959b61b9eSSebastian Pop Dst = SE->getMulExpr(Dst, A);
320059b61b9eSSebastian Pop Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, C));
320159b61b9eSSebastian Pop Src = zeroCoefficient(Src, CurLoop);
320259b61b9eSSebastian Pop Dst = addToCoefficient(Dst, CurLoop, SE->getMulExpr(A_K, B));
320359b61b9eSSebastian Pop if (!findCoefficient(Dst, CurLoop)->isZero())
320459b61b9eSSebastian Pop Consistent = false;
320559b61b9eSSebastian Pop }
3206d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tnew Src = " << *Src << "\n");
3207d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tnew Dst = " << *Dst << "\n");
320859b61b9eSSebastian Pop return true;
320959b61b9eSSebastian Pop }
321059b61b9eSSebastian Pop
321159b61b9eSSebastian Pop
321259b61b9eSSebastian Pop // Attempt to propagate a point
321359b61b9eSSebastian Pop // constraint into a subscript pair (Src and Dst).
321459b61b9eSSebastian Pop // Return true if some simplification occurs.
propagatePoint(const SCEV * & Src,const SCEV * & Dst,Constraint & CurConstraint)321549c22190SChandler Carruth bool DependenceInfo::propagatePoint(const SCEV *&Src, const SCEV *&Dst,
321659b61b9eSSebastian Pop Constraint &CurConstraint) {
321759b61b9eSSebastian Pop const Loop *CurLoop = CurConstraint.getAssociatedLoop();
321859b61b9eSSebastian Pop const SCEV *A_K = findCoefficient(Src, CurLoop);
321959b61b9eSSebastian Pop const SCEV *AP_K = findCoefficient(Dst, CurLoop);
322059b61b9eSSebastian Pop const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
322159b61b9eSSebastian Pop const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
3222d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
322359b61b9eSSebastian Pop Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
322459b61b9eSSebastian Pop Src = zeroCoefficient(Src, CurLoop);
3225d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
3226d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
322759b61b9eSSebastian Pop Dst = zeroCoefficient(Dst, CurLoop);
3228d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
322959b61b9eSSebastian Pop return true;
323059b61b9eSSebastian Pop }
323159b61b9eSSebastian Pop
323259b61b9eSSebastian Pop
323359b61b9eSSebastian Pop // Update direction vector entry based on the current constraint.
updateDirection(Dependence::DVEntry & Level,const Constraint & CurConstraint) const323449c22190SChandler Carruth void DependenceInfo::updateDirection(Dependence::DVEntry &Level,
323549c22190SChandler Carruth const Constraint &CurConstraint) const {
3236d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tUpdate direction, constraint =");
3237d34e60caSNicola Zaghen LLVM_DEBUG(CurConstraint.dump(dbgs()));
323859b61b9eSSebastian Pop if (CurConstraint.isAny())
323959b61b9eSSebastian Pop ; // use defaults
324059b61b9eSSebastian Pop else if (CurConstraint.isDistance()) {
324159b61b9eSSebastian Pop // this one is consistent, the others aren't
324259b61b9eSSebastian Pop Level.Scalar = false;
324359b61b9eSSebastian Pop Level.Distance = CurConstraint.getD();
324459b61b9eSSebastian Pop unsigned NewDirection = Dependence::DVEntry::NONE;
324559b61b9eSSebastian Pop if (!SE->isKnownNonZero(Level.Distance)) // if may be zero
324659b61b9eSSebastian Pop NewDirection = Dependence::DVEntry::EQ;
324759b61b9eSSebastian Pop if (!SE->isKnownNonPositive(Level.Distance)) // if may be positive
324859b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::LT;
324959b61b9eSSebastian Pop if (!SE->isKnownNonNegative(Level.Distance)) // if may be negative
325059b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::GT;
325159b61b9eSSebastian Pop Level.Direction &= NewDirection;
325259b61b9eSSebastian Pop }
325359b61b9eSSebastian Pop else if (CurConstraint.isLine()) {
325459b61b9eSSebastian Pop Level.Scalar = false;
32559f008867SCraig Topper Level.Distance = nullptr;
325659b61b9eSSebastian Pop // direction should be accurate
325759b61b9eSSebastian Pop }
325859b61b9eSSebastian Pop else if (CurConstraint.isPoint()) {
325959b61b9eSSebastian Pop Level.Scalar = false;
32609f008867SCraig Topper Level.Distance = nullptr;
326159b61b9eSSebastian Pop unsigned NewDirection = Dependence::DVEntry::NONE;
326259b61b9eSSebastian Pop if (!isKnownPredicate(CmpInst::ICMP_NE,
326359b61b9eSSebastian Pop CurConstraint.getY(),
326459b61b9eSSebastian Pop CurConstraint.getX()))
326559b61b9eSSebastian Pop // if X may be = Y
326659b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::EQ;
326759b61b9eSSebastian Pop if (!isKnownPredicate(CmpInst::ICMP_SLE,
326859b61b9eSSebastian Pop CurConstraint.getY(),
326959b61b9eSSebastian Pop CurConstraint.getX()))
327059b61b9eSSebastian Pop // if Y may be > X
327159b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::LT;
327259b61b9eSSebastian Pop if (!isKnownPredicate(CmpInst::ICMP_SGE,
327359b61b9eSSebastian Pop CurConstraint.getY(),
327459b61b9eSSebastian Pop CurConstraint.getX()))
327559b61b9eSSebastian Pop // if Y may be < X
327659b61b9eSSebastian Pop NewDirection |= Dependence::DVEntry::GT;
327759b61b9eSSebastian Pop Level.Direction &= NewDirection;
327859b61b9eSSebastian Pop }
327959b61b9eSSebastian Pop else
328059b61b9eSSebastian Pop llvm_unreachable("constraint has unexpected kind");
328159b61b9eSSebastian Pop }
328259b61b9eSSebastian Pop
3283c62c679cSSebastian Pop /// Check if we can delinearize the subscripts. If the SCEVs representing the
3284c62c679cSSebastian Pop /// source and destination array references are recurrences on a nested loop,
3285cb402911SAlp Toker /// this function flattens the nested recurrences into separate recurrences
3286c62c679cSSebastian Pop /// for each loop level.
tryDelinearize(Instruction * Src,Instruction * Dst,SmallVectorImpl<Subscript> & Pair)328749c22190SChandler Carruth bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
328849c22190SChandler Carruth SmallVectorImpl<Subscript> &Pair) {
3289038ede2aSRenato Golin assert(isLoadOrStore(Src) && "instruction is not load or store");
3290038ede2aSRenato Golin assert(isLoadOrStore(Dst) && "instruction is not load or store");
3291038ede2aSRenato Golin Value *SrcPtr = getLoadStorePointerOperand(Src);
3292038ede2aSRenato Golin Value *DstPtr = getLoadStorePointerOperand(Dst);
32930ef2b10fSHal Finkel Loop *SrcLoop = LI->getLoopFor(Src->getParent());
32940ef2b10fSHal Finkel Loop *DstLoop = LI->getLoopFor(Dst->getParent());
32951b811ff8SBardia Mahjour const SCEV *SrcAccessFn = SE->getSCEVAtScope(SrcPtr, SrcLoop);
32961b811ff8SBardia Mahjour const SCEV *DstAccessFn = SE->getSCEVAtScope(DstPtr, DstLoop);
329728e6b97bSSebastian Pop const SCEVUnknown *SrcBase =
32980ef2b10fSHal Finkel dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
329928e6b97bSSebastian Pop const SCEVUnknown *DstBase =
33000ef2b10fSHal Finkel dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
330128e6b97bSSebastian Pop
330228e6b97bSSebastian Pop if (!SrcBase || !DstBase || SrcBase != DstBase)
330328e6b97bSSebastian Pop return false;
330428e6b97bSSebastian Pop
33051b811ff8SBardia Mahjour SmallVector<const SCEV *, 4> SrcSubscripts, DstSubscripts;
33061b811ff8SBardia Mahjour
33071b811ff8SBardia Mahjour if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
33081b811ff8SBardia Mahjour SrcSubscripts, DstSubscripts) &&
33091b811ff8SBardia Mahjour !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
33101b811ff8SBardia Mahjour SrcSubscripts, DstSubscripts))
33111b811ff8SBardia Mahjour return false;
33121b811ff8SBardia Mahjour
33131b811ff8SBardia Mahjour int Size = SrcSubscripts.size();
33141b811ff8SBardia Mahjour LLVM_DEBUG({
33151b811ff8SBardia Mahjour dbgs() << "\nSrcSubscripts: ";
33161b811ff8SBardia Mahjour for (int I = 0; I < Size; I++)
33171b811ff8SBardia Mahjour dbgs() << *SrcSubscripts[I];
33181b811ff8SBardia Mahjour dbgs() << "\nDstSubscripts: ";
33191b811ff8SBardia Mahjour for (int I = 0; I < Size; I++)
33201b811ff8SBardia Mahjour dbgs() << *DstSubscripts[I];
33211b811ff8SBardia Mahjour });
33221b811ff8SBardia Mahjour
33231b811ff8SBardia Mahjour // The delinearization transforms a single-subscript MIV dependence test into
33241b811ff8SBardia Mahjour // a multi-subscript SIV dependence test that is easier to compute. So we
33251b811ff8SBardia Mahjour // resize Pair to contain as many pairs of subscripts as the delinearization
33261b811ff8SBardia Mahjour // has found, and then initialize the pairs following the delinearization.
33271b811ff8SBardia Mahjour Pair.resize(Size);
33281b811ff8SBardia Mahjour for (int I = 0; I < Size; ++I) {
33291b811ff8SBardia Mahjour Pair[I].Src = SrcSubscripts[I];
33301b811ff8SBardia Mahjour Pair[I].Dst = DstSubscripts[I];
33311b811ff8SBardia Mahjour unifySubscriptType(&Pair[I]);
33321b811ff8SBardia Mahjour }
33331b811ff8SBardia Mahjour
33341b811ff8SBardia Mahjour return true;
33351b811ff8SBardia Mahjour }
33361b811ff8SBardia Mahjour
33374c77d027SCongzhe Cao /// Try to delinearize \p SrcAccessFn and \p DstAccessFn if the underlying
33384c77d027SCongzhe Cao /// arrays accessed are fixed-size arrays. Return true if delinearization was
33394c77d027SCongzhe Cao /// successful.
tryDelinearizeFixedSize(Instruction * Src,Instruction * Dst,const SCEV * SrcAccessFn,const SCEV * DstAccessFn,SmallVectorImpl<const SCEV * > & SrcSubscripts,SmallVectorImpl<const SCEV * > & DstSubscripts)33401b811ff8SBardia Mahjour bool DependenceInfo::tryDelinearizeFixedSize(
33411b811ff8SBardia Mahjour Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
33421b811ff8SBardia Mahjour const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
33431b811ff8SBardia Mahjour SmallVectorImpl<const SCEV *> &DstSubscripts) {
3344*df6087eeSSterling Augustine LLVM_DEBUG({
33451b811ff8SBardia Mahjour const SCEVUnknown *SrcBase =
33461b811ff8SBardia Mahjour dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
33471b811ff8SBardia Mahjour const SCEVUnknown *DstBase =
33481b811ff8SBardia Mahjour dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
33491b811ff8SBardia Mahjour assert(SrcBase && DstBase && SrcBase == DstBase &&
33501b811ff8SBardia Mahjour "expected src and dst scev unknowns to be equal");
3351*df6087eeSSterling Augustine });
33521b811ff8SBardia Mahjour
33534c77d027SCongzhe Cao SmallVector<int, 4> SrcSizes;
33544c77d027SCongzhe Cao SmallVector<int, 4> DstSizes;
33554c77d027SCongzhe Cao if (!tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts,
33564c77d027SCongzhe Cao SrcSizes) ||
33574c77d027SCongzhe Cao !tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts,
33584c77d027SCongzhe Cao DstSizes))
33591b811ff8SBardia Mahjour return false;
33601b811ff8SBardia Mahjour
33611b811ff8SBardia Mahjour // Check that the two size arrays are non-empty and equal in length and
33621b811ff8SBardia Mahjour // value.
33634c77d027SCongzhe Cao if (SrcSizes.size() != DstSizes.size() ||
33641b811ff8SBardia Mahjour !std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.begin())) {
33651b811ff8SBardia Mahjour SrcSubscripts.clear();
33661b811ff8SBardia Mahjour DstSubscripts.clear();
33671b811ff8SBardia Mahjour return false;
33681b811ff8SBardia Mahjour }
33691b811ff8SBardia Mahjour
33701b811ff8SBardia Mahjour assert(SrcSubscripts.size() == DstSubscripts.size() &&
33714c77d027SCongzhe Cao "Expected equal number of entries in the list of SrcSubscripts and "
33724c77d027SCongzhe Cao "DstSubscripts.");
33734c77d027SCongzhe Cao
33744c77d027SCongzhe Cao Value *SrcPtr = getLoadStorePointerOperand(Src);
33754c77d027SCongzhe Cao Value *DstPtr = getLoadStorePointerOperand(Dst);
33767086025dSAndy Kaylor
33777086025dSAndy Kaylor // In general we cannot safely assume that the subscripts recovered from GEPs
33787086025dSAndy Kaylor // are in the range of values defined for their corresponding array
33797086025dSAndy Kaylor // dimensions. For example some C language usage/interpretation make it
33807086025dSAndy Kaylor // impossible to verify this at compile-time. As such we can only delinearize
33817086025dSAndy Kaylor // iff the subscripts are positive and are less than the range of the
33827086025dSAndy Kaylor // dimension.
33837086025dSAndy Kaylor if (!DisableDelinearizationChecks) {
33847086025dSAndy Kaylor auto AllIndiciesInRange = [&](SmallVector<int, 4> &DimensionSizes,
33857086025dSAndy Kaylor SmallVectorImpl<const SCEV *> &Subscripts,
33867086025dSAndy Kaylor Value *Ptr) {
33877086025dSAndy Kaylor size_t SSize = Subscripts.size();
33887086025dSAndy Kaylor for (size_t I = 1; I < SSize; ++I) {
33897086025dSAndy Kaylor const SCEV *S = Subscripts[I];
33907086025dSAndy Kaylor if (!isKnownNonNegative(S, Ptr))
33917086025dSAndy Kaylor return false;
33927086025dSAndy Kaylor if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
33937086025dSAndy Kaylor const SCEV *Range = SE->getConstant(
33947086025dSAndy Kaylor ConstantInt::get(SType, DimensionSizes[I - 1], false));
33957086025dSAndy Kaylor if (!isKnownLessThan(S, Range))
33967086025dSAndy Kaylor return false;
33977086025dSAndy Kaylor }
33987086025dSAndy Kaylor }
33997086025dSAndy Kaylor return true;
34007086025dSAndy Kaylor };
34017086025dSAndy Kaylor
34027086025dSAndy Kaylor if (!AllIndiciesInRange(SrcSizes, SrcSubscripts, SrcPtr) ||
34037086025dSAndy Kaylor !AllIndiciesInRange(DstSizes, DstSubscripts, DstPtr)) {
34047086025dSAndy Kaylor SrcSubscripts.clear();
34057086025dSAndy Kaylor DstSubscripts.clear();
34067086025dSAndy Kaylor return false;
34077086025dSAndy Kaylor }
34087086025dSAndy Kaylor }
34091b811ff8SBardia Mahjour LLVM_DEBUG({
34101b811ff8SBardia Mahjour dbgs() << "Delinearized subscripts of fixed-size array\n"
34114c77d027SCongzhe Cao << "SrcGEP:" << *SrcPtr << "\n"
34124c77d027SCongzhe Cao << "DstGEP:" << *DstPtr << "\n";
34131b811ff8SBardia Mahjour });
34141b811ff8SBardia Mahjour return true;
34151b811ff8SBardia Mahjour }
34161b811ff8SBardia Mahjour
tryDelinearizeParametricSize(Instruction * Src,Instruction * Dst,const SCEV * SrcAccessFn,const SCEV * DstAccessFn,SmallVectorImpl<const SCEV * > & SrcSubscripts,SmallVectorImpl<const SCEV * > & DstSubscripts)34171b811ff8SBardia Mahjour bool DependenceInfo::tryDelinearizeParametricSize(
34181b811ff8SBardia Mahjour Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
34191b811ff8SBardia Mahjour const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
34201b811ff8SBardia Mahjour SmallVectorImpl<const SCEV *> &DstSubscripts) {
34211b811ff8SBardia Mahjour
34221b811ff8SBardia Mahjour Value *SrcPtr = getLoadStorePointerOperand(Src);
34231b811ff8SBardia Mahjour Value *DstPtr = getLoadStorePointerOperand(Dst);
34241b811ff8SBardia Mahjour const SCEVUnknown *SrcBase =
34251b811ff8SBardia Mahjour dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
34261b811ff8SBardia Mahjour const SCEVUnknown *DstBase =
34271b811ff8SBardia Mahjour dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
34281b811ff8SBardia Mahjour assert(SrcBase && DstBase && SrcBase == DstBase &&
34291b811ff8SBardia Mahjour "expected src and dst scev unknowns to be equal");
34301b811ff8SBardia Mahjour
34310ef2b10fSHal Finkel const SCEV *ElementSize = SE->getElementSize(Src);
34320ef2b10fSHal Finkel if (ElementSize != SE->getElementSize(Dst))
34330ef2b10fSHal Finkel return false;
34340ef2b10fSHal Finkel
34350ef2b10fSHal Finkel const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
34360ef2b10fSHal Finkel const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);
343728e6b97bSSebastian Pop
3438c62c679cSSebastian Pop const SCEVAddRecExpr *SrcAR = dyn_cast<SCEVAddRecExpr>(SrcSCEV);
3439c62c679cSSebastian Pop const SCEVAddRecExpr *DstAR = dyn_cast<SCEVAddRecExpr>(DstSCEV);
3440c62c679cSSebastian Pop if (!SrcAR || !DstAR || !SrcAR->isAffine() || !DstAR->isAffine())
3441c62c679cSSebastian Pop return false;
3442c62c679cSSebastian Pop
3443448712b1SSebastian Pop // First step: collect parametric terms in both array references.
3444448712b1SSebastian Pop SmallVector<const SCEV *, 4> Terms;
3445585c594dSPhilip Reames collectParametricTerms(*SE, SrcAR, Terms);
3446585c594dSPhilip Reames collectParametricTerms(*SE, DstAR, Terms);
3447c62c679cSSebastian Pop
3448448712b1SSebastian Pop // Second step: find subscript sizes.
3449448712b1SSebastian Pop SmallVector<const SCEV *, 4> Sizes;
3450585c594dSPhilip Reames findArrayDimensions(*SE, Terms, Sizes, ElementSize);
3451448712b1SSebastian Pop
3452448712b1SSebastian Pop // Third step: compute the access functions for each subscript.
3453585c594dSPhilip Reames computeAccessFunctions(*SE, SrcAR, SrcSubscripts, Sizes);
3454585c594dSPhilip Reames computeAccessFunctions(*SE, DstAR, DstSubscripts, Sizes);
3455448712b1SSebastian Pop
34565133d2e9SSebastian Pop // Fail when there is only a subscript: that's a linearized access function.
3457448712b1SSebastian Pop if (SrcSubscripts.size() < 2 || DstSubscripts.size() < 2 ||
3458448712b1SSebastian Pop SrcSubscripts.size() != DstSubscripts.size())
3459c62c679cSSebastian Pop return false;
3460c62c679cSSebastian Pop
34611b811ff8SBardia Mahjour size_t Size = SrcSubscripts.size();
346229026d3eSSebastian Pop
3463d143c65dSDavid Green // Statically check that the array bounds are in-range. The first subscript we
3464d143c65dSDavid Green // don't have a size for and it cannot overflow into another subscript, so is
3465d143c65dSDavid Green // always safe. The others need to be 0 <= subscript[i] < bound, for both src
3466d143c65dSDavid Green // and dst.
3467d143c65dSDavid Green // FIXME: It may be better to record these sizes and add them as constraints
3468d143c65dSDavid Green // to the dependency checks.
346903e8369aSWhitney Tsang if (!DisableDelinearizationChecks)
34701b811ff8SBardia Mahjour for (size_t I = 1; I < Size; ++I) {
34711b811ff8SBardia Mahjour if (!isKnownNonNegative(SrcSubscripts[I], SrcPtr))
3472d143c65dSDavid Green return false;
3473d143c65dSDavid Green
34741b811ff8SBardia Mahjour if (!isKnownLessThan(SrcSubscripts[I], Sizes[I - 1]))
3475d143c65dSDavid Green return false;
3476d143c65dSDavid Green
34771b811ff8SBardia Mahjour if (!isKnownNonNegative(DstSubscripts[I], DstPtr))
3478d143c65dSDavid Green return false;
3479d143c65dSDavid Green
34801b811ff8SBardia Mahjour if (!isKnownLessThan(DstSubscripts[I], Sizes[I - 1]))
3481d143c65dSDavid Green return false;
3482d143c65dSDavid Green }
3483d143c65dSDavid Green
3484c62c679cSSebastian Pop return true;
3485c62c679cSSebastian Pop }
348659b61b9eSSebastian Pop
348759b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
348859b61b9eSSebastian Pop
348959b61b9eSSebastian Pop #ifndef NDEBUG
349059b61b9eSSebastian Pop // For debugging purposes, dump a small bit vector to dbgs().
dumpSmallBitVector(SmallBitVector & BV)349159b61b9eSSebastian Pop static void dumpSmallBitVector(SmallBitVector &BV) {
349259b61b9eSSebastian Pop dbgs() << "{";
3493b52e0366SFrancis Visoiu Mistrih for (unsigned VI : BV.set_bits()) {
349459b61b9eSSebastian Pop dbgs() << VI;
349559b61b9eSSebastian Pop if (BV.find_next(VI) >= 0)
349659b61b9eSSebastian Pop dbgs() << ' ';
349759b61b9eSSebastian Pop }
349859b61b9eSSebastian Pop dbgs() << "}\n";
349959b61b9eSSebastian Pop }
350059b61b9eSSebastian Pop #endif
350159b61b9eSSebastian Pop
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator & Inv)35029438585fSPhilip Pfaffe bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
35039438585fSPhilip Pfaffe FunctionAnalysisManager::Invalidator &Inv) {
35049438585fSPhilip Pfaffe // Check if the analysis itself has been invalidated.
35059438585fSPhilip Pfaffe auto PAC = PA.getChecker<DependenceAnalysis>();
35069438585fSPhilip Pfaffe if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>())
35079438585fSPhilip Pfaffe return true;
35089438585fSPhilip Pfaffe
35099438585fSPhilip Pfaffe // Check transitive dependencies.
35109438585fSPhilip Pfaffe return Inv.invalidate<AAManager>(F, PA) ||
35119438585fSPhilip Pfaffe Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
35129438585fSPhilip Pfaffe Inv.invalidate<LoopAnalysis>(F, PA);
35139438585fSPhilip Pfaffe }
35149438585fSPhilip Pfaffe
351559b61b9eSSebastian Pop // depends -
351659b61b9eSSebastian Pop // Returns NULL if there is no dependence.
351759b61b9eSSebastian Pop // Otherwise, return a Dependence with as many details as possible.
351859b61b9eSSebastian Pop // Corresponds to Section 3.1 in the paper
351959b61b9eSSebastian Pop //
352059b61b9eSSebastian Pop // Practical Dependence Testing
352159b61b9eSSebastian Pop // Goff, Kennedy, Tseng
352259b61b9eSSebastian Pop // PLDI 1991
352359b61b9eSSebastian Pop //
35243ad39493SPreston Briggs // Care is required to keep the routine below, getSplitIteration(),
35253ad39493SPreston Briggs // up to date with respect to this routine.
35262cae60e7SDylan Noblesmith std::unique_ptr<Dependence>
depends(Instruction * Src,Instruction * Dst,bool PossiblyLoopIndependent)352749c22190SChandler Carruth DependenceInfo::depends(Instruction *Src, Instruction *Dst,
352859b61b9eSSebastian Pop bool PossiblyLoopIndependent) {
35291084fa2eSPreston Briggs if (Src == Dst)
35301084fa2eSPreston Briggs PossiblyLoopIndependent = false;
35311084fa2eSPreston Briggs
3532916d37a2SBardia Mahjour if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
353359b61b9eSSebastian Pop // if both instructions don't reference memory, there's no dependence
35349f008867SCraig Topper return nullptr;
353559b61b9eSSebastian Pop
35363ad39493SPreston Briggs if (!isLoadOrStore(Src) || !isLoadOrStore(Dst)) {
353759b61b9eSSebastian Pop // can only analyze simple loads and stores, i.e., no calls, invokes, etc.
3538d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "can only handle simple loads and stores\n");
35390eaee545SJonas Devlieghere return std::make_unique<Dependence>(Src, Dst);
35403ad39493SPreston Briggs }
354159b61b9eSSebastian Pop
3542038ede2aSRenato Golin assert(isLoadOrStore(Src) && "instruction is not load or store");
3543038ede2aSRenato Golin assert(isLoadOrStore(Dst) && "instruction is not load or store");
3544038ede2aSRenato Golin Value *SrcPtr = getLoadStorePointerOperand(Src);
3545038ede2aSRenato Golin Value *DstPtr = getLoadStorePointerOperand(Dst);
354659b61b9eSSebastian Pop
35475ef933b0SDavid Green switch (underlyingObjectsAlias(AA, F->getParent()->getDataLayout(),
35485ef933b0SDavid Green MemoryLocation::get(Dst),
35495ef933b0SDavid Green MemoryLocation::get(Src))) {
3550d0660797Sdfukalov case AliasResult::MayAlias:
3551d0660797Sdfukalov case AliasResult::PartialAlias:
355259b61b9eSSebastian Pop // cannot analyse objects if we don't understand their aliasing.
3553d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "can't analyze may or partial alias\n");
35540eaee545SJonas Devlieghere return std::make_unique<Dependence>(Src, Dst);
3555d0660797Sdfukalov case AliasResult::NoAlias:
355659b61b9eSSebastian Pop // If the objects noalias, they are distinct, accesses are independent.
3557d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "no alias\n");
35589f008867SCraig Topper return nullptr;
3559d0660797Sdfukalov case AliasResult::MustAlias:
356059b61b9eSSebastian Pop break; // The underlying objects alias; test accesses for dependence.
356159b61b9eSSebastian Pop }
356259b61b9eSSebastian Pop
356359b61b9eSSebastian Pop // establish loop nesting levels
356459b61b9eSSebastian Pop establishNestingLevels(Src, Dst);
3565d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " common nesting levels = " << CommonLevels << "\n");
3566d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " maximum nesting levels = " << MaxLevels << "\n");
356759b61b9eSSebastian Pop
3568d8422ce0SNAKAMURA Takumi FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
356959b61b9eSSebastian Pop ++TotalArrayPairs;
357059b61b9eSSebastian Pop
3571bf6e1c26SSebastian Pop unsigned Pairs = 1;
3572bf6e1c26SSebastian Pop SmallVector<Subscript, 2> Pair(Pairs);
35733ad39493SPreston Briggs const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
35743ad39493SPreston Briggs const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3575d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " SrcSCEV = " << *SrcSCEV << "\n");
3576d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " DstSCEV = " << *DstSCEV << "\n");
35775d5b0876SEli Friedman if (SE->getPointerBase(SrcSCEV) != SE->getPointerBase(DstSCEV)) {
35785d5b0876SEli Friedman // If two pointers have different bases, trying to analyze indexes won't
35795d5b0876SEli Friedman // work; we can't compare them to each other. This can happen, for example,
35805d5b0876SEli Friedman // if one is produced by an LCSSA PHI node.
35815d5b0876SEli Friedman //
35825d5b0876SEli Friedman // We check this upfront so we don't crash in cases where getMinusSCEV()
35835d5b0876SEli Friedman // returns a SCEVCouldNotCompute.
35845d5b0876SEli Friedman LLVM_DEBUG(dbgs() << "can't analyze SCEV with different pointer base\n");
35855d5b0876SEli Friedman return std::make_unique<Dependence>(Src, Dst);
35865d5b0876SEli Friedman }
35873ad39493SPreston Briggs Pair[0].Src = SrcSCEV;
35883ad39493SPreston Briggs Pair[0].Dst = DstSCEV;
35893ad39493SPreston Briggs
3590bf6e1c26SSebastian Pop if (Delinearize) {
35910ef2b10fSHal Finkel if (tryDelinearize(Src, Dst, Pair)) {
3592d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " delinearized\n");
3593c62c679cSSebastian Pop Pairs = Pair.size();
3594c62c679cSSebastian Pop }
35950ef2b10fSHal Finkel }
3596c62c679cSSebastian Pop
35973ad39493SPreston Briggs for (unsigned P = 0; P < Pairs; ++P) {
35983ad39493SPreston Briggs Pair[P].Loops.resize(MaxLevels + 1);
35993ad39493SPreston Briggs Pair[P].GroupLoops.resize(MaxLevels + 1);
36003ad39493SPreston Briggs Pair[P].Group.resize(Pairs);
36013ad39493SPreston Briggs removeMatchingExtensions(&Pair[P]);
36023ad39493SPreston Briggs Pair[P].Classification =
36033ad39493SPreston Briggs classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
36043ad39493SPreston Briggs Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
36053ad39493SPreston Briggs Pair[P].Loops);
36063ad39493SPreston Briggs Pair[P].GroupLoops = Pair[P].Loops;
36073ad39493SPreston Briggs Pair[P].Group.set(P);
3608d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " subscript " << P << "\n");
3609d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tsrc = " << *Pair[P].Src << "\n");
3610d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tdst = " << *Pair[P].Dst << "\n");
3611d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tclass = " << Pair[P].Classification << "\n");
3612d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tloops = ");
3613d34e60caSNicola Zaghen LLVM_DEBUG(dumpSmallBitVector(Pair[P].Loops));
361459b61b9eSSebastian Pop }
361559b61b9eSSebastian Pop
361659b61b9eSSebastian Pop SmallBitVector Separable(Pairs);
361759b61b9eSSebastian Pop SmallBitVector Coupled(Pairs);
361859b61b9eSSebastian Pop
361959b61b9eSSebastian Pop // Partition subscripts into separable and minimally-coupled groups
362059b61b9eSSebastian Pop // Algorithm in paper is algorithmically better;
362159b61b9eSSebastian Pop // this may be faster in practice. Check someday.
362259b61b9eSSebastian Pop //
362359b61b9eSSebastian Pop // Here's an example of how it works. Consider this code:
362459b61b9eSSebastian Pop //
362559b61b9eSSebastian Pop // for (i = ...) {
362659b61b9eSSebastian Pop // for (j = ...) {
362759b61b9eSSebastian Pop // for (k = ...) {
362859b61b9eSSebastian Pop // for (l = ...) {
362959b61b9eSSebastian Pop // for (m = ...) {
363059b61b9eSSebastian Pop // A[i][j][k][m] = ...;
363159b61b9eSSebastian Pop // ... = A[0][j][l][i + j];
363259b61b9eSSebastian Pop // }
363359b61b9eSSebastian Pop // }
363459b61b9eSSebastian Pop // }
363559b61b9eSSebastian Pop // }
363659b61b9eSSebastian Pop // }
363759b61b9eSSebastian Pop //
363859b61b9eSSebastian Pop // There are 4 subscripts here:
363959b61b9eSSebastian Pop // 0 [i] and [0]
364059b61b9eSSebastian Pop // 1 [j] and [j]
364159b61b9eSSebastian Pop // 2 [k] and [l]
364259b61b9eSSebastian Pop // 3 [m] and [i + j]
364359b61b9eSSebastian Pop //
364459b61b9eSSebastian Pop // We've already classified each subscript pair as ZIV, SIV, etc.,
364559b61b9eSSebastian Pop // and collected all the loops mentioned by pair P in Pair[P].Loops.
364659b61b9eSSebastian Pop // In addition, we've initialized Pair[P].GroupLoops to Pair[P].Loops
364759b61b9eSSebastian Pop // and set Pair[P].Group = {P}.
364859b61b9eSSebastian Pop //
364959b61b9eSSebastian Pop // Src Dst Classification Loops GroupLoops Group
365059b61b9eSSebastian Pop // 0 [i] [0] SIV {1} {1} {0}
365159b61b9eSSebastian Pop // 1 [j] [j] SIV {2} {2} {1}
365259b61b9eSSebastian Pop // 2 [k] [l] RDIV {3,4} {3,4} {2}
365359b61b9eSSebastian Pop // 3 [m] [i + j] MIV {1,2,5} {1,2,5} {3}
365459b61b9eSSebastian Pop //
365559b61b9eSSebastian Pop // For each subscript SI 0 .. 3, we consider each remaining subscript, SJ.
365659b61b9eSSebastian Pop // So, 0 is compared against 1, 2, and 3; 1 is compared against 2 and 3, etc.
365759b61b9eSSebastian Pop //
365859b61b9eSSebastian Pop // We begin by comparing 0 and 1. The intersection of the GroupLoops is empty.
365959b61b9eSSebastian Pop // Next, 0 and 2. Again, the intersection of their GroupLoops is empty.
366059b61b9eSSebastian Pop // Next 0 and 3. The intersection of their GroupLoop = {1}, not empty,
366159b61b9eSSebastian Pop // so Pair[3].Group = {0,3} and Done = false (that is, 0 will not be added
366259b61b9eSSebastian Pop // to either Separable or Coupled).
366359b61b9eSSebastian Pop //
366459b61b9eSSebastian Pop // Next, we consider 1 and 2. The intersection of the GroupLoops is empty.
366559b61b9eSSebastian Pop // Next, 1 and 3. The intersection of their GroupLoops = {2}, not empty,
366659b61b9eSSebastian Pop // so Pair[3].Group = {0, 1, 3} and Done = false.
366759b61b9eSSebastian Pop //
366859b61b9eSSebastian Pop // Next, we compare 2 against 3. The intersection of the GroupLoops is empty.
366959b61b9eSSebastian Pop // Since Done remains true, we add 2 to the set of Separable pairs.
367059b61b9eSSebastian Pop //
367159b61b9eSSebastian Pop // Finally, we consider 3. There's nothing to compare it with,
367259b61b9eSSebastian Pop // so Done remains true and we add it to the Coupled set.
367359b61b9eSSebastian Pop // Pair[3].Group = {0, 1, 3} and GroupLoops = {1, 2, 5}.
367459b61b9eSSebastian Pop //
367559b61b9eSSebastian Pop // In the end, we've got 1 separable subscript and 1 coupled group.
367659b61b9eSSebastian Pop for (unsigned SI = 0; SI < Pairs; ++SI) {
367759b61b9eSSebastian Pop if (Pair[SI].Classification == Subscript::NonLinear) {
367859b61b9eSSebastian Pop // ignore these, but collect loops for later
367959b61b9eSSebastian Pop ++NonlinearSubscriptPairs;
368059b61b9eSSebastian Pop collectCommonLoops(Pair[SI].Src,
368159b61b9eSSebastian Pop LI->getLoopFor(Src->getParent()),
368259b61b9eSSebastian Pop Pair[SI].Loops);
368359b61b9eSSebastian Pop collectCommonLoops(Pair[SI].Dst,
368459b61b9eSSebastian Pop LI->getLoopFor(Dst->getParent()),
368559b61b9eSSebastian Pop Pair[SI].Loops);
3686d8422ce0SNAKAMURA Takumi Result.Consistent = false;
3687478559a5SNAKAMURA Takumi } else if (Pair[SI].Classification == Subscript::ZIV) {
368859b61b9eSSebastian Pop // always separable
368959b61b9eSSebastian Pop Separable.set(SI);
369059b61b9eSSebastian Pop }
369159b61b9eSSebastian Pop else {
369259b61b9eSSebastian Pop // SIV, RDIV, or MIV, so check for coupled group
369359b61b9eSSebastian Pop bool Done = true;
369459b61b9eSSebastian Pop for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
369559b61b9eSSebastian Pop SmallBitVector Intersection = Pair[SI].GroupLoops;
369659b61b9eSSebastian Pop Intersection &= Pair[SJ].GroupLoops;
369759b61b9eSSebastian Pop if (Intersection.any()) {
369859b61b9eSSebastian Pop // accumulate set of all the loops in group
369959b61b9eSSebastian Pop Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
370059b61b9eSSebastian Pop // accumulate set of all subscripts in group
370159b61b9eSSebastian Pop Pair[SJ].Group |= Pair[SI].Group;
370259b61b9eSSebastian Pop Done = false;
370359b61b9eSSebastian Pop }
370459b61b9eSSebastian Pop }
370559b61b9eSSebastian Pop if (Done) {
370659b61b9eSSebastian Pop if (Pair[SI].Group.count() == 1) {
370759b61b9eSSebastian Pop Separable.set(SI);
370859b61b9eSSebastian Pop ++SeparableSubscriptPairs;
370959b61b9eSSebastian Pop }
371059b61b9eSSebastian Pop else {
371159b61b9eSSebastian Pop Coupled.set(SI);
371259b61b9eSSebastian Pop ++CoupledSubscriptPairs;
371359b61b9eSSebastian Pop }
371459b61b9eSSebastian Pop }
371559b61b9eSSebastian Pop }
371659b61b9eSSebastian Pop }
371759b61b9eSSebastian Pop
3718d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Separable = ");
3719d34e60caSNicola Zaghen LLVM_DEBUG(dumpSmallBitVector(Separable));
3720d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Coupled = ");
3721d34e60caSNicola Zaghen LLVM_DEBUG(dumpSmallBitVector(Coupled));
372259b61b9eSSebastian Pop
372359b61b9eSSebastian Pop Constraint NewConstraint;
372459b61b9eSSebastian Pop NewConstraint.setAny(SE);
372559b61b9eSSebastian Pop
372659b61b9eSSebastian Pop // test separable subscripts
3727b52e0366SFrancis Visoiu Mistrih for (unsigned SI : Separable.set_bits()) {
3728d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "testing subscript " << SI);
372959b61b9eSSebastian Pop switch (Pair[SI].Classification) {
373059b61b9eSSebastian Pop case Subscript::ZIV:
3731d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", ZIV\n");
3732d8422ce0SNAKAMURA Takumi if (testZIV(Pair[SI].Src, Pair[SI].Dst, Result))
37339f008867SCraig Topper return nullptr;
373459b61b9eSSebastian Pop break;
373559b61b9eSSebastian Pop case Subscript::SIV: {
3736d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", SIV\n");
373759b61b9eSSebastian Pop unsigned Level;
37389f008867SCraig Topper const SCEV *SplitIter = nullptr;
3739478559a5SNAKAMURA Takumi if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
3740478559a5SNAKAMURA Takumi SplitIter))
37419f008867SCraig Topper return nullptr;
374259b61b9eSSebastian Pop break;
374359b61b9eSSebastian Pop }
374459b61b9eSSebastian Pop case Subscript::RDIV:
3745d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", RDIV\n");
3746d8422ce0SNAKAMURA Takumi if (testRDIV(Pair[SI].Src, Pair[SI].Dst, Result))
37479f008867SCraig Topper return nullptr;
374859b61b9eSSebastian Pop break;
374959b61b9eSSebastian Pop case Subscript::MIV:
3750d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ", MIV\n");
3751d8422ce0SNAKAMURA Takumi if (testMIV(Pair[SI].Src, Pair[SI].Dst, Pair[SI].Loops, Result))
37529f008867SCraig Topper return nullptr;
375359b61b9eSSebastian Pop break;
375459b61b9eSSebastian Pop default:
375559b61b9eSSebastian Pop llvm_unreachable("subscript has unexpected classification");
375659b61b9eSSebastian Pop }
375759b61b9eSSebastian Pop }
375859b61b9eSSebastian Pop
375959b61b9eSSebastian Pop if (Coupled.count()) {
376059b61b9eSSebastian Pop // test coupled subscript groups
3761d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "starting on coupled subscripts\n");
3762d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "MaxLevels + 1 = " << MaxLevels + 1 << "\n");
376359b61b9eSSebastian Pop SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
376459b61b9eSSebastian Pop for (unsigned II = 0; II <= MaxLevels; ++II)
376559b61b9eSSebastian Pop Constraints[II].setAny(SE);
3766b52e0366SFrancis Visoiu Mistrih for (unsigned SI : Coupled.set_bits()) {
3767d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "testing subscript group " << SI << " { ");
376859b61b9eSSebastian Pop SmallBitVector Group(Pair[SI].Group);
376959b61b9eSSebastian Pop SmallBitVector Sivs(Pairs);
377059b61b9eSSebastian Pop SmallBitVector Mivs(Pairs);
377159b61b9eSSebastian Pop SmallBitVector ConstrainedLevels(MaxLevels + 1);
3772a84feb17SJingyue Wu SmallVector<Subscript *, 4> PairsInGroup;
3773b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Group.set_bits()) {
3774d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << SJ << " ");
377559b61b9eSSebastian Pop if (Pair[SJ].Classification == Subscript::SIV)
377659b61b9eSSebastian Pop Sivs.set(SJ);
377759b61b9eSSebastian Pop else
377859b61b9eSSebastian Pop Mivs.set(SJ);
3779a84feb17SJingyue Wu PairsInGroup.push_back(&Pair[SJ]);
378059b61b9eSSebastian Pop }
3781a84feb17SJingyue Wu unifySubscriptType(PairsInGroup);
3782d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "}\n");
378359b61b9eSSebastian Pop while (Sivs.any()) {
378459b61b9eSSebastian Pop bool Changed = false;
3785b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Sivs.set_bits()) {
3786d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "testing subscript " << SJ << ", SIV\n");
378759b61b9eSSebastian Pop // SJ is an SIV subscript that's part of the current coupled group
378859b61b9eSSebastian Pop unsigned Level;
37899f008867SCraig Topper const SCEV *SplitIter = nullptr;
3790d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "SIV\n");
3791478559a5SNAKAMURA Takumi if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
3792478559a5SNAKAMURA Takumi SplitIter))
37939f008867SCraig Topper return nullptr;
379459b61b9eSSebastian Pop ConstrainedLevels.set(Level);
379559b61b9eSSebastian Pop if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
379659b61b9eSSebastian Pop if (Constraints[Level].isEmpty()) {
379759b61b9eSSebastian Pop ++DeltaIndependence;
37989f008867SCraig Topper return nullptr;
379959b61b9eSSebastian Pop }
380059b61b9eSSebastian Pop Changed = true;
380159b61b9eSSebastian Pop }
380259b61b9eSSebastian Pop Sivs.reset(SJ);
380359b61b9eSSebastian Pop }
380459b61b9eSSebastian Pop if (Changed) {
380559b61b9eSSebastian Pop // propagate, possibly creating new SIVs and ZIVs
3806d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " propagating\n");
3807d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tMivs = ");
3808d34e60caSNicola Zaghen LLVM_DEBUG(dumpSmallBitVector(Mivs));
3809b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Mivs.set_bits()) {
381059b61b9eSSebastian Pop // SJ is an MIV subscript that's part of the current coupled group
3811d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\tSJ = " << SJ << "\n");
381259b61b9eSSebastian Pop if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
3813d8422ce0SNAKAMURA Takumi Constraints, Result.Consistent)) {
3814d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\t Changed\n");
381559b61b9eSSebastian Pop ++DeltaPropagations;
381659b61b9eSSebastian Pop Pair[SJ].Classification =
381759b61b9eSSebastian Pop classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
381859b61b9eSSebastian Pop Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
381959b61b9eSSebastian Pop Pair[SJ].Loops);
382059b61b9eSSebastian Pop switch (Pair[SJ].Classification) {
382159b61b9eSSebastian Pop case Subscript::ZIV:
3822d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ZIV\n");
3823d8422ce0SNAKAMURA Takumi if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
38249f008867SCraig Topper return nullptr;
382559b61b9eSSebastian Pop Mivs.reset(SJ);
382659b61b9eSSebastian Pop break;
382759b61b9eSSebastian Pop case Subscript::SIV:
382859b61b9eSSebastian Pop Sivs.set(SJ);
382959b61b9eSSebastian Pop Mivs.reset(SJ);
383059b61b9eSSebastian Pop break;
383159b61b9eSSebastian Pop case Subscript::RDIV:
383259b61b9eSSebastian Pop case Subscript::MIV:
383359b61b9eSSebastian Pop break;
383459b61b9eSSebastian Pop default:
383559b61b9eSSebastian Pop llvm_unreachable("bad subscript classification");
383659b61b9eSSebastian Pop }
383759b61b9eSSebastian Pop }
383859b61b9eSSebastian Pop }
383959b61b9eSSebastian Pop }
384059b61b9eSSebastian Pop }
384159b61b9eSSebastian Pop
384259b61b9eSSebastian Pop // test & propagate remaining RDIVs
3843b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Mivs.set_bits()) {
384459b61b9eSSebastian Pop if (Pair[SJ].Classification == Subscript::RDIV) {
3845d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "RDIV test\n");
3846d8422ce0SNAKAMURA Takumi if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
38479f008867SCraig Topper return nullptr;
384859b61b9eSSebastian Pop // I don't yet understand how to propagate RDIV results
384959b61b9eSSebastian Pop Mivs.reset(SJ);
385059b61b9eSSebastian Pop }
385159b61b9eSSebastian Pop }
385259b61b9eSSebastian Pop
385359b61b9eSSebastian Pop // test remaining MIVs
385459b61b9eSSebastian Pop // This code is temporary.
385559b61b9eSSebastian Pop // Better to somehow test all remaining subscripts simultaneously.
3856b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Mivs.set_bits()) {
385759b61b9eSSebastian Pop if (Pair[SJ].Classification == Subscript::MIV) {
3858d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "MIV test\n");
3859d8422ce0SNAKAMURA Takumi if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
38609f008867SCraig Topper return nullptr;
386159b61b9eSSebastian Pop }
386259b61b9eSSebastian Pop else
386359b61b9eSSebastian Pop llvm_unreachable("expected only MIV subscripts at this point");
386459b61b9eSSebastian Pop }
386559b61b9eSSebastian Pop
3866d8422ce0SNAKAMURA Takumi // update Result.DV from constraint vector
3867d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " updating\n");
3868b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : ConstrainedLevels.set_bits()) {
3869b52e0366SFrancis Visoiu Mistrih if (SJ > CommonLevels)
38708d7f7edaSKarthik Bhat break;
3871d8422ce0SNAKAMURA Takumi updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
3872d8422ce0SNAKAMURA Takumi if (Result.DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
38739f008867SCraig Topper return nullptr;
387459b61b9eSSebastian Pop }
387559b61b9eSSebastian Pop }
387659b61b9eSSebastian Pop }
387759b61b9eSSebastian Pop
38784eb7ee56SPreston Briggs // Make sure the Scalar flags are set correctly.
387959b61b9eSSebastian Pop SmallBitVector CompleteLoops(MaxLevels + 1);
388059b61b9eSSebastian Pop for (unsigned SI = 0; SI < Pairs; ++SI)
388159b61b9eSSebastian Pop CompleteLoops |= Pair[SI].Loops;
388259b61b9eSSebastian Pop for (unsigned II = 1; II <= CommonLevels; ++II)
388359b61b9eSSebastian Pop if (CompleteLoops[II])
3884d8422ce0SNAKAMURA Takumi Result.DV[II - 1].Scalar = false;
388559b61b9eSSebastian Pop
388659b61b9eSSebastian Pop if (PossiblyLoopIndependent) {
38875cb8cfaeSPreston Briggs // Make sure the LoopIndependent flag is set correctly.
38885cb8cfaeSPreston Briggs // All directions must include equal, otherwise no
38895cb8cfaeSPreston Briggs // loop-independent dependence is possible.
389059b61b9eSSebastian Pop for (unsigned II = 1; II <= CommonLevels; ++II) {
3891d8422ce0SNAKAMURA Takumi if (!(Result.getDirection(II) & Dependence::DVEntry::EQ)) {
3892d8422ce0SNAKAMURA Takumi Result.LoopIndependent = false;
389359b61b9eSSebastian Pop break;
389459b61b9eSSebastian Pop }
389559b61b9eSSebastian Pop }
389659b61b9eSSebastian Pop }
38975cb8cfaeSPreston Briggs else {
38985cb8cfaeSPreston Briggs // On the other hand, if all directions are equal and there's no
38995cb8cfaeSPreston Briggs // loop-independent dependence possible, then no dependence exists.
39005cb8cfaeSPreston Briggs bool AllEqual = true;
39015cb8cfaeSPreston Briggs for (unsigned II = 1; II <= CommonLevels; ++II) {
3902d8422ce0SNAKAMURA Takumi if (Result.getDirection(II) != Dependence::DVEntry::EQ) {
39035cb8cfaeSPreston Briggs AllEqual = false;
39045cb8cfaeSPreston Briggs break;
39055cb8cfaeSPreston Briggs }
39065cb8cfaeSPreston Briggs }
39075cb8cfaeSPreston Briggs if (AllEqual)
39089f008867SCraig Topper return nullptr;
39095cb8cfaeSPreston Briggs }
391059b61b9eSSebastian Pop
39110eaee545SJonas Devlieghere return std::make_unique<FullDependence>(std::move(Result));
391259b61b9eSSebastian Pop }
391359b61b9eSSebastian Pop
391459b61b9eSSebastian Pop //===----------------------------------------------------------------------===//
391559b61b9eSSebastian Pop // getSplitIteration -
391659b61b9eSSebastian Pop // Rather than spend rarely-used space recording the splitting iteration
391759b61b9eSSebastian Pop // during the Weak-Crossing SIV test, we re-compute it on demand.
391859b61b9eSSebastian Pop // The re-computation is basically a repeat of the entire dependence test,
391959b61b9eSSebastian Pop // though simplified since we know that the dependence exists.
392059b61b9eSSebastian Pop // It's tedious, since we must go through all propagations, etc.
392159b61b9eSSebastian Pop //
39223ad39493SPreston Briggs // Care is required to keep this code up to date with respect to the routine
39233ad39493SPreston Briggs // above, depends().
392459b61b9eSSebastian Pop //
392559b61b9eSSebastian Pop // Generally, the dependence analyzer will be used to build
392659b61b9eSSebastian Pop // a dependence graph for a function (basically a map from instructions
392759b61b9eSSebastian Pop // to dependences). Looking for cycles in the graph shows us loops
392859b61b9eSSebastian Pop // that cannot be trivially vectorized/parallelized.
392959b61b9eSSebastian Pop //
393059b61b9eSSebastian Pop // We can try to improve the situation by examining all the dependences
393159b61b9eSSebastian Pop // that make up the cycle, looking for ones we can break.
393259b61b9eSSebastian Pop // Sometimes, peeling the first or last iteration of a loop will break
393359b61b9eSSebastian Pop // dependences, and we've got flags for those possibilities.
393459b61b9eSSebastian Pop // Sometimes, splitting a loop at some other iteration will do the trick,
393559b61b9eSSebastian Pop // and we've got a flag for that case. Rather than waste the space to
393659b61b9eSSebastian Pop // record the exact iteration (since we rarely know), we provide
393759b61b9eSSebastian Pop // a method that calculates the iteration. It's a drag that it must work
393859b61b9eSSebastian Pop // from scratch, but wonderful in that it's possible.
393959b61b9eSSebastian Pop //
394059b61b9eSSebastian Pop // Here's an example:
394159b61b9eSSebastian Pop //
394259b61b9eSSebastian Pop // for (i = 0; i < 10; i++)
394359b61b9eSSebastian Pop // A[i] = ...
394459b61b9eSSebastian Pop // ... = A[11 - i]
394559b61b9eSSebastian Pop //
394659b61b9eSSebastian Pop // There's a loop-carried flow dependence from the store to the load,
394759b61b9eSSebastian Pop // found by the weak-crossing SIV test. The dependence will have a flag,
394859b61b9eSSebastian Pop // indicating that the dependence can be broken by splitting the loop.
394959b61b9eSSebastian Pop // Calling getSplitIteration will return 5.
395059b61b9eSSebastian Pop // Splitting the loop breaks the dependence, like so:
395159b61b9eSSebastian Pop //
395259b61b9eSSebastian Pop // for (i = 0; i <= 5; i++)
395359b61b9eSSebastian Pop // A[i] = ...
395459b61b9eSSebastian Pop // ... = A[11 - i]
395559b61b9eSSebastian Pop // for (i = 6; i < 10; i++)
395659b61b9eSSebastian Pop // A[i] = ...
395759b61b9eSSebastian Pop // ... = A[11 - i]
395859b61b9eSSebastian Pop //
395959b61b9eSSebastian Pop // breaks the dependence and allows us to vectorize/parallelize
396059b61b9eSSebastian Pop // both loops.
getSplitIteration(const Dependence & Dep,unsigned SplitLevel)396149c22190SChandler Carruth const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
396259b61b9eSSebastian Pop unsigned SplitLevel) {
3963d96ce66cSDylan Noblesmith assert(Dep.isSplitable(SplitLevel) &&
396459b61b9eSSebastian Pop "Dep should be splitable at SplitLevel");
3965d96ce66cSDylan Noblesmith Instruction *Src = Dep.getSrc();
3966d96ce66cSDylan Noblesmith Instruction *Dst = Dep.getDst();
396759b61b9eSSebastian Pop assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
396859b61b9eSSebastian Pop assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
396959b61b9eSSebastian Pop assert(isLoadOrStore(Src));
397059b61b9eSSebastian Pop assert(isLoadOrStore(Dst));
3971038ede2aSRenato Golin Value *SrcPtr = getLoadStorePointerOperand(Src);
3972038ede2aSRenato Golin Value *DstPtr = getLoadStorePointerOperand(Dst);
3973d0660797Sdfukalov assert(underlyingObjectsAlias(
3974d0660797Sdfukalov AA, F->getParent()->getDataLayout(), MemoryLocation::get(Dst),
3975d0660797Sdfukalov MemoryLocation::get(Src)) == AliasResult::MustAlias);
397659b61b9eSSebastian Pop
397759b61b9eSSebastian Pop // establish loop nesting levels
397859b61b9eSSebastian Pop establishNestingLevels(Src, Dst);
397959b61b9eSSebastian Pop
398059b61b9eSSebastian Pop FullDependence Result(Src, Dst, false, CommonLevels);
398159b61b9eSSebastian Pop
3982bf6e1c26SSebastian Pop unsigned Pairs = 1;
3983bf6e1c26SSebastian Pop SmallVector<Subscript, 2> Pair(Pairs);
39843ad39493SPreston Briggs const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
39853ad39493SPreston Briggs const SCEV *DstSCEV = SE->getSCEV(DstPtr);
39863ad39493SPreston Briggs Pair[0].Src = SrcSCEV;
39873ad39493SPreston Briggs Pair[0].Dst = DstSCEV;
39883ad39493SPreston Briggs
3989bf6e1c26SSebastian Pop if (Delinearize) {
39900ef2b10fSHal Finkel if (tryDelinearize(Src, Dst, Pair)) {
3991d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " delinearized\n");
3992c62c679cSSebastian Pop Pairs = Pair.size();
3993c62c679cSSebastian Pop }
39940ef2b10fSHal Finkel }
3995c62c679cSSebastian Pop
39963ad39493SPreston Briggs for (unsigned P = 0; P < Pairs; ++P) {
39973ad39493SPreston Briggs Pair[P].Loops.resize(MaxLevels + 1);
39983ad39493SPreston Briggs Pair[P].GroupLoops.resize(MaxLevels + 1);
39993ad39493SPreston Briggs Pair[P].Group.resize(Pairs);
40003ad39493SPreston Briggs removeMatchingExtensions(&Pair[P]);
40013ad39493SPreston Briggs Pair[P].Classification =
40023ad39493SPreston Briggs classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
40033ad39493SPreston Briggs Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
40043ad39493SPreston Briggs Pair[P].Loops);
40053ad39493SPreston Briggs Pair[P].GroupLoops = Pair[P].Loops;
40063ad39493SPreston Briggs Pair[P].Group.set(P);
400759b61b9eSSebastian Pop }
400859b61b9eSSebastian Pop
400959b61b9eSSebastian Pop SmallBitVector Separable(Pairs);
401059b61b9eSSebastian Pop SmallBitVector Coupled(Pairs);
401159b61b9eSSebastian Pop
401259b61b9eSSebastian Pop // partition subscripts into separable and minimally-coupled groups
401359b61b9eSSebastian Pop for (unsigned SI = 0; SI < Pairs; ++SI) {
401459b61b9eSSebastian Pop if (Pair[SI].Classification == Subscript::NonLinear) {
401559b61b9eSSebastian Pop // ignore these, but collect loops for later
401659b61b9eSSebastian Pop collectCommonLoops(Pair[SI].Src,
401759b61b9eSSebastian Pop LI->getLoopFor(Src->getParent()),
401859b61b9eSSebastian Pop Pair[SI].Loops);
401959b61b9eSSebastian Pop collectCommonLoops(Pair[SI].Dst,
402059b61b9eSSebastian Pop LI->getLoopFor(Dst->getParent()),
402159b61b9eSSebastian Pop Pair[SI].Loops);
402259b61b9eSSebastian Pop Result.Consistent = false;
402359b61b9eSSebastian Pop }
402459b61b9eSSebastian Pop else if (Pair[SI].Classification == Subscript::ZIV)
402559b61b9eSSebastian Pop Separable.set(SI);
402659b61b9eSSebastian Pop else {
402759b61b9eSSebastian Pop // SIV, RDIV, or MIV, so check for coupled group
402859b61b9eSSebastian Pop bool Done = true;
402959b61b9eSSebastian Pop for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
403059b61b9eSSebastian Pop SmallBitVector Intersection = Pair[SI].GroupLoops;
403159b61b9eSSebastian Pop Intersection &= Pair[SJ].GroupLoops;
403259b61b9eSSebastian Pop if (Intersection.any()) {
403359b61b9eSSebastian Pop // accumulate set of all the loops in group
403459b61b9eSSebastian Pop Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
403559b61b9eSSebastian Pop // accumulate set of all subscripts in group
403659b61b9eSSebastian Pop Pair[SJ].Group |= Pair[SI].Group;
403759b61b9eSSebastian Pop Done = false;
403859b61b9eSSebastian Pop }
403959b61b9eSSebastian Pop }
404059b61b9eSSebastian Pop if (Done) {
404159b61b9eSSebastian Pop if (Pair[SI].Group.count() == 1)
404259b61b9eSSebastian Pop Separable.set(SI);
404359b61b9eSSebastian Pop else
404459b61b9eSSebastian Pop Coupled.set(SI);
404559b61b9eSSebastian Pop }
404659b61b9eSSebastian Pop }
404759b61b9eSSebastian Pop }
404859b61b9eSSebastian Pop
404959b61b9eSSebastian Pop Constraint NewConstraint;
405059b61b9eSSebastian Pop NewConstraint.setAny(SE);
405159b61b9eSSebastian Pop
405259b61b9eSSebastian Pop // test separable subscripts
4053b52e0366SFrancis Visoiu Mistrih for (unsigned SI : Separable.set_bits()) {
405459b61b9eSSebastian Pop switch (Pair[SI].Classification) {
405559b61b9eSSebastian Pop case Subscript::SIV: {
405659b61b9eSSebastian Pop unsigned Level;
40579f008867SCraig Topper const SCEV *SplitIter = nullptr;
405859b61b9eSSebastian Pop (void) testSIV(Pair[SI].Src, Pair[SI].Dst, Level,
405959b61b9eSSebastian Pop Result, NewConstraint, SplitIter);
406059b61b9eSSebastian Pop if (Level == SplitLevel) {
40619f008867SCraig Topper assert(SplitIter != nullptr);
406259b61b9eSSebastian Pop return SplitIter;
406359b61b9eSSebastian Pop }
406459b61b9eSSebastian Pop break;
406559b61b9eSSebastian Pop }
406659b61b9eSSebastian Pop case Subscript::ZIV:
406759b61b9eSSebastian Pop case Subscript::RDIV:
406859b61b9eSSebastian Pop case Subscript::MIV:
406959b61b9eSSebastian Pop break;
407059b61b9eSSebastian Pop default:
407159b61b9eSSebastian Pop llvm_unreachable("subscript has unexpected classification");
407259b61b9eSSebastian Pop }
407359b61b9eSSebastian Pop }
407459b61b9eSSebastian Pop
407559b61b9eSSebastian Pop if (Coupled.count()) {
407659b61b9eSSebastian Pop // test coupled subscript groups
407759b61b9eSSebastian Pop SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
407859b61b9eSSebastian Pop for (unsigned II = 0; II <= MaxLevels; ++II)
407959b61b9eSSebastian Pop Constraints[II].setAny(SE);
4080b52e0366SFrancis Visoiu Mistrih for (unsigned SI : Coupled.set_bits()) {
408159b61b9eSSebastian Pop SmallBitVector Group(Pair[SI].Group);
408259b61b9eSSebastian Pop SmallBitVector Sivs(Pairs);
408359b61b9eSSebastian Pop SmallBitVector Mivs(Pairs);
408459b61b9eSSebastian Pop SmallBitVector ConstrainedLevels(MaxLevels + 1);
4085b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Group.set_bits()) {
408659b61b9eSSebastian Pop if (Pair[SJ].Classification == Subscript::SIV)
408759b61b9eSSebastian Pop Sivs.set(SJ);
408859b61b9eSSebastian Pop else
408959b61b9eSSebastian Pop Mivs.set(SJ);
409059b61b9eSSebastian Pop }
409159b61b9eSSebastian Pop while (Sivs.any()) {
409259b61b9eSSebastian Pop bool Changed = false;
4093b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Sivs.set_bits()) {
409459b61b9eSSebastian Pop // SJ is an SIV subscript that's part of the current coupled group
409559b61b9eSSebastian Pop unsigned Level;
40969f008867SCraig Topper const SCEV *SplitIter = nullptr;
409759b61b9eSSebastian Pop (void) testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
409859b61b9eSSebastian Pop Result, NewConstraint, SplitIter);
409959b61b9eSSebastian Pop if (Level == SplitLevel && SplitIter)
410059b61b9eSSebastian Pop return SplitIter;
410159b61b9eSSebastian Pop ConstrainedLevels.set(Level);
410259b61b9eSSebastian Pop if (intersectConstraints(&Constraints[Level], &NewConstraint))
410359b61b9eSSebastian Pop Changed = true;
410459b61b9eSSebastian Pop Sivs.reset(SJ);
410559b61b9eSSebastian Pop }
410659b61b9eSSebastian Pop if (Changed) {
410759b61b9eSSebastian Pop // propagate, possibly creating new SIVs and ZIVs
4108b52e0366SFrancis Visoiu Mistrih for (unsigned SJ : Mivs.set_bits()) {
410959b61b9eSSebastian Pop // SJ is an MIV subscript that's part of the current coupled group
411059b61b9eSSebastian Pop if (propagate(Pair[SJ].Src, Pair[SJ].Dst,
411159b61b9eSSebastian Pop Pair[SJ].Loops, Constraints, Result.Consistent)) {
411259b61b9eSSebastian Pop Pair[SJ].Classification =
411359b61b9eSSebastian Pop classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
411459b61b9eSSebastian Pop Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
411559b61b9eSSebastian Pop Pair[SJ].Loops);
411659b61b9eSSebastian Pop switch (Pair[SJ].Classification) {
411759b61b9eSSebastian Pop case Subscript::ZIV:
411859b61b9eSSebastian Pop Mivs.reset(SJ);
411959b61b9eSSebastian Pop break;
412059b61b9eSSebastian Pop case Subscript::SIV:
412159b61b9eSSebastian Pop Sivs.set(SJ);
412259b61b9eSSebastian Pop Mivs.reset(SJ);
412359b61b9eSSebastian Pop break;
412459b61b9eSSebastian Pop case Subscript::RDIV:
412559b61b9eSSebastian Pop case Subscript::MIV:
412659b61b9eSSebastian Pop break;
412759b61b9eSSebastian Pop default:
412859b61b9eSSebastian Pop llvm_unreachable("bad subscript classification");
412959b61b9eSSebastian Pop }
413059b61b9eSSebastian Pop }
413159b61b9eSSebastian Pop }
413259b61b9eSSebastian Pop }
413359b61b9eSSebastian Pop }
413459b61b9eSSebastian Pop }
413559b61b9eSSebastian Pop }
413659b61b9eSSebastian Pop llvm_unreachable("somehow reached end of routine");
41379f008867SCraig Topper return nullptr;
413859b61b9eSSebastian Pop }
4139