-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[DA] remove getSplitIteration #167698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sebpop
wants to merge
2
commits into
llvm:main
Choose a base branch
from
sebpop:da-remove-split-iter
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
[DA] remove getSplitIteration #167698
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Remove all constraint propagation functions. Simplify depends() and getSplitIteration() to test subscripts individually.
Member
|
@llvm/pr-subscribers-llvm-analysis Author: Sebastian Pop (sebpop) ChangesSeparate PR to be committed separately based on top of #160924 Patch is 93.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167698.diff 7 Files Affected:
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index f66c79d915665..ae260cd153177 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -302,48 +302,6 @@ class DependenceInfo {
depends(Instruction *Src, Instruction *Dst,
bool UnderRuntimeAssumptions = false);
- /// getSplitIteration - Give a dependence that's splittable at some
- /// particular level, return the iteration that should be used to split
- /// the loop.
- ///
- /// Generally, the dependence analyzer will be used to build
- /// a dependence graph for a function (basically a map from instructions
- /// to dependences). Looking for cycles in the graph shows us loops
- /// that cannot be trivially vectorized/parallelized.
- ///
- /// We can try to improve the situation by examining all the dependences
- /// that make up the cycle, looking for ones we can break.
- /// Sometimes, peeling the first or last iteration of a loop will break
- /// dependences, and there are flags for those possibilities.
- /// Sometimes, splitting a loop at some other iteration will do the trick,
- /// and we've got a flag for that case. Rather than waste the space to
- /// record the exact iteration (since we rarely know), we provide
- /// a method that calculates the iteration. It's a drag that it must work
- /// from scratch, but wonderful in that it's possible.
- ///
- /// Here's an example:
- ///
- /// for (i = 0; i < 10; i++)
- /// A[i] = ...
- /// ... = A[11 - i]
- ///
- /// There's a loop-carried flow dependence from the store to the load,
- /// found by the weak-crossing SIV test. The dependence will have a flag,
- /// indicating that the dependence can be broken by splitting the loop.
- /// Calling getSplitIteration will return 5.
- /// Splitting the loop breaks the dependence, like so:
- ///
- /// for (i = 0; i <= 5; i++)
- /// A[i] = ...
- /// ... = A[11 - i]
- /// for (i = 6; i < 10; i++)
- /// A[i] = ...
- /// ... = A[11 - i]
- ///
- /// breaks the dependence and allows us to vectorize/parallelize
- /// both loops.
- LLVM_ABI const SCEV *getSplitIteration(const Dependence &Dep, unsigned Level);
-
Function *getFunction() const { return F; }
/// getRuntimeAssumptions - Returns all the runtime assumptions under which
@@ -623,8 +581,7 @@ class DependenceInfo {
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
- FullDependence &Result, Constraint &NewConstraint,
- const SCEV *&SplitIter) const;
+ FullDependence &Result, Constraint &NewConstraint) const;
/// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j]
@@ -669,8 +626,7 @@ class DependenceInfo {
bool weakCrossingSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
const SCEV *DstConst, const Loop *CurrentLoop,
unsigned Level, FullDependence &Result,
- Constraint &NewConstraint,
- const SCEV *&SplitIter) const;
+ Constraint &NewConstraint) const;
/// ExactSIVtest - Tests the SIV subscript pair
/// (Src and Dst) for dependence.
@@ -838,35 +794,6 @@ class DependenceInfo {
/// of the Constraints X and Y. Returns true if X has changed.
bool intersectConstraints(Constraint *X, const Constraint *Y);
- /// propagate - Review the constraints, looking for opportunities
- /// to simplify a subscript pair (Src and Dst).
- /// Return true if some simplification occurs.
- /// If the simplification isn't exact (that is, if it is conservative
- /// in terms of dependence), set consistent to false.
- bool propagate(const SCEV *&Src, const SCEV *&Dst, SmallBitVector &Loops,
- SmallVectorImpl<Constraint> &Constraints, bool &Consistent);
-
- /// propagateDistance - Attempt to propagate a distance
- /// constraint into a subscript pair (Src and Dst).
- /// Return true if some simplification occurs.
- /// If the simplification isn't exact (that is, if it is conservative
- /// in terms of dependence), set consistent to false.
- bool propagateDistance(const SCEV *&Src, const SCEV *&Dst,
- Constraint &CurConstraint, bool &Consistent);
-
- /// propagatePoint - Attempt to propagate a point
- /// constraint into a subscript pair (Src and Dst).
- /// Return true if some simplification occurs.
- bool propagatePoint(const SCEV *&Src, const SCEV *&Dst,
- Constraint &CurConstraint);
-
- /// propagateLine - Attempt to propagate a line
- /// constraint into a subscript pair (Src and Dst).
- /// Return true if some simplification occurs.
- /// If the simplification isn't exact (that is, if it is conservative
- /// in terms of dependence), set consistent to false.
- bool propagateLine(const SCEV *&Src, const SCEV *&Dst,
- Constraint &CurConstraint, bool &Consistent);
/// findCoefficient - Given a linear SCEV,
/// return the coefficient corresponding to specified loop.
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index da86a8d2cc9c0..c9ecc936424c3 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -73,8 +73,6 @@ using namespace llvm;
// statistics
STATISTIC(TotalArrayPairs, "Array pairs tested");
-STATISTIC(SeparableSubscriptPairs, "Separable subscript pairs");
-STATISTIC(CoupledSubscriptPairs, "Coupled subscript pairs");
STATISTIC(NonlinearSubscriptPairs, "Nonlinear subscript pairs");
STATISTIC(ZIVapplications, "ZIV applications");
STATISTIC(ZIVindependence, "ZIV independence");
@@ -96,8 +94,6 @@ STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
STATISTIC(DeltaApplications, "Delta applications");
STATISTIC(DeltaSuccesses, "Delta successes");
-STATISTIC(DeltaIndependence, "Delta independence");
-STATISTIC(DeltaPropagations, "Delta propagations");
STATISTIC(GCDapplications, "GCD applications");
STATISTIC(GCDsuccesses, "GCD successes");
STATISTIC(GCDindependence, "GCD independence");
@@ -208,7 +204,6 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
if (D->isSplitable(Level)) {
OS << " da analyze - split level = " << Level;
- OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
OS << "!\n";
}
}
@@ -1351,10 +1346,12 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
// Can determine iteration for splitting.
//
// Return true if dependence disproved.
-bool DependenceInfo::weakCrossingSIVtest(
- const SCEV *Coeff, const SCEV *SrcConst, const SCEV *DstConst,
- const Loop *CurLoop, unsigned Level, FullDependence &Result,
- Constraint &NewConstraint, const SCEV *&SplitIter) const {
+bool DependenceInfo::weakCrossingSIVtest(const SCEV *Coeff,
+ const SCEV *SrcConst,
+ const SCEV *DstConst,
+ const Loop *CurLoop, unsigned Level,
+ FullDependence &Result,
+ Constraint &NewConstraint) const {
LLVM_DEBUG(dbgs() << "\tWeak-Crossing SIV test\n");
LLVM_DEBUG(dbgs() << "\t Coeff = " << *Coeff << "\n");
LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n");
@@ -1390,12 +1387,6 @@ bool DependenceInfo::weakCrossingSIVtest(
}
assert(SE->isKnownPositive(ConstCoeff) && "ConstCoeff should be positive");
- // compute SplitIter for use by DependenceInfo::getSplitIteration()
- SplitIter = SE->getUDivExpr(
- SE->getSMaxExpr(SE->getZero(Delta->getType()), Delta),
- SE->getMulExpr(SE->getConstant(Delta->getType(), 2), ConstCoeff));
- LLVM_DEBUG(dbgs() << "\t Split iter = " << *SplitIter << "\n");
-
const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
if (!ConstDelta)
return false;
@@ -2232,8 +2223,8 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
//
// Return true if dependence disproved.
bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
- FullDependence &Result, Constraint &NewConstraint,
- const SCEV *&SplitIter) const {
+ FullDependence &Result,
+ Constraint &NewConstraint) const {
LLVM_DEBUG(dbgs() << " src = " << *Src << "\n");
LLVM_DEBUG(dbgs() << " dst = " << *Dst << "\n");
const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
@@ -2253,7 +2244,7 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
Result, NewConstraint);
else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
- Level, Result, NewConstraint, SplitIter);
+ Level, Result, NewConstraint);
else
disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
Level, Result, NewConstraint);
@@ -3116,153 +3107,8 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
AddRec->getNoWrapFlags());
}
-// Review the constraints, looking for opportunities
-// to simplify a subscript pair (Src and Dst).
-// Return true if some simplification occurs.
-// If the simplification isn't exact (that is, if it is conservative
-// in terms of dependence), set consistent to false.
-// Corresponds to Figure 5 from the paper
-//
-// Practical Dependence Testing
-// Goff, Kennedy, Tseng
-// PLDI 1991
-bool DependenceInfo::propagate(const SCEV *&Src, const SCEV *&Dst,
- SmallBitVector &Loops,
- SmallVectorImpl<Constraint> &Constraints,
- bool &Consistent) {
- bool Result = false;
- for (unsigned LI : Loops.set_bits()) {
- LLVM_DEBUG(dbgs() << "\t Constraint[" << LI << "] is");
- LLVM_DEBUG(Constraints[LI].dump(dbgs()));
- if (Constraints[LI].isDistance())
- Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
- else if (Constraints[LI].isLine())
- Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
- else if (Constraints[LI].isPoint())
- Result |= propagatePoint(Src, Dst, Constraints[LI]);
- }
- return Result;
-}
-// Attempt to propagate a distance
-// constraint into a subscript pair (Src and Dst).
-// Return true if some simplification occurs.
-// If the simplification isn't exact (that is, if it is conservative
-// in terms of dependence), set consistent to false.
-bool DependenceInfo::propagateDistance(const SCEV *&Src, const SCEV *&Dst,
- Constraint &CurConstraint,
- bool &Consistent) {
- const Loop *CurLoop = CurConstraint.getAssociatedLoop();
- LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
- const SCEV *A_K = findCoefficient(Src, CurLoop);
- if (A_K->isZero())
- return false;
- const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
- Src = SE->getMinusSCEV(Src, DA_K);
- Src = zeroCoefficient(Src, CurLoop);
- LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
- LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
- Dst = addToCoefficient(Dst, CurLoop, SE->getNegativeSCEV(A_K));
- LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
- if (!findCoefficient(Dst, CurLoop)->isZero())
- Consistent = false;
- return true;
-}
-// Attempt to propagate a line
-// constraint into a subscript pair (Src and Dst).
-// Return true if some simplification occurs.
-// If the simplification isn't exact (that is, if it is conservative
-// in terms of dependence), set consistent to false.
-bool DependenceInfo::propagateLine(const SCEV *&Src, const SCEV *&Dst,
- Constraint &CurConstraint,
- bool &Consistent) {
- const Loop *CurLoop = CurConstraint.getAssociatedLoop();
- const SCEV *A = CurConstraint.getA();
- const SCEV *B = CurConstraint.getB();
- const SCEV *C = CurConstraint.getC();
- LLVM_DEBUG(dbgs() << "\t\tA = " << *A << ", B = " << *B << ", C = " << *C
- << "\n");
- LLVM_DEBUG(dbgs() << "\t\tSrc = " << *Src << "\n");
- LLVM_DEBUG(dbgs() << "\t\tDst = " << *Dst << "\n");
- if (A->isZero()) {
- const SCEVConstant *Bconst = dyn_cast<SCEVConstant>(B);
- const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
- if (!Bconst || !Cconst)
- return false;
- APInt Beta = Bconst->getAPInt();
- APInt Charlie = Cconst->getAPInt();
- APInt CdivB = Charlie.sdiv(Beta);
- assert(Charlie.srem(Beta) == 0 && "C should be evenly divisible by B");
- const SCEV *AP_K = findCoefficient(Dst, CurLoop);
- Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
- Dst = zeroCoefficient(Dst, CurLoop);
- if (!findCoefficient(Src, CurLoop)->isZero())
- Consistent = false;
- } else if (B->isZero()) {
- const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
- const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
- if (!Aconst || !Cconst)
- return false;
- APInt Alpha = Aconst->getAPInt();
- APInt Charlie = Cconst->getAPInt();
- APInt CdivA = Charlie.sdiv(Alpha);
- assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
- const SCEV *A_K = findCoefficient(Src, CurLoop);
- Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
- Src = zeroCoefficient(Src, CurLoop);
- if (!findCoefficient(Dst, CurLoop)->isZero())
- Consistent = false;
- } else if (isKnownPredicate(CmpInst::ICMP_EQ, A, B)) {
- const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
- const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
- if (!Aconst || !Cconst)
- return false;
- APInt Alpha = Aconst->getAPInt();
- APInt Charlie = Cconst->getAPInt();
- APInt CdivA = Charlie.sdiv(Alpha);
- assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
- const SCEV *A_K = findCoefficient(Src, CurLoop);
- Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
- Src = zeroCoefficient(Src, CurLoop);
- Dst = addToCoefficient(Dst, CurLoop, A_K);
- if (!findCoefficient(Dst, CurLoop)->isZero())
- Consistent = false;
- } else {
- // paper is incorrect here, or perhaps just misleading
- const SCEV *A_K = findCoefficient(Src, CurLoop);
- Src = SE->getMulExpr(Src, A);
- Dst = SE->getMulExpr(Dst, A);
- Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, C));
- Src = zeroCoefficient(Src, CurLoop);
- Dst = addToCoefficient(Dst, CurLoop, SE->getMulExpr(A_K, B));
- if (!findCoefficient(Dst, CurLoop)->isZero())
- Consistent = false;
- }
- LLVM_DEBUG(dbgs() << "\t\tnew Src = " << *Src << "\n");
- LLVM_DEBUG(dbgs() << "\t\tnew Dst = " << *Dst << "\n");
- return true;
-}
-
-// Attempt to propagate a point
-// constraint into a subscript pair (Src and Dst).
-// Return true if some simplification occurs.
-bool DependenceInfo::propagatePoint(const SCEV *&Src, const SCEV *&Dst,
- Constraint &CurConstraint) {
- const Loop *CurLoop = CurConstraint.getAssociatedLoop();
- const SCEV *A_K = findCoefficient(Src, CurLoop);
- const SCEV *AP_K = findCoefficient(Dst, CurLoop);
- const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
- const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
- LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
- Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
- Src = zeroCoefficient(Src, CurLoop);
- LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
- LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
- Dst = zeroCoefficient(Dst, CurLoop);
- LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
- return true;
-}
// Update direction vector entry based on the current constraint.
void DependenceInfo::updateDirection(Dependence::DVEntry &Level,
@@ -3579,8 +3425,6 @@ SCEVUnionPredicate DependenceInfo::getRuntimeAssumptions() const {
// Goff, Kennedy, Tseng
// PLDI 1991
//
-// Care is required to keep the routine below, getSplitIteration(),
-// up to date with respect to this routine.
std::unique_ptr<Dependence>
DependenceInfo::depends(Instruction *Src, Instruction *Dst,
bool UnderRuntimeAssumptions) {
@@ -3726,68 +3570,11 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
LLVM_DEBUG(dumpSmallBitVector(Pair[P].Loops));
}
- SmallBitVector Separable(Pairs);
- SmallBitVector Coupled(Pairs);
-
- // Partition subscripts into separable and minimally-coupled groups
- // Algorithm in paper is algorithmically better;
- // this may be faster in practice. Check someday.
- //
- // Here's an example of how it works. Consider this code:
- //
- // for (i = ...) {
- // for (j = ...) {
- // for (k = ...) {
- // for (l = ...) {
- // for (m = ...) {
- // A[i][j][k][m] = ...;
- // ... = A[0][j][l][i + j];
- // }
- // }
- // }
- // }
- // }
- //
- // There are 4 subscripts here:
- // 0 [i] and [0]
- // 1 [j] and [j]
- // 2 [k] and [l]
- // 3 [m] and [i + j]
- //
- // We've already classified each subscript pair as ZIV, SIV, etc.,
- // and collected all the loops mentioned by pair P in Pair[P].Loops.
- // In addition, we've initialized Pair[P].GroupLoops to Pair[P].Loops
- // and set Pair[P].Group = {P}.
- //
- // Src Dst Classification Loops GroupLoops Group
- // 0 [i] [0] SIV {1} {1} {0}
- // 1 [j] [j] SIV {2} {2} {1}
- // 2 [k] [l] RDIV {3,4} {3,4} {2}
- // 3 [m] [i + j] MIV {1,2,5} {1,2,5} {3}
- //
- // For each subscript SI 0 .. 3, we consider each remaining subscript, SJ.
- // So, 0 is compared against 1, 2, and 3; 1 is compared against 2 and 3, etc.
- //
- // We begin by comparing 0 and 1. The intersection of the GroupLoops is empty.
- // Next, 0 and 2. Again, the intersection of their GroupLoops is empty.
- // Next 0 and 3. The intersection of their GroupLoop = {1}, not empty,
- // so Pair[3].Group = {0,3} and Done = false (that is, 0 will not be added
- // to either Separable or Coupled).
- //
- // Next, we consider 1 and 2. The intersection of the GroupLoops is empty.
- // Next, 1 and 3. The intersection of their GroupLoops = {2}, not empty,
- // so Pair[3].Group = {0, 1, 3} and Done = false.
- //
- // Next, we compare 2 against 3. The intersection of the GroupLoops is empty.
- // Since Done remains true, we add 2 to the set of Separable pairs.
- //
- // Finally, we consider 3. There's nothing to compare it with,
- // so Done remains true and we add it to the Coupled set.
- // Pair[3].Group = {0, 1, 3} and GroupLoops = {1, 2, 5}.
- //
- // In the end, we've got 1 separable subscript and 1 coupled group.
+ // Test each subscript individually
for (unsigned SI = 0; SI < Pairs; ++SI) {
- if (Pair[SI].Classification == Subscript::NonLinear) {
+ LLVM_DEBUG(dbgs() << "testing subscript " << SI);
+ switch (Pair[SI].Classification) {
+ case Subscript::NonLinear:
// ignore these, but collect loops for later
++NonlinearSubscriptPairs;
collectCommonLoops(Pair[SI].Src, LI->getLoopFor(Src->getParent()),
@@ -3795,47 +3582,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
collectCommonLoops(Pair[SI].Dst, LI->getLoopFor(Dst->getParent()),
Pair[SI].Loops);
Result.Consistent = false;
- } ...
[truncated]
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Separate PR to be committed separately based on top of #160924