39#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
40#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
49 template <
typename T>
class ArrayRef;
52 class ScalarEvolution;
78 :
Src(Source),
Dst(Destination) {}
85 enum :
unsigned char {
179 virtual bool isPeelLast(
unsigned Level)
const {
return false; }
188 virtual bool isScalar(
unsigned Level)
const;
214 const Dependence *NextPredecessor =
nullptr, *NextSuccessor =
nullptr;
272 bool isPeelLast(
unsigned Level)
const override;
281 bool isScalar(
unsigned Level)
const override;
284 unsigned short Levels;
285 bool LoopIndependent;
287 std::unique_ptr<DVEntry[]> DV;
297 : AA(AA), SE(SE), LI(LI),
F(
F) {}
311 bool PossiblyLoopIndependent);
369 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
370 SmallBitVector
Loops;
371 SmallBitVector GroupLoops;
372 SmallBitVector Group;
375 struct CoefficientInfo {
379 const SCEV *Iterations;
383 const SCEV *Iterations;
384 const SCEV *
Upper[8];
385 const SCEV *
Lower[8];
387 unsigned char DirSet;
412 const Loop *AssociatedLoop;
416 bool isEmpty()
const {
return Kind ==
Empty; }
419 bool isPoint()
const {
return Kind == Point; }
422 bool isDistance()
const {
return Kind == Distance; }
427 bool isLine()
const {
return Kind ==
Line ||
Kind == Distance; }
430 bool isAny()
const {
return Kind ==
Any; }
434 const SCEV *getX()
const;
438 const SCEV *getY()
const;
442 const SCEV *getA()
const;
446 const SCEV *getB()
const;
450 const SCEV *getC()
const;
454 const SCEV *getD()
const;
457 const Loop *getAssociatedLoop()
const;
460 void setPoint(
const SCEV *
X,
const SCEV *
Y,
const Loop *CurrentLoop);
463 void setLine(
const SCEV *A,
const SCEV *B,
464 const SCEV *C,
const Loop *CurrentLoop);
467 void setDistance(
const SCEV *
D,
const Loop *CurrentLoop);
473 void setAny(ScalarEvolution *SE);
477 void dump(raw_ostream &
OS)
const;
530 void establishNestingLevels(
const Instruction *Src,
531 const Instruction *Dst);
533 unsigned CommonLevels, SrcLevels, MaxLevels;
537 unsigned mapSrcLoop(
const Loop *SrcLoop)
const;
541 unsigned mapDstLoop(
const Loop *DstLoop)
const;
545 bool isLoopInvariant(
const SCEV *Expression,
const Loop *LoopNest)
const;
551 void unifySubscriptType(ArrayRef<Subscript *> Pairs);
557 void removeMatchingExtensions(Subscript *Pair);
561 void collectCommonLoops(
const SCEV *Expression,
562 const Loop *LoopNest,
563 SmallBitVector &
Loops)
const;
567 bool checkSrcSubscript(
const SCEV *Src,
568 const Loop *LoopNest,
569 SmallBitVector &
Loops);
573 bool checkDstSubscript(
const SCEV *Dst,
574 const Loop *LoopNest,
575 SmallBitVector &
Loops);
583 const SCEV *
Y)
const;
589 bool isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const;
594 bool isKnownNonNegative(
const SCEV *S,
const Value *
Ptr)
const;
601 const SCEV *collectUpperBound(
const Loop *l, Type *
T)
const;
606 const SCEVConstant *collectConstantUpperBound(
const Loop *l, Type *
T)
const;
611 Subscript::ClassificationKind classifyPair(
const SCEV *Src,
612 const Loop *SrcLoopNest,
614 const Loop *DstLoopNest,
615 SmallBitVector &
Loops);
622 bool testZIV(
const SCEV *Src,
624 FullDependence &Result)
const;
636 bool testSIV(
const SCEV *Src,
639 FullDependence &Result,
640 Constraint &NewConstraint,
641 const SCEV *&SplitIter)
const;
652 bool testRDIV(
const SCEV *Src,
654 FullDependence &Result)
const;
659 bool testMIV(
const SCEV *Src,
661 const SmallBitVector &
Loops,
662 FullDependence &Result)
const;
672 bool strongSIVtest(
const SCEV *Coeff,
673 const SCEV *SrcConst,
674 const SCEV *DstConst,
675 const Loop *CurrentLoop,
677 FullDependence &Result,
678 Constraint &NewConstraint)
const;
690 bool weakCrossingSIVtest(
const SCEV *SrcCoeff,
691 const SCEV *SrcConst,
692 const SCEV *DstConst,
693 const Loop *CurrentLoop,
695 FullDependence &Result,
696 Constraint &NewConstraint,
697 const SCEV *&SplitIter)
const;
708 bool exactSIVtest(
const SCEV *SrcCoeff,
709 const SCEV *DstCoeff,
710 const SCEV *SrcConst,
711 const SCEV *DstConst,
712 const Loop *CurrentLoop,
714 FullDependence &Result,
715 Constraint &NewConstraint)
const;
727 bool weakZeroSrcSIVtest(
const SCEV *DstCoeff,
728 const SCEV *SrcConst,
729 const SCEV *DstConst,
730 const Loop *CurrentLoop,
732 FullDependence &Result,
733 Constraint &NewConstraint)
const;
745 bool weakZeroDstSIVtest(
const SCEV *SrcCoeff,
746 const SCEV *SrcConst,
747 const SCEV *DstConst,
748 const Loop *CurrentLoop,
750 FullDependence &Result,
751 Constraint &NewConstraint)
const;
761 bool exactRDIVtest(
const SCEV *SrcCoeff,
762 const SCEV *DstCoeff,
763 const SCEV *SrcConst,
764 const SCEV *DstConst,
767 FullDependence &Result)
const;
778 bool symbolicRDIVtest(
const SCEV *SrcCoeff,
779 const SCEV *DstCoeff,
780 const SCEV *SrcConst,
781 const SCEV *DstConst,
783 const Loop *DstLoop)
const;
791 bool gcdMIVtest(
const SCEV *Src,
793 FullDependence &Result)
const;
799 bool banerjeeMIVtest(
const SCEV *Src,
801 const SmallBitVector &
Loops,
802 FullDependence &Result)
const;
807 CoefficientInfo *collectCoeffInfo(
const SCEV *Subscript,
809 const SCEV *&Constant)
const;
813 const SCEV *getPositivePart(
const SCEV *
X)
const;
817 const SCEV *getNegativePart(
const SCEV *
X)
const;
822 const SCEV *getLowerBound(BoundInfo *Bound)
const;
827 const SCEV *getUpperBound(BoundInfo *Bound)
const;
834 unsigned exploreDirections(
unsigned Level,
838 const SmallBitVector &
Loops,
839 unsigned &DepthExpanded,
840 const SCEV *Delta)
const;
843 bool testBounds(
unsigned char DirKind,
846 const SCEV *Delta)
const;
850 void findBoundsALL(CoefficientInfo *
A,
857 void findBoundsLT(CoefficientInfo *
A,
864 void findBoundsGT(CoefficientInfo *
A,
871 void findBoundsEQ(CoefficientInfo *
A,
878 bool intersectConstraints(Constraint *
X,
879 const Constraint *
Y);
886 bool propagate(
const SCEV *&Src,
888 SmallBitVector &
Loops,
889 SmallVectorImpl<Constraint> &Constraints,
897 bool propagateDistance(
const SCEV *&Src,
899 Constraint &CurConstraint,
905 bool propagatePoint(
const SCEV *&Src,
907 Constraint &CurConstraint);
914 bool propagateLine(
const SCEV *&Src,
916 Constraint &CurConstraint,
924 const SCEV *findCoefficient(
const SCEV *Expr,
925 const Loop *TargetLoop)
const;
932 const SCEV *zeroCoefficient(
const SCEV *Expr,
933 const Loop *TargetLoop)
const;
940 const SCEV *addToCoefficient(
const SCEV *Expr,
941 const Loop *TargetLoop,
942 const SCEV *Value)
const;
946 void updateDirection(Dependence::DVEntry &Level,
947 const Constraint &CurConstraint)
const;
951 bool tryDelinearize(Instruction *Src, Instruction *Dst,
952 SmallVectorImpl<Subscript> &Pair);
957 bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
958 const SCEV *SrcAccessFn,
959 const SCEV *DstAccessFn,
960 SmallVectorImpl<const SCEV *> &SrcSubscripts,
961 SmallVectorImpl<const SCEV *> &DstSubscripts);
966 bool tryDelinearizeParametricSize(
967 Instruction *Src, Instruction *Dst,
const SCEV *SrcAccessFn,
968 const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
969 SmallVectorImpl<const SCEV *> &DstSubscripts);
973 bool checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
974 SmallBitVector &
Loops,
bool IsSrc);
992 bool NormalizeResults =
false)
993 :
OS(
OS), NormalizeResults(NormalizeResults) {}
1001 bool NormalizeResults;
1017 std::unique_ptr<DependenceInfo> info;
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This header defines various interfaces for pass management in LLVM.
Loop::LoopBounds::Direction Direction
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
FunctionAnalysisManager FAM
This file implements the SmallBitVector class.
API to communicate dependencies between analyses during invalidation.
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Legacy pass manager pass to access dependence information.
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void print(raw_ostream &, const Module *=nullptr) const override
print - Print out the internal state of the pass.
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.
Result run(Function &F, FunctionAnalysisManager &FAM)
DependenceInfo - This class is the main dependence-analysis driver.
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle transitive invalidation when the cached analysis results go away.
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
std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool PossiblyLoopIndependent)
depends - Tests for a dependence between the Src and Dst instructions.
DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE, LoopInfo *LI)
Dependence - This class represents a dependence between two memory memory references in a function.
virtual unsigned getDirection(unsigned Level) const
getDirection - Returns the direction associated with a particular level.
virtual bool isPeelFirst(unsigned Level) const
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence.
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.
Dependence(Dependence &&)=default
bool isUnordered() const
isUnordered - Returns true if dependence is Input
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
virtual bool isSplitable(unsigned Level) const
isSplitable - Returns true if splitting this loop will break the dependence.
virtual const SCEV * getDistance(unsigned Level) const
getDistance - Returns the distance (or NULL) associated with a particular level.
virtual bool isScalar(unsigned Level) const
isScalar - Returns true if a particular level is scalar; that is, if no subscript in the source or de...
virtual bool isConsistent() const
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
virtual bool isPeelLast(unsigned Level) const
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence.
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.
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
Dependence(Instruction *Source, Instruction *Destination)
virtual ~Dependence()=default
bool isInput() const
isInput - Returns true if this is an input dependence.
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.
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.
void dump(raw_ostream &OS) const
dump - For debugging purposes, dumps a dependence to OS.
FullDependence - This class represents a dependence between two memory references in a function.
unsigned getDirection(unsigned Level) const override
getDirection - Returns the direction associated with a particular level.
const SCEV * getDistance(unsigned Level) const override
getDistance - Returns the distance (or NULL) associated with a particular level.
bool isConfused() const override
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
bool isDirectionNegative() const override
Check if the direction vector is negative.
bool isSplitable(unsigned Level) const override
isSplitable - Returns true if splitting the loop will break the dependence.
bool isLoopIndependent() const override
isLoopIndependent - Returns true if this is a loop-independent dependence.
bool isScalar(unsigned Level) const override
isScalar - Returns true if a particular level is scalar; that is, if no subscript in the source or de...
bool isPeelLast(unsigned Level) const override
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence.
unsigned getLevels() const override
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
bool isPeelFirst(unsigned Level) const override
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence.
bool isConsistent() const override
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
bool normalize(ScalarEvolution *SE) override
If the direction vector is negative, normalize the direction vector to make it non-negative.
FunctionPass class - This class is used to implement most global optimizations.
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 an analyzed expression in the program.
The main scalar evolution driver.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
ArrayRef(const T &OneElt) -> ArrayRef< T >
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...
Printer pass to dump DA results.
DependenceAnalysisPrinterPass(raw_ostream &OS, bool NormalizeResults=false)
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.