39#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
40#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
79 :
Src(Source),
Dst(Destination), Assumptions(
A) {}
96 enum :
unsigned char {
125 bool isOutput()
const;
165 virtual unsigned getDirection(
unsigned Level,
bool SameSD =
false)
const {
187 virtual bool isPeelFirst(
unsigned Level,
bool SameSD =
false)
const {
193 virtual bool isPeelLast(
unsigned Level,
bool SameSD =
false)
const {
205 virtual bool isScalar(
unsigned Level,
bool SameSD =
false)
const;
229 void dumpImp(
raw_ostream &OS,
bool IsSameSD =
false)
const;
236 const Dependence *NextPredecessor =
nullptr, *NextSuccessor =
nullptr;
252 bool PossiblyLoopIndependent,
unsigned Levels);
279 assert(0 < Level && Level <= Levels &&
"Level out of range");
280 return DV[Level - 1];
283 Level <=
static_cast<unsigned>(Levels) + SameSDLevels &&
284 "isSameSD level out of range");
285 return DVSameSD[Level - Levels - 1];
291 unsigned getDirection(
unsigned Level,
bool SameSD =
false)
const override;
295 const SCEV *getDistance(
unsigned Level,
bool SameSD =
false)
const override;
299 bool isDirectionNegative()
const override;
309 bool isPeelFirst(
unsigned Level,
bool SameSD =
false)
const override;
313 bool isPeelLast(
unsigned Level,
bool SameSD =
false)
const override;
318 bool inSameSDLoops(
unsigned Level)
const override;
323 bool isScalar(
unsigned Level,
bool SameSD =
false)
const override;
326 unsigned short Levels;
327 unsigned short SameSDLevels;
328 bool LoopIndependent;
330 std::unique_ptr<DVEntry[]> DV;
331 std::unique_ptr<DVEntry[]> DVSameSD;
339 : AA(AA), SE(SE), LI(LI), F(F) {}
343 FunctionAnalysisManager::Invalidator &Inv);
352 LLVM_ABI std::unique_ptr<Dependence>
354 bool UnderRuntimeAssumptions =
false);
375 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
376 SmallBitVector
Loops;
377 SmallBitVector GroupLoops;
378 SmallBitVector Group;
381 struct CoefficientInfo {
385 const SCEV *Iterations;
389 const SCEV *Iterations;
390 const SCEV *Upper[8];
391 const SCEV *Lower[8];
392 unsigned char Direction;
393 unsigned char DirSet;
400 bool haveSameSD(
const Loop *SrcLoop,
const Loop *DstLoop)
const;
464 void establishNestingLevels(
const Instruction *Src,
const Instruction *Dst);
466 unsigned CommonLevels, SrcLevels, MaxLevels, SameSDLevels;
470 unsigned mapSrcLoop(
const Loop *SrcLoop)
const;
474 unsigned mapDstLoop(
const Loop *DstLoop)
const;
478 bool isLoopInvariant(
const SCEV *Expression,
const Loop *LoopNest)
const;
490 void removeMatchingExtensions(Subscript *Pair);
494 void collectCommonLoops(
const SCEV *Expression,
const Loop *LoopNest,
495 SmallBitVector &
Loops)
const;
499 bool checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
500 SmallBitVector &
Loops);
504 bool checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
505 SmallBitVector &
Loops);
512 const SCEV *
Y)
const;
518 bool isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const;
523 bool isKnownNonNegative(
const SCEV *S,
const Value *Ptr)
const;
530 const SCEV *collectUpperBound(
const Loop *l,
Type *
T)
const;
535 const SCEVConstant *collectConstantUpperBound(
const Loop *l,
Type *
T)
const;
540 Subscript::ClassificationKind
541 classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
542 const Loop *DstLoopNest, SmallBitVector &
Loops);
549 bool testZIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
561 bool testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
562 FullDependence &Result)
const;
573 bool testRDIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
578 bool testMIV(
const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &
Loops,
579 FullDependence &Result)
const;
589 bool strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
590 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
591 const Loop *CurrentDstLoop,
unsigned Level,
592 FullDependence &Result)
const;
603 bool weakCrossingSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
604 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
605 const Loop *CurrentDstLoop,
unsigned Level,
606 FullDependence &Result)
const;
617 bool exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
618 const SCEV *SrcConst,
const SCEV *DstConst,
619 const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop,
620 unsigned Level, FullDependence &Result)
const;
632 bool weakZeroSrcSIVtest(
const SCEV *DstCoeff,
const SCEV *SrcConst,
633 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
634 const Loop *CurrentDstLoop,
unsigned Level,
635 FullDependence &Result)
const;
647 bool weakZeroDstSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
648 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
649 const Loop *CurrentDstLoop,
unsigned Level,
650 FullDependence &Result)
const;
660 bool exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
661 const SCEV *SrcConst,
const SCEV *DstConst,
662 const Loop *SrcLoop,
const Loop *DstLoop,
663 FullDependence &Result)
const;
674 bool symbolicRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
675 const SCEV *SrcConst,
const SCEV *DstConst,
676 const Loop *SrcLoop,
const Loop *DstLoop)
const;
684 bool gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
685 FullDependence &Result)
const;
691 bool banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
692 const SmallBitVector &
Loops,
693 FullDependence &Result)
const;
698 CoefficientInfo *collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
699 const SCEV *&Constant)
const;
716 bool accumulateCoefficientsGCD(
const SCEV *Expr,
const Loop *CurLoop,
717 const SCEV *&CurLoopCoeff,
718 APInt &RunningGCD)
const;
721 const SCEV *getPositivePart(
const SCEV *
X)
const;
724 const SCEV *getNegativePart(
const SCEV *
X)
const;
729 const SCEV *getLowerBound(BoundInfo *Bound)
const;
734 const SCEV *getUpperBound(BoundInfo *Bound)
const;
741 unsigned exploreDirections(
unsigned Level, CoefficientInfo *
A,
742 CoefficientInfo *
B, BoundInfo *Bound,
743 const SmallBitVector &
Loops,
744 unsigned &DepthExpanded,
const SCEV *Delta)
const;
747 bool testBounds(
unsigned char DirKind,
unsigned Level, BoundInfo *Bound,
748 const SCEV *Delta)
const;
752 void findBoundsALL(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
757 void findBoundsLT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
762 void findBoundsGT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
767 void findBoundsEQ(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
772 bool tryDelinearize(Instruction *Src, Instruction *Dst,
773 SmallVectorImpl<Subscript> &Pair);
778 bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
779 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
780 SmallVectorImpl<const SCEV *> &SrcSubscripts,
781 SmallVectorImpl<const SCEV *> &DstSubscripts);
787 tryDelinearizeParametricSize(Instruction *Src, Instruction *Dst,
788 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
789 SmallVectorImpl<const SCEV *> &SrcSubscripts,
790 SmallVectorImpl<const SCEV *> &DstSubscripts);
794 bool checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
795 SmallBitVector &
Loops,
bool IsSrc);
813 : OS(OS), NormalizeResults(NormalizeResults) {}
821 bool NormalizeResults;
837 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< 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.
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.
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...
DVEntry getDVEntry(unsigned Level, bool IsSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level
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.
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.
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
DVEntry getDVEntry(unsigned Level, bool IsSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level.
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...
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.