Skip to content

Commit 8e263a3

Browse files
committed
[DependenceAnalysis] Extending SIV to handle separate loops
When there is a dependency between two memory instructions in separate loops, SIV will be able to test them and compute the direction and the distance of the dependency.
1 parent 789bfdc commit 8e263a3

File tree

7 files changed

+758
-201
lines changed

7 files changed

+758
-201
lines changed

llvm/include/llvm/Analysis/DependenceAnalysis.h

Lines changed: 120 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,28 @@ namespace llvm {
152152
/// source and destination of the dependence.
153153
virtual unsigned getLevels() const { return 0; }
154154

155+
/// getSeparateLevels - Returns the number of separate loops surrounding
156+
/// the source and destination of the dependence.
157+
virtual unsigned getSeparateLevels() const { return 0; }
158+
159+
/// getDVEntry - Returns the DV entry associated with a regular or a
160+
/// separate level
161+
DVEntry getDVEntry(unsigned Level, bool Separate) const;
162+
155163
/// getDirection - Returns the direction associated with a particular
156-
/// level.
157-
virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
164+
/// level. If Separate is set to true, information about a separate
165+
/// level is provided.
166+
virtual unsigned getDirection(unsigned Level, bool Separate = false) const {
167+
return DVEntry::ALL;
168+
}
158169

159170
/// getDistance - Returns the distance (or NULL) associated with a
160-
/// particular level.
161-
virtual const SCEV *getDistance(unsigned Level) const { return nullptr; }
171+
/// particular level. If Separate is set to true, information about
172+
/// a separate level is provided.
173+
virtual const SCEV *getDistance(unsigned Level,
174+
bool Separate = false) const {
175+
return nullptr;
176+
}
162177

163178
/// Check if the direction vector is negative. A negative direction
164179
/// vector means Src and Dst are reversed in the actual program.
@@ -171,21 +186,35 @@ namespace llvm {
171186
virtual bool normalize(ScalarEvolution *SE) { return false; }
172187

173188
/// isPeelFirst - Returns true if peeling the first iteration from
174-
/// this loop will break this dependence.
175-
virtual bool isPeelFirst(unsigned Level) const { return false; }
189+
/// this loop will break this dependence. If Separate is set to true,
190+
/// information about a separate level is provided.
191+
virtual bool isPeelFirst(unsigned Level, bool Separate = false) const {
192+
return false;
193+
}
176194

177195
/// isPeelLast - Returns true if peeling the last iteration from
178-
/// this loop will break this dependence.
179-
virtual bool isPeelLast(unsigned Level) const { return false; }
196+
/// this loop will break this dependence. If Separate is set to true,
197+
/// information about a separate level is provided.
198+
virtual bool isPeelLast(unsigned Level, bool Separate = false) const {
199+
return false;
200+
}
180201

181202
/// isSplitable - Returns true if splitting this loop will break
182-
/// the dependence.
183-
virtual bool isSplitable(unsigned Level) const { return false; }
203+
/// the dependence. If Separate is set to true, information about a
204+
/// separate level is provided.
205+
virtual bool isSplitable(unsigned Level, bool Separate = false) const {
206+
return false;
207+
}
208+
209+
/// inSeparateLoops - Returns true if this level is performed across
210+
/// two separate loop nests.
211+
virtual bool inSeparateLoops(unsigned Level) const { return false; }
184212

185213
/// isScalar - Returns true if a particular level is scalar; that is,
186214
/// if no subscript in the source or destination mention the induction
187-
/// variable associated with the loop at this level.
188-
virtual bool isScalar(unsigned Level) const;
215+
/// variable associated with the loop at this level. If Separate is
216+
/// set to true, information about a separate level is provided.
217+
virtual bool isScalar(unsigned Level, bool Separate = false) const;
189218

190219
/// getNextPredecessor - Returns the value of the NextPredecessor
191220
/// field.
@@ -245,13 +274,33 @@ namespace llvm {
245274
/// source and destination of the dependence.
246275
unsigned getLevels() const override { return Levels; }
247276

277+
/// getSeparateLevels - Returns the number of separate loops surrounding
278+
/// the source and destination of the dependence.
279+
unsigned getSeparateLevels() const override { return SeparateLevels; }
280+
281+
/// getDVEntry - Returns the DV entry associated with a regular or a
282+
/// separate level
283+
DVEntry getDVEntry(unsigned Level, bool Separate) const {
284+
if (!Separate) {
285+
assert(0 < Level && Level <= Levels && "Level out of range");
286+
return DV[Level - 1];
287+
} else {
288+
assert(Levels < Level && Level <= Levels + SeparateLevels &&
289+
"Separate level out of range");
290+
return DVSeparate[Level - Levels - 1];
291+
}
292+
}
293+
248294
/// getDirection - Returns the direction associated with a particular
249-
/// level.
250-
unsigned getDirection(unsigned Level) const override;
295+
/// level. If Separate is set to true, information about a separate
296+
/// level is provided.
297+
unsigned getDirection(unsigned Level, bool Separate = false) const override;
251298

252299
/// getDistance - Returns the distance (or NULL) associated with a
253-
/// particular level.
254-
const SCEV *getDistance(unsigned Level) const override;
300+
/// particular level. If Separate is set to true, information about
301+
/// a separate level is provided.
302+
const SCEV *getDistance(unsigned Level,
303+
bool Separate = false) const override;
255304

256305
/// Check if the direction vector is negative. A negative direction
257306
/// vector means Src and Dst are reversed in the actual program.
@@ -264,27 +313,37 @@ namespace llvm {
264313
bool normalize(ScalarEvolution *SE) override;
265314

266315
/// isPeelFirst - Returns true if peeling the first iteration from
267-
/// this loop will break this dependence.
268-
bool isPeelFirst(unsigned Level) const override;
316+
/// this loop will break this dependence. If Separate is set to true,
317+
/// information about a separate level is provided.
318+
bool isPeelFirst(unsigned Level, bool Separate = false) const override;
269319

270320
/// isPeelLast - Returns true if peeling the last iteration from
271-
/// this loop will break this dependence.
272-
bool isPeelLast(unsigned Level) const override;
321+
/// this loop will break this dependence. If Separate is set to true,
322+
/// information about a separate level is provided.
323+
bool isPeelLast(unsigned Level, bool Separate = false) const override;
273324

274325
/// isSplitable - Returns true if splitting the loop will break
275-
/// the dependence.
276-
bool isSplitable(unsigned Level) const override;
326+
/// the dependence. If Separate is set to true, information about a
327+
/// separate level is provided.
328+
bool isSplitable(unsigned Level, bool Separate = false) const override;
329+
330+
/// inSeparateLoops - Returns true if this level is performed across
331+
/// two separate loop nests.
332+
bool inSeparateLoops(unsigned Level) const override;
277333

278334
/// isScalar - Returns true if a particular level is scalar; that is,
279335
/// if no subscript in the source or destination mention the induction
280-
/// variable associated with the loop at this level.
281-
bool isScalar(unsigned Level) const override;
336+
/// variable associated with the loop at this level. If Separate is
337+
/// set to true, information about a separate level is provided.
338+
bool isScalar(unsigned Level, bool Separate = false) const override;
282339

283340
private:
284341
unsigned short Levels;
342+
unsigned short SeparateLevels;
285343
bool LoopIndependent;
286344
bool Consistent; // Init to true, then refine.
287345
std::unique_ptr<DVEntry[]> DV;
346+
std::unique_ptr<DVEntry[]> DVSeparate;
288347
friend class DependenceInfo;
289348
};
290349

@@ -405,7 +464,8 @@ namespace llvm {
405464
const SCEV *A;
406465
const SCEV *B;
407466
const SCEV *C;
408-
const Loop *AssociatedLoop;
467+
const Loop *AssociatedSrcLoop;
468+
const Loop *AssociatedDstLoop;
409469

410470
public:
411471
/// isEmpty - Return true if the constraint is of kind Empty.
@@ -449,18 +509,25 @@ namespace llvm {
449509
/// Otherwise assert.
450510
const SCEV *getD() const;
451511

452-
/// getAssociatedLoop - Returns the loop associated with this constraint.
453-
const Loop *getAssociatedLoop() const;
512+
/// getAssociatedSrcLoop - Returns the source loop associated with this
513+
/// constraint.
514+
const Loop *getAssociatedSrcLoop() const;
515+
516+
/// getAssociatedDstLoop - Returns the destination loop associated with
517+
/// this constraint.
518+
const Loop *getAssociatedDstLoop() const;
454519

455520
/// setPoint - Change a constraint to Point.
456-
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
521+
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentSrcLoop,
522+
const Loop *CurrentDstLoop);
457523

458524
/// setLine - Change a constraint to Line.
459-
void setLine(const SCEV *A, const SCEV *B,
460-
const SCEV *C, const Loop *CurrentLoop);
525+
void setLine(const SCEV *A, const SCEV *B, const SCEV *C,
526+
const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop);
461527

462528
/// setDistance - Change a constraint to Distance.
463-
void setDistance(const SCEV *D, const Loop *CurrentLoop);
529+
void setDistance(const SCEV *D, const Loop *CurrentSrcLoop,
530+
const Loop *CurrentDstLoop);
464531

465532
/// setEmpty - Change a constraint to Empty.
466533
void setEmpty();
@@ -473,6 +540,10 @@ namespace llvm {
473540
void dump(raw_ostream &OS) const;
474541
};
475542

543+
/// Returns true if two loops are the same or they have the same tripcount
544+
/// and depth
545+
bool areLoopsSimilar(const Loop *SrcLoop, const Loop *DstLoop) const;
546+
476547
/// establishNestingLevels - Examines the loop nesting of the Src and Dst
477548
/// instructions and establishes their shared loops. Sets the variables
478549
/// CommonLevels, SrcLevels, and MaxLevels.
@@ -523,10 +594,15 @@ namespace llvm {
523594
/// e - 5
524595
/// f - 6
525596
/// g - 7 = MaxLevels
526-
void establishNestingLevels(const Instruction *Src,
527-
const Instruction *Dst);
597+
/// SeparateLevels counts the number of loop levels after the common levels
598+
/// that are not identical but are considered similar. Two levels are
599+
/// considered similar if they have the same trip count and the same
600+
/// nesting depth.
601+
/// For example, if loops `c` and `e` are similar, then they contribute to
602+
/// the SeparateLevels count and SeparateLevels is set to 1.
603+
void establishNestingLevels(const Instruction *Src, const Instruction *Dst);
528604

529-
unsigned CommonLevels, SrcLevels, MaxLevels;
605+
unsigned CommonLevels, SrcLevels, MaxLevels, SeparateLevels;
530606

531607
/// mapSrcLoop - Given one of the loops containing the source, return
532608
/// its level index in our numbering scheme.
@@ -668,7 +744,8 @@ namespace llvm {
668744
bool strongSIVtest(const SCEV *Coeff,
669745
const SCEV *SrcConst,
670746
const SCEV *DstConst,
671-
const Loop *CurrentLoop,
747+
const Loop *CurrentSrcLoop,
748+
const Loop *CurrentDstLoop,
672749
unsigned Level,
673750
FullDependence &Result,
674751
Constraint &NewConstraint) const;
@@ -686,7 +763,8 @@ namespace llvm {
686763
bool weakCrossingSIVtest(const SCEV *SrcCoeff,
687764
const SCEV *SrcConst,
688765
const SCEV *DstConst,
689-
const Loop *CurrentLoop,
766+
const Loop *CurrentSrcLoop,
767+
const Loop *CurrentDstLoop,
690768
unsigned Level,
691769
FullDependence &Result,
692770
Constraint &NewConstraint,
@@ -705,7 +783,8 @@ namespace llvm {
705783
const SCEV *DstCoeff,
706784
const SCEV *SrcConst,
707785
const SCEV *DstConst,
708-
const Loop *CurrentLoop,
786+
const Loop *CurrentSrcLoop,
787+
const Loop *CurrentDstLoop,
709788
unsigned Level,
710789
FullDependence &Result,
711790
Constraint &NewConstraint) const;
@@ -723,7 +802,8 @@ namespace llvm {
723802
bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
724803
const SCEV *SrcConst,
725804
const SCEV *DstConst,
726-
const Loop *CurrentLoop,
805+
const Loop *CurrentSrcLoop,
806+
const Loop *CurrentDstLoop,
727807
unsigned Level,
728808
FullDependence &Result,
729809
Constraint &NewConstraint) const;
@@ -741,7 +821,8 @@ namespace llvm {
741821
bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
742822
const SCEV *SrcConst,
743823
const SCEV *DstConst,
744-
const Loop *CurrentLoop,
824+
const Loop *CurrentSrcLoop,
825+
const Loop *CurrentDstLoop,
745826
unsigned Level,
746827
FullDependence &Result,
747828
Constraint &NewConstraint) const;

0 commit comments

Comments
 (0)