-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[DA] remove Constraints class #168963
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-constraints
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 Constraints class #168963
+40
−764
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
Member
|
@llvm/pr-subscribers-llvm-analysis Author: Sebastian Pop (sebpop) ChangesThis is to be committed on top of #167698 Patch is 49.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/168963.diff 6 Files Affected:
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 85c9af4fffcde..2e845104464a5 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -365,48 +365,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
@@ -447,106 +405,6 @@ class DependenceInfo {
unsigned char DirSet;
};
- /// Constraint - This private class represents a constraint, as defined
- /// in the paper
- ///
- /// Practical Dependence Testing
- /// Goff, Kennedy, Tseng
- /// PLDI 1991
- ///
- /// There are 5 kinds of constraint, in a hierarchy.
- /// 1) Any - indicates no constraint, any dependence is possible.
- /// 2) Line - A line ax + by = c, where a, b, and c are parameters,
- /// representing the dependence equation.
- /// 3) Distance - The value d of the dependence distance;
- /// 4) Point - A point <x, y> representing the dependence from
- /// iteration x to iteration y.
- /// 5) Empty - No dependence is possible.
- class Constraint {
- private:
- enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
- ScalarEvolution *SE;
- const SCEV *A;
- const SCEV *B;
- const SCEV *C;
- const Loop *AssociatedSrcLoop;
- const Loop *AssociatedDstLoop;
-
- public:
- /// isEmpty - Return true if the constraint is of kind Empty.
- bool isEmpty() const { return Kind == Empty; }
-
- /// isPoint - Return true if the constraint is of kind Point.
- bool isPoint() const { return Kind == Point; }
-
- /// isDistance - Return true if the constraint is of kind Distance.
- bool isDistance() const { return Kind == Distance; }
-
- /// isLine - Return true if the constraint is of kind Line.
- /// Since Distance's can also be represented as Lines, we also return
- /// true if the constraint is of kind Distance.
- bool isLine() const { return Kind == Line || Kind == Distance; }
-
- /// isAny - Return true if the constraint is of kind Any;
- bool isAny() const { return Kind == Any; }
-
- /// getX - If constraint is a point <X, Y>, returns X.
- /// Otherwise assert.
- LLVM_ABI const SCEV *getX() const;
-
- /// getY - If constraint is a point <X, Y>, returns Y.
- /// Otherwise assert.
- LLVM_ABI const SCEV *getY() const;
-
- /// getA - If constraint is a line AX + BY = C, returns A.
- /// Otherwise assert.
- LLVM_ABI const SCEV *getA() const;
-
- /// getB - If constraint is a line AX + BY = C, returns B.
- /// Otherwise assert.
- LLVM_ABI const SCEV *getB() const;
-
- /// getC - If constraint is a line AX + BY = C, returns C.
- /// Otherwise assert.
- LLVM_ABI const SCEV *getC() const;
-
- /// getD - If constraint is a distance, returns D.
- /// Otherwise assert.
- LLVM_ABI const SCEV *getD() const;
-
- /// getAssociatedSrcLoop - Returns the source loop associated with this
- /// constraint.
- LLVM_ABI const Loop *getAssociatedSrcLoop() const;
-
- /// getAssociatedDstLoop - Returns the destination loop associated with
- /// this constraint.
- LLVM_ABI const Loop *getAssociatedDstLoop() const;
-
- /// setPoint - Change a constraint to Point.
- LLVM_ABI void setPoint(const SCEV *X, const SCEV *Y,
- const Loop *CurrentSrcLoop,
- const Loop *CurrentDstLoop);
-
- /// setLine - Change a constraint to Line.
- LLVM_ABI void setLine(const SCEV *A, const SCEV *B, const SCEV *C,
- const Loop *CurrentSrcLoop,
- const Loop *CurrentDstLoop);
-
- /// setDistance - Change a constraint to Distance.
- LLVM_ABI void setDistance(const SCEV *D, const Loop *CurrentSrcLoop,
- const Loop *CurrentDstLoop);
-
- /// setEmpty - Change a constraint to Empty.
- LLVM_ABI void setEmpty();
-
- /// setAny - Change a constraint to Any.
- LLVM_ABI void setAny(ScalarEvolution *SE);
-
- /// dump - For debugging purposes. Dumps the constraint
- /// out to OS.
- LLVM_ABI void dump(raw_ostream &OS) const;
- };
-
/// Returns true if two loops have the Same iteration Space and Depth. To be
/// more specific, two loops have SameSD if they are in the same nesting
/// depth and have the same backedge count. SameSD stands for Same iteration
@@ -713,8 +571,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) const;
/// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j]
@@ -744,7 +601,7 @@ class DependenceInfo {
bool strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
const SCEV *DstConst, const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop, unsigned Level,
- FullDependence &Result, Constraint &NewConstraint) const;
+ FullDependence &Result) const;
/// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
/// (Src and Dst) for dependence.
@@ -759,8 +616,7 @@ class DependenceInfo {
bool weakCrossingSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
const SCEV *DstConst, const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop, unsigned Level,
- FullDependence &Result, Constraint &NewConstraint,
- const SCEV *&SplitIter) const;
+ FullDependence &Result) const;
/// ExactSIVtest - Tests the SIV subscript pair
/// (Src and Dst) for dependence.
@@ -774,8 +630,7 @@ class DependenceInfo {
bool exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
const SCEV *SrcConst, const SCEV *DstConst,
const Loop *CurrentSrcLoop, const Loop *CurrentDstLoop,
- unsigned Level, FullDependence &Result,
- Constraint &NewConstraint) const;
+ unsigned Level, FullDependence &Result) const;
/// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
@@ -790,8 +645,7 @@ class DependenceInfo {
bool weakZeroSrcSIVtest(const SCEV *DstCoeff, const SCEV *SrcConst,
const SCEV *DstConst, const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop, unsigned Level,
- FullDependence &Result,
- Constraint &NewConstraint) const;
+ FullDependence &Result) const;
/// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
@@ -806,8 +660,7 @@ class DependenceInfo {
bool weakZeroDstSIVtest(const SCEV *SrcCoeff, const SCEV *SrcConst,
const SCEV *DstConst, const Loop *CurrentSrcLoop,
const Loop *CurrentDstLoop, unsigned Level,
- FullDependence &Result,
- Constraint &NewConstraint) const;
+ FullDependence &Result) const;
/// exactRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
@@ -927,37 +780,6 @@ class DependenceInfo {
void findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B, BoundInfo *Bound,
unsigned K) const;
- /// intersectConstraints - Updates X with the intersection
- /// of the Constraints X and Y. Returns true if X has changed.
- bool intersectConstraints(Constraint *X, const Constraint *Y);
-
- /// findCoefficient - Given a linear SCEV,
- /// return the coefficient corresponding to specified loop.
- /// If there isn't one, return the SCEV constant 0.
- /// For example, given a*i + b*j + c*k, returning the coefficient
- /// corresponding to the j loop would yield b.
- const SCEV *findCoefficient(const SCEV *Expr, const Loop *TargetLoop) const;
-
- /// zeroCoefficient - Given a linear SCEV,
- /// return the SCEV given by zeroing out the coefficient
- /// corresponding to the specified loop.
- /// For example, given a*i + b*j + c*k, zeroing the coefficient
- /// corresponding to the j loop would yield a*i + c*k.
- const SCEV *zeroCoefficient(const SCEV *Expr, const Loop *TargetLoop) const;
-
- /// addToCoefficient - Given a linear SCEV Expr,
- /// return the SCEV given by adding some Value to the
- /// coefficient corresponding to the specified TargetLoop.
- /// For example, given a*i + b*j + c*k, adding 1 to the coefficient
- /// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
- const SCEV *addToCoefficient(const SCEV *Expr, const Loop *TargetLoop,
- const SCEV *Value) const;
-
- /// updateDirection - Update direction vector entry
- /// based on the current constraint.
- void updateDirection(Dependence::DVEntry &Level,
- const Constraint &CurConstraint) const;
-
/// Given a linear access function, tries to recover subscripts
/// for each dimension of the array element access.
bool tryDelinearize(Instruction *Src, Instruction *Dst,
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index ea261820fb2e6..940cedea33def 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -18,11 +18,6 @@
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
-// Currently, the implementation cannot propagate constraints between
-// coupled RDIV subscripts and lacks a multi-subscript MIV test.
-// Both of these are conservative weaknesses;
-// that is, not a source of correctness problems.
-//
// Since Clang linearizes some array subscripts, the dependence
// analysis is using SCEV->delinearize to recover the representation of multiple
// subscripts, and thus avoid the more expensive and less precise MIV tests. The
@@ -92,8 +87,6 @@ STATISTIC(ExactRDIVapplications, "Exact RDIV applications");
STATISTIC(ExactRDIVindependence, "Exact RDIV independence");
STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
-STATISTIC(DeltaApplications, "Delta applications");
-STATISTIC(DeltaSuccesses, "Delta successes");
STATISTIC(GCDapplications, "GCD applications");
STATISTIC(GCDsuccesses, "GCD successes");
STATISTIC(GCDindependence, "GCD independence");
@@ -445,7 +438,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";
}
}
@@ -625,282 +617,6 @@ bool FullDependence::inSameSDLoops(unsigned Level) const {
return Level > Levels;
}
-//===----------------------------------------------------------------------===//
-// DependenceInfo::Constraint methods
-
-// If constraint is a point <X, Y>, returns X.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getX() const {
- assert(Kind == Point && "Kind should be Point");
- return A;
-}
-
-// If constraint is a point <X, Y>, returns Y.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getY() const {
- assert(Kind == Point && "Kind should be Point");
- return B;
-}
-
-// If constraint is a line AX + BY = C, returns A.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getA() const {
- assert((Kind == Line || Kind == Distance) &&
- "Kind should be Line (or Distance)");
- return A;
-}
-
-// If constraint is a line AX + BY = C, returns B.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getB() const {
- assert((Kind == Line || Kind == Distance) &&
- "Kind should be Line (or Distance)");
- return B;
-}
-
-// If constraint is a line AX + BY = C, returns C.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getC() const {
- assert((Kind == Line || Kind == Distance) &&
- "Kind should be Line (or Distance)");
- return C;
-}
-
-// If constraint is a distance, returns D.
-// Otherwise assert.
-const SCEV *DependenceInfo::Constraint::getD() const {
- assert(Kind == Distance && "Kind should be Distance");
- return SE->getNegativeSCEV(C);
-}
-
-// Returns the source loop associated with this constraint.
-const Loop *DependenceInfo::Constraint::getAssociatedSrcLoop() const {
- assert((Kind == Distance || Kind == Line || Kind == Point) &&
- "Kind should be Distance, Line, or Point");
- return AssociatedSrcLoop;
-}
-
-// Returns the destination loop associated with this constraint.
-const Loop *DependenceInfo::Constraint::getAssociatedDstLoop() const {
- assert((Kind == Distance || Kind == Line || Kind == Point) &&
- "Kind should be Distance, Line, or Point");
- return AssociatedDstLoop;
-}
-
-void DependenceInfo::Constraint::setPoint(const SCEV *X, const SCEV *Y,
- const Loop *CurSrcLoop,
- const Loop *CurDstLoop) {
- Kind = Point;
- A = X;
- B = Y;
- AssociatedSrcLoop = CurSrcLoop;
- AssociatedDstLoop = CurDstLoop;
-}
-
-void DependenceInfo::Constraint::setLine(const SCEV *AA, const SCEV *BB,
- const SCEV *CC, const Loop *CurSrcLoop,
- const Loop *CurDstLoop) {
- Kind = Line;
- A = AA;
- B = BB;
- C = CC;
- AssociatedSrcLoop = CurSrcLoop;
- AssociatedDstLoop = CurDstLoop;
-}
-
-void DependenceInfo::Constraint::setDistance(const SCEV *D,
- const Loop *CurSrcLoop,
- const Loop *CurDstLoop) {
- Kind = Distance;
- A = SE->getOne(D->getType());
- B = SE->getNegativeSCEV(A);
- C = SE->getNegativeSCEV(D);
- AssociatedSrcLoop = CurSrcLoop;
- AssociatedDstLoop = CurDstLoop;
-}
-
-void DependenceInfo::Constraint::setEmpty() { Kind = Empty; }
-
-void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
- SE = NewSE;
- Kind = Any;
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-// For debugging purposes. Dumps the constraint out to OS.
-LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS) const {
- if (isEmpty())
- OS << " Empty\n";
- else if (isAny())
- OS << " Any\n";
- else if (isPoint())
- OS << " Point is <" << *getX() << ", " << *getY() << ">\n";
- else if (isDistance())
- OS << " Distance is " << *getD() << " (" << *getA() << "*X + " << *getB()
- << "*Y = " << *getC() << ")\n";
- else if (isLine())
- OS << " Line is " << *getA() << "*X + " << *getB() << "*Y = " << *getC()
- << "\n";
- else
- llvm_unreachable("unknown constraint type in Constraint::dump");
-}
-#endif
-
-// Updates X with the intersection
-// of the Constraints X and Y. Returns true if X has changed.
-// Corresponds to Figure 4 from the paper
-//
-// Practical Dependence Testing
-// Goff, Kennedy, Tseng
-// PLDI 1991
-bool DependenceInfo::intersectConstraints(Constraint *X, const Constraint *Y) {
- ++DeltaApplications;
- LLVM_DEBUG(dbgs() << "\tintersect constraints\n");
- LLVM_DEBUG(dbgs() << "\t X ="; X->dump(dbgs()));
- LLVM_DEBUG(dbgs() << "\t Y ="; Y->dump(dbgs()));
- assert(!Y->isPoint() && "Y must not be a Point");
- if (X->isAny()) {
- if (Y->isAny())
- return false;
- *X = *Y;
- return true;
- }
- if (X->isEmpty())
- return false;
- if (Y->isEmpty()) {
- X->setEmpty();
- return true;
- }
-
- if (X->isDistance() && Y->isDistance()) {
- LLVM_DEBUG(dbgs() << "\t intersect 2 distances\n");
- if (isKnownPredicate(CmpInst::ICMP_EQ, X->getD(), Y->getD()))
- return false;
- if (isKnownPredicate(CmpInst::ICMP_NE, X->getD(), Y->getD())) {
- X->setEmpty();
- ++DeltaSuccesses;
- return true;
- }
- // Hmmm, interesting situation.
- // I guess if either is constant, keep it and ignore the other.
- if (isa<SCEVConstant>(Y->getD())) {
- *X = *Y;
- return true;
- }
- return false;
- }
-
- // At this point, the pseudo-code in Figure 4 of the paper
- // checks if (X->isPoint() && Y->isPoint()).
- // This case can't occur in our implementation,
- // since a Point can only arise as the result of intersecting
- // two Line constraints, and the right-hand value, Y, is never
- // the result of an intersection.
- assert(!(X->isPoint() && Y->isPoint()) &&
- "We shouldn't ever see X->isPoint() && Y->isPoint()");
-
- if (X->isLine() && Y->isLine()) {
- LLVM_DEBUG(dbgs() << "\t intersect 2 lines\n");
- const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
- const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
- if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2)) {
- // slopes are equal, so lines are parallel
- LLVM_DEBUG(dbgs() << "\t\tsame slope\n");
- Prod1 = SE->getMulExpr(X->getC(), Y->getB());
- Prod2 = SE->getMulExpr(X->getB(), Y->getC());
- if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2))
- return false;
- if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
- X->setEmpty();
- ++DeltaSuccesses;
- return true;
- }
- return false;
- }
- if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
- // slopes differ, so lines intersect
- LLVM_DEBUG(dbgs() << "\t\tdifferent slopes\n");
- const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
- const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
- const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
- const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->g...
[truncated]
|
🐧 Linux x64 Test Results
|
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.
This is to be committed on top of #167698