//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// DependenceAnalysis is an LLVM pass that analyses dependences between memory
// accesses. Currently, it is an implementation of the approach described in
//
//            Practical Dependence Testing
//            Goff, Kennedy, Tseng
//            PLDI 1991
//
// There's a single entry point that analyzes the dependence between a pair
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
// This pass exists to support the DependenceGraph pass. There are two separate
// passes because there's a useful separation of concerns. A dependence exists
// if two conditions are met:
//
//    1) Two instructions reference the same memory location, and
//    2) There is a flow of control leading from one instruction to the other.
//
// DependenceAnalysis attacks the first condition; DependenceGraph will attack
// the second (it's not yet ready).
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// Plausible changes:
//    Return a set of more precise dependences instead of just one dependence
//    summarizing all.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H

#include "llvm/ADT/SmallBitVector.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"

namespace llvm {
  class AAResults;
  template <typename T> class ArrayRef;
  class Loop;
  class LoopInfo;
  class ScalarEvolution;
  class SCEV;
  class SCEVConstant;
  class raw_ostream;

  /// Dependence - This class represents a dependence between two memory
  /// memory references in a function. It contains minimal information and
  /// is used in the very common situation where the compiler is unable to
  /// determine anything beyond the existence of a dependence; that is, it
  /// represents a confused dependence (see also FullDependence). In most
  /// cases (for output, flow, and anti dependences), the dependence implies
  /// an ordering, where the source must precede the destination; in contrast,
  /// input dependences are unordered.
  ///
  /// When a dependence graph is built, each Dependence will be a member of
  /// the set of predecessor edges for its destination instruction and a set
  /// if successor edges for its source instruction. These sets are represented
  /// as singly-linked lists, with the "next" fields stored in the dependence
  /// itelf.
  class Dependence {
  protected:
    Dependence(Dependence &&) = default;
    Dependence &operator=(Dependence &&) = default;

  public:
    Dependence(Instruction *Source, Instruction *Destination)
        : Src(Source), Dst(Destination) {}
    virtual ~Dependence() = default;

    /// Dependence::DVEntry - Each level in the distance/direction vector
    /// has a direction (or perhaps a union of several directions), and
    /// perhaps a distance.
    struct DVEntry {
      enum { NONE = 0,
             LT = 1,
             EQ = 2,
             LE = 3,
             GT = 4,
             NE = 5,
             GE = 6,
             ALL = 7 };
      unsigned char Direction : 3; // Init to ALL, then refine.
      bool Scalar    : 1; // Init to true.
      bool PeelFirst : 1; // Peeling the first iteration will break dependence.
      bool PeelLast  : 1; // Peeling the last iteration will break the dependence.
      bool Splitable : 1; // Splitting the loop will break dependence.
      const SCEV *Distance = nullptr; // NULL implies no distance available.
      DVEntry()
          : Direction(ALL), Scalar(true), PeelFirst(false), PeelLast(false),
            Splitable(false) {}
    };

    /// getSrc - Returns the source instruction for this dependence.
    ///
    Instruction *getSrc() const { return Src; }

    /// getDst - Returns the destination instruction for this dependence.
    ///
    Instruction *getDst() const { return Dst; }

    /// isInput - Returns true if this is an input dependence.
    ///
    bool isInput() const;

    /// isOutput - Returns true if this is an output dependence.
    ///
    bool isOutput() const;

    /// isFlow - Returns true if this is a flow (aka true) dependence.
    ///
    bool isFlow() const;

    /// isAnti - Returns true if this is an anti dependence.
    ///
    bool isAnti() const;

    /// isOrdered - Returns true if dependence is Output, Flow, or Anti
    ///
    bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }

    /// isUnordered - Returns true if dependence is Input
    ///
    bool isUnordered() const { return isInput(); }

    /// isLoopIndependent - Returns true if this is a loop-independent
    /// dependence.
    virtual bool isLoopIndependent() const { return true; }

    /// isConfused - Returns true if this dependence is confused
    /// (the compiler understands nothing and makes worst-case
    /// assumptions).
    virtual bool isConfused() const { return true; }

    /// isConsistent - Returns true if this dependence is consistent
    /// (occurs every time the source and destination are executed).
    virtual bool isConsistent() const { return false; }

    /// getLevels - Returns the number of common loops surrounding the
    /// source and destination of the dependence.
    virtual unsigned getLevels() const { return 0; }

