@@ -82,6 +82,16 @@ class LLVM_ABI Dependence {
8282 // / Dependence::DVEntry - Each level in the distance/direction vector
8383 // / has a direction (or perhaps a union of several directions), and
8484 // / perhaps a distance.
85+ // / The dependency information could be across a single loop level or across
86+ // / two separate levels that have the same trip count and nesting depth,
87+ // / which helps to provide information for loop fusion candidation.
88+ // / For example, loops b and c have the same iteration count and depth:
89+ // / for (a = ...) {
90+ // / for (b = 0; b < 10; b++) {
91+ // / }
92+ // / for (c = 0; c < 10; c++) {
93+ // / }
94+ // / }
8595 struct DVEntry {
8696 enum : unsigned char {
8797 NONE = 0 ,
@@ -144,12 +154,25 @@ class LLVM_ABI Dependence {
144154 // / source and destination of the dependence.
145155 virtual unsigned getLevels () const { return 0 ; }
146156
147- // / getDirection - Returns the direction associated with a particular level.
148- virtual unsigned getDirection (unsigned Level) const { return DVEntry::ALL; }
157+ // / getSameSDLevels - Returns the number of separate SameSD loops surrounding
158+ // / the source and destination of the dependence.
159+ virtual unsigned getSameSDLevels () const { return 0 ; }
149160
150- // / getDistance - Returns the distance (or NULL) associated with a particular
151- // / level.
152- virtual const SCEV *getDistance (unsigned Level) const { return nullptr ; }
161+ // / getDVEntry - Returns the DV entry associated with a regular or a
162+ // / SameSD level
163+ DVEntry getDVEntry (unsigned Level, bool isSameSD) const ;
164+
165+ // / getDirection - Returns the direction associated with a particular
166+ // / common or SameSD level.
167+ virtual unsigned getDirection (unsigned Level, bool SameSD = false ) const {
168+ return DVEntry::ALL;
169+ }
170+
171+ // / getDistance - Returns the distance (or NULL) associated with a
172+ // / particular common or SameSD level.
173+ virtual const SCEV *getDistance (unsigned Level, bool SameSD = false ) const {
174+ return nullptr ;
175+ }
153176
154177 // / Check if the direction vector is negative. A negative direction
155178 // / vector means Src and Dst are reversed in the actual program.
@@ -162,21 +185,32 @@ class LLVM_ABI Dependence {
162185 virtual bool normalize (ScalarEvolution *SE) { return false ; }
163186
164187 // / isPeelFirst - Returns true if peeling the first iteration from
165- // / this loop will break this dependence.
166- virtual bool isPeelFirst (unsigned Level) const { return false ; }
188+ // / this regular or SameSD loop level will break this dependence.
189+ virtual bool isPeelFirst (unsigned Level, bool SameSD = false ) const {
190+ return false ;
191+ }
167192
168193 // / isPeelLast - Returns true if peeling the last iteration from
169- // / this loop will break this dependence.
170- virtual bool isPeelLast (unsigned Level) const { return false ; }
194+ // / this regular or SameSD loop level will break this dependence.
195+ virtual bool isPeelLast (unsigned Level, bool SameSD = false ) const {
196+ return false ;
197+ }
171198
172- // / isSplitable - Returns true if splitting this loop will break the
173- // / dependence.
174- virtual bool isSplitable (unsigned Level) const { return false ; }
199+ // / isSplitable - Returns true if splitting the loop will break
200+ // / the dependence.
201+ virtual bool isSplitable (unsigned Level, bool SameSD = false ) const {
202+ return false ;
203+ }
175204
176- // / isScalar - Returns true if a particular level is scalar; that is,
177- // / if no subscript in the source or destination mention the induction
178- // / variable associated with the loop at this level.
179- virtual bool isScalar (unsigned Level) const ;
205+ // / inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
206+ // / performed across two separate loop nests that have the Same Iteration and
207+ // / Depth.
208+ virtual bool inSameSDLoops (unsigned Level) const { return false ; }
209+
210+ // / isScalar - Returns true if a particular regular or SameSD level is
211+ // / scalar; that is, if no subscript in the source or destination mention
212+ // / the induction variable associated with the loop at this level.
213+ virtual bool isScalar (unsigned Level, bool SameSD = false ) const ;
180214
181215 // / getNextPredecessor - Returns the value of the NextPredecessor field.
182216 const Dependence *getNextPredecessor () const { return NextPredecessor; }
@@ -198,6 +232,10 @@ class LLVM_ABI Dependence {
198232 // / dump - For debugging purposes, dumps a dependence to OS.
199233 void dump (raw_ostream &OS) const ;
200234
235+ // / dumpImp - For debugging purposes. Dumps a dependence to OS with or
236+ // / without considering the SameSD levels.
237+ void dumpImp (raw_ostream &OS, bool SameSD = false ) const ;
238+
201239protected:
202240 Instruction *Src, *Dst;
203241
@@ -238,13 +276,30 @@ class LLVM_ABI FullDependence final : public Dependence {
238276 // / source and destination of the dependence.
239277 unsigned getLevels () const override { return Levels; }
240278
279+ // / getSameSDLevels - Returns the number of separate SameSD loops surrounding
280+ // / the source and destination of the dependence.
281+ unsigned getSameSDLevels () const override { return SameSDLevels; }
282+
283+ // / getDVEntry - Returns the DV entry associated with a regular or a
284+ // / SameSD level.
285+ DVEntry getDVEntry (unsigned Level, bool isSameSD) const {
286+ if (!isSameSD) {
287+ assert (0 < Level && Level <= Levels && " Level out of range" );
288+ return DV[Level - 1 ];
289+ } else {
290+ assert (Levels < Level && Level <= Levels + SameSDLevels &&
291+ " isSameSD level out of range" );
292+ return DVSameSD[Level - Levels - 1 ];
293+ }
294+ }
295+
241296 // / getDirection - Returns the direction associated with a particular
242- // / level.
243- unsigned getDirection (unsigned Level) const override ;
297+ // / common or SameSD level.
298+ unsigned getDirection (unsigned Level, bool SameSD = false ) const override ;
244299
245300 // / getDistance - Returns the distance (or NULL) associated with a
246- // / particular level.
247- const SCEV *getDistance (unsigned Level) const override ;
301+ // / particular common or SameSD level.
302+ const SCEV *getDistance (unsigned Level, bool SameSD = false ) const override ;
248303
249304 // / Check if the direction vector is negative. A negative direction
250305 // / vector means Src and Dst are reversed in the actual program.
@@ -257,27 +312,34 @@ class LLVM_ABI FullDependence final : public Dependence {
257312 bool normalize (ScalarEvolution *SE) override ;
258313
259314 // / isPeelFirst - Returns true if peeling the first iteration from
260- // / this loop will break this dependence.
261- bool isPeelFirst (unsigned Level) const override ;
315+ // / this regular or SameSD loop level will break this dependence.
316+ bool isPeelFirst (unsigned Level, bool SameSD = false ) const override ;
262317
263318 // / isPeelLast - Returns true if peeling the last iteration from
264- // / this loop will break this dependence.
265- bool isPeelLast (unsigned Level) const override ;
319+ // / this regular or SameSD loop level will break this dependence.
320+ bool isPeelLast (unsigned Level, bool SameSD = false ) const override ;
266321
267322 // / isSplitable - Returns true if splitting the loop will break
268323 // / the dependence.
269- bool isSplitable (unsigned Level) const override ;
324+ bool isSplitable (unsigned Level, bool SameSD = false ) const override ;
325+
326+ // / inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
327+ // / performed across two separate loop nests that have the Same Iteration and
328+ // / Depth.
329+ bool inSameSDLoops (unsigned Level) const override ;
270330
271- // / isScalar - Returns true if a particular level is scalar; that is,
272- // / if no subscript in the source or destination mention the induction
273- // / variable associated with the loop at this level.
274- bool isScalar (unsigned Level) const override ;
331+ // / isScalar - Returns true if a particular regular or SameSD level is
332+ // / scalar; that is, if no subscript in the source or destination mention
333+ // / the induction variable associated with the loop at this level.
334+ bool isScalar (unsigned Level, bool SameSD = false ) const override ;
275335
276336private:
277337 unsigned short Levels;
338+ unsigned short SameSDLevels;
278339 bool LoopIndependent;
279340 bool Consistent; // Init to true, then refine.
280341 std::unique_ptr<DVEntry[]> DV;
342+ std::unique_ptr<DVEntry[]> DVSameSD; // DV entries on SameSD levels
281343 friend class DependenceInfo ;
282344};
283345
@@ -406,7 +468,8 @@ class DependenceInfo {
406468 const SCEV *A;
407469 const SCEV *B;
408470 const SCEV *C;
409- const Loop *AssociatedLoop;
471+ const Loop *AssociatedSrcLoop;
472+ const Loop *AssociatedDstLoop;
410473
411474 public:
412475 // / isEmpty - Return true if the constraint is of kind Empty.
@@ -450,19 +513,27 @@ class DependenceInfo {
450513 // / Otherwise assert.
451514 LLVM_ABI const SCEV *getD () const ;
452515
453- // / getAssociatedLoop - Returns the loop associated with this constraint.
454- LLVM_ABI const Loop *getAssociatedLoop () const ;
516+ // / getAssociatedSrcLoop - Returns the source loop associated with this
517+ // / constraint.
518+ LLVM_ABI const Loop *getAssociatedSrcLoop () const ;
519+
520+ // / getAssociatedDstLoop - Returns the destination loop associated with
521+ // / this constraint.
522+ LLVM_ABI const Loop *getAssociatedDstLoop () const ;
455523
456524 // / setPoint - Change a constraint to Point.
457525 LLVM_ABI void setPoint (const SCEV *X, const SCEV *Y,
458- const Loop *CurrentLoop);
526+ const Loop *CurrentSrcLoop,
527+ const Loop *CurrentDstLoop);
459528
460529 // / setLine - Change a constraint to Line.
461530 LLVM_ABI void setLine (const SCEV *A, const SCEV *B, const SCEV *C,
462- const Loop *CurrentLoop);
531+ const Loop *CurrentSrcLoop,
532+ const Loop *CurrentDstLoop);
463533
464534 // / setDistance - Change a constraint to Distance.
465- LLVM_ABI void setDistance (const SCEV *D, const Loop *CurrentLoop);
535+ LLVM_ABI void setDistance (const SCEV *D, const Loop *CurrentSrcLoop,
536+ const Loop *CurrentDstLoop);
466537
467538 // / setEmpty - Change a constraint to Empty.
468539 LLVM_ABI void setEmpty ();
@@ -475,6 +546,12 @@ class DependenceInfo {
475546 LLVM_ABI void dump (raw_ostream &OS) const ;
476547 };
477548
549+ // / Returns true if two loops have the Same iteration Space and Depth. To be
550+ // / more specific, two loops have SameSD if they are in the same nesting
551+ // / depth and have the same backedge count. SameSD stands for Same iteration
552+ // / Space and Depth.
553+ bool haveSameSD (const Loop *SrcLoop, const Loop *DstLoop) const ;
554+
478555 // / establishNestingLevels - Examines the loop nesting of the Src and Dst
479556 // / instructions and establishes their shared loops. Sets the variables
480557 // / CommonLevels, SrcLevels, and MaxLevels.
@@ -525,9 +602,21 @@ class DependenceInfo {
525602 // / e - 5
526603 // / f - 6
527604 // / g - 7 = MaxLevels
605+ // / SameSDLevels counts the number of levels after common levels that are
606+ // / not common but have the same iteration space and depth. Internally this
607+ // / is checked using haveSameSD. Assume that in this code fragment, levels c
608+ // / and e have the same iteration space and depth, but levels d and f does
609+ // / not. Then SameSDLevels is set to 1. In that case the level numbers for the
610+ // / previous code look like
611+ // / a - 1
612+ // / b - 2
613+ // / c,e - 3 = CommonLevels
614+ // / d - 4 = SrcLevels
615+ // / f - 5
616+ // / g - 6 = MaxLevels
528617 void establishNestingLevels (const Instruction *Src, const Instruction *Dst);
529618
530- unsigned CommonLevels, SrcLevels, MaxLevels;
619+ unsigned CommonLevels, SrcLevels, MaxLevels, SameSDLevels ;
531620
532621 // / mapSrcLoop - Given one of the loops containing the source, return
533622 // / its level index in our numbering scheme.
@@ -652,9 +741,9 @@ class DependenceInfo {
652741 // / If there might be a dependence, returns false.
653742 // / Sets appropriate direction and distance.
654743 bool strongSIVtest (const SCEV *Coeff, const SCEV *SrcConst,
655- const SCEV *DstConst, const Loop *CurrentLoop ,
656- unsigned Level, FullDependence &Result ,
657- Constraint &NewConstraint) const ;
744+ const SCEV *DstConst, const Loop *CurrentSrcLoop ,
745+ const Loop *CurrentDstLoop, unsigned Level ,
746+ FullDependence &Result, Constraint &NewConstraint) const ;
658747
659748 // / weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
660749 // / (Src and Dst) for dependence.
@@ -667,9 +756,9 @@ class DependenceInfo {
667756 // / Set consistent to false.
668757 // / Marks the dependence as splitable.
669758 bool weakCrossingSIVtest (const SCEV *SrcCoeff, const SCEV *SrcConst,
670- const SCEV *DstConst, const Loop *CurrentLoop ,
671- unsigned Level, FullDependence &Result ,
672- Constraint &NewConstraint,
759+ const SCEV *DstConst, const Loop *CurrentSrcLoop ,
760+ const Loop *CurrentDstLoop, unsigned Level ,
761+ FullDependence &Result, Constraint &NewConstraint,
673762 const SCEV *&SplitIter) const ;
674763
675764 // / ExactSIVtest - Tests the SIV subscript pair
@@ -683,8 +772,9 @@ class DependenceInfo {
683772 // / Set consistent to false.
684773 bool exactSIVtest (const SCEV *SrcCoeff, const SCEV *DstCoeff,
685774 const SCEV *SrcConst, const SCEV *DstConst,
686- const Loop *CurrentLoop, unsigned Level,
687- FullDependence &Result, Constraint &NewConstraint) const ;
775+ const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop,
776+ unsigned Level, FullDependence &Result,
777+ Constraint &NewConstraint) const ;
688778
689779 // / weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
690780 // / (Src and Dst) for dependence.
@@ -697,8 +787,9 @@ class DependenceInfo {
697787 // / Set consistent to false.
698788 // / If loop peeling will break the dependence, mark appropriately.
699789 bool weakZeroSrcSIVtest (const SCEV *DstCoeff, const SCEV *SrcConst,
700- const SCEV *DstConst, const Loop *CurrentLoop,
701- unsigned Level, FullDependence &Result,
790+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
791+ const Loop *CurrentDstLoop, unsigned Level,
792+ FullDependence &Result,
702793 Constraint &NewConstraint) const ;
703794
704795 // / weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
@@ -712,8 +803,9 @@ class DependenceInfo {
712803 // / Set consistent to false.
713804 // / If loop peeling will break the dependence, mark appropriately.
714805 bool weakZeroDstSIVtest (const SCEV *SrcCoeff, const SCEV *SrcConst,
715- const SCEV *DstConst, const Loop *CurrentLoop,
716- unsigned Level, FullDependence &Result,
806+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
807+ const Loop *CurrentDstLoop, unsigned Level,
808+ FullDependence &Result,
717809 Constraint &NewConstraint) const ;
718810
719811 // / exactRDIVtest - Tests the RDIV subscript pair for dependence.
0 commit comments