@@ -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,32 @@ 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 that are treated like a single
218
+ // / fused loop.
219
+ virtual bool inSeparateLoops (unsigned Level) const { return false ; }
185
220
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 ;
221
+ // / isScalar - Returns true if a particular regular or separate level is
222
+ // / scalar; that is, if no subscript in the source or destination mention
223
+ // / the induction variable associated with the loop at this level.
224
+ virtual bool isScalar (unsigned Level, bool Separate = false ) const ;
190
225
191
226
// / getNextPredecessor - Returns the value of the NextPredecessor
192
227
// / field.
@@ -212,6 +247,10 @@ namespace llvm {
212
247
// /
213
248
void dump (raw_ostream &OS) const ;
214
249
250
+ // / dumpImp - For debugging purposes. Dumps a dependence to OS with or
251
+ // / without considering the separate levels.
252
+ void dumpImp (raw_ostream &OS, bool Separate = false ) const ;
253
+
215
254
protected:
216
255
Instruction *Src, *Dst;
217
256
@@ -252,13 +291,31 @@ namespace llvm {
252
291
// / source and destination of the dependence.
253
292
unsigned getLevels () const override { return Levels; }
254
293
294
+ // / getSeparateLevels - Returns the number of separate loops surrounding
295
+ // / the source and destination of the dependence.
296
+ unsigned getSeparateLevels () const override { return SeparateLevels; }
297
+
298
+ // / getDVEntry - Returns the DV entry associated with a regular or a
299
+ // / separate level
300
+ DVEntry getDVEntry (unsigned Level, bool Separate) const {
301
+ if (!Separate) {
302
+ assert (0 < Level && Level <= Levels && " Level out of range" );
303
+ return DV[Level - 1 ];
304
+ } else {
305
+ assert (Levels < Level && Level <= Levels + SeparateLevels &&
306
+ " Separate level out of range" );
307
+ return DVSeparate[Level - Levels - 1 ];
308
+ }
309
+ }
310
+
255
311
// / getDirection - Returns the direction associated with a particular
256
- // / level.
257
- unsigned getDirection (unsigned Level) const override ;
312
+ // / common or separate level.
313
+ unsigned getDirection (unsigned Level, bool Separate = false ) const override ;
258
314
259
315
// / getDistance - Returns the distance (or NULL) associated with a
260
- // / particular level.
261
- const SCEV *getDistance (unsigned Level) const override ;
316
+ // / particular common or separate level.
317
+ const SCEV *getDistance (unsigned Level,
318
+ bool Separate = false ) const override ;
262
319
263
320
// / Check if the direction vector is negative. A negative direction
264
321
// / vector means Src and Dst are reversed in the actual program.
@@ -271,27 +328,34 @@ namespace llvm {
271
328
bool normalize (ScalarEvolution *SE) override ;
272
329
273
330
// / isPeelFirst - Returns true if peeling the first iteration from
274
- // / this loop will break this dependence.
275
- bool isPeelFirst (unsigned Level) const override ;
331
+ // / this regular or separate loop level will break this dependence.
332
+ bool isPeelFirst (unsigned Level, bool Separate = false ) const override ;
276
333
277
334
// / isPeelLast - Returns true if peeling the last iteration from
278
- // / this loop will break this dependence.
279
- bool isPeelLast (unsigned Level) const override ;
335
+ // / this regular or separate loop level will break this dependence.
336
+ bool isPeelLast (unsigned Level, bool Separate = false ) const override ;
280
337
281
338
// / isSplitable - Returns true if splitting the loop will break
282
339
// / the dependence.
283
- bool isSplitable (unsigned Level) const override ;
340
+ bool isSplitable (unsigned Level, bool Separate = false ) const override ;
284
341
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 ;
342
+ // / inSeparateLoops - Returns true if this level is a separate level, i.e.,
343
+ // / performed across two separate loop nests that are treated like a single
344
+ // / fused loop.
345
+ bool inSeparateLoops (unsigned Level) const override ;
346
+
347
+ // / isScalar - Returns true if a particular regular or separate level is
348
+ // / scalar; that is, if no subscript in the source or destination mention
349
+ // / the induction variable associated with the loop at this level.
350
+ bool isScalar (unsigned Level, bool Separate = false ) const override ;
289
351
290
352
private:
291
353
unsigned short Levels;
354
+ unsigned short SeparateLevels;
292
355
bool LoopIndependent;
293
356
bool Consistent; // Init to true, then refine.
294
357
std::unique_ptr<DVEntry[]> DV;
358
+ std::unique_ptr<DVEntry[]> DVSeparate;
295
359
friend class DependenceInfo ;
296
360
};
297
361
@@ -423,7 +487,8 @@ namespace llvm {
423
487
const SCEV *A;
424
488
const SCEV *B;
425
489
const SCEV *C;
426
- const Loop *AssociatedLoop;
490
+ const Loop *AssociatedSrcLoop;
491
+ const Loop *AssociatedDstLoop;
427
492
428
493
public:
429
494
// / isEmpty - Return true if the constraint is of kind Empty.
@@ -467,19 +532,27 @@ namespace llvm {
467
532
// / Otherwise assert.
468
533
LLVM_ABI const SCEV *getD () const ;
469
534
470
- // / getAssociatedLoop - Returns the loop associated with this constraint.
471
- LLVM_ABI const Loop *getAssociatedLoop () const ;
535
+ // / getAssociatedSrcLoop - Returns the source loop associated with this
536
+ // / constraint.
537
+ LLVM_ABI const Loop *getAssociatedSrcLoop () const ;
538
+
539
+ // / getAssociatedDstLoop - Returns the destination loop associated with
540
+ // / this constraint.
541
+ LLVM_ABI const Loop *getAssociatedDstLoop () const ;
472
542
473
543
// / setPoint - Change a constraint to Point.
474
544
LLVM_ABI void setPoint (const SCEV *X, const SCEV *Y,
475
- const Loop *CurrentLoop);
545
+ const Loop *CurrentSrcLoop,
546
+ const Loop *CurrentDstLoop);
476
547
477
548
// / setLine - Change a constraint to Line.
478
549
LLVM_ABI void setLine (const SCEV *A, const SCEV *B, const SCEV *C,
479
- const Loop *CurrentLoop);
550
+ const Loop *CurrentSrcLoop,
551
+ const Loop *CurrentDstLoop);
480
552
481
553
// / setDistance - Change a constraint to Distance.
482
- LLVM_ABI void setDistance (const SCEV *D, const Loop *CurrentLoop);
554
+ LLVM_ABI void setDistance (const SCEV *D, const Loop *CurrentSrcLoop,
555
+ const Loop *CurrentDstLoop);
483
556
484
557
// / setEmpty - Change a constraint to Empty.
485
558
LLVM_ABI void setEmpty ();
@@ -492,6 +565,10 @@ namespace llvm {
492
565
LLVM_ABI void dump (raw_ostream &OS) const ;
493
566
};
494
567
568
+ // / Returns true if two loops are the same or they have the same tripcount
569
+ // / and depth
570
+ bool areLoopsSimilar (const Loop *SrcLoop, const Loop *DstLoop) const ;
571
+
495
572
// / establishNestingLevels - Examines the loop nesting of the Src and Dst
496
573
// / instructions and establishes their shared loops. Sets the variables
497
574
// / CommonLevels, SrcLevels, and MaxLevels.
@@ -542,10 +619,23 @@ namespace llvm {
542
619
// / e - 5
543
620
// / f - 6
544
621
// / g - 7 = MaxLevels
545
- void establishNestingLevels (const Instruction *Src,
546
- const Instruction *Dst);
547
-
548
- unsigned CommonLevels, SrcLevels, MaxLevels;
622
+ // / SeparateLevels counts the number of levels after common levels that are
623
+ // / not common but are similar, meaning that they have the same tripcount
624
+ // / and depth. Assume that in this code fragment, levels c and e are
625
+ // / similar. In this case only the loop nests at the next level after
626
+ // / common levels are similar, and SeparateLevel is set to 1.
627
+ // / If there are similar loop nests, we could use the APIs with considering
628
+ // / them as fused loops. In that case the level numbers for the previous
629
+ // / code look like
630
+ // / a - 1
631
+ // / b - 2
632
+ // / c,e - 3 = CommonLevels
633
+ // / d - 4 = SrcLevels
634
+ // / f - 5
635
+ // / g - 6 = MaxLevels
636
+ void establishNestingLevels (const Instruction *Src, const Instruction *Dst);
637
+
638
+ unsigned CommonLevels, SrcLevels, MaxLevels, SeparateLevels;
549
639
550
640
// / mapSrcLoop - Given one of the loops containing the source, return
551
641
// / its level index in our numbering scheme.
@@ -684,13 +774,10 @@ namespace llvm {
684
774
// / Returns true if any possible dependence is disproved.
685
775
// / If there might be a dependence, returns false.
686
776
// / 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 ;
777
+ bool strongSIVtest (const SCEV *Coeff, const SCEV *SrcConst,
778
+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
779
+ const Loop *CurrentDstLoop, unsigned Level,
780
+ FullDependence &Result, Constraint &NewConstraint) const ;
694
781
695
782
// / weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
696
783
// / (Src and Dst) for dependence.
@@ -702,13 +789,10 @@ namespace llvm {
702
789
// / Sets appropriate direction entry.
703
790
// / Set consistent to false.
704
791
// / 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,
792
+ bool weakCrossingSIVtest (const SCEV *SrcCoeff, const SCEV *SrcConst,
793
+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
794
+ const Loop *CurrentDstLoop, unsigned Level,
795
+ FullDependence &Result, Constraint &NewConstraint,
712
796
const SCEV *&SplitIter) const ;
713
797
714
798
// / ExactSIVtest - Tests the SIV subscript pair
@@ -720,13 +804,10 @@ namespace llvm {
720
804
// / If there might be a dependence, returns false.
721
805
// / Sets appropriate direction entry.
722
806
// / 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,
807
+ bool exactSIVtest (const SCEV *SrcCoeff, const SCEV *DstCoeff,
808
+ const SCEV *SrcConst, const SCEV *DstConst,
809
+ const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop,
810
+ unsigned Level, FullDependence &Result,
730
811
Constraint &NewConstraint) const ;
731
812
732
813
// / weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
@@ -739,11 +820,9 @@ namespace llvm {
739
820
// / Sets appropriate direction entry.
740
821
// / Set consistent to false.
741
822
// / 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,
823
+ bool weakZeroSrcSIVtest (const SCEV *DstCoeff, const SCEV *SrcConst,
824
+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
825
+ const Loop *CurrentDstLoop, unsigned Level,
747
826
FullDependence &Result,
748
827
Constraint &NewConstraint) const ;
749
828
@@ -757,11 +836,9 @@ namespace llvm {
757
836
// / Sets appropriate direction entry.
758
837
// / Set consistent to false.
759
838
// / 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,
839
+ bool weakZeroDstSIVtest (const SCEV *SrcCoeff, const SCEV *SrcConst,
840
+ const SCEV *DstConst, const Loop *CurrentSrcLoop,
841
+ const Loop *CurrentDstLoop, unsigned Level,
765
842
FullDependence &Result,
766
843
Constraint &NewConstraint) const ;
767
844
0 commit comments