Skip to content

Commit 9d2b7ec

Browse files
authored
[DA] remove getSplitIteration (#167698)
Remove getSplitIteration. A follow-up patch will also remove DVEntry::Splitable and Dependnece::isSplitable.
1 parent e724009 commit 9d2b7ec

File tree

6 files changed

+15
-238
lines changed

6 files changed

+15
-238
lines changed

llvm/include/llvm/Analysis/DependenceAnalysis.h

Lines changed: 4 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,9 @@ class LLVM_ABI Dependence {
107107
bool Scalar : 1; // Init to true.
108108
bool PeelFirst : 1; // Peeling the first iteration will break dependence.
109109
bool PeelLast : 1; // Peeling the last iteration will break the dependence.
110-
bool Splitable : 1; // Splitting the loop will break dependence.
111110
const SCEV *Distance = nullptr; // NULL implies no distance available.
112111
DVEntry()
113-
: Direction(ALL), Scalar(true), PeelFirst(false), PeelLast(false),
114-
Splitable(false) {}
112+
: Direction(ALL), Scalar(true), PeelFirst(false), PeelLast(false) {}
115113
};
116114

117115
/// getSrc - Returns the source instruction for this dependence.
@@ -196,12 +194,6 @@ class LLVM_ABI Dependence {
196194
return false;
197195
}
198196

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-
}
204-
205197
/// inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
206198
/// performed across two separate loop nests that have the Same Iteration and
207199
/// Depth.
@@ -320,10 +312,6 @@ class LLVM_ABI FullDependence final : public Dependence {
320312
/// this regular or SameSD loop level will break this dependence.
321313
bool isPeelLast(unsigned Level, bool SameSD = false) const override;
322314

323-
/// isSplitable - Returns true if splitting the loop will break
324-
/// the dependence.
325-
bool isSplitable(unsigned Level, bool SameSD = false) const override;
326-
327315
/// inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
328316
/// performed across two separate loop nests that have the Same Iteration and
329317
/// Depth.
@@ -365,48 +353,6 @@ class DependenceInfo {
365353
depends(Instruction *Src, Instruction *Dst,
366354
bool UnderRuntimeAssumptions = false);
367355

368-
/// getSplitIteration - Give a dependence that's splittable at some
369-
/// particular level, return the iteration that should be used to split
370-
/// the loop.
371-
///
372-
/// Generally, the dependence analyzer will be used to build
373-
/// a dependence graph for a function (basically a map from instructions
374-
/// to dependences). Looking for cycles in the graph shows us loops
375-
/// that cannot be trivially vectorized/parallelized.
376-
///
377-
/// We can try to improve the situation by examining all the dependences
378-
/// that make up the cycle, looking for ones we can break.
379-
/// Sometimes, peeling the first or last iteration of a loop will break
380-
/// dependences, and there are flags for those possibilities.
381-
/// Sometimes, splitting a loop at some other iteration will do the trick,
382-
/// and we've got a flag for that case. Rather than waste the space to
383-
/// record the exact iteration (since we rarely know), we provide
384-
/// a method that calculates the iteration. It's a drag that it must work
385-
/// from scratch, but wonderful in that it's possible.
386-
///
387-
/// Here's an example:
388-
///
389-
/// for (i = 0; i < 10; i++)
390-
/// A[i] = ...
391-
/// ... = A[11 - i]
392-
///
393-
/// There's a loop-carried flow dependence from the store to the load,
394-
/// found by the weak-crossing SIV test. The dependence will have a flag,
395-
/// indicating that the dependence can be broken by splitting the loop.
396-
/// Calling getSplitIteration will return 5.
397-
/// Splitting the loop breaks the dependence, like so:
398-
///
399-
/// for (i = 0; i <= 5; i++)
400-
/// A[i] = ...
401-
/// ... = A[11 - i]
402-
/// for (i = 6; i < 10; i++)
403-
/// A[i] = ...
404-
/// ... = A[11 - i]
405-
///
406-
/// breaks the dependence and allows us to vectorize/parallelize
407-
/// both loops.
408-
LLVM_ABI const SCEV *getSplitIteration(const Dependence &Dep, unsigned Level);
409-
410356
Function *getFunction() const { return F; }
411357

412358
/// getRuntimeAssumptions - Returns all the runtime assumptions under which
@@ -713,8 +659,7 @@ class DependenceInfo {
713659
/// If the dependence isn't proven to exist,
714660
/// marks the Result as inconsistent.
715661
bool testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
716-
FullDependence &Result, Constraint &NewConstraint,
717-
const SCEV *&SplitIter) const;
662+
FullDependence &Result, Constraint &NewConstraint) const;
718663

719664
/// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
720665
/// Things of the form [c1 + a1*i] and [c2 + a2*j]
@@ -755,12 +700,11 @@ class DependenceInfo {
755700
/// If there might be a dependence, returns false.
756701
/// Sets appropriate direction entry.
757702
/// Set consistent to false.
758-
/// Marks the dependence as splitable.
759703
bool weakCrossingSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
760704
const SCEV *DstConst, const Loop *CurrentSrcLoop,
761705
const Loop *CurrentDstLoop, unsigned Level,
762-
FullDependence &Result, Constraint &NewConstraint,
763-
const SCEV *&SplitIter) const;
706+
FullDependence &Result,
707+
Constraint &NewConstraint) const;
764708