    /// getDirection - Returns the direction associated with a particular
    /// level.
    virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }

    /// getDistance - Returns the distance (or NULL) associated with a
    /// particular level.
    virtual const SCEV *getDistance(unsigned Level) const { return nullptr; }

    /// Check if the direction vector is negative. A negative direction
    /// vector means Src and Dst are reversed in the actual program.
    virtual bool isDirectionNegative() const { return false; }

    /// If the direction vector is negative, normalize the direction
    /// vector to make it non-negative. Normalization is done by reversing
    /// Src and Dst, plus reversing the dependence directions and distances
    /// in the vector.
    virtual bool normalize(ScalarEvolution *SE) { return false; }

    /// isPeelFirst - Returns true if peeling the first iteration from
    /// this loop will break this dependence.
    virtual bool isPeelFirst(unsigned Level) const { return false; }

    /// isPeelLast - Returns true if peeling the last iteration from
    /// this loop will break this dependence.
    virtual bool isPeelLast(unsigned Level) const { return false; }

    /// isSplitable - Returns true if splitting this loop will break
    /// the dependence.
    virtual bool isSplitable(unsigned Level) const { return false; }

    /// isScalar - Returns true if a particular level is scalar; that is,
    /// if no subscript in the source or destination mention the induction
    /// variable associated with the loop at this level.
    virtual bool isScalar(unsigned Level) const;

    /// getNextPredecessor - Returns the value of the NextPredecessor
    /// field.
    const Dependence *getNextPredecessor() const { return NextPredecessor; }

    /// getNextSuccessor - Returns the value of the NextSuccessor
    /// field.
    const Dependence *getNextSuccessor() const { return NextSuccessor; }

    /// setNextPredecessor - Sets the value of the NextPredecessor
    /// field.
    void setNextPredecessor(const Dependence *pred) { NextPredecessor = pred; }

    /// setNextSuccessor - Sets the value of the NextSuccessor
    /// field.
    void setNextSuccessor(const Dependence *succ) { NextSuccessor = succ; }

    /// dump - For debugging purposes, dumps a dependence to OS.
    ///
    void dump(raw_ostream &OS) const;

  protected:
    Instruction *Src, *Dst;

  private:
    const Dependence *NextPredecessor = nullptr, *NextSuccessor = nullptr;
    friend class DependenceInfo;
  };

  /// FullDependence - This class represents a dependence between two memory
  /// references in a function. It contains detailed information about the
  /// dependence (direction vectors, etc.) and is used when the compiler is
  /// able to accurately analyze the interaction of the references; that is,
  /// it is not a confused dependence (see Dependence). In most cases
  /// (for output, flow, and anti dependences), the dependence implies an
  /// ordering, where the source must precede the destination; in contrast,
  /// input dependences are unordered.
  class FullDependence final : public Dependence {
  public:
    FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent,
                   unsigned Levels);

    /// isLoopIndependent - Returns true if this is a loop-independent
    /// dependence.
    bool isLoopIndependent() const override { return LoopIndependent; }

    /// isConfused - Returns true if this dependence is confused
    /// (the compiler understands nothing and makes worst-case
    /// assumptions).
    bool isConfused() const override { return false; }

    /// isConsistent - Returns true if this dependence is consistent
    /// (occurs every time the source and destination are executed).
    bool isConsistent() const override { return Consistent; }

    /// getLevels - Returns the number of common loops surrounding the
    /// source and destination of the dependence.
    unsigned getLevels() const override { return Levels; }

    /// getDirection - Returns the direction associated with a particular
    /// level.
    unsigned getDirection(unsigned Level) const override;

    /// getDistance - Returns the distance (or NULL) associated with a
    /// particular level.
    const SCEV *getDistance(unsigned Level) const override;

    /// Check if the direction vector is negative. A negative direction
    /// vector means Src and Dst are reversed in the actual program.
    bool isDirectionNegative() const override;

    /// If the direction vector is negative, normalize the direction
    /// vector to make it non-negative. Normalization is done by reversing
    /// Src and Dst, plus reversing the dependence directions and distances
    /// in the vector.
    bool normalize(ScalarEvolution *SE) override;

    /// isPeelFirst - Returns true if peeling the first iteration from
    /// this loop will break this dependence.
    bool isPeelFirst(unsigned Level) const override;

    /// isPeelLast - Returns true if peeling the last iteration from
    /// this loop will break this dependence.
    bool isPeelLast(unsigned Level) const override;

    /// isSplitable - Returns true if splitting the loop will break
    /// the dependence.
    bool isSplitable(unsigned Level) const override;

    /// isScalar - Returns true if a particular level is scalar; that is,
    /// if no subscript in the source or destination mention the induction
    /// variable associated with the loop at this level.
    bool isScalar(unsigned Level) const override;

  private:
    unsigned short Levels;
    bool LoopIndependent;
    bool Consistent; // Init to true, then refine.
    std::unique_ptr<DVEntry[]> DV;
    friend class DependenceInfo;
  };

  /// DependenceInfo - This class is the main dependence-analysis driver.
  ///
  class DependenceInfo {
  public:
    DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE,
                   LoopInfo *LI)
        : AA(AA), SE(SE), LI(LI), F(F) {}

    /// Handle transitive invalidation when the cached analysis results go away.
    bool invalidate(Function &F, const PreservedAnalyses &PA,
                    FunctionAnalysisManager::Invalidator &Inv);

    /// depends - Tests for a dependence between the Src and Dst instructions.
    /// Returns NULL if no dependence; otherwise, returns a Dependence (or a
    /// FullDependence) with as much information as can be gleaned.
    /// The flag PossiblyLoopIndependent should be set by the caller
    /// if it appears that control flow can reach from Src to Dst
    /// without traversing a loop back edge.
    std::unique_ptr<Dependence> depends(Instruction *Src,
                                        Instruction *Dst,
                                        bool PossiblyLoopIndependent);

    /// getSplitIteration - Give a dependence that's splittable at some
    /// particular level, return the iteration that should be used to split
    /// the loop.
    ///
    /// Generally, the dependence analyzer will be used to build
    /// a dependence graph for a function (basically a map from instructions
    /// to dependences). Looking for cycles in the graph shows us loops
    /// that cannot be trivially vectorized/parallelized.
    ///
    /// We can try to improve the situation by examining all the dependences
    /// that make up the cycle, looking for ones we can break.
    /// Sometimes, peeling the first or last iteration of a loop will break
    /// dependences, and there are flags for those possibilities.
    /// Sometimes, splitting a loop at some other iteration will do the trick,
    /// and we've got a flag for that case. Rather than waste the space to
    /// record the exact iteration (since we rarely know), we provide
    /// a method that calculates the iteration. It's a drag that it must work
    /// from scratch, but wonderful in that it's possible.
    ///
    /// Here's an example:
    ///
    ///    for (i = 0; i < 10; i++)
    ///        A[i] = ...
    ///        ... = A[11 - i]
    ///
    /// There's a loop-carried flow dependence from the store to the load,
    /// found by the weak-crossing SIV test. The dependence will have a flag,
    /// indicating that the dependence can be broken by splitting the loop.
    /// Calling getSplitIteration will return 5.
    /// Splitting the loop breaks the dependence, like so:
    ///
    ///    for (i = 0; i <= 5; i++)
    ///        A[i] = ...
    ///        ... = A[11 - i]
    ///    for (i = 6; i < 10; i++)
    ///        A[i] = ...
    ///        ... = A[11 - i]
    ///
    /// breaks the dependence and allows us to vectorize/parallelize
    /// both loops.
    const SCEV *getSplitIteration(const Dependence &Dep, unsigned Level);

    Function *getFunction() const { return F; }

  private:
    AAResults *AA;
    ScalarEvolution *SE;
    LoopInfo *LI;
    Function *F;

    /// Subscript - This private struct represents a pair of subscripts from
    /// a pair of potentially multi-dimensional array references. We use a
    /// vector of them to guide subscript partitioning.
    struct Subscript {
      const SCEV *Src;
      const SCEV *Dst;
      enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
      SmallBitVector Loops;
      SmallBitVector GroupLoops;
      SmallBitVector Group;
    };

    struct CoefficientInfo {
      const SCEV *Coeff;
      const SCEV *PosPart;
      const SCEV *NegPart;
      const SCEV *Iterations;
    };

    struct BoundInfo {
      const SCEV *Iterations;
      const SCEV *Upper[8];
      const SCEV *Lower[8];
      unsigned char Direction;
      unsigned char DirSet;
    };

    /// Constraint - This private class represents a constraint, as defined
    /// in the paper
    ///
    ///           Practical Dependence Testing
    ///           Goff, Kennedy, Tseng
    ///           PLDI 1991
    ///
    /// There are 5 kinds of constraint, in a hierarchy.
    ///   1) Any - indicates no constraint, any dependence is possible.
    ///   2) Line - A line ax + by = c, where a, b, and c are parameters,
    ///             representing the dependence equation.
    ///   3) Distance - The value d of the dependence distance;
    ///   4) Point - A point <x, y> representing the dependence from
    ///              iteration x to iteration y.
    ///   5) Empty - No dependence is possible.
    class Constraint {
    private:
      enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
      ScalarEvolution *SE;
      const SCEV *A;
      const SCEV *B;
      const SCEV *C;
      const Loop *AssociatedLoop;

    public:
      /// isEmpty - Return true if the constraint is of kind Empty.
      bool isEmpty() const { return Kind == Empty; }

      /// isPoint - Return true if the constraint is of kind Point.
      bool isPoint() const { return Kind == Point; }

      /// isDistance - Return true if the constraint is of kind Distance.
      bool isDistance() const { return Kind == Distance; }

      /// isLine - Return true if the constraint is of kind Line.
      /// Since Distance's can also be represented as Lines, we also return
      /// true if the constraint is of kind Distance.
      bool isLine() const { return Kind == Line || Kind == Distance; }

      /// isAny - Return true if the constraint is of kind Any;
      bool isAny() const { return Kind == Any; }

      /// getX - If constraint is a point <X, Y>, returns X.
      /// Otherwise assert.
      const SCEV *getX() const;

      /// getY - If constraint is a point <X, Y>, returns Y.
      /// Otherwise assert.
      const SCEV *getY() const;

      /// getA - If constraint is a line AX + BY = C, returns A.
      /// Otherwise assert.
      const SCEV *getA() const;

      /// getB - If constraint is a line AX + BY = C, returns B.
      /// Otherwise assert.
      const SCEV *getB() const;

      /// getC - If constraint is a line AX + BY = C, returns C.
      /// Otherwise assert.
      const SCEV *getC() const;

      /// getD - If constraint is a distance, returns D.
      /// Otherwise assert.
      const SCEV *getD() const;

      /// getAssociatedLoop - Returns the loop associated with this constraint.
      const Loop *getAssociatedLoop() const;

      /// setPoint - Change a constraint to Point.
      void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);

      /// setLine - Change a constraint to Line.
      void setLine(const SCEV *A, const SCEV *B,
                   const SCEV *C, const Loop *CurrentLoop);

      /// setDistance - Change a constraint to Distance.
      void setDistance(const SCEV *D, const Loop *CurrentLoop);

      /// setEmpty - Change a constraint to Empty.
      void setEmpty();

      /// setAny - Change a constraint to Any.
      void setAny(ScalarEvolution *SE);

      /// dump - For debugging purposes. Dumps the constraint
      /// out to OS.
      void dump(raw_ostream &OS) const;
    };

    /// establishNestingLevels - Examines the loop nesting of the Src and Dst
    /// instructions and establishes their shared loops. Sets the variables
    /// CommonLevels, SrcLevels, and MaxLevels.
    /// The source and destination instructions needn't be contained in the same
    /// loop. The routine establishNestingLevels finds the level of most deeply
    /// nested loop that contains them both, CommonLevels. An instruction that's
    /// not contained in a loop is at level = 0. MaxLevels is equal to the level
    /// of the source plus the level of the destination, minus CommonLevels.
    /// This lets us allocate vectors MaxLevels in length, with room for every
    /// distinct loop referenced in both the source and destination subscripts.
    /// The variable SrcLevels is the nesting depth of the source instruction.
    /// It's used to help calculate distinct loops referenced by the destination.
    /// Here's the map from loops to levels:
    ///            0 - unused
    ///            1 - outermost common loop
    ///          ... - other common loops
    /// CommonLevels - innermost common loop
    ///          ... - loops containing Src but not Dst
    ///    SrcLevels - innermost loop containing Src but not Dst
    ///          ... - loops containing Dst but not Src
    ///    MaxLevels - innermost loop containing Dst but not Src
    /// Consider the follow code fragment:
    ///    for (a = ...) {
    ///      for (b = ...) {
    ///        for (c = ...) {
    ///          for (d = ...) {
    ///            A[] = ...;
    ///          }
    ///        }
    ///        for (e = ...) {
    ///          for (f = ...) {
    ///            for (g = ...) {
    ///              ... = A[];
    ///            }
    ///          }
    ///        }
    ///      }
    ///    }
    /// If we're looking at the possibility of a dependence between the store
    /// to A (the Src) and the load from A (the Dst), we'll note that they
    /// have 2 loops in common, so CommonLevels will equal 2 and the direction
    /// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
    /// A map from loop names to level indices would look like
    ///     a - 1
    ///     b - 2 = CommonLevels
    ///     c - 3
    ///     d - 4 = SrcLevels
    ///     e - 5
    ///     f - 6
    ///     g - 7 = MaxLevels
    void establishNestingLevels(const Instruction *Src,
                                const Instruction *Dst);

    unsigned CommonLevels, SrcLevels, MaxLevels;

    /// mapSrcLoop - Given one of the loops containing the source, return
    /// its level index in our numbering scheme.
    unsigned mapSrcLoop(const Loop *SrcLoop) const;

    /// mapDstLoop - Given one of the loops containing the destination,
    /// return its level index in our numbering scheme.
    unsigned mapDstLoop(const Loop *DstLoop) const;

    /// isLoopInvariant - Returns true if Expression is loop invariant
    /// in LoopNest.
    bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;

    /// Makes sure all subscript pairs share the same integer type by
    /// sign-extending as necessary.
    /// Sign-extending a subscript is safe because getelementptr assumes the
    /// array subscripts are signed.
    void unifySubscriptType(ArrayRef<Subscript *> Pairs);

    /// removeMatchingExtensions - Examines a subscript pair.
    /// If the source and destination are identically sign (or zero)
    /// extended, it strips off the extension in an effort to
    /// simplify the actual analysis.
    void removeMatchingExtensions(Subscript *Pair);

    /// collectCommonLoops - Finds the set of loops from the LoopNest that
    /// have a level <= CommonLevels and are referred to by the SCEV Expression.
    void collectCommonLoops(const SCEV *Expression,
                            const Loop *LoopNest,
                            SmallBitVector &Loops) const;

    /// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
    /// linear. Collect the set of loops mentioned by Src.
    bool checkSrcSubscript(const SCEV *Src,
                           const Loop *LoopNest,
                           SmallBitVector &Loops);

    /// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
    /// linear. Collect the set of loops mentioned by Dst.
    bool checkDstSubscript(const SCEV *Dst,
                           const Loop *LoopNest,
                           SmallBitVector &Loops);

    /// isKnownPredicate - Compare X and Y using the predicate Pred.
    /// Basically a wrapper for SCEV::isKnownPredicate,
    /// but tries harder, especially in the presence of sign and zero
    /// extensions and symbolics.
    bool isKnownPredicate(ICmpInst::Predicate Pred,
                          const SCEV *X,
                          const SCEV *Y) const;

    /// isKnownLessThan - Compare to see if S is less than Size
    /// Another wrapper for isKnownNegative(S - max(Size, 1)) with some extra
    /// checking if S is an AddRec and we can prove lessthan using the loop
    /// bounds.
    bool isKnownLessThan(const SCEV *S, const SCEV *Size) const;

    /// isKnownNonNegative - Compare to see if S is known not to be negative
    /// Uses the fact that S comes from Ptr, which may be an inbound GEP,
    /// Proving there is no wrapping going on.
    bool isKnownNonNegative(const SCEV *S, const Value *Ptr) const;

    /// collectUpperBound - All subscripts are the same type (on my machine,
    /// an i64). The loop bound may be a smaller type. collectUpperBound
    /// find the bound, if available, and zero extends it to the Type T.
    /// (I zero extend since the bound should always be >= 0.)
    /// If no upper bound is available, return NULL.
    const SCEV *collectUpperBound(const Loop *l, Type *T) const;

    /// collectConstantUpperBound - Calls collectUpperBound(), then
    /// attempts to cast it to SCEVConstant. If the cast fails,
    /// returns NULL.
    const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const;

    /// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
    /// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
    /// Collects the associated loops in a set.
    Subscript::ClassificationKind classifyPair(const SCEV *Src,
                                           const Loop *SrcLoopNest,
                                           const SCEV *Dst,
                                           const Loop *DstLoopNest,
                                           SmallBitVector &Loops);

    /// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// If the dependence isn't proven to exist,
    /// marks the Result as inconsistent.
    bool testZIV(const SCEV *Src,
                 const SCEV *Dst,
                 FullDependence &Result) const;

    /// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
    /// Things of the form [c1 + a1*i] and [c2 + a2*j], where
    /// i and j are induction variables, c1 and c2 are loop invariant,
    /// and a1 and a2 are constant.
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Sets appropriate direction vector entry and, when possible,
    /// the distance vector entry.
    /// If the dependence isn't proven to exist,
    /// marks the Result as inconsistent.
    bool testSIV(const SCEV *Src,
                 const SCEV *Dst,
                 unsigned &Level,
                 FullDependence &Result,
                 Constraint &NewConstraint,
                 const SCEV *&SplitIter) const;

    /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
    /// Things of the form [c1 + a1*i] and [c2 + a2*j]
    /// where i and j are induction variables, c1 and c2 are loop invariant,
    /// and a1 and a2 are constant.
    /// With minor algebra, this test can also be used for things like
    /// [c1 + a1*i + a2*j][c2].
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Marks the Result as inconsistent.
    bool testRDIV(const SCEV *Src,
                  const SCEV *Dst,
                  FullDependence &Result) const;

    /// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
    /// Returns true if dependence disproved.
    /// Can sometimes refine direction vectors.
    bool testMIV(const SCEV *Src,
                 const SCEV *Dst,
                 const SmallBitVector &Loops,
                 FullDependence &Result) const;

    /// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst)
    /// for dependence.
    /// Things of the form [c1 + a*i] and [c2 + a*i],
    /// where i is an induction variable, c1 and c2 are loop invariant,
    /// and a is a constant
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Sets appropriate direction and distance.
    bool strongSIVtest(const SCEV *Coeff,
                       const SCEV *SrcConst,
                       const SCEV *DstConst,
                       const Loop *CurrentLoop,
                       unsigned Level,
                       FullDependence &Result,
                       Constraint &NewConstraint) const;

    /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
    /// (Src and Dst) for dependence.
    /// Things of the form [c1 + a*i] and [c2 - a*i],
    /// where i is an induction variable, c1 and c2 are loop invariant,
    /// and a is a constant.
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Sets appropriate direction entry.
    /// Set consistent to false.
    /// Marks the dependence as splitable.
    bool weakCrossingSIVtest(const SCEV *SrcCoeff,
                             const SCEV *SrcConst,
                             const SCEV *DstConst,
                             const Loop *CurrentLoop,
                             unsigned Level,
                             FullDependence &Result,
                             Constraint &NewConstraint,
                             const SCEV *&SplitIter) const;

    /// ExactSIVtest - Tests the SIV subscript pair
    /// (Src and Dst) for dependence.
    /// Things of the form [c1 + a1*i] and [c2 + a2*i],
    /// where i is an induction variable, c1 and c2 are loop invariant,
    /// and a1 and a2 are constant.
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Sets appropriate direction entry.
    /// Set consistent to false.
    bool exactSIVtest(const SCEV *SrcCoeff,
                      const SCEV *DstCoeff,
                      const SCEV *SrcConst,
                      const SCEV *DstConst,
                      const Loop *CurrentLoop,
                      unsigned Level,
                      FullDependence &Result,
                      Constraint &NewConstraint) const;

    /// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
    /// (Src and Dst) for dependence.
    /// Things of the form [c1] and [c2 + a*i],
    /// where i is an induction variable, c1 and c2 are loop invariant,
    /// and a is a constant. See also weakZeroDstSIVtest.
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Sets appropriate direction entry.
    /// Set consistent to false.
    /// If loop peeling will break the dependence, mark appropriately.
    bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
                            const SCEV *SrcConst,
                            const SCEV *DstConst,
                            const Loop *CurrentLoop,
                            unsigned Level,
                            FullDependence &Result,
                            Constraint &NewConstraint) const;

    /// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
    /// (Src and Dst) for dependence.
    /// Things of the form [c1 + a*i] and [c2],
    /// where i is an induction variable, c1 and c2 are loop invariant,
    /// and a is a constant. See also weakZeroSrcSIVtest.
    /// Returns true if any possible dependence is disproved.
    /// If there might be a dependence, returns false.
    /// Sets appropriate direction entry.
    /// Set consistent to false.
    /// If loop peeling will break the dependence, mark appropriately.
    bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
                            const SCEV *SrcConst,
                            const SCEV *DstConst,
                            const Loop *CurrentLoop,
                            unsigned Level,
                            FullDependence &Result,
                            Constraint &NewConstraint) const;

    /// exactRDIVtest - Tests the RDIV subscript pair for dependence.
    /// Things of the form [c1 + a*i] and [c2 + b*j],
    /// where i and j are induction variable, c1 and c2 are loop invariant,
    /// and a and b are constants.
    /// Returns true if any possible dependence is disproved.
    /// Marks the result as inconsistent.
    /// Works in some cases that symbolicRDIVtest doesn't,
    /// and vice versa.
    bool exactRDIVtest(const SCEV *SrcCoeff,
                       const SCEV *DstCoeff,
                       const SCEV *SrcConst,
                       const SCEV *DstConst,
                       const Loop *SrcLoop,
                       const Loop *DstLoop,
                       FullDependence &Result) const;

    /// symbolicRDIVtest - Tests the RDIV subscript pair for dependence.
    /// Things of the form [c1 + a*i] and [c2 + b*j],
    /// where i and j are induction variable, c1 and c2 are loop invariant,
    /// and a and b are constants.
    /// Returns true if any possible dependence is disproved.
    /// Marks the result as inconsistent.
    /// Works in some cases that exactRDIVtest doesn't,
    /// and vice versa. Can also be used as a backup for
    /// ordinary SIV tests.
    bool symbolicRDIVtest(const SCEV *SrcCoeff,
                          const SCEV *DstCoeff,
                          const SCEV *SrcConst,
                          const SCEV *DstConst,
                          const Loop *SrcLoop,
                          const Loop *DstLoop) const;

    /// gcdMIVtest - Tests an MIV subscript pair for dependence.
    /// Returns true if any possible dependence is disproved.
    /// Marks the result as inconsistent.
    /// Can sometimes disprove the equal direction for 1 or more loops.
    //  Can handle some symbolics that even the SIV tests don't get,
    /// so we use it as a backup for everything.
    bool gcdMIVtest(const SCEV *Src,
                    const SCEV *Dst,
                    FullDependence &Result) const;

    /// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
    /// Returns true if any possible dependence is disproved.
    /// Marks the result as inconsistent.
    /// Computes directions.
    bool banerjeeMIVtest(const SCEV *Src,
                         const SCEV *Dst,
                         const SmallBitVector &Loops,
                         FullDependence &Result) const;

    /// collectCoefficientInfo - Walks through the subscript,
    /// collecting each coefficient, the associated loop bounds,
    /// and recording its positive and negative parts for later use.
    CoefficientInfo *collectCoeffInfo(const SCEV *Subscript,
                                      bool SrcFlag,
                                      const SCEV *&Constant) const;

    /// getPositivePart - X^+ = max(X, 0).
    ///
    const SCEV *getPositivePart(const SCEV *X) const;

    /// getNegativePart - X^- = min(X, 0).
    ///
    const SCEV *getNegativePart(const SCEV *X) const;

    /// getLowerBound - Looks through all the bounds info and
    /// computes the lower bound given the current direction settings
    /// at each level.
    const SCEV *getLowerBound(BoundInfo *Bound) const;

    /// getUpperBound - Looks through all the bounds info and
    /// computes the upper bound given the current direction settings
    /// at each level.
    const SCEV *getUpperBound(BoundInfo *Bound) const;

    /// exploreDirections - Hierarchically expands the direction vector
    /// search space, combining the directions of discovered dependences
    /// in the DirSet field of Bound. Returns the number of distinct
    /// dependences discovered. If the dependence is disproved,
    /// it will return 0.
    unsigned exploreDirections(unsigned Level,
                               CoefficientInfo *A,
                               CoefficientInfo *B,
                               BoundInfo *Bound,
                               const SmallBitVector &Loops,
                               unsigned &DepthExpanded,
                               const SCEV *Delta) const;

    /// testBounds - Returns true iff the current bounds are plausible.
    bool testBounds(unsigned char DirKind,
                    unsigned Level,
                    BoundInfo *Bound,
                    const SCEV *Delta) const;

    /// findBoundsALL - Computes the upper and lower bounds for level K
    /// using the * direction. Records them in Bound.
    void findBoundsALL(CoefficientInfo *A,
                       CoefficientInfo *B,
                       BoundInfo *Bound,
                       unsigned K) const;

    /// findBoundsLT - Computes the upper and lower bounds for level K
    /// using the < direction. Records them in Bound.
    void findBoundsLT(CoefficientInfo *A,
                      CoefficientInfo *B,
                      BoundInfo *Bound,
                      unsigned K) const;

    /// findBoundsGT - Computes the upper and lower bounds for level K
    /// using the > direction. Records them in Bound.
    void findBoundsGT(CoefficientInfo *A,
                      CoefficientInfo *B,
                      BoundInfo *Bound,
                      unsigned K) const;

    /// findBoundsEQ - Computes the upper and lower bounds for level K
    /// using the = direction. Records them in Bound.
    void findBoundsEQ(CoefficientInfo *A,
                      CoefficientInfo *B,
                      BoundInfo *Bound,
                      unsigned K) const;

    /// intersectConstraints - Updates X with the intersection
    /// of the Constraints X and Y. Returns true if X has changed.
    bool intersectConstraints(Constraint *X,
                              const Constraint *Y);

    /// propagate - Review the constraints, looking for opportunities
    /// to simplify a subscript pair (Src and Dst).
    /// Return true if some simplification occurs.
    /// If the simplification isn't exact (that is, if it is conservative
    /// in terms of dependence), set consistent to false.
    bool propagate(const SCEV *&Src,
                   const SCEV *&Dst,
                   SmallBitVector &Loops,
                   SmallVectorImpl<Constraint> &Constraints,
                   bool &Consistent);

    /// propagateDistance - Attempt to propagate a distance
    /// constraint into a subscript pair (Src and Dst).
    /// Return true if some simplification occurs.
    /// If the simplification isn't exact (that is, if it is conservative
    /// in terms of dependence), set consistent to false.
    bool propagateDistance(const SCEV *&Src,
                           const SCEV *&Dst,
                           Constraint &CurConstraint,
                           bool &Consistent);

    /// propagatePoint - Attempt to propagate a point
    /// constraint into a subscript pair (Src and Dst).
    /// Return true if some simplification occurs.
    bool propagatePoint(const SCEV *&Src,
                        const SCEV *&Dst,
                        Constraint &CurConstraint);

    /// propagateLine - Attempt to propagate a line
    /// constraint into a subscript pair (Src and Dst).
    /// Return true if some simplification occurs.
    /// If the simplification isn't exact (that is, if it is conservative
    /// in terms of dependence), set consistent to false.
    bool propagateLine(const SCEV *&Src,
                       const SCEV *&Dst,
                       Constraint &CurConstraint,
                       bool &Consistent);

    /// findCoefficient - Given a linear SCEV,
    /// return the coefficient corresponding to specified loop.
    /// If there isn't one, return the SCEV constant 0.
    /// For example, given a*i + b*j + c*k, returning the coefficient
    /// corresponding to the j loop would yield b.
    const SCEV *findCoefficient(const SCEV *Expr,
                                const Loop *TargetLoop) const;

    /// zeroCoefficient - Given a linear SCEV,
    /// return the SCEV given by zeroing out the coefficient
    /// corresponding to the specified loop.
    /// For example, given a*i + b*j + c*k, zeroing the coefficient
    /// corresponding to the j loop would yield a*i + c*k.
    const SCEV *zeroCoefficient(const SCEV *Expr,
                                const Loop *TargetLoop) const;

    /// addToCoefficient - Given a linear SCEV Expr,
    /// return the SCEV given by adding some Value to the
    /// coefficient corresponding to the specified TargetLoop.
    /// For example, given a*i + b*j + c*k, adding 1 to the coefficient
    /// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
    const SCEV *addToCoefficient(const SCEV *Expr,
                                 const Loop *TargetLoop,
                                 const SCEV *Value)  const;

    /// updateDirection - Update direction vector entry
    /// based on the current constraint.
    void updateDirection(Dependence::DVEntry &Level,
                         const Constraint &CurConstraint) const;

    /// Given a linear access function, tries to recover subscripts
    /// for each dimension of the array element access.
    bool tryDelinearize(Instruction *Src, Instruction *Dst,
                        SmallVectorImpl<Subscript> &Pair);

    /// Tries to delinearize \p Src and \p Dst access functions for a fixed size
    /// multi-dimensional array. Calls tryDelinearizeFixedSizeImpl() to
    /// delinearize \p Src and \p Dst separately,
    bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
                                 const SCEV *SrcAccessFn,
                                 const SCEV *DstAccessFn,
                                 SmallVectorImpl<const SCEV *> &SrcSubscripts,
                                 SmallVectorImpl<const SCEV *> &DstSubscripts);

    /// Tries to delinearize access function for a multi-dimensional array with
    /// symbolic runtime sizes.
    /// Returns true upon success and false otherwise.
    bool tryDelinearizeParametricSize(
        Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
        const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
        SmallVectorImpl<const SCEV *> &DstSubscripts);

    /// checkSubscript - Helper function for checkSrcSubscript and
    /// checkDstSubscript to avoid duplicate code
    bool checkSubscript(const SCEV *Expr, const Loop *LoopNest,
                        SmallBitVector &Loops, bool IsSrc);
  }; // class DependenceInfo

  /// AnalysisPass to compute dependence information in a function
  class DependenceAnalysis : public AnalysisInfoMixin<DependenceAnalysis> {
  public:
    typedef DependenceInfo Result;
    Result run(Function &F, FunctionAnalysisManager &FAM);

  private:
    static AnalysisKey Key;
    friend struct AnalysisInfoMixin<DependenceAnalysis>;
  }; // class DependenceAnalysis

  /// Printer pass to dump DA results.
  struct DependenceAnalysisPrinterPass
      : public PassInfoMixin<DependenceAnalysisPrinterPass> {
    DependenceAnalysisPrinterPass(raw_ostream &OS,
                                  bool NormalizeResults = false)
        : OS(OS), NormalizeResults(NormalizeResults) {}

    PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);

  private:
    raw_ostream &OS;
    bool NormalizeResults;
  }; // class DependenceAnalysisPrinterPass

  /// Legacy pass manager pass to access dependence information
  class DependenceAnalysisWrapperPass : public FunctionPass {
  public:
    static char ID; // Class identification, replacement for typeinfo
    DependenceAnalysisWrapperPass();

    bool runOnFunction(Function &F) override;
    void releaseMemory() override;
    void getAnalysisUsage(AnalysisUsage &) const override;
    void print(raw_ostream &, const Module * = nullptr) const override;
    DependenceInfo &getDI() const;

  private:
    std::unique_ptr<DependenceInfo> info;
  }; // class DependenceAnalysisWrapperPass

  /// createDependenceAnalysisPass - This creates an instance of the
  /// DependenceAnalysis wrapper pass.
  FunctionPass *createDependenceAnalysisWrapperPass();

} // namespace llvm

#endif
