39#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
40#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
79 :
Src(Source),
Dst(Destination), Assumptions(
A) {}
86 enum :
unsigned char {
117 bool isOutput()
const;
170 virtual bool isPeelLast(
unsigned Level)
const {
return false; }
179 virtual bool isScalar(
unsigned Level)
const;
206 const Dependence *NextPredecessor =
nullptr, *NextSuccessor =
nullptr;
222 bool PossiblyLoopIndependent,
unsigned Levels);
243 unsigned getDirection(
unsigned Level)
const override;
247 const SCEV *getDistance(
unsigned Level)
const override;
251 bool isDirectionNegative()
const override;
261 bool isPeelFirst(
unsigned Level)
const override;
265 bool isPeelLast(
unsigned Level)
const override;
269 bool isSplitable(
unsigned Level)
const override;
274 bool isScalar(
unsigned Level)
const override;
277 unsigned short Levels;
278 bool LoopIndependent;
280 std::unique_ptr<DVEntry[]> DV;
288 : AA(AA), SE(SE), LI(LI), F(F) {}
292 FunctionAnalysisManager::Invalidator &Inv);
301 LLVM_ABI std::unique_ptr<Dependence>
303 bool UnderRuntimeAssumptions =
false);
366 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
367 SmallBitVector
Loops;
368 SmallBitVector GroupLoops;
369 SmallBitVector Group;
372 struct CoefficientInfo {
376 const SCEV *Iterations;
380 const SCEV *Iterations;
381 const SCEV *Upper[8];
382 const SCEV *Lower[8];
383 unsigned char Direction;
384 unsigned char DirSet;
404 enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
409 const Loop *AssociatedLoop;
413 bool isEmpty()
const {
return Kind == Empty; }
416 bool isPoint()
const {
return Kind == Point; }
419 bool isDistance()
const {
return Kind == Distance; }
424 bool isLine()
const {
return Kind == Line || Kind == Distance; }
427 bool isAny()
const {
return Kind == Any; }
454 LLVM_ABI const Loop *getAssociatedLoop()
const;
457 LLVM_ABI void setPoint(
const SCEV *
X,
const SCEV *
Y,
458 const Loop *CurrentLoop);
461 LLVM_ABI void setLine(
const SCEV *A,
const SCEV *B,
const SCEV *C,
462 const Loop *CurrentLoop);
465 LLVM_ABI void setDistance(
const SCEV *
D,
const Loop *CurrentLoop);
471 LLVM_ABI void setAny(ScalarEvolution *SE);
475 LLVM_ABI void dump(raw_ostream &OS)
const;
528 void establishNestingLevels(
const Instruction *Src,
const Instruction *Dst);
530 unsigned CommonLevels, SrcLevels, MaxLevels;
534 unsigned mapSrcLoop(
const Loop *SrcLoop)
const;
538 unsigned mapDstLoop(
const Loop *DstLoop)
const;
542 bool isLoopInvariant(
const SCEV *Expression,
const Loop *LoopNest)
const;
554 void removeMatchingExtensions(Subscript *Pair);
558 void collectCommonLoops(
const SCEV *Expression,
const Loop *LoopNest,
559 SmallBitVector &
Loops)
const;
563 bool checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
564 SmallBitVector &
Loops);
568 bool checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
569 SmallBitVector &
Loops);
576 const SCEV *
Y)
const;
582 bool isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const;
587 bool isKnownNonNegative(
const SCEV *S,
const Value *
Ptr)
const;
594 const SCEV *collectUpperBound(
const Loop *l,
Type *
T)
const;
599 const SCEVConstant *collectConstantUpperBound(
const Loop *l,
Type *
T)
const;
604 Subscript::ClassificationKind
605 classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
606 const Loop *DstLoopNest, SmallBitVector &
Loops);
613 bool testZIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
625 bool testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
626 FullDependence &Result, Constraint &NewConstraint,
627 const SCEV *&SplitIter)
const;
638 bool testRDIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
643 bool testMIV(
const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &
Loops,
644 FullDependence &Result)
const;
654 bool strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
655 const SCEV *DstConst,
const Loop *CurrentLoop,
656 unsigned Level, FullDependence &Result,
657 Constraint &NewConstraint)
const;
669 bool weakCrossingSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
670 const SCEV *DstConst,
const Loop *CurrentLoop,
671 unsigned Level, FullDependence &Result,
672 Constraint &NewConstraint,
673 const SCEV *&SplitIter)
const;
684 bool exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
685 const SCEV *SrcConst,
const SCEV *DstConst,
686 const Loop *CurrentLoop,
unsigned Level,
687 FullDependence &Result, Constraint &NewConstraint)
const;
699 bool weakZeroSrcSIVtest(
const SCEV *DstCoeff,
const SCEV *SrcConst,
700 const SCEV *DstConst,
const Loop *CurrentLoop,
701 unsigned Level, FullDependence &Result,
702 Constraint &NewConstraint)
const;
714 bool weakZeroDstSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
715 const SCEV *DstConst,
const Loop *CurrentLoop,
716 unsigned Level, FullDependence &Result,
717 Constraint &NewConstraint)
const;
727 bool exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
728 const SCEV *SrcConst,
const SCEV *DstConst,
729 const Loop *SrcLoop,
const Loop *DstLoop,
730 FullDependence &Result)
const;
741 bool symbolicRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
742 const SCEV *SrcConst,
const SCEV *DstConst,
743 const Loop *SrcLoop,
const Loop *DstLoop)
const;
751 bool gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
752 FullDependence &Result)
const;
758 bool banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
759 const SmallBitVector &
Loops,
760 FullDependence &Result)
const;
765 CoefficientInfo *collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
766 const SCEV *&Constant)
const;
783 bool accumulateCoefficientsGCD(
const SCEV *Expr,
const Loop *CurLoop,
784 const SCEV *&CurLoopCoeff,
785 APInt &RunningGCD)
const;
788 const SCEV *getPositivePart(
const SCEV *
X)
const;
791 const SCEV *getNegativePart(
const SCEV *
X)
const;
796 const SCEV *getLowerBound(BoundInfo *Bound)
const;
801 const SCEV *getUpperBound(BoundInfo *Bound)
const;
808 unsigned exploreDirections(
unsigned Level, CoefficientInfo *
A,
809 CoefficientInfo *
B, BoundInfo *Bound,
810 const SmallBitVector &
Loops,
811 unsigned &DepthExpanded,
const SCEV *Delta)
const;
814 bool testBounds(
unsigned char DirKind,
unsigned Level, BoundInfo *Bound,
815 const SCEV *Delta)
const;
819 void findBoundsALL(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
824 void findBoundsLT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
829 void findBoundsGT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
834 void findBoundsEQ(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
839 bool intersectConstraints(Constraint *
X,
const Constraint *
Y);
846 bool propagate(
const SCEV *&Src,
const SCEV *&Dst, SmallBitVector &
Loops,
847 SmallVectorImpl<Constraint> &Constraints,
bool &Consistent);
854 bool propagateDistance(
const SCEV *&Src,
const SCEV *&Dst,
855 Constraint &CurConstraint,
bool &Consistent);
860 bool propagatePoint(
const SCEV *&Src,
const SCEV *&Dst,
861 Constraint &CurConstraint);
868 bool propagateLine(
const SCEV *&Src,
const SCEV *&Dst,
869 Constraint &CurConstraint,
bool &Consistent);
876 const SCEV *findCoefficient(
const SCEV *Expr,
const Loop *TargetLoop)
const;
883 const SCEV *zeroCoefficient(
const SCEV *Expr,
const Loop *TargetLoop)
const;
890 const SCEV *addToCoefficient(
const SCEV *Expr,
const Loop *TargetLoop,
891 const SCEV *
Value)
const;
895 void updateDirection(Dependence::DVEntry &Level,
896 const Constraint &CurConstraint)
const;
900 bool tryDelinearize(Instruction *Src, Instruction *Dst,
901 SmallVectorImpl<Subscript> &Pair);
906 bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
907 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
908 SmallVectorImpl<const SCEV *> &SrcSubscripts,
909 SmallVectorImpl<const SCEV *> &DstSubscripts);
915 tryDelinearizeParametricSize(Instruction *Src, Instruction *Dst,
916 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
917 SmallVectorImpl<const SCEV *> &SrcSubscripts,
918 SmallVectorImpl<const SCEV *> &DstSubscripts);
922 bool checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
923 SmallBitVector &
Loops,
bool IsSrc);
941 : OS(OS), NormalizeResults(NormalizeResults) {}
949 bool NormalizeResults;
965 std::unique_ptr<DependenceInfo> info;
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.
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.
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 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 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.
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.
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.
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 getLevels() const override
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
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)
A CRTP mix-in to automatically provide informational APIs needed for passes.