765709
/// ExactSIVtest - Tests the SIV subscript pair
766710
/// (Src and Dst) for dependence.

llvm/lib/Analysis/DependenceAnalysis.cpp

Lines changed: 5 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -442,13 +442,6 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
442442
if (NormalizeResults && D->normalize(&SE))
443443
OS << "normalized - ";
444444
D->dump(OS);
445-
for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
446-
if (D->isSplitable(Level)) {
447-
OS << " da analyze - split level = " << Level;
448-
OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
449-
OS << "!\n";
450-
}
451-
}
452445
} else
453446
OS << "none!\n";
454447
}
@@ -611,11 +604,6 @@ bool FullDependence::isPeelLast(unsigned Level, bool IsSameSD) const {
611604
return getDVEntry(Level, IsSameSD).PeelLast;
612605
}
613606

614-
// Returns true if splitting loop will break the dependence.
615-
bool FullDependence::isSplitable(unsigned Level, bool IsSameSD) const {
616-
return getDVEntry(Level, IsSameSD).Splitable;
617-
}
618-
619607
// inSameSDLoops - Returns true if this level is an SameSD level, i.e.,
620608
// performed across two separate loop nests that have the Same iteration space
621609
// and Depth.
@@ -1015,7 +1003,6 @@ void Dependence::dump(raw_ostream &OS) const {
10151003
// For debugging purposes. Dumps a dependence to OS with or without considering
10161004
// the SameSD levels.
10171005
void Dependence::dumpImp(raw_ostream &OS, bool IsSameSD) const {
1018-
bool Splitable = false;
10191006
unsigned Levels = getLevels();
10201007
unsigned SameSDLevels = getSameSDLevels();
10211008
bool OnSameSD = false;
@@ -1026,8 +1013,6 @@ void Dependence::dumpImp(raw_ostream &OS, bool IsSameSD) const {
10261013
for (unsigned II = 1; II <= LevelNum; ++II) {
10271014
if (!OnSameSD && inSameSDLoops(II))
10281015
OnSameSD = true;
1029-
if (isSplitable(II, OnSameSD))
1030-
Splitable = true;
10311016
if (isPeelFirst(II, OnSameSD))
10321017
OS << 'p';
10331018
const SCEV *Distance = getDistance(II, OnSameSD);
@@ -1056,8 +1041,6 @@ void Dependence::dumpImp(raw_ostream &OS, bool IsSameSD) const {
10561041
if (isLoopIndependent())
10571042
OS << "|<";
10581043
OS << "]";
1059-
if (Splitable)
1060-
OS << " splitable";
10611044
}
10621045

10631046
// Returns NoAlias/MayAliass/MustAlias for two memory locations based upon their
@@ -1825,8 +1808,7 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
18251808
bool DependenceInfo::weakCrossingSIVtest(
18261809
const SCEV *Coeff, const SCEV *SrcConst, const SCEV *DstConst,
18271810
const Loop *CurSrcLoop, const Loop *CurDstLoop, unsigned Level,
1828-
FullDependence &Result, Constraint &NewConstraint,
1829-
const SCEV *&SplitIter) const {
1811+
FullDependence &Result, Constraint &NewConstraint) const {
18301812
if (!isDependenceTestEnabled(DependenceTestType::WeakCrossingSIV))
18311813
return false;
18321814

@@ -1856,7 +1838,6 @@ bool DependenceInfo::weakCrossingSIVtest(
18561838
if (!ConstCoeff)
18571839
return false;
18581840

1859-
Result.DV[Level].Splitable = true;
18601841
if (SE->isKnownNegative(ConstCoeff)) {
18611842
ConstCoeff = dyn_cast<SCEVConstant>(SE->getNegativeSCEV(ConstCoeff));
18621843
assert(ConstCoeff &&
@@ -1865,12 +1846,6 @@ bool DependenceInfo::weakCrossingSIVtest(
18651846
}
18661847
assert(SE->isKnownPositive(ConstCoeff) && "ConstCoeff should be positive");
18671848

1868-
// compute SplitIter for use by DependenceInfo::getSplitIteration()
1869-
SplitIter = SE->getUDivExpr(
1870-
SE->getSMaxExpr(SE->getZero(Delta->getType()), Delta),
1871-
SE->getMulExpr(SE->getConstant(Delta->getType(), 2), ConstCoeff));
1872-
LLVM_DEBUG(dbgs() << "\t Split iter = " << *SplitIter << "\n");
1873-
18741849
const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
18751850
if (!ConstDelta)
18761851
return false;
@@ -1910,7 +1885,6 @@ bool DependenceInfo::weakCrossingSIVtest(
19101885
++WeakCrossingSIVindependence;
19111886
return true;
19121887
}
1913-
Result.DV[Level].Splitable = false;
19141888
Result.DV[Level].Distance = SE->getZero(Delta->getType());
19151889
return false;
19161890
}
@@ -2731,8 +2705,8 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
27312705
//
27322706
// Return true if dependence disproved.
27332707
bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
2734-
FullDependence &Result, Constraint &NewConstraint,
2735-
const SCEV *&SplitIter) const {
2708+
FullDependence &Result,
2709+
Constraint &NewConstraint) const {
27362710
LLVM_DEBUG(dbgs() << " src = " << *Src << "\n");
27372711
LLVM_DEBUG(dbgs() << " dst = " << *Dst << "\n");
27382712
const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
@@ -2754,8 +2728,7 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
27542728
CurDstLoop, Level, Result, NewConstraint);
27552729
else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
27562730
disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2757-
CurDstLoop, Level, Result, NewConstraint,
2758-
SplitIter);
2731+
CurDstLoop, Level, Result, NewConstraint);
27592732
else
27602733
disproven =
27612734
exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurSrcLoop,
@@ -3951,8 +3924,6 @@ SCEVUnionPredicate DependenceInfo::getRuntimeAssumptions() const {
39513924
// Goff, Kennedy, Tseng
39523925
// PLDI 1991
39533926
//
3954-
// Care is required to keep the routine below, getSplitIteration(),
3955-
// up to date with respect to this routine.
39563927
std::unique_ptr<Dependence>
39573928
DependenceInfo::depends(Instruction *Src, Instruction *Dst,
39583929
bool UnderRuntimeAssumptions) {
@@ -4158,11 +4129,9 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
41584129
case Subscript::SIV: {
41594130
LLVM_DEBUG(dbgs() << ", SIV\n");
41604131
unsigned Level;
4161-
const SCEV *SplitIter = nullptr;
41624132
Constraint NewConstraint;
41634133
NewConstraint.setAny(SE);
4164-
if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
4165-
SplitIter))
4134+
if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint))
41664135
return nullptr;
41674136
break;
41684137
}
@@ -4256,133 +4225,3 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
42564225

42574226
return std::make_unique<FullDependence>(std::move(Result));
42584227
}
4259-
4260-
//===----------------------------------------------------------------------===//
4261-
// getSplitIteration -
4262-
// Rather than spend rarely-used space recording the splitting iteration
4263-
// during the Weak-Crossing SIV test, we re-compute it on demand.
4264-
// The re-computation is basically a repeat of the entire dependence test,
4265-
// though simplified since we know that the dependence exists.
4266-
// It's tedious, since we must go through all propagations, etc.
4267-
//
4268-
// Care is required to keep this code up to date with respect to the routine
4269-
// above, depends().
4270-
//
4271-
// Generally, the dependence analyzer will be used to build
4272-
// a dependence graph for a function (basically a map from instructions
4273-
// to dependences). Looking for cycles in the graph shows us loops
4274-
// that cannot be trivially vectorized/parallelized.
4275-
//
4276-
// We can try to improve the situation by examining all the dependences
4277-
// that make up the cycle, looking for ones we can break.
4278-
// Sometimes, peeling the first or last iteration of a loop will break
4279-
// dependences, and we've got flags for those possibilities.
4280-
// Sometimes, splitting a loop at some other iteration will do the trick,
4281-
// and we've got a flag for that case. Rather than waste the space to
4282-
// record the exact iteration (since we rarely know), we provide
4283-
// a method that calculates the iteration. It's a drag that it must work
4284-
// from scratch, but wonderful in that it's possible.
4285-
//
4286-
// Here's an example:
4287-
//
4288-
// for (i = 0; i < 10; i++)
4289-
// A[i] = ...
4290-
// ... = A[11 - i]
4291-
//
4292-
// There's a loop-carried flow dependence from the store to the load,
4293-
// found by the weak-crossing SIV test. The dependence will have a flag,
4294-
// indicating that the dependence can be broken by splitting the loop.
4295-
// Calling getSplitIteration will return 5.
4296-
// Splitting the loop breaks the dependence, like so:
4297-
//
4298-
// for (i = 0; i <= 5; i++)
4299-
// A[i] = ...
4300-
// ... = A[11 - i]
4301-
// for (i = 6; i < 10; i++)
4302-
// A[i] = ...
4303-
// ... = A[11 - i]
4304-
//
4305-
// breaks the dependence and allows us to vectorize/parallelize
4306-
// both loops.
4307-
const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
4308-
unsigned SplitLevel) {
4309-
assert(Dep.isSplitable(SplitLevel) &&
4310-
"Dep should be splitable at SplitLevel");
4311-
Instruction *Src = Dep.getSrc();
4312-
Instruction *Dst = Dep.getDst();
4313-
assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
4314-
assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
4315-
assert(isLoadOrStore(Src));
4316-
assert(isLoadOrStore(Dst));
4317-
Value *SrcPtr = getLoadStorePointerOperand(Src);
4318-
Value *DstPtr = getLoadStorePointerOperand(Dst);
4319-
assert(underlyingObjectsAlias(
4320-
AA, F->getDataLayout(), MemoryLocation::get(Dst),
4321-
MemoryLocation::get(Src)) == AliasResult::MustAlias);
4322-
4323-
// establish loop nesting levels
4324-
establishNestingLevels(Src, Dst);
4325-
4326-
FullDependence Result(Src, Dst, Dep.Assumptions, false, CommonLevels);
4327-
4328-
unsigned Pairs = 1;
4329-
SmallVector<Subscript, 2> Pair(Pairs);
4330-
const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
4331-
const SCEV *DstSCEV = SE->getSCEV(DstPtr);
4332-
Pair[0].Src = SE->removePointerBase(SrcSCEV);
4333-
Pair[0].Dst = SE->removePointerBase(DstSCEV);
4334-
4335-
if (Delinearize) {
4336-
if (tryDelinearize(Src, Dst, Pair)) {
4337-
LLVM_DEBUG(dbgs() << " delinearized\n");
4338-
Pairs = Pair.size();
4339-
}
4340-
}
4341-
4342-
for (unsigned P = 0; P < Pairs; ++P) {
4343-
assert(Pair[P].Src->getType()->isIntegerTy() && "Src must be an integer");
4344-
assert(Pair[P].Dst->getType()->isIntegerTy() && "Dst must be an integer");
4345-
Pair[P].Loops.resize(MaxLevels + 1);
4346-
Pair[P].GroupLoops.resize(MaxLevels + 1);
4347-
Pair[P].Group.resize(Pairs);
4348-
removeMatchingExtensions(&Pair[P]);
4349-
Pair[P].Classification =
4350-
classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()), Pair[P].Dst,
4351-
LI->getLoopFor(Dst->getParent()), Pair[P].Loops);
4352-
Pair[P].GroupLoops = Pair[P].Loops;
4353-
Pair[P].Group.set(P);
4354-
}
4355-
4356-
Constraint NewConstraint;
4357-
NewConstraint.setAny(SE);
4358-
4359-
// Test each subscript individually for split iteration
4360-
for (unsigned SI = 0; SI < Pairs; ++SI) {
4361-
switch (Pair[SI].Classification) {
4362-
case Subscript::NonLinear:
4363-
// ignore these, but collect loops for later
4364-
collectCommonLoops(Pair[SI].Src, LI->getLoopFor(Src->getParent()),
4365-
Pair[SI].Loops);
4366-
collectCommonLoops(Pair[SI].Dst, LI->getLoopFor(Dst->getParent()),
4367-
Pair[SI].Loops);
4368-
Result.Consistent = false;
4369-
break;
4370-
case Subscript::SIV: {
4371-
unsigned Level;
4372-
const SCEV *SplitIter = nullptr;
4373-
(void)testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
4374-
SplitIter);
4375-
if (Level == SplitLevel && SplitIter != nullptr) {
4376-
return SplitIter;
4377-
}
4378-
break;
4379-
}
4380-
case Subscript::ZIV:
4381-
case Subscript::RDIV:
4382-
case Subscript::MIV:
4383-
break;
4384-
}
4385-
}
4386-
// No split iteration found
4387-
return nullptr;
4388-
}

