@@ -82,6 +82,17 @@ namespace llvm {
82
82
// / Dependence::DVEntry - Each level in the distance/direction vector
83
83
// / has a direction (or perhaps a union of several directions), and
84
84
// / 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
+ // / }
85
96
struct DVEntry {
86
97
enum : unsigned char {
87
98
NONE = 0 ,
@@ -153,13 +164,26 @@ namespace llvm {
153
164
// / source and destination of the dependence.
154
165
virtual unsigned getLevels () const { return 0 ; }
155
166
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
+
156
175
// / 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
+ }
159
180
160
181
// / 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
+ }
163
187
164
188
// / Check if the direction vector is negative. A negative direction
165
189
// / vector means Src and Dst are reversed in the actual program.
@@ -172,21 +196,31 @@ namespace llvm {
172
196
virtual bool normalize (ScalarEvolution *SE) { return false ; }
173
197
174
198
// / 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
+ }
177
203
178
204
// / 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
+ }
181
209
182
- // / isSplitable - Returns true if splitting this loop will break
210
+ // / isSplitable - Returns true if splitting the loop will break
183
211
// / 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 ; }
185
219
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 ;
190
224
191
225
// / getNextPredecessor - Returns the value of the NextPredecessor
192
226
// / field.
@@ -212,6 +246,10 @@ namespace llvm {
212
246
// /
213
247
void dump (raw_ostream &OS) const ;
214
248
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
+
215
253
protected:
216
254
Instruction *Src, *Dst;
217
255
@@ -252,13 +290,31 @@ namespace llvm {
252
290
// / source and destination of the dependence.
253
291
unsigned getLevels () const override { return Levels; }
254
292
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
+
255
310
// / 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 ;
258
313
259
314
// / 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 ;
262
318
263
319
// / Check if the direction vector is negative. A negative direction
264
320
// / vector means Src and Dst are reversed in the actual program.
@@ -271,27 +327,33 @@ namespace llvm {
271
327
bool normalize (ScalarEvolution *SE) override ;
272
328
273
329
// / 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 ;
276
332
277
333
// / 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 ;
280
336
281
337
// / isSplitable - Returns true if splitting the loop will break
282
338
// / the dependence.
283
- bool isSplitable (unsigned Level) const override ;
339
+ bool isSplitable (unsigned Level, bool Separate = false ) const override ;
284
340
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 ;
289
349
290
350
private:
291
351
unsigned short Levels;
352
+ unsigned short SeparateLevels;
292
353
bool LoopIndependent;
293
354
bool Consistent; // Init to true, then refine.
294
355
std::unique_ptr<DVEntry[]> DV;
356
+ std::unique_ptr<DVEntry[]> DVSeparate;
295
357
friend class DependenceInfo ;
296
358
};
297
359
@@ -423,7 +485,8 @@ namespace llvm {
423
485
const SCEV *A;
424
486
const SCEV *B;
425
487
const SCEV *C;
426
- const Loop *AssociatedLoop;
488
+ const Loop *AssociatedSrcLoop;
489
+ const Loop *AssociatedDstLoop;
427
490
428
491
public:
429
492
// / isEmpty - Return true if the constraint is of kind Empty.
@@ -467,19 +530,27 @@ namespace llvm {
467
530
// / Otherwise assert.
468
531
LLVM_ABI const SCEV *getD () const ;
469
532
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 ;
472
540
473
541
// / setPoint - Change a constraint to Point.
474
542
LLVM_ABI void setPoint (const SCEV *X, const SCEV *Y,
475
- const Loop *CurrentLoop);
543
+ const Loop *CurrentSrcLoop,
544
+ const Loop *CurrentDstLoop);
476
545
477
546
// / setLine - Change a constraint to Line.
478
547
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);
480
550
481
551
// / 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);
483
554
484
555
// / setEmpty - Change a constraint to Empty.
485
556
LLVM_ABI void setEmpty ();
@@ -492,6 +563,10 @@ namespace llvm {
492
563
LLVM_ABI void dump (raw_ostream &OS) const ;
493
564
};
494
565
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
+
495
570
// / establishNestingLevels - Examines the loop nesting of the Src and Dst
496
571
// / instructions and establishes their shared loops. Sets the variables
497
572
// / CommonLevels, SrcLevels, and MaxLevels.
@@ -542,10 +617,15 @@ namespace llvm {
542
617
// / e - 5
543
618
// / f - 6
544
619
// / 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);
547
627
548
- unsigned CommonLevels, SrcLevels, MaxLevels;
628
+ unsigned CommonLevels, SrcLevels, MaxLevels, SeparateLevels ;
549
629
550
630
// / mapSrcLoop - Given one of the loops containing the source, return
551
631
// / its level index in our numbering scheme.
@@ -684,13 +764,10 @@ namespace llvm {
684
764
// / Returns true if any possible dependence is disproved.
685
765
// / If there might be a dependence, returns false.
686
766
// / 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 ;
694
771
695
772
// / weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
696
773
// / (Src and Dst) for dependence.
@@ -702,13 +779,10 @@ namespace llvm {
702
779
// / Sets appropriate direction entry.
703
780
// / Set consistent to false.
704
781
// / 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,
712
786
const SCEV *&SplitIter) const ;
713
787
714
788
// / ExactSIVtest - Tests the SIV subscript pair
@@ -720,13 +794,10 @@ namespace llvm {
720
794
// / If there might be a dependence, returns false.
721
795
// / Sets appropriate direction entry.
722
796
// / 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,
730
801
Constraint &NewConstraint) const ;
731
802
732
803
// / weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
@@ -739,11 +810,9 @@ namespace llvm {
739
810
// / Sets appropriate direction entry.
740
811
// / Set consistent to false.
741
812
// / 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,
747
816
FullDependence &Result,
748
817
Constraint &NewConstraint) const ;
749
818
@@ -757,11 +826,9 @@ namespace llvm {
757
826
// / Sets appropriate direction entry.
758
827
// / Set consistent to false.
759
828
// / 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,
765
832
FullDependence &Result,
766
833
Constraint &NewConstraint) const ;
767
834
0 commit comments