@@ -82,6 +82,17 @@ namespace llvm {
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 are similar. Two levels are considered similar
87+ // / if they can be interpreted as a single fused loop, i.e., have the same
88+ // / trip count and the same nesting depth.
89+ // / For example, loops b and c are similar and considered as separate loops:
90+ // / for (a = ...) {
91+ // / for (b = 0; b < 10; b++) {
92+ // / }
93+ // / for (c = 0; c < 10; c++) {
94+ // / }
95+ // / }
8596 struct DVEntry {
8697 enum : unsigned char {
8798 NONE = 0 ,
@@ -153,13 +164,26 @@ namespace llvm {
153164 // / source and destination of the dependence.
154165 virtual unsigned getLevels () const { return 0 ; }
155166
167+ // / getSeparateLevels - Returns the number of separate loops surrounding
168+ // / the source and destination of the dependence.
169+ virtual unsigned getSeparateLevels () const { return 0 ; }
170+
171+ // / getDVEntry - Returns the DV entry associated with a regular or a
172+ // / separate level
173+ DVEntry getDVEntry (unsigned Level, bool Separate) const ;
174+
156175 // / getDirection - Returns the direction associated with a particular
157- // / level.
158- virtual unsigned getDirection (unsigned Level) const { return DVEntry::ALL; }
176+ // / common or separate level.
177+ virtual unsigned getDirection (unsigned Level, bool Separate = false ) const {
178+ return DVEntry::ALL;
179+ }
159180
160181 // / getDistance - Returns the distance (or NULL) associated with a
161- // / particular level.
162- virtual const SCEV *getDistance (unsigned Level) const { return nullptr ; }
182+ // / particular common or separate level.
183+ virtual const SCEV *getDistance (unsigned Level,
184+ bool Separate = false ) const {
185+ return nullptr ;
186+ }
163187
164188 // / Check if the direction vector is negative. A negative direction
165189 // / vector means Src and Dst are reversed in the actual program.
@@ -172,21 +196,31 @@ namespace llvm {
172196 virtual bool normalize (ScalarEvolution *SE) { return false ; }
173197
174198 // / isPeelFirst - Returns true if peeling the first iteration from
175- // / this loop will break this dependence.
176- virtual bool isPeelFirst (unsigned Level) const { return false ; }
199+ // / this regular or separate loop level will break this dependence.
200+ virtual bool isPeelFirst (unsigned Level, bool Separate = false ) const {
201+ return false ;
202+ }
177203
178204 // / isPeelLast - Returns true if peeling the last iteration from
179- // / this loop will break this dependence.
180- virtual bool isPeelLast (unsigned Level) const { return false ; }
205+ // / this regular or separate loop level will break this dependence.
206+ virtual bool isPeelLast (unsigned Level, bool Separate = false ) const {
207+ return false ;
208+ }
181209
182- // / isSplitable - Returns true if splitting this loop will break
210+ // / isSplitable - Returns true if splitting the loop will break
183211 // / the dependence.
184- virtual bool isSplitable (unsigned Level) const { return false ; }
212+ virtual bool isSplitable (unsigned Level, bool Separate = false ) const {
213+ return false ;
214+ }
215+
216+ // / inSeparateLoops - Returns true if this level is a separate level, i.e.,
217+ // / performed across two separate loop nests.
218+ virtual bool inSeparateLoops (unsigned Level) const { return false ; }
185219
186- // / isScalar - Returns true if a particular level is scalar; that is,
187- // / if no subscript in the source or destination mention the induction
188- // / variable associated with the loop at this level.
189- virtual bool isScalar (unsigned Level) const ;
220+ // / isScalar - Returns true if a particular regular or separate level is
221+ // / scalar; that is, if no subscript in the source or destination mention
222+ // / the induction variable associated with the loop at this level.
223+ virtual bool isScalar (unsigned Level, bool Separate = false ) const ;
190224
191225 // / getNextPredecessor - Returns the value of the NextPredecessor
192226 // / field.
@@ -212,6 +246,10 @@ namespace llvm {
212246 // /
213247 void dump (raw_ostream &OS) const ;
214248
249+ // / dumpImp - For debugging purposes. Dumps a dependence to OS with or
250+ // / without considering the separate levels.
251+ void dumpImp (raw_ostream &OS, bool Separate = false ) const ;
252+
215253 protected:
216254 Instruction *Src, *Dst;
217255
@@ -252,13 +290,31 @@ namespace llvm {
252290 // / source and destination of the dependence.
253291 unsigned getLevels () const override { return Levels; }
254292
293+ // / getSeparateLevels - Returns the number of separate loops surrounding
294+ // / the source and destination of the dependence.
295+ unsigned getSeparateLevels () const override { return SeparateLevels; }
296+
297+ // / getDVEntry - Returns the DV entry associated with a regular or a
298+ // / separate level
299+ DVEntry getDVEntry (unsigned Level, bool Separate) const {
300+ if (!Separate) {
301+ assert (0 < Level && Level <= Levels && " Level out of range" );
302+ return DV[Level - 1 ];
303+ } else {
304+ assert (Levels < Level && Level <= Levels + SeparateLevels &&
305+ " Separate level out of range" );
306+ return DVSeparate[Level - Levels - 1 ];
307+ }
308+ }
309+
255310 // / getDirection - Returns the direction associated with a particular
256- // / level.
257- unsigned getDirection (unsigned Level) const override ;
311+ // / common or separate level.
312+ unsigned getDirection (unsigned Level, bool Separate = false ) const override ;
258313
259314 // / getDistance - Returns the distance (or NULL) associated with a
260- // / particular level.
261- const SCEV *getDistance (unsigned Level) const override ;
315+ // / particular common or separate level.
316+ const SCEV *getDistance (unsigned Level,
317+ bool Separate = false ) const override ;
262318
263319 // / Check if the direction vector is negative. A negative direction
264320 // / vector means Src and Dst are reversed in the actual program.
@@ -271,27 +327,33 @@ namespace llvm {
271327 bool normalize (ScalarEvolution *SE) override ;
272328
273329 // / isPeelFirst - Returns true if peeling the first iteration from
274- // / this loop will break this dependence.
275- bool isPeelFirst (unsigned Level) const override ;
330+ // / this regular or separate loop level will break this dependence.
331+ bool isPeelFirst (unsigned Level, bool Separate = false ) const override ;
276332
277333 // / isPeelLast - Returns true if peeling the last iteration from
278- // / this loop will break this dependence.
279- bool isPeelLast (unsigned Level) const override ;
334+ // / this regular or separate loop level will break this dependence.
335+ bool isPeelLast (unsigned Level, bool Separate = false ) const override ;
280336
281337 // / isSplitable - Returns true if splitting the loop will break
282338 // / the dependence.
283- bool isSplitable (unsigned Level) const override ;
339+ bool isSplitable (unsigned Level, bool Separate = false ) const override ;
284340
285- // / isScalar - Returns true if a particular level is scalar; that is,
286- // / if no subscript in the source or destination mention the induction
287- // / variable associated with the loop at this level.
288- bool isScalar (unsigned Level) const override ;
341+ // / inSeparateLoops - Returns true if this level is a separate level, i.e.,
342+ // / performed across two separate loop nests.
343+ bool inSeparateLoops (unsigned Level) const override ;
344+
345+ // / isScalar - Returns true if a particular regular or separate level is
346+ // / scalar; that is, if no subscript in the source or destination mention
347+ // / the induction variable associated with the loop at this level.
348+ bool isScalar (unsigned Level, bool Separate = false ) const override ;
289349
290350 private:
291351 unsigned short Levels;
352+ unsigned short SeparateLevels;
292353 bool LoopIndependent;
293354 bool Consistent; // Init to true, then refine.
294355 std::unique_ptr<DVEntry[]> DV;
356+ std::unique_ptr<DVEntry[]> DVSeparate;
295357 friend class DependenceInfo ;
296358 };
297359
@@ -423,7 +485,8 @@ namespace llvm {
423485 const SCEV *A;
424486 const SCEV *B;
425487 const SCEV *C;
426- const Loop *AssociatedLoop;
488+ const Loop *AssociatedSrcLoop;
489+ const Loop *AssociatedDstLoop;
427490
428491 public:
429492 // / isEmpty - Return true if the constraint is of kind Empty.
@@ -467,19 +530,27 @@ namespace llvm {
467530 // / Otherwise assert.
468531 LLVM_ABI const SCEV *getD () const ;
469532
470- // / getAssociatedLoop - Returns the loop associated with this constraint.
471- LLVM_ABI const Loop *getAssociatedLoop () const ;
533+ // / getAssociatedSrcLoop - Returns the source loop associated with this
534+ // / constraint.
535+ LLVM_ABI const Loop *getAssociatedSrcLoop () const ;
536+
537+ // / getAssociatedDstLoop - Returns the destination loop associated with
538+ // / this constraint.
539+ LLVM_ABI const Loop *getAssociatedDstLoop () const ;
472540
473541 // / setPoint - Change a constraint to Point.
474542 LLVM_ABI void setPoint (const SCEV *X, const SCEV *Y,
475- const Loop *CurrentLoop);
543+ const Loop *CurrentSrcLoop,
544+ const Loop *CurrentDstLoop);
476545
477546 // / setLine - Change a constraint to Line.
478547 LLVM_ABI void setLine (const SCEV *A, const SCEV *B, const SCEV *C,
479- const Loop *CurrentLoop);
548+ const Loop *CurrentSrcLoop,
549+ const Loop *CurrentDstLoop);
480550
481551 // / setDistance - Change a constraint to Distance.
482- LLVM_ABI void setDistance (const SCEV *D, const Loop *CurrentLoop);
552+ LLVM_ABI void setDistance (const SCEV *D, const Loop *CurrentSrcLoop,
553+ const Loop *CurrentDstLoop);
483554
484555 // / setEmpty - Change a constraint to Empty.
485556 LLVM_ABI void setEmpty ();
@@ -492,6 +563,10 @@ namespace llvm {
492563 LLVM_ABI void dump (raw_ostream &OS) const ;
493564 };
494565
566+ // / Returns true if two loops are the same or they have the same tripcount
567+ // / and depth
568+ bool areLoopsSimilar (const Loop *SrcLoop, const Loop *DstLoop) const ;
569+
495570 // / establishNestingLevels - Examines the loop nesting of the Src and Dst
496571 // / instructions and establishes their shared loops. Sets the variables
497572 // / CommonLevels, SrcLevels, and MaxLevels.
@@ -542,10 +617,15 @@ namespace llvm {
542617 // / e - 5
543618 // / f - 6
544619 // / g - 7 = MaxLevels
545- void establishNestingLevels (const Instruction *Src,
546- const Instruction *Dst);
620+ // / SeparateLevels counts the number of loop levels after the common levels
621+ // / that are not identical but are considered similar. Two levels are
622+ // / considered similar if they have the same trip count and the same
623+ // / nesting depth.
624+ // / For example, if loops `c` and `e` are similar, then they contribute to
625+ // / the SeparateLevels count and SeparateLevels is set to 1.
626+ void establishNestingLevels (const Instruction *Src, const Instruction *Dst);
547627
548- unsigned CommonLevels, SrcLevels, MaxLevels;
628+ unsigned CommonLevels, SrcLevels, MaxLevels, SeparateLevels ;
549629
550630 // / mapSrcLoop - Given one of the loops containing the source, return
551631 // / its level index in our numbering scheme.
@@ -684,13 +764,10 @@ namespace llvm {
684764 // / Returns true if any possible dependence is disproved.
685765 // / If there might be a dependence, returns false.
686766 // / Sets appropriate direction and distance.
687- bool strongSIVtest (const SCEV *Coeff,
688- const SCEV *SrcConst,
689- const SCEV *DstConst,
690- const Loop *CurrentLoop,
691- unsigned Level,
692- FullDependence &Result,
693- Constraint &NewConstraint) const ;
767+ bool strongSIVtest (const SCEV *Coeff, const SCEV *SrcConst,
768+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
769+ const Loop *CurrentDstLoop, unsigned Level,
770+ FullDependence &Result, Constraint &NewConstraint) const ;
694771
695772 // / weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
696773 // / (Src and Dst) for dependence.
@@ -702,13 +779,10 @@ namespace llvm {
702779 // / Sets appropriate direction entry.
703780 // / Set consistent to false.
704781 // / Marks the dependence as splitable.
705- bool weakCrossingSIVtest (const SCEV *SrcCoeff,
706- const SCEV *SrcConst,
707- const SCEV *DstConst,
708- const Loop *CurrentLoop,
709- unsigned Level,
710- FullDependence &Result,
711- Constraint &NewConstraint,
782+ bool weakCrossingSIVtest (const SCEV *SrcCoeff, const SCEV *SrcConst,
783+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
784+ const Loop *CurrentDstLoop, unsigned Level,
785+ FullDependence &Result, Constraint &NewConstraint,
712786 const SCEV *&SplitIter) const ;
713787
714788 // / ExactSIVtest - Tests the SIV subscript pair
@@ -720,13 +794,10 @@ namespace llvm {
720794 // / If there might be a dependence, returns false.
721795 // / Sets appropriate direction entry.
722796 // / Set consistent to false.
723- bool exactSIVtest (const SCEV *SrcCoeff,
724- const SCEV *DstCoeff,
725- const SCEV *SrcConst,
726- const SCEV *DstConst,
727- const Loop *CurrentLoop,
728- unsigned Level,
729- FullDependence &Result,
797+ bool exactSIVtest (const SCEV *SrcCoeff, const SCEV *DstCoeff,
798+ const SCEV *SrcConst, const SCEV *DstConst,
799+ const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop,
800+ unsigned Level, FullDependence &Result,
730801 Constraint &NewConstraint) const ;
731802
732803 // / weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
@@ -739,11 +810,9 @@ namespace llvm {
739810 // / Sets appropriate direction entry.
740811 // / Set consistent to false.
741812 // / If loop peeling will break the dependence, mark appropriately.
742- bool weakZeroSrcSIVtest (const SCEV *DstCoeff,
743- const SCEV *SrcConst,
744- const SCEV *DstConst,
745- const Loop *CurrentLoop,
746- unsigned Level,
813+ bool weakZeroSrcSIVtest (const SCEV *DstCoeff, const SCEV *SrcConst,
814+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
815+ const Loop *CurrentDstLoop, unsigned Level,
747816 FullDependence &Result,
748817 Constraint &NewConstraint) const ;
749818
@@ -757,11 +826,9 @@ namespace llvm {
757826 // / Sets appropriate direction entry.
758827 // / Set consistent to false.
759828 // / If loop peeling will break the dependence, mark appropriately.
760- bool weakZeroDstSIVtest (const SCEV *SrcCoeff,
761- const SCEV *SrcConst,
762- const SCEV *DstConst,
763- const Loop *CurrentLoop,
764- unsigned Level,
829+ bool weakZeroDstSIVtest (const SCEV *SrcCoeff, const SCEV *SrcConst,
830+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
831+ const Loop *CurrentDstLoop, unsigned Level,
765832 FullDependence &Result,
766833 Constraint &NewConstraint) const ;
767834
0 commit comments