Skip to content

Commit f840335

Browse files
committed
[DependenceAnalysis] Extending SIV to handle separate loops
When there is a dependency between two memory instructions in separate loops, SIV will be able to test them and compute the direction and the distance of the dependency.
1 parent 789bfdc commit f840335

File tree

4 files changed

+496
-160
lines changed

4 files changed

+496
-160
lines changed

llvm/include/llvm/Analysis/DependenceAnalysis.h

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ namespace llvm {
9797
bool PeelFirst : 1; // Peeling the first iteration will break dependence.
9898
bool PeelLast : 1; // Peeling the last iteration will break the dependence.
9999
bool Splitable : 1; // Splitting the loop will break dependence.
100+
bool SeparateLoops : 1; // Is performed across two separate loop nests.
100101
const SCEV *Distance = nullptr; // NULL implies no distance available.
101102
DVEntry()
102103
: Direction(ALL), Scalar(true), PeelFirst(false), PeelLast(false),
103-
Splitable(false) {}
104+
Splitable(false), SeparateLoops(false) {}
104105
};
105106

106107
/// getSrc - Returns the source instruction for this dependence.
@@ -182,6 +183,10 @@ namespace llvm {
182183
/// the dependence.
183184
virtual bool isSplitable(unsigned Level) const { return false; }
184185

186+
/// inSeparateLoops - Returns true if this level is performed across
187+
/// two separate loop nests.
188+
virtual bool inSeparateLoops(unsigned Level) const { return false; }
189+
185190
/// isScalar - Returns true if a particular level is scalar; that is,
186191
/// if no subscript in the source or destination mention the induction
187192
/// variable associated with the loop at this level.
@@ -275,6 +280,10 @@ namespace llvm {
275280
/// the dependence.
276281
bool isSplitable(unsigned Level) const override;
277282

283+
/// inSeparateLoops - Returns true if this level is performed across
284+
/// two separate loop nests.
285+
bool inSeparateLoops(unsigned Level) const override;
286+
278287
/// isScalar - Returns true if a particular level is scalar; that is,
279288
/// if no subscript in the source or destination mention the induction
280289
/// variable associated with the loop at this level.
@@ -405,7 +414,8 @@ namespace llvm {
405414
const SCEV *A;
406415
const SCEV *B;
407416
const SCEV *C;
408-
const Loop *AssociatedLoop;
417+
const Loop *AssociatedSrcLoop;
418+
const Loop *AssociatedDstLoop;
409419

410420
public:
411421
/// isEmpty - Return true if the constraint is of kind Empty.
@@ -449,18 +459,25 @@ namespace llvm {
449459
/// Otherwise assert.
450460
const SCEV *getD() const;
451461

452-
/// getAssociatedLoop - Returns the loop associated with this constraint.
453-
const Loop *getAssociatedLoop() const;
462+
/// getAssociatedSrcLoop - Returns the source loop associated with this
463+
/// constraint.
464+
const Loop *getAssociatedSrcLoop() const;
465+
466+
/// getAssociatedDstLoop - Returns the destination loop associated with
467+
/// this constraint.
468+
const Loop *getAssociatedDstLoop() const;
454469

455470
/// setPoint - Change a constraint to Point.
456-
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
471+
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentSrcLoop,
472+
const Loop *CurrentDstLoop);
457473

458474
/// setLine - Change a constraint to Line.
459-
void setLine(const SCEV *A, const SCEV *B,
460-
const SCEV *C, const Loop *CurrentLoop);
475+
void setLine(const SCEV *A, const SCEV *B, const SCEV *C,
476+
const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop);
461477

462478
/// setDistance - Change a constraint to Distance.
463-
void setDistance(const SCEV *D, const Loop *CurrentLoop);
479+
void setDistance(const SCEV *D, const Loop *CurrentSrcLoop,
480+
const Loop *CurrentDstLoop);
464481

465482
/// setEmpty - Change a constraint to Empty.
466483
void setEmpty();
@@ -473,6 +490,10 @@ namespace llvm {
473490
void dump(raw_ostream &OS) const;
474491
};
475492

493+
/// Returns true if two loops are the same or they have the same upperbound
494+
/// and depth
495+
bool areLoopsSimilar(const Loop *SrcLoop, const Loop *DstLoop) const;
496+
476497
/// establishNestingLevels - Examines the loop nesting of the Src and Dst
477498
/// instructions and establishes their shared loops. Sets the variables
478499
/// CommonLevels, SrcLevels, and MaxLevels.
@@ -484,8 +505,8 @@ namespace llvm {
484505
/// This lets us allocate vectors MaxLevels in length, with room for every
485506
/// distinct loop referenced in both the source and destination subscripts.
486507
/// The variable SrcLevels is the nesting depth of the source instruction.
487-
/// It's used to help calculate distinct loops referenced by the destination.
488-
/// Here's the map from loops to levels:
508+
/// It's used to help calculate distinct loops referenced by the
509+
/// destination. Here's the map from loops to levels:
489510
/// 0 - unused
490511
/// 1 - outermost common loop
491512
/// ... - other common loops
@@ -523,10 +544,22 @@ namespace llvm {
523544
/// e - 5
524545
/// f - 6
525546
/// g - 7 = MaxLevels
526-
void establishNestingLevels(const Instruction *Src,
527-
const Instruction *Dst);
528-
529-
unsigned CommonLevels, SrcLevels, MaxLevels;
547+
/// If ConsiderSeparateLoops is true then we also want to consider similar
548+
/// seperate loops. Assume that loop nests at level c and e are similar,
549+
/// meaning that they have the same upperbound and depth. Then we consider
550+
/// them as a common level.
551+
/// a - 1
552+
/// b - 2
553+
/// <c, e> - 3 = CommonLevels
554+
/// d - 4 = SrcLevels
555+
/// f - 5
556+
/// g - 6 = MaxLevels
557+
/// SeparateLevels means that how many of the last common levels are
558+
/// separated, which is 1 in this case.
559+
void establishNestingLevels(const Instruction *Src, const Instruction *Dst,
560+
bool ConsiderSeparateLoops = false);
561+
562+
unsigned CommonLevels, SrcLevels, MaxLevels, SeparateLevels;
530563

531564
/// mapSrcLoop - Given one of the loops containing the source, return
532565
/// its level index in our numbering scheme.
@@ -665,13 +698,10 @@ namespace llvm {
665698
/// Returns true if any possible dependence is disproved.
666699
/// If there might be a dependence, returns false.
667700
/// Sets appropriate direction and distance.
668-
bool strongSIVtest(const SCEV *Coeff,
669-
const SCEV *SrcConst,
670-
const SCEV *DstConst,
671-
const Loop *CurrentLoop,
672-
unsigned Level,
673-
FullDependence &Result,
674-
Constraint &NewConstraint) const;
701+
bool strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
702+
const SCEV *DstConst, const Loop *CurrentSrcLoop,
703+
const Loop *CurrentDstLoop, unsigned Level,
704+
FullDependence &Result, Constraint &NewConstraint) const;
675705

676706
/// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
677707
/// (Src and Dst) for dependence.
@@ -683,13 +713,10 @@ namespace llvm {
683713
/// Sets appropriate direction entry.
684714
/// Set consistent to false.
685715
/// Marks the dependence as splitable.
686-
bool weakCrossingSIVtest(const SCEV *SrcCoeff,
687-
const SCEV *SrcConst,
688-
const SCEV *DstConst,
689-
const Loop *CurrentLoop,
690-
unsigned Level,
691-
FullDependence &Result,
692-
Constraint &NewConstraint,
716+
bool weakCrossingSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
717+
const SCEV *DstConst, const Loop *CurrentSrcLoop,
718+
const Loop *CurrentDstLoop, unsigned Level,
719+
FullDependence &Result, Constraint &NewConstraint,
693720
const SCEV *&SplitIter) const;
694721

695722
/// ExactSIVtest - Tests the SIV subscript pair
@@ -701,13 +728,10 @@ namespace llvm {
701728
/// If there might be a dependence, returns false.
702729
/// Sets appropriate direction entry.
703730
/// Set consistent to false.
704-
bool exactSIVtest(const SCEV *SrcCoeff,
705-
const SCEV *DstCoeff,
706-
const SCEV *SrcConst,
707-
const SCEV *DstConst,
708-
const Loop *CurrentLoop,
709-
unsigned Level,
710-
FullDependence &Result,
731+
bool exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
732+
const SCEV *SrcConst, const SCEV *DstConst,
733+
const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop,
734+
unsigned Level, FullDependence &Result,
711735
Constraint &NewConstraint) const;
712736

713737
/// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
@@ -720,11 +744,9 @@ namespace llvm {
720744
/// Sets appropriate direction entry.
721745
/// Set consistent to false.
722746
/// If loop peeling will break the dependence, mark appropriately.
723-
bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
724-
const SCEV *SrcConst,
725-
const SCEV *DstConst,
726-
const Loop *CurrentLoop,
727-
unsigned Level,
747+
bool weakZeroSrcSIVtest(const SCEV *DstCoeff, const SCEV *SrcConst,
748+
const SCEV *DstConst, const Loop *CurrentSrcLoop,
749+
const Loop *CurrentDstLoop, unsigned Level,
728750
FullDependence &Result,
729751
Constraint &NewConstraint) const;
730752

@@ -738,11 +760,9 @@ namespace llvm {
738760
/// Sets appropriate direction entry.
739761
/// Set consistent to false.
740762
/// If loop peeling will break the dependence, mark appropriately.
741-
bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
742-
const SCEV *SrcConst,
743-
const SCEV *DstConst,
744-
const Loop *CurrentLoop,
745-
unsigned Level,
763+
bool weakZeroDstSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
764+
const SCEV *DstConst, const Loop *CurrentSrcLoop,
765+
const Loop *CurrentDstLoop, unsigned Level,
746766
FullDependence &Result,
747767
Constraint &NewConstraint) const;
748768

0 commit comments

Comments
 (0)