Skip to content

Commit 3cfd2e0

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 3cfd2e0

File tree

4 files changed

+655
-192
lines changed

4 files changed

+655
-192
lines changed

llvm/include/llvm/Analysis/DependenceAnalysis.h

Lines changed: 119 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,24 @@ 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+
155159
/// getDirection - Returns the direction associated with a particular
156-
/// level.
157-
virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
160+
/// level. If Separate is set to true, information about a separate
161+
/// level is provided.
162+
virtual unsigned getDirection(unsigned Level, bool Separate = false) const {
163+
return DVEntry::ALL;
164+
}
158165

159166
/// getDistance - Returns the distance (or NULL) associated with a
160-
/// particular level.
161-
virtual const SCEV *getDistance(unsigned Level) const { return nullptr; }
167+
/// particular level. If Separate is set to true, information about
168+
/// a separate level is provided.
169+
virtual const SCEV *getDistance(unsigned Level,
170+
bool Separate = false) const {
171+
return nullptr;
172+
}
162173

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

173184
/// 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; }
185+
/// this loop will break this dependence. If Separate is set to true,
186+
/// information about a separate level is provided.
187+
virtual bool isPeelFirst(unsigned Level, bool Separate = false) const {
188+
return false;
189+
}
176190

177191
/// 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; }
192+
/// this loop will break this dependence. If Separate is set to true,
193+
/// information about a separate level is provided.
194+
virtual bool isPeelLast(unsigned Level, bool Separate = false) const {
195+
return false;
196+
}
180197

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

185209
/// isScalar - Returns true if a particular level is scalar; that is,
186210
/// 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;
211+
/// variable associated with the loop at this level. If Separate is
212+
/// set to true, information about a separate level is provided.
213+
virtual bool isScalar(unsigned Level, bool Separate = false) const;
189214

190215
/// getNextPredecessor - Returns the value of the NextPredecessor
191216
/// field.
@@ -245,13 +270,20 @@ namespace llvm {
245270
/// source and destination of the dependence.
246271
unsigned getLevels() const override { return Levels; }
247272

273+
/// getSeparateLevels - Returns the number of separate loops surrounding
274+
/// the source and destination of the dependence.
275+
unsigned getSeparateLevels() const override { return SeparateLevels; }
276+
248277
/// getDirection - Returns the direction associated with a particular
249-
/// level.
250-
unsigned getDirection(unsigned Level) const override;
278+
/// level. If Separate is set to true, information about a separate
279+
/// level is provided.
280+
unsigned getDirection(unsigned Level, bool Separate = false) const override;
251281

252282
/// getDistance - Returns the distance (or NULL) associated with a
253-
/// particular level.
254-
const SCEV *getDistance(unsigned Level) const override;
283+
/// particular level. If Separate is set to true, information about
284+
/// a separate level is provided.
285+
const SCEV *getDistance(unsigned Level,
286+
bool Separate = false) const override;
255287

256288
/// Check if the direction vector is negative. A negative direction
257289
/// vector means Src and Dst are reversed in the actual program.
@@ -264,27 +296,37 @@ namespace llvm {
264296
bool normalize(ScalarEvolution *SE) override;
265297

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

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

274308
/// isSplitable - Returns true if splitting the loop will break
275-
/// the dependence.
276-
bool isSplitable(unsigned Level) const override;
309+
/// the dependence. If Separate is set to true, information about a
310+
/// separate level is provided.
311+
bool isSplitable(unsigned Level, bool Separate = false) const override;
312+
313+
/// inSeparateLoops - Returns true if this level is performed across
314+
/// two separate loop nests.
315+
bool inSeparateLoops(unsigned Level) const override;
277316

278317
/// isScalar - Returns true if a particular level is scalar; that is,
279318
/// 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;
319+
/// variable associated with the loop at this level. If Separate is
320+
/// set to true, information about a separate level is provided.
321+
bool isScalar(unsigned Level, bool Separate = false) const override;
282322

283323
private:
284324
unsigned short Levels;
325+
unsigned short SeparateLevels;
285326
bool LoopIndependent;
286327
bool Consistent; // Init to true, then refine.
287328
std::unique_ptr<DVEntry[]> DV;
329+
std::unique_ptr<DVEntry[]> DVSeparate;
288330
friend class DependenceInfo;
289331
};
290332

@@ -405,7 +447,8 @@ namespace llvm {
405447
const SCEV *A;
406448
const SCEV *B;
407449
const SCEV *C;
408-
const Loop *AssociatedLoop;
450+
const Loop *AssociatedSrcLoop;
451+
const Loop *AssociatedDstLoop;
409452

410453
public:
411454
/// isEmpty - Return true if the constraint is of kind Empty.
@@ -449,18 +492,25 @@ namespace llvm {
449492
/// Otherwise assert.
450493
const SCEV *getD() const;
451494

452-
/// getAssociatedLoop - Returns the loop associated with this constraint.
453-
const Loop *getAssociatedLoop() const;
495+
/// getAssociatedSrcLoop - Returns the source loop associated with this
496+
/// constraint.
497+
const Loop *getAssociatedSrcLoop() const;
498+
499+
/// getAssociatedDstLoop - Returns the destination loop associated with
500+
/// this constraint.
501+
const Loop *getAssociatedDstLoop() const;
454502

455503
/// setPoint - Change a constraint to Point.
456-
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
504+
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentSrcLoop,
505+
const Loop *CurrentDstLoop);
457506

458507
/// setLine - Change a constraint to Line.
459-
void setLine(const SCEV *A, const SCEV *B,
460-
const SCEV *C, const Loop *CurrentLoop);
508+
void setLine(const SCEV *A, const SCEV *B, const SCEV *C,
509+
const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop);
461510

462511
/// setDistance - Change a constraint to Distance.
463-
void setDistance(const SCEV *D, const Loop *CurrentLoop);
512+
void setDistance(const SCEV *D, const Loop *CurrentSrcLoop,
513+
const Loop *CurrentDstLoop);
464514

465515
/// setEmpty - Change a constraint to Empty.
466516
void setEmpty();
@@ -473,6 +523,10 @@ namespace llvm {
473523
void dump(raw_ostream &OS) const;
474524
};
475525

526+
/// Returns true if two loops are the same or they have the same tripcount
527+
/// and depth
528+
bool areLoopsSimilar(const Loop *SrcLoop, const Loop *DstLoop) const;
529+
476530
/// establishNestingLevels - Examines the loop nesting of the Src and Dst
477531
/// instructions and establishes their shared loops. Sets the variables
478532
/// CommonLevels, SrcLevels, and MaxLevels.
@@ -523,10 +577,30 @@ namespace llvm {
523577
/// e - 5
524578
/// f - 6
525579
/// g - 7 = MaxLevels
526-
void establishNestingLevels(const Instruction *Src,
527-
const Instruction *Dst);
528-
529-
unsigned CommonLevels, SrcLevels, MaxLevels;
580+
/// If ConsiderSeparateLoops is true then we also want to consider similar
581+
/// seperate loops. Assume that loop nests at level c and e are similar,
582+
/// meaning that they have the same tripcount and depth. Then we consider
583+
/// them as a separate common level.
584+
/// a - 1
585+
/// b - 2
586+
/// <c, e> - 3 = CommonLevels
587+
/// d - 4 = SrcLevels
588+
/// f - 5
589+
/// g - 6 = MaxLevels
590+
/// Initially similar separate levels are included in common levels. After
591+
/// the separate level extraction at the end of the depends api we have
592+
/// a - 1
593+
/// b - 2 = CommonLevels
594+
/// <c, e> - 3 : A SeparateLevel
595+
/// d - 4 = SrcLevels
596+
/// f - 6
597+
/// g - 7 = MaxLevels
598+
/// SeparateLevels is the number of levels after CommonLevels that are
599+
/// similar, which is 1 in this case.
600+
void establishNestingLevels(const Instruction *Src, const Instruction *Dst,
601+
bool ConsiderSeparateLoops = false);
602+
603+
unsigned CommonLevels, SrcLevels, MaxLevels, SeparateLevels;
530604

531605
/// mapSrcLoop - Given one of the loops containing the source, return
532606
/// its level index in our numbering scheme.
@@ -668,7 +742,8 @@ namespace llvm {
668742
bool strongSIVtest(const SCEV *Coeff,
669743
const SCEV *SrcConst,
670744
const SCEV *DstConst,
671-
const Loop *CurrentLoop,
745+
const Loop *CurrentSrcLoop,
746+
const Loop *CurrentDstLoop,
672747
unsigned Level,
673748
FullDependence &Result,
674749
Constraint &NewConstraint) const;
@@ -686,7 +761,8 @@ namespace llvm {
686761
bool weakCrossingSIVtest(const SCEV *SrcCoeff,
687762
const SCEV *SrcConst,
688763
const SCEV *DstConst,
689-
const Loop *CurrentLoop,
764+
const Loop *CurrentSrcLoop,
765+
const Loop *CurrentDstLoop,
690766
unsigned Level,
691767
FullDependence &Result,
692768
Constraint &NewConstraint,
@@ -705,7 +781,8 @@ namespace llvm {
705781
const SCEV *DstCoeff,
706782
const SCEV *SrcConst,
707783
const SCEV *DstConst,
708-
const Loop *CurrentLoop,
784+
const Loop *CurrentSrcLoop,
785+
const Loop *CurrentDstLoop,
709786
unsigned Level,
710787
FullDependence &Result,
711788
Constraint &NewConstraint) const;
@@ -723,7 +800,8 @@ namespace llvm {
723800
bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
724801
const SCEV *SrcConst,
725802
const SCEV *DstConst,
726-
const Loop *CurrentLoop,
803+
const Loop *CurrentSrcLoop,
804+
const Loop *CurrentDstLoop,
727805
unsigned Level,
728806
FullDependence &Result,
729807
Constraint &NewConstraint) const;
@@ -741,7 +819,8 @@ namespace llvm {
741819
bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
742820
const SCEV *SrcConst,
743821
const SCEV *DstConst,
744-
const Loop *CurrentLoop,
822+
const Loop *CurrentSrcLoop,
823+
const Loop *CurrentDstLoop,
745824
unsigned Level,
746825
FullDependence &Result,
747826
Constraint &NewConstraint) const;

0 commit comments

Comments
 (0)