@@ -82,6 +82,16 @@ class LLVM_ABI Dependence {
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 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
+ // / }
85
95
struct DVEntry {
86
96
enum : unsigned char {
87
97
NONE = 0 ,
@@ -144,12 +154,25 @@ class LLVM_ABI Dependence {
144
154
// / source and destination of the dependence.
145
155
virtual unsigned getLevels () const { return 0 ; }
146
156
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 ; }
149
160
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
+ }
153
176
154
177
// / Check if the direction vector is negative. A negative direction
155
178
// / vector means Src and Dst are reversed in the actual program.
@@ -162,21 +185,32 @@ class LLVM_ABI Dependence {
162
185
virtual bool normalize (ScalarEvolution *SE) { return false ; }
163
186
164
187
// / 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
+ }
167
192
168
193
// / 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
+ }
171
198
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
+ }
175
204
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 ;
180
214
181
215
// / getNextPredecessor - Returns the value of the NextPredecessor field.
182
216
const Dependence *getNextPredecessor () const { return NextPredecessor; }
@@ -198,6 +232,10 @@ class LLVM_ABI Dependence {
198
232
// / dump - For debugging purposes, dumps a dependence to OS.
199
233
void dump (raw_ostream &OS) const ;
200
234
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
+
201
239
protected:
202
240
Instruction *Src, *Dst;
203
241
@@ -238,13 +276,30 @@ class LLVM_ABI FullDependence final : public Dependence {
238
276
// / source and destination of the dependence.
239
277
unsigned getLevels () const override { return Levels; }
240
278
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
+
241
296
// / 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 ;
244
299
245
300
// / 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 ;
248
303
249
304
// / Check if the direction vector is negative. A negative direction
250
305
// / vector means Src and Dst are reversed in the actual program.
@@ -257,27 +312,34 @@ class LLVM_ABI FullDependence final : public Dependence {
257
312
bool normalize (ScalarEvolution *SE) override ;
258
313
259
314
// / 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 ;
262
317
263
318
// / 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 ;
266
321
267
322
// / isSplitable - Returns true if splitting the loop will break
268
323
// / 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 ;
270
330
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 ;
275
335
276
336
private:
277
337
unsigned short Levels;
338
+ unsigned short SameSDLevels;
278
339
bool LoopIndependent;
279
340
bool Consistent; // Init to true, then refine.
280
341
std::unique_ptr<DVEntry[]> DV;
342
+ std::unique_ptr<DVEntry[]> DVSameSD; // DV entries on SameSD levels
281
343
friend class DependenceInfo ;
282
344
};
283
345
@@ -406,7 +468,8 @@ class DependenceInfo {
406
468
const SCEV *A;
407
469
const SCEV *B;
408
470
const SCEV *C;
409
- const Loop *AssociatedLoop;
471
+ const Loop *AssociatedSrcLoop;
472
+ const Loop *AssociatedDstLoop;
410
473
411
474
public:
412
475
// / isEmpty - Return true if the constraint is of kind Empty.
@@ -450,19 +513,27 @@ class DependenceInfo {
450
513
// / Otherwise assert.
451
514
LLVM_ABI const SCEV *getD () const ;
452
515
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 ;
455
523
456
524
// / setPoint - Change a constraint to Point.
457
525
LLVM_ABI void setPoint (const SCEV *X, const SCEV *Y,
458
- const Loop *CurrentLoop);
526
+ const Loop *CurrentSrcLoop,
527
+ const Loop *CurrentDstLoop);
459
528
460
529
// / setLine - Change a constraint to Line.
461
530
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);
463
533
464
534
// / 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);
466
537
467
538
// / setEmpty - Change a constraint to Empty.
468
539
LLVM_ABI void setEmpty ();
@@ -475,6 +546,12 @@ class DependenceInfo {
475
546
LLVM_ABI void dump (raw_ostream &OS) const ;
476
547
};
477
548
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
+
478
555
// / establishNestingLevels - Examines the loop nesting of the Src and Dst
479
556
// / instructions and establishes their shared loops. Sets the variables
480
557
// / CommonLevels, SrcLevels, and MaxLevels.
@@ -525,9 +602,21 @@ class DependenceInfo {
525
602
// / e - 5
526
603
// / f - 6
527
604
// / 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
528
617
void establishNestingLevels (const Instruction *Src, const Instruction *Dst);
529
618
530
- unsigned CommonLevels, SrcLevels, MaxLevels;
619
+ unsigned CommonLevels, SrcLevels, MaxLevels, SameSDLevels ;
531
620
532
621
// / mapSrcLoop - Given one of the loops containing the source, return
533
622
// / its level index in our numbering scheme.
@@ -652,9 +741,9 @@ class DependenceInfo {
652
741
// / If there might be a dependence, returns false.
653
742
// / Sets appropriate direction and distance.
654
743
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 ;
658
747
659
748
// / weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
660
749
// / (Src and Dst) for dependence.
@@ -667,9 +756,9 @@ class DependenceInfo {
667
756
// / Set consistent to false.
668
757
// / Marks the dependence as splitable.
669
758
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,
673
762
const SCEV *&SplitIter) const ;
674
763
675
764
// / ExactSIVtest - Tests the SIV subscript pair
@@ -683,8 +772,9 @@ class DependenceInfo {
683
772
// / Set consistent to false.
684
773
bool exactSIVtest (const SCEV *SrcCoeff, const SCEV *DstCoeff,
685
774
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 ;
688
778
689
779
// / weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
690
780
// / (Src and Dst) for dependence.
@@ -697,8 +787,9 @@ class DependenceInfo {
697
787
// / Set consistent to false.
698
788
// / If loop peeling will break the dependence, mark appropriately.
699
789
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,
702
793
Constraint &NewConstraint) const ;
703
794
704
795
// / weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
@@ -712,8 +803,9 @@ class DependenceInfo {
712
803
// / Set consistent to false.
713
804
// / If loop peeling will break the dependence, mark appropriately.
714
805
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,
717
809
Constraint &NewConstraint) const ;
718
810
719
811
// / exactRDIVtest - Tests the RDIV subscript pair for dependence.
0 commit comments