39#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
40#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
79 :
Src(Source),
Dst(Destination), Assumptions(
A) {}
96 enum :
unsigned char {
127 bool isOutput()
const;
167 virtual unsigned getDirection(
unsigned Level,
bool SameSD =
false)
const {
189 virtual bool isPeelFirst(
unsigned Level,
bool SameSD =
false)
const {
195 virtual bool isPeelLast(
unsigned Level,
bool SameSD =
false)
const {
201 virtual bool isSplitable(
unsigned Level,
bool SameSD =
false)
const {
213 virtual bool isScalar(
unsigned Level,
bool SameSD =
false)
const;
237 void dumpImp(
raw_ostream &OS,
bool SameSD =
false)
const;
244 const Dependence *NextPredecessor =
nullptr, *NextSuccessor =
nullptr;
260 bool PossiblyLoopIndependent,
unsigned Levels);
287 assert(0 < Level && Level <= Levels &&
"Level out of range");
288 return DV[Level - 1];
291 Level <=
static_cast<unsigned>(Levels) + SameSDLevels &&
292 "isSameSD level out of range");
293 return DVSameSD[Level - Levels - 1];
299 unsigned getDirection(
unsigned Level,
bool SameSD =
false)
const override;
303 const SCEV *getDistance(
unsigned Level,
bool SameSD =
false)
const override;
307 bool isDirectionNegative()
const override;
317 bool isPeelFirst(
unsigned Level,
bool SameSD =
false)
const override;
321 bool isPeelLast(
unsigned Level,
bool SameSD =
false)
const override;
325 bool isSplitable(
unsigned Level,
bool SameSD =
false)
const override;
330 bool inSameSDLoops(
unsigned Level)
const override;
335 bool isScalar(
unsigned Level,
bool SameSD =
false)
const override;
338 unsigned short Levels;
339 unsigned short SameSDLevels;
340 bool LoopIndependent;
342 std::unique_ptr<DVEntry[]> DV;
343 std::unique_ptr<DVEntry[]> DVSameSD;
351 : AA(AA), SE(SE), LI(LI), F(F) {}
355 FunctionAnalysisManager::Invalidator &Inv);
364 LLVM_ABI std::unique_ptr<Dependence>
366 bool UnderRuntimeAssumptions =
false);
429 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
430 SmallBitVector
Loops;
431 SmallBitVector GroupLoops;
432 SmallBitVector Group;
435 struct CoefficientInfo {
439 const SCEV *Iterations;
443 const SCEV *Iterations;
444 const SCEV *Upper[8];
445 const SCEV *Lower[8];
446 unsigned char Direction;
447 unsigned char DirSet;
467 enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
472 const Loop *AssociatedSrcLoop;
473 const Loop *AssociatedDstLoop;
477 bool isEmpty()
const {
return Kind == Empty; }
480 bool isPoint()
const {
return Kind == Point; }
483 bool isDistance()
const {
return Kind == Distance; }
488 bool isLine()
const {
return Kind == Line || Kind == Distance; }
491 bool isAny()
const {
return Kind == Any; }
519 LLVM_ABI const Loop *getAssociatedSrcLoop()
const;
523 LLVM_ABI const Loop *getAssociatedDstLoop()
const;
526 LLVM_ABI void setPoint(
const SCEV *
X,
const SCEV *
Y,
527 const Loop *CurrentSrcLoop,
528 const Loop *CurrentDstLoop);
531 LLVM_ABI void setLine(
const SCEV *A,
const SCEV *B,
const SCEV *C,
532 const Loop *CurrentSrcLoop,
533 const Loop *CurrentDstLoop);
536 LLVM_ABI void setDistance(
const SCEV *
D,
const Loop *CurrentSrcLoop,
537 const Loop *CurrentDstLoop);
543 LLVM_ABI void setAny(ScalarEvolution *SE);
547 LLVM_ABI void dump(raw_ostream &OS)
const;
554 bool haveSameSD(
const Loop *SrcLoop,
const Loop *DstLoop)
const;
618 void establishNestingLevels(
const Instruction *Src,
const Instruction *Dst);
620 unsigned CommonLevels, SrcLevels, MaxLevels, SameSDLevels;
624 unsigned mapSrcLoop(
const Loop *SrcLoop)
const;
628 unsigned mapDstLoop(
const Loop *DstLoop)
const;
632 bool isLoopInvariant(
const SCEV *Expression,
const Loop *LoopNest)
const;
644 void removeMatchingExtensions(Subscript *Pair);
648 void collectCommonLoops(
const SCEV *Expression,
const Loop *LoopNest,
649 SmallBitVector &
Loops)
const;
653 bool checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
654 SmallBitVector &
Loops);
658 bool checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
659 SmallBitVector &
Loops);
666 const SCEV *
Y)
const;
672 bool isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const;
677 bool isKnownNonNegative(
const SCEV *S,
const Value *
Ptr)
const;
684 const SCEV *collectUpperBound(
const Loop *l,
Type *
T)
const;
689 const SCEVConstant *collectConstantUpperBound(
const Loop *l,
Type *
T)
const;
694 Subscript::ClassificationKind
695 classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
696 const Loop *DstLoopNest, SmallBitVector &
Loops);
703 bool testZIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
715 bool testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
716 FullDependence &Result, Constraint &NewConstraint,
717 const SCEV *&SplitIter)
const;
728 bool testRDIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
733 bool testMIV(
const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &
Loops,
734 FullDependence &Result)
const;
744 bool strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
745 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
746 const Loop *CurrentDstLoop,
unsigned Level,
747 FullDependence &Result, Constraint &NewConstraint)
const;
759 bool weakCrossingSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
760 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
761 const Loop *CurrentDstLoop,
unsigned Level,
762 FullDependence &Result, Constraint &NewConstraint,
763 const SCEV *&SplitIter)
const;
774 bool exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
775 const SCEV *SrcConst,
const SCEV *DstConst,
776 const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop,
777 unsigned Level, FullDependence &Result,
778 Constraint &NewConstraint)
const;
790 bool weakZeroSrcSIVtest(
const SCEV *DstCoeff,
const SCEV *SrcConst,
791 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
792 const Loop *CurrentDstLoop,
unsigned Level,
793 FullDependence &Result,
794 Constraint &NewConstraint)
const;
806 bool weakZeroDstSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
807 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
808 const Loop *CurrentDstLoop,
unsigned Level,
809 FullDependence &Result,
810 Constraint &NewConstraint)
const;
820 bool exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
821 const SCEV *SrcConst,
const SCEV *DstConst,
822 const Loop *SrcLoop,
const Loop *DstLoop,
823 FullDependence &Result)
const;
834 bool symbolicRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
835 const SCEV *SrcConst,
const SCEV *DstConst,
836 const Loop *SrcLoop,
const Loop *DstLoop)
const;
844 bool gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
845 FullDependence &Result)
const;
851 bool banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
852 const SmallBitVector &
Loops,
853 FullDependence &Result)
const;
858 CoefficientInfo *collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
859 const SCEV *&Constant)
const;
876 bool accumulateCoefficientsGCD(
const SCEV *Expr,
const Loop *CurLoop,
877 const SCEV *&CurLoopCoeff,
878 APInt &RunningGCD)
const;
881 const SCEV *getPositivePart(
const SCEV *
X)
const;
884 const SCEV *getNegativePart(
const SCEV *
X)
const;
889 const SCEV *getLowerBound(BoundInfo *Bound)
const;
894 const SCEV *getUpperBound(BoundInfo *Bound)
const;
901 unsigned exploreDirections(
unsigned Level, CoefficientInfo *
A,
902 CoefficientInfo *
B, BoundInfo *Bound,
903 const SmallBitVector &
Loops,
904 unsigned &DepthExpanded,
const SCEV *Delta)
const;
907 bool testBounds(
unsigned char DirKind,
unsigned Level, BoundInfo *Bound,
908 const SCEV *Delta)
const;
912 void findBoundsALL(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
917 void findBoundsLT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
922 void findBoundsGT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
927 void findBoundsEQ(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
932 bool intersectConstraints(Constraint *
X,
const Constraint *
Y);
939 bool propagate(
const SCEV *&Src,
const SCEV *&Dst, SmallBitVector &
Loops,
940 SmallVectorImpl<Constraint> &Constraints,
bool &Consistent);
947 bool propagateDistance(
const SCEV *&Src,
const SCEV *&Dst,
948 Constraint &CurConstraint,
bool &Consistent);
953 bool propagatePoint(
const SCEV *&Src,
const SCEV *&Dst,
954 Constraint &CurConstraint);
961 bool propagateLine(
const SCEV *&Src,
const SCEV *&Dst,
962 Constraint &CurConstraint,
bool &Consistent);
969 const SCEV *findCoefficient(
const SCEV *Expr,
const Loop *TargetLoop)
const;
976 const SCEV *zeroCoefficient(
const SCEV *Expr,
const Loop *TargetLoop)
const;
983 const SCEV *addToCoefficient(
const SCEV *Expr,
const Loop *TargetLoop,
984 const SCEV *
Value)
const;
988 void updateDirection(Dependence::DVEntry &Level,
989 const Constraint &CurConstraint)
const;
993 bool tryDelinearize(Instruction *Src, Instruction *Dst,
994 SmallVectorImpl<Subscript> &Pair);
999 bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
1000 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
1001 SmallVectorImpl<const SCEV *> &SrcSubscripts,
1002 SmallVectorImpl<const SCEV *> &DstSubscripts);
1008 tryDelinearizeParametricSize(Instruction *Src, Instruction *Dst,
1009 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
1010 SmallVectorImpl<const SCEV *> &SrcSubscripts,
1011 SmallVectorImpl<const SCEV *> &DstSubscripts);
1015 bool checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
1016 SmallBitVector &
Loops,
bool IsSrc);
1034 : OS(OS), NormalizeResults(NormalizeResults) {}
1042 bool NormalizeResults;
1058 std::unique_ptr<DependenceInfo> info;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runOnFunction(Function &F, bool PostInlining)
This header defines various interfaces for pass management in LLVM.
static bool isInput(const ArrayRef< StringRef > &Prefixes, StringRef Arg)
FunctionAnalysisManager FAM
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Represent the analysis usage information of a pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
DependenceInfo & getDI() const
DependenceAnalysisWrapperPass()
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
AnalysisPass to compute dependence information in a function.
LLVM_ABI Result run(Function &F, FunctionAnalysisManager &FAM)
DependenceInfo - This class is the main dependence-analysis driver.
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle transitive invalidation when the cached analysis results go away.
LLVM_ABI const SCEV * getSplitIteration(const Dependence &Dep, unsigned Level)
getSplitIteration - Give a dependence that's splittable at some particular level, return the iteratio...
Function * getFunction() const
LLVM_ABI SCEVUnionPredicate getRuntimeAssumptions() const
getRuntimeAssumptions - Returns all the runtime assumptions under which the dependence test is valid.
DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE, LoopInfo *LI)
LLVM_ABI std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool UnderRuntimeAssumptions=false)
depends - Tests for a dependence between the Src and Dst instructions.
Dependence - This class represents a dependence between two memory memory references in a function.
Instruction * getDst() const
getDst - Returns the destination instruction for this dependence.
Dependence & operator=(Dependence &&)=default
bool isOrdered() const
isOrdered - Returns true if dependence is Output, Flow, or Anti
void setNextSuccessor(const Dependence *succ)
setNextSuccessor - Sets the value of the NextSuccessor field.
friend class DependenceInfo
Dependence(Instruction *Source, Instruction *Destination, const SCEVUnionPredicate &A)
Dependence(Dependence &&)=default
bool isUnordered() const
isUnordered - Returns true if dependence is Input
SCEVUnionPredicate getRuntimeAssumptions() const
getRuntimeAssumptions - Returns the runtime assumptions under which this Dependence relation is valid...
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
virtual unsigned getSameSDLevels() const
getSameSDLevels - Returns the number of separate SameSD loops surrounding the source and destination ...
virtual const SCEV * getDistance(unsigned Level, bool SameSD=false) const
getDistance - Returns the distance (or NULL) associated with a particular common or SameSD level.
virtual bool isPeelLast(unsigned Level, bool SameSD=false) const
isPeelLast - Returns true if peeling the last iteration from this regular or SameSD loop level will b...
virtual bool isConsistent() const
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
virtual unsigned getLevels() const
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
const Dependence * getNextPredecessor() const
getNextPredecessor - Returns the value of the NextPredecessor field.
virtual unsigned getDirection(unsigned Level, bool SameSD=false) const
getDirection - Returns the direction associated with a particular common or SameSD level.
DVEntry getDVEntry(unsigned Level, bool isSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
virtual bool isPeelFirst(unsigned Level, bool SameSD=false) const
isPeelFirst - Returns true if peeling the first iteration from this regular or SameSD loop level will...
virtual ~Dependence()=default
virtual bool normalize(ScalarEvolution *SE)
If the direction vector is negative, normalize the direction vector to make it non-negative.
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
virtual bool isSplitable(unsigned Level, bool SameSD=false) const
isSplitable - Returns true if splitting the loop will break the dependence.
const Dependence * getNextSuccessor() const
getNextSuccessor - Returns the value of the NextSuccessor field.
virtual bool isDirectionNegative() const
Check if the direction vector is negative.
Instruction * getSrc() const
getSrc - Returns the source instruction for this dependence.
virtual bool isLoopIndependent() const
isLoopIndependent - Returns true if this is a loop-independent dependence.
bool isOutput() const
isOutput - Returns true if this is an output dependence.
void setNextPredecessor(const Dependence *pred)
setNextPredecessor - Sets the value of the NextPredecessor field.
virtual bool inSameSDLoops(unsigned Level) const
inSameSDLoops - Returns true if this level is an SameSD level, i.e., performed across two separate lo...
FullDependence(Instruction *Source, Instruction *Destination, const SCEVUnionPredicate &Assumes, bool PossiblyLoopIndependent, unsigned Levels)
bool isConfused() const override
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
friend class DependenceInfo
bool isLoopIndependent() const override
isLoopIndependent - Returns true if this is a loop-independent dependence.
unsigned getSameSDLevels() const override
getSameSDLevels - Returns the number of separate SameSD loops surrounding the source and destination ...
unsigned getLevels() const override
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
DVEntry getDVEntry(unsigned Level, bool isSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level.
bool isConsistent() const override
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
FunctionPass class - This class is used to implement most global optimizations.
Represents a single loop in the control flow graph.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
This class represents a constant integer value.
This class represents a composition of other SCEV predicates, and is the class that most clients will...
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
Abstract Attribute helper functions.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
ArrayRef(const T &OneElt) -> ArrayRef< T >
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI FunctionPass * createDependenceAnalysisWrapperPass()
createDependenceAnalysisPass - This creates an instance of the DependenceAnalysis wrapper pass.
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
DependenceAnalysisPrinterPass(raw_ostream &OS, bool NormalizeResults=false)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Dependence::DVEntry - Each level in the distance/direction vector has a direction (or perhaps a union...
A CRTP mix-in to automatically provide informational APIs needed for passes.