llvm/test/Analysis/DependenceAnalysis/Propagating.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,7 @@ define void @prop7(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
437437
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx7, align 4 --> Dst: store i32 %conv, ptr %arrayidx7, align 4
438438
; CHECK-NEXT: da analyze - none!
439439
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx7, align 4 --> Dst: %0 = load i32, ptr %arrayidx13, align 4
440-
; CHECK-NEXT: da analyze - flow [* -38] splitable!
441-
; CHECK-NEXT: da analyze - split level = 1, iteration = 4!
440+
; CHECK-NEXT: da analyze - flow [* -38]!
442441
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx7, align 4 --> Dst: store i32 %0, ptr %B.addr.11, align 4
443442
; CHECK-NEXT: da analyze - confused!
444443
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx13, align 4 --> Dst: %0 = load i32, ptr %arrayidx13, align 4

llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,7 @@ define void @weaktest(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
332332
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
333333
; CHECK-NEXT: da analyze - none!
334334
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
335-
; CHECK-NEXT: da analyze - flow [*|<] splitable!
336-
; CHECK-NEXT: da analyze - split level = 1, iteration = ((0 smax (-4 + (-4 * %n))) /u 8)!
335+
; CHECK-NEXT: da analyze - flow [*|<]!
337336
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
338337
; CHECK-NEXT: da analyze - confused!
339338
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4

0 commit comments

Comments
 (0)