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);
370 enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
371 SmallBitVector
Loops;
372 SmallBitVector GroupLoops;
373 SmallBitVector Group;
376 struct CoefficientInfo {
380 const SCEV *Iterations;
384 const SCEV *Iterations;
385 const SCEV *Upper[8];
386 const SCEV *Lower[8];
387 unsigned char Direction;
388 unsigned char DirSet;
395 bool haveSameSD(
const Loop *SrcLoop,
const Loop *DstLoop)
const;
459 void establishNestingLevels(
const Instruction *Src,
const Instruction *Dst);
461 unsigned CommonLevels, SrcLevels, MaxLevels, SameSDLevels;
465 unsigned mapSrcLoop(
const Loop *SrcLoop)
const;
469 unsigned mapDstLoop(
const Loop *DstLoop)
const;
473 bool isLoopInvariant(
const SCEV *Expression,
const Loop *LoopNest)
const;
485 void removeMatchingExtensions(Subscript *Pair);
489 void collectCommonLoops(
const SCEV *Expression,
const Loop *LoopNest,
490 SmallBitVector &
Loops)
const;
494 bool checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
495 SmallBitVector &
Loops);
499 bool checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
500 SmallBitVector &
Loops);
507 const SCEV *collectUpperBound(
const Loop *l,
Type *
T)
const;
512 const SCEVConstant *collectConstantUpperBound(
const Loop *l,
Type *
T)
const;
517 Subscript::ClassificationKind
518 classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
519 const Loop *DstLoopNest, SmallBitVector &
Loops);
526 bool testZIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
538 bool testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
539 FullDependence &Result,
bool UnderRuntimeAssumptions);
550 bool testRDIV(
const SCEV *Src,
const SCEV *Dst, FullDependence &Result)
const;
555 bool testMIV(
const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &
Loops,
556 FullDependence &Result)
const;
566 bool strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
567 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
568 const Loop *CurrentDstLoop,
unsigned Level,
569 FullDependence &Result,
bool UnderRuntimeAssumptions);
580 bool weakCrossingSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
581 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
582 const Loop *CurrentDstLoop,
unsigned Level,
583 FullDependence &Result)
const;
594 bool exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
595 const SCEV *SrcConst,
const SCEV *DstConst,
596 const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop,
597 unsigned Level, FullDependence &Result)
const;
609 bool weakZeroSrcSIVtest(
const SCEV *DstCoeff,
const SCEV *SrcConst,
610 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
611 const Loop *CurrentDstLoop,
unsigned Level,
612 FullDependence &Result)
const;
624 bool weakZeroDstSIVtest(
const SCEV *SrcCoeff,
const SCEV *SrcConst,
625 const SCEV *DstConst,
const Loop *CurrentSrcLoop,
626 const Loop *CurrentDstLoop,
unsigned Level,
627 FullDependence &Result)
const;
637 bool exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
638 const SCEV *SrcConst,
const SCEV *DstConst,
639 const Loop *SrcLoop,
const Loop *DstLoop,
640 FullDependence &Result)
const;
651 bool symbolicRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
652 const SCEV *SrcConst,
const SCEV *DstConst,
653 const Loop *SrcLoop,
const Loop *DstLoop)
const;
661 bool gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
662 FullDependence &Result)
const;
668 bool banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
669 const SmallBitVector &
Loops,
670 FullDependence &Result)
const;
675 CoefficientInfo *collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
676 const SCEV *&Constant)
const;
693 bool accumulateCoefficientsGCD(
const SCEV *Expr,
const Loop *CurLoop,
694 const SCEV *&CurLoopCoeff,
695 APInt &RunningGCD)
const;
698 const SCEV *getPositivePart(
const SCEV *
X)
const;
701 const SCEV *getNegativePart(
const SCEV *
X)
const;
706 const SCEV *getLowerBound(BoundInfo *Bound)
const;
711 const SCEV *getUpperBound(BoundInfo *Bound)
const;
718 unsigned exploreDirections(
unsigned Level, CoefficientInfo *
A,
719 CoefficientInfo *
B, BoundInfo *Bound,
720 const SmallBitVector &
Loops,
721 unsigned &DepthExpanded,
const SCEV *Delta)
const;
724 bool testBounds(
unsigned char DirKind,
unsigned Level, BoundInfo *Bound,
725 const SCEV *Delta)
const;
729 void findBoundsALL(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
734 void findBoundsLT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
739 void findBoundsGT(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
744 void findBoundsEQ(CoefficientInfo *
A, CoefficientInfo *
B, BoundInfo *Bound,
749 bool tryDelinearize(Instruction *Src, Instruction *Dst,
750 SmallVectorImpl<Subscript> &Pair);
755 bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
756 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
757 SmallVectorImpl<const SCEV *> &SrcSubscripts,
758 SmallVectorImpl<const SCEV *> &DstSubscripts);
764 tryDelinearizeParametricSize(Instruction *Src, Instruction *Dst,
765 const SCEV *SrcAccessFn,
const SCEV *DstAccessFn,
766 SmallVectorImpl<const SCEV *> &SrcSubscripts,
767 SmallVectorImpl<const SCEV *> &DstSubscripts);
771 bool checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
772 SmallBitVector &
Loops,
bool IsSrc);
790 : OS(OS), NormalizeResults(NormalizeResults) {}
798 bool NormalizeResults;
814 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::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),...
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
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 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)
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.