40 #ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
41 #define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
49 template <
typename T>
class ArrayRef;
52 class ScalarEvolution;
81 NextPredecessor(nullptr),
82 NextSuccessor(nullptr) {}
203 const Dependence *NextPredecessor, *NextSuccessor;
263 unsigned short Levels;
264 bool LoopIndependent;
266 std::unique_ptr<DVEntry[]> DV;
276 : AA(AA), SE(SE), LI(LI), F(F) {}
286 bool PossiblyLoopIndependent);
344 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
345 SmallBitVector
Loops;
346 SmallBitVector GroupLoops;
347 SmallBitVector Group;
350 struct CoefficientInfo {
354 const SCEV *Iterations;
358 const SCEV *Iterations;
359 const SCEV *
Upper[8];
360 const SCEV *
Lower[8];
361 unsigned char Direction;
362 unsigned char DirSet;
382 enum ConstraintKind {
Empty, Point, Distance, Line,
Any }
Kind;
387 const Loop *AssociatedLoop;
391 bool isEmpty()
const {
return Kind ==
Empty; }
394 bool isPoint()
const {
return Kind == Point; }
397 bool isDistance()
const {
return Kind == Distance; }
402 bool isLine()
const {
return Kind == Line ||
Kind == Distance; }
405 bool isAny()
const {
return Kind ==
Any; }
409 const SCEV *getX()
const;
413 const SCEV *getY()
const;
417 const SCEV *getA()
const;
421 const SCEV *getB()
const;
425 const SCEV *getC()
const;
429 const SCEV *getD()
const;
432 const Loop *getAssociatedLoop()
const;
435 void setPoint(
const SCEV *
X,
const SCEV *
Y,
const Loop *CurrentLoop);
438 void setLine(
const SCEV *
A,
const SCEV *
B,
439 const SCEV *
C,
const Loop *CurrentLoop);
442 void setDistance(
const SCEV *
D,
const Loop *CurrentLoop);
448 void setAny(ScalarEvolution *SE);
452 void dump(raw_ostream &OS)
const;
505 void establishNestingLevels(
const Instruction *Src,
506 const Instruction *Dst);
508 unsigned CommonLevels, SrcLevels, MaxLevels;
512 unsigned mapSrcLoop(
const Loop *SrcLoop)
const;
516 unsigned mapDstLoop(
const Loop *DstLoop)
const;
520 bool isLoopInvariant(
const SCEV *Expression,
const Loop *LoopNest)
const;
526 void unifySubscriptType(ArrayRef<Subscript *> Pairs);
532 void removeMatchingExtensions(Subscript *Pair);
536 void collectCommonLoops(
const SCEV *Expression,
537 const Loop *LoopNest,
538 SmallBitVector &
Loops)
const;
542 bool checkSrcSubscript(
const SCEV *Src,
543 const Loop *LoopNest,
544 SmallBitVector &
Loops);
548 bool checkDstSubscript(
const SCEV *Dst,
549 const Loop *LoopNest,
550 SmallBitVector &
Loops);
558 const SCEV *
Y)
const;
565 const SCEV *collectUpperBound(
const Loop *l,
Type *
T)
const;
570 const SCEVConstant *collectConstantUpperBound(
const Loop *l,
Type *
T)
const;
575 Subscript::ClassificationKind classifyPair(
const SCEV *Src,
576 const Loop *SrcLoopNest,
578 const Loop *DstLoopNest,
579 SmallBitVector &
Loops);
586 bool testZIV(
const SCEV *Src,
588 FullDependence &Result)
const;
600 bool testSIV(
const SCEV *Src,
603 FullDependence &Result,
604 Constraint &NewConstraint,
605 const SCEV *&SplitIter)
const;
616 bool testRDIV(
const SCEV *Src,
618 FullDependence &Result)
const;
623 bool testMIV(
const SCEV *Src,
625 const SmallBitVector &
Loops,
626 FullDependence &Result)
const;
636 bool strongSIVtest(
const SCEV *Coeff,
637 const SCEV *SrcConst,
638 const SCEV *DstConst,
639 const Loop *CurrentLoop,
641 FullDependence &Result,
642 Constraint &NewConstraint)
const;
654 bool weakCrossingSIVtest(
const SCEV *SrcCoeff,
655 const SCEV *SrcConst,
656 const SCEV *DstConst,
657 const Loop *CurrentLoop,
659 FullDependence &Result,
660 Constraint &NewConstraint,
661 const SCEV *&SplitIter)
const;
672 bool exactSIVtest(
const SCEV *SrcCoeff,
673 const SCEV *DstCoeff,
674 const SCEV *SrcConst,
675 const SCEV *DstConst,
676 const Loop *CurrentLoop,
678 FullDependence &Result,
679 Constraint &NewConstraint)
const;
691 bool weakZeroSrcSIVtest(
const SCEV *DstCoeff,
692 const SCEV *SrcConst,
693 const SCEV *DstConst,
694 const Loop *CurrentLoop,
696 FullDependence &Result,
697 Constraint &NewConstraint)
const;
709 bool weakZeroDstSIVtest(
const SCEV *SrcCoeff,
710 const SCEV *SrcConst,
711 const SCEV *DstConst,
712 const Loop *CurrentLoop,
714 FullDependence &Result,
715 Constraint &NewConstraint)
const;
725 bool exactRDIVtest(
const SCEV *SrcCoeff,
726 const SCEV *DstCoeff,
727 const SCEV *SrcConst,
728 const SCEV *DstConst,
731 FullDependence &Result)
const;
742 bool symbolicRDIVtest(
const SCEV *SrcCoeff,
743 const SCEV *DstCoeff,
744 const SCEV *SrcConst,
745 const SCEV *DstConst,
747 const Loop *DstLoop)
const;
755 bool gcdMIVtest(
const SCEV *Src,
757 FullDependence &Result)
const;
763 bool banerjeeMIVtest(
const SCEV *Src,
765 const SmallBitVector &
Loops,
766 FullDependence &Result)
const;
771 CoefficientInfo *collectCoeffInfo(
const SCEV *Subscript,
773 const SCEV *&Constant)
const;
777 const SCEV *getPositivePart(
const SCEV *
X)
const;
781 const SCEV *getNegativePart(
const SCEV *
X)
const;
786 const SCEV *getLowerBound(BoundInfo *Bound)
const;
791 const SCEV *getUpperBound(BoundInfo *Bound)
const;
798 unsigned exploreDirections(
unsigned Level,
802 const SmallBitVector &
Loops,
803 unsigned &DepthExpanded,
804 const SCEV *Delta)
const;
807 bool testBounds(
unsigned char DirKind,
810 const SCEV *Delta)
const;
814 void findBoundsALL(CoefficientInfo *
A,
821 void findBoundsLT(CoefficientInfo *
A,
828 void findBoundsGT(CoefficientInfo *
A,
835 void findBoundsEQ(CoefficientInfo *
A,
842 bool intersectConstraints(Constraint *
X,
843 const Constraint *
Y);
850 bool propagate(
const SCEV *&Src,
852 SmallBitVector &
Loops,
853 SmallVectorImpl<Constraint> &Constraints,
861 bool propagateDistance(
const SCEV *&Src,
863 Constraint &CurConstraint,
869 bool propagatePoint(
const SCEV *&Src,
871 Constraint &CurConstraint);
878 bool propagateLine(
const SCEV *&Src,
880 Constraint &CurConstraint,
888 const SCEV *findCoefficient(
const SCEV *Expr,
889 const Loop *TargetLoop)
const;
896 const SCEV *zeroCoefficient(
const SCEV *Expr,
897 const Loop *TargetLoop)
const;
904 const SCEV *addToCoefficient(
const SCEV *Expr,
905 const Loop *TargetLoop,
906 const SCEV *Value)
const;
910 void updateDirection(Dependence::DVEntry &
Level,
911 const Constraint &CurConstraint)
const;
913 bool tryDelinearize(Instruction *Src, Instruction *Dst,
914 SmallVectorImpl<Subscript> &Pair);
944 std::unique_ptr<DependenceInfo> info;
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
Dependence(Dependence &&)=default
DependenceInfo(Function *F, AliasAnalysis *AA, ScalarEvolution *SE, LoopInfo *LI)
const SCEV * getDistance(unsigned Level) const override
getDistance - Returns the distance (or NULL) associated with a particular level.
FunctionPass * createDependenceAnalysisWrapperPass()
createDependenceAnalysisPass - This creates an instance of the DependenceAnalysis wrapper pass...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
AnalysisPass to compute dependence information in a function.
const SCEV * getSplitIteration(const Dependence &Dep, unsigned Level)
getSplitIteration - Give a dependence that's splittable at some particular level, return the iteratio...
DependenceAnalysisWrapperPass()
bool isOrdered() const
isOrdered - Returns true if dependence is Output, Flow, or Anti
A Module instance is used to store all the information related to an LLVM module. ...
virtual bool isPeelFirst(unsigned Level) const
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence...
Legacy pass manager pass to access dependence information.
The main scalar evolution driver.
DependenceInfo - This class is the main dependence-analysis driver.
bool isConsistent() const override
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool isPeelLast(unsigned Level) const override
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence...
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
void initializeDependenceAnalysisWrapperPassPass(PassRegistry &)
virtual bool isSplitable(unsigned Level) const
isSplitable - Returns true if splitting this loop will break the dependence.
Function Alias Analysis false
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
unsigned getLevels() const override
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
bool isLoopIndependent() const override
isLoopIndependent - Returns true if this is a loop-independent dependence.
void setNextPredecessor(const Dependence *pred)
setNextPredecessor - Sets the value of the NextPredecessor field.
unsigned getDirection(unsigned Level) const override
getDirection - Returns the direction associated with a particular level.
const Dependence * getNextSuccessor() const
getNextSuccessor - Returns the value of the NextSuccessor field.
std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool PossiblyLoopIndependent)
depends - Tests for a dependence between the Src and Dst instructions.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
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...
Function * getFunction() const
bool isConfused() const override
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
bool isSplitable(unsigned Level) const override
isSplitable - Returns true if splitting the loop will break the dependence.
A CRTP mix-in that provides informational APIs needed for analysis passes.
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
Represent the analysis usage information of a pass.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
bool isPeelFirst(unsigned Level) const override
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence...
virtual const SCEV * getDistance(unsigned Level) const
getDistance - Returns the distance (or NULL) associated with a particular level.
Instruction * getSrc() const
getSrc - Returns the source instruction for this dependence.
virtual unsigned getDirection(unsigned Level) const
getDirection - Returns the direction associated with a particular level.
virtual bool isConsistent() const
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
Dependence & operator=(Dependence &&)=default
void print(raw_ostream &, const Module *=nullptr) const override
print - Print out the internal state of the pass.
const Dependence * getNextPredecessor() const
getNextPredecessor - Returns the value of the NextPredecessor field.
virtual unsigned getLevels() const
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
virtual bool isPeelLast(unsigned Level) const
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence...
Dependence(Instruction *Source, Instruction *Destination)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent, unsigned Levels)
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...
This class represents an analyzed expression in the program.
virtual bool isLoopIndependent() const
isLoopIndependent - Returns true if this is a loop-independent dependence.
Instruction * getDst() const
getDst - Returns the destination instruction for this dependence.
void dump(raw_ostream &OS) const
dump - For debugging purposes, dumps a dependence to OS.
DependenceInfo & getDI() const
FullDependence - This class represents a dependence between two memory references in a function...
Dependence::DVEntry - Each level in the distance/direction vector has a direction (or perhaps a union...
bool isInput() const
isInput - Returns true if this is an input dependence.
Result run(Function &F, FunctionAnalysisManager &FAM)
bool isUnordered() const
isUnordered - Returns true if dependence is Input
This class implements an extremely fast bulk output stream that can only output to a stream...
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
A container for analyses that lazily runs them and caches their results.
bool isOutput() const
isOutput - Returns true if this is an output dependence.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Dependence - This class represents a dependence between two memory memory references in a function...
void setNextSuccessor(const Dependence *succ)
setNextSuccessor - Sets the value of the NextSuccessor field.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
A special type used by analysis passes to provide an address that identifies that particular analysis...