[Mlir-commits] [mlir] mlir/Presburger: optimize to avoid creating copies (PR #97897)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sat Jul 6 06:45:53 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-presburger
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
Optimize the Presburger library to avoid unnecessarily creating copies. While at it, fix some other minor issues in the codebase.
---
Patch is 34.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97897.diff
9 Files Affected:
- (modified) mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h (+5-5)
- (modified) mlir/lib/Analysis/Presburger/Barvinok.cpp (+21-20)
- (modified) mlir/lib/Analysis/Presburger/IntegerRelation.cpp (+15-15)
- (modified) mlir/lib/Analysis/Presburger/LinearTransform.cpp (+2-2)
- (modified) mlir/lib/Analysis/Presburger/PWMAFunction.cpp (+3-3)
- (modified) mlir/lib/Analysis/Presburger/PresburgerRelation.cpp (+20-14)
- (modified) mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp (+13-13)
- (modified) mlir/lib/Analysis/Presburger/Simplex.cpp (+40-34)
- (modified) mlir/lib/Analysis/Presburger/Utils.cpp (+4-5)
``````````diff
diff --git a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
index aeac19e827b44..5a0962df89d37 100644
--- a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
+++ b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
@@ -36,10 +36,10 @@ namespace presburger {
// g_{ij} : Q^n -> Q are affine functionals.
class QuasiPolynomial : public PresburgerSpace {
public:
- QuasiPolynomial(unsigned numVars, SmallVector<Fraction> coeffs = {},
- std::vector<std::vector<SmallVector<Fraction>>> aff = {});
+ QuasiPolynomial(unsigned numVars, ArrayRef<Fraction> coeffs = {},
+ ArrayRef<std::vector<SmallVector<Fraction>>> aff = {});
- QuasiPolynomial(unsigned numVars, Fraction constant);
+ QuasiPolynomial(unsigned numVars, const Fraction &constant);
// Find the number of inputs (numDomain) to the polynomial.
// numSymbols is set to zero.
@@ -57,7 +57,7 @@ class QuasiPolynomial : public PresburgerSpace {
QuasiPolynomial operator+(const QuasiPolynomial &x) const;
QuasiPolynomial operator-(const QuasiPolynomial &x) const;
QuasiPolynomial operator*(const QuasiPolynomial &x) const;
- QuasiPolynomial operator/(const Fraction x) const;
+ QuasiPolynomial operator/(const Fraction &x) const;
// Removes terms which evaluate to zero from the expression
// and folds affine functions which are constant into the
@@ -77,4 +77,4 @@ class QuasiPolynomial : public PresburgerSpace {
} // namespace presburger
} // namespace mlir
-#endif // MLIR_ANALYSIS_PRESBURGER_QUASIPOLYNOMIAL_H
\ No newline at end of file
+#endif // MLIR_ANALYSIS_PRESBURGER_QUASIPOLYNOMIAL_H
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index dae840e00ff2e..fad4364391d56 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -361,7 +361,7 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
continue;
// If this subset corresponds to a vertex that has not been considered,
// store it.
- vertices.push_back(*vertex);
+ vertices.emplace_back(*vertex);
// If a vertex is formed by the intersection of more than d facets, we
// assume that any d-subset of these facets can be solved to obtain its
@@ -472,10 +472,10 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
Point mlir::presburger::detail::getNonOrthogonalVector(
ArrayRef<Point> vectors) {
unsigned dim = vectors[0].size();
- assert(
- llvm::all_of(vectors,
- [&](const Point &vector) { return vector.size() == dim; }) &&
- "all vectors need to be the same size!");
+ assert(llvm::all_of(
+ vectors,
+ [&dim](const Point &vector) { return vector.size() == dim; }) &&
+ "all vectors need to be the same size!");
SmallVector<Fraction> newPoint = {Fraction(1, 1)};
Fraction maxDisallowedValue = -Fraction(1, 0),
@@ -493,7 +493,7 @@ Point mlir::presburger::detail::getNonOrthogonalVector(
// Find the biggest such value
maxDisallowedValue = std::max(maxDisallowedValue, disallowedValue);
}
- newPoint.push_back(maxDisallowedValue + 1);
+ newPoint.emplace_back(maxDisallowedValue + 1);
}
return newPoint;
}
@@ -519,19 +519,20 @@ QuasiPolynomial mlir::presburger::detail::getCoefficientInRationalFunction(
unsigned numParam = num[0].getNumInputs();
// We use the `isEqual` method of PresburgerSpace, which QuasiPolynomial
// inherits from.
- assert(
- llvm::all_of(
- num, [&](const QuasiPolynomial &qp) { return num[0].isEqual(qp); }) &&
- "the quasipolynomials should all belong to the same space!");
+ assert(llvm::all_of(num,
+ [&num](const QuasiPolynomial &qp) {
+ return num[0].isEqual(qp);
+ }) &&
+ "the quasipolynomials should all belong to the same space!");
std::vector<QuasiPolynomial> coefficients;
coefficients.reserve(power + 1);
- coefficients.push_back(num[0] / den[0]);
+ coefficients.emplace_back(num[0] / den[0]);
for (unsigned i = 1; i <= power; ++i) {
// If the power is not there in the numerator, the coefficient is zero.
- coefficients.push_back(i < num.size() ? num[i]
- : QuasiPolynomial(numParam, 0));
+ coefficients.emplace_back(i < num.size() ? num[i]
+ : QuasiPolynomial(numParam, 0));
// After den.size(), the coefficients are zero, so we stop
// subtracting at that point (if it is less than i).
@@ -573,7 +574,7 @@ substituteMuInTerm(unsigned numParams, const ParamPoint &v,
SmallVector<Fraction> coefficients;
coefficients.reserve(numDims);
for (const Point &d : ds)
- coefficients.push_back(-dotProduct(mu, d));
+ coefficients.emplace_back(-dotProduct(mu, d));
// Then, the affine function is a single floor expression, given by the
// corresponding column of v.
@@ -581,7 +582,7 @@ substituteMuInTerm(unsigned numParams, const ParamPoint &v,
std::vector<std::vector<SmallVector<Fraction>>> affine;
affine.reserve(numDims);
for (unsigned j = 0; j < numDims; ++j)
- affine.push_back({SmallVector<Fraction>(vTranspose.getRow(j))});
+ affine.push_back({SmallVector<Fraction>{vTranspose.getRow(j)}});
QuasiPolynomial num(numParams, coefficients, affine);
num = num.simplify();
@@ -593,7 +594,7 @@ substituteMuInTerm(unsigned numParams, const ParamPoint &v,
for (const Point &d : ds) {
// This term in the denominator is
// (1 - t^dens.back())
- dens.push_back(dotProduct(d, mu));
+ dens.emplace_back(dotProduct(d, mu));
}
return {num, dens};
@@ -641,7 +642,7 @@ std::vector<QuasiPolynomial> getBinomialCoefficients(const QuasiPolynomial &n,
coefficients.emplace_back(numParams, 1);
for (unsigned j = 1; j <= r; ++j)
// We use the recursive formula for binomial coefficients here and below.
- coefficients.push_back(
+ coefficients.emplace_back(
(coefficients[j - 1] * (n - QuasiPolynomial(numParams, j - 1)) /
Fraction(j, 1))
.simplify());
@@ -656,7 +657,7 @@ std::vector<Fraction> getBinomialCoefficients(const Fraction &n,
coefficients.reserve((int64_t)floor(r));
coefficients.emplace_back(1);
for (unsigned j = 1; j <= r; ++j)
- coefficients.push_back(coefficients[j - 1] * (n - (j - 1)) / (j));
+ coefficients.emplace_back(coefficients[j - 1] * (n - (j - 1)) / (j));
return coefficients;
}
@@ -764,8 +765,8 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
eachTermDenCoefficients.reserve(r);
for (const Fraction &den : dens) {
singleTermDenCoefficients = getBinomialCoefficients(den + 1, den + 1);
- eachTermDenCoefficients.push_back(
- ArrayRef<Fraction>(singleTermDenCoefficients).slice(1));
+ eachTermDenCoefficients.emplace_back(
+ ArrayRef<Fraction>(singleTermDenCoefficients).drop_front());
}
// Now we find the coefficients in Q(s) itself
diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 095a7dcb287f3..bdcb55251b104 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -511,10 +511,10 @@ void IntegerRelation::getLowerAndUpperBoundIndices(
continue;
if (atIneq(r, pos) >= 1) {
// Lower bound.
- lbIndices->push_back(r);
+ lbIndices->emplace_back(r);
} else if (atIneq(r, pos) <= -1) {
// Upper bound.
- ubIndices->push_back(r);
+ ubIndices->emplace_back(r);
}
}
@@ -528,7 +528,7 @@ void IntegerRelation::getLowerAndUpperBoundIndices(
continue;
if (containsConstraintDependentOnRange(r, /*isEq=*/true))
continue;
- eqIndices->push_back(r);
+ eqIndices->emplace_back(r);
}
}
@@ -791,7 +791,7 @@ IntMatrix IntegerRelation::getBoundedDirections() const {
// processes all the inequalities.
for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
if (simplex.isBoundedAlongConstraint(i))
- boundedIneqs.push_back(i);
+ boundedIneqs.emplace_back(i);
}
// The direction vector is given by the coefficients and does not include the
@@ -1981,13 +1981,13 @@ void IntegerRelation::fourierMotzkinEliminate(unsigned pos, bool darkShadow,
for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
if (atIneq(r, pos) == 0) {
// Var does not appear in bound.
- nbIndices.push_back(r);
+ nbIndices.emplace_back(r);
} else if (atIneq(r, pos) >= 1) {
// Lower bound.
- lbIndices.push_back(r);
+ lbIndices.emplace_back(r);
} else {
// Upper bound.
- ubIndices.push_back(r);
+ ubIndices.emplace_back(r);
}
}
@@ -2028,8 +2028,8 @@ void IntegerRelation::fourierMotzkinEliminate(unsigned pos, bool darkShadow,
continue;
assert(lbCoeff >= 1 && ubCoeff >= 1 && "bounds wrongly identified");
DynamicAPInt lcm = llvm::lcm(lbCoeff, ubCoeff);
- ineq.push_back(atIneq(ubPos, l) * (lcm / ubCoeff) +
- atIneq(lbPos, l) * (lcm / lbCoeff));
+ ineq.emplace_back(atIneq(ubPos, l) * (lcm / ubCoeff) +
+ atIneq(lbPos, l) * (lcm / lbCoeff));
assert(lcm > 0 && "lcm should be positive!");
if (lcm != 1)
allLCMsAreOne = false;
@@ -2057,7 +2057,7 @@ void IntegerRelation::fourierMotzkinEliminate(unsigned pos, bool darkShadow,
for (unsigned l = 0, e = getNumCols(); l < e; l++) {
if (l == pos)
continue;
- ineq.push_back(atIneq(nbPos, l));
+ ineq.emplace_back(atIneq(nbPos, l));
}
newRel.addInequality(ineq);
}
@@ -2072,7 +2072,7 @@ void IntegerRelation::fourierMotzkinEliminate(unsigned pos, bool darkShadow,
for (unsigned l = 0, e = getNumCols(); l < e; l++) {
if (l == pos)
continue;
- eq.push_back(atEq(r, l));
+ eq.emplace_back(atEq(r, l));
}
newRel.addEquality(eq);
}
@@ -2264,8 +2264,8 @@ IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
std::negate<DynamicAPInt>());
std::copy(maxUb.begin(), maxUb.end(), newUb.begin() + getNumDimVars());
- boundingLbs.push_back(newLb);
- boundingUbs.push_back(newUb);
+ boundingLbs.emplace_back(newLb);
+ boundingUbs.emplace_back(newUb);
}
// Clear all constraints and add the lower/upper bounds for the bounding box.
@@ -2309,7 +2309,7 @@ static void getIndependentConstraints(const IntegerRelation &cst, unsigned pos,
break;
}
if (c == pos + num)
- nbIneqIndices.push_back(r);
+ nbIneqIndices.emplace_back(r);
}
for (unsigned r = 0, e = cst.getNumEqualities(); r < e; r++) {
@@ -2320,7 +2320,7 @@ static void getIndependentConstraints(const IntegerRelation &cst, unsigned pos,
break;
}
if (c == pos + num)
- nbEqIndices.push_back(r);
+ nbEqIndices.emplace_back(r);
}
}
diff --git a/mlir/lib/Analysis/Presburger/LinearTransform.cpp b/mlir/lib/Analysis/Presburger/LinearTransform.cpp
index cccbf4c9991d3..1e389ca69e4e8 100644
--- a/mlir/lib/Analysis/Presburger/LinearTransform.cpp
+++ b/mlir/lib/Analysis/Presburger/LinearTransform.cpp
@@ -51,7 +51,7 @@ IntegerRelation LinearTransform::applyTo(const IntegerRelation &rel) const {
const DynamicAPInt &c = eq.back();
SmallVector<DynamicAPInt, 8> newEq = preMultiplyWithRow(eq.drop_back());
- newEq.push_back(c);
+ newEq.emplace_back(c);
result.addEquality(newEq);
}
@@ -61,7 +61,7 @@ IntegerRelation LinearTransform::applyTo(const IntegerRelation &rel) const {
const DynamicAPInt &c = ineq.back();
SmallVector<DynamicAPInt, 8> newIneq = preMultiplyWithRow(ineq.drop_back());
- newIneq.push_back(c);
+ newIneq.emplace_back(c);
result.addInequality(newIneq);
}
diff --git a/mlir/lib/Analysis/Presburger/PWMAFunction.cpp b/mlir/lib/Analysis/Presburger/PWMAFunction.cpp
index f78eb7d2d98ce..beb9f3e82e22d 100644
--- a/mlir/lib/Analysis/Presburger/PWMAFunction.cpp
+++ b/mlir/lib/Analysis/Presburger/PWMAFunction.cpp
@@ -46,7 +46,7 @@ static SmallVector<DynamicAPInt, 8> subtractExprs(ArrayRef<DynamicAPInt> vecA,
SmallVector<DynamicAPInt, 8> result;
result.reserve(vecA.size());
for (unsigned i = 0, e = vecA.size(); i < e; ++i)
- result.push_back(vecA[i] - vecB[i]);
+ result.emplace_back(vecA[i] - vecB[i]);
return result;
}
@@ -78,7 +78,7 @@ MultiAffineFunction::valueAt(ArrayRef<DynamicAPInt> point) const {
// function of; we have computed one possible set of values and use them here.
pointHomogenous.reserve(pointHomogenous.size() + divValues.size());
for (const std::optional<DynamicAPInt> &divVal : divValues)
- pointHomogenous.push_back(*divVal);
+ pointHomogenous.emplace_back(*divVal);
// The matrix `output` has an affine expression in the ith row, corresponding
// to the expression for the ith value in the output vector. The last column
// of the matrix contains the constant term. Let v be the input point with
@@ -295,7 +295,7 @@ void PWMAFunction::addPiece(const Piece &piece) {
assert(piece.isConsistent() && "Piece should be consistent");
assert(piece.domain.intersect(getDomain()).isIntegerEmpty() &&
"Piece should be disjoint from the function");
- pieces.push_back(piece);
+ pieces.emplace_back(piece);
}
void PWMAFunction::print(raw_ostream &os) const {
diff --git a/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp b/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp
index e284ca82420ba..239ffe6aaaa76 100644
--- a/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp
@@ -79,7 +79,7 @@ const IntegerRelation &PresburgerRelation::getDisjunct(unsigned index) const {
/// IntegerRelation.
void PresburgerRelation::unionInPlace(const IntegerRelation &disjunct) {
assert(space.isCompatible(disjunct.getSpace()) && "Spaces should match");
- disjuncts.push_back(disjunct);
+ disjuncts.emplace_back(disjunct);
}
/// Mutate this set, turning it into the union of this set and the given set.
@@ -121,8 +121,8 @@ PresburgerRelation::unionSet(const PresburgerRelation &set) const {
/// A point is contained in the union iff any of the parts contain the point.
bool PresburgerRelation::containsPoint(ArrayRef<DynamicAPInt> point) const {
- return llvm::any_of(disjuncts, [&](const IntegerRelation &disjunct) {
- return (disjunct.containsPointNoLocal(point));
+ return llvm::any_of(disjuncts, [&point](const IntegerRelation &disjunct) {
+ return disjunct.containsPointNoLocal(point);
});
}
@@ -376,6 +376,15 @@ static PresburgerRelation getSetDifference(IntegerRelation b,
// The index of the last inequality that was processed at this level.
// This is empty when we are coming to this level for the first time.
std::optional<unsigned> lastIneqProcessed;
+
+ // Convenience constructor.
+ Frame(unsigned simplexSnapshot,
+ const IntegerRelation::CountsSnapshot &bCounts,
+ const IntegerRelation &sI, ArrayRef<unsigned> ineqsToProcess = {},
+ std::optional<unsigned> lastIneqProcessed = std::nullopt)
+ : simplexSnapshot(simplexSnapshot), bCounts(bCounts), sI(sI),
+ ineqsToProcess(ineqsToProcess), lastIneqProcessed(lastIneqProcessed) {
+ }
};
SmallVector<Frame, 2> frames;
@@ -489,9 +498,7 @@ static PresburgerRelation getSetDifference(IntegerRelation b,
//
// TODO: consider supporting tail recursion directly if this becomes
// relevant for performance.
- frames.push_back(Frame{initialSnapshot, initBCounts, sI,
- /*ineqsToProcess=*/{},
- /*lastIneqProcessed=*/{}});
+ frames.emplace_back(Frame{initialSnapshot, initBCounts, sI});
++level;
continue;
}
@@ -521,7 +528,7 @@ static PresburgerRelation getSetDifference(IntegerRelation b,
ineqsToProcess.reserve(totalNewSimplexInequalities);
for (unsigned i = 0; i < totalNewSimplexInequalities; ++i)
if (!canIgnoreIneq[i])
- ineqsToProcess.push_back(i);
+ ineqsToProcess.emplace_back(i);
if (ineqsToProcess.empty()) {
// Nothing to process; return. (we have no frame to pop.)
@@ -531,8 +538,7 @@ static PresburgerRelation getSetDifference(IntegerRelation b,
unsigned simplexSnapshot = simplex.getSnapshot();
IntegerRelation::CountsSnapshot bCounts = b.getCounts();
- frames.push_back(Frame{simplexSnapshot, bCounts, sI, ineqsToProcess,
- /*lastIneqProcessed=*/std::nullopt});
+ frames.emplace_back(Frame{simplexSnapshot, bCounts, sI, ineqsToProcess});
// We have completed the initial setup for this level.
// Fallthrough to the main recursive part below.
}
@@ -796,7 +802,7 @@ SetCoalescer::SetCoalescer(const PresburgerRelation &s) : space(s.getSpace()) {
continue;
}
++i;
- simplices.push_back(simp);
+ simplices.emplace_back(simp);
}
}
@@ -928,9 +934,9 @@ LogicalResult SetCoalescer::typeInequality(ArrayRef<DynamicAPInt> ineq,
Simplex &simp) {
Simplex::IneqType type = simp.findIneqType(ineq);
if (type == Simplex::IneqType::Redundant)
- redundantIneqsB.push_back(ineq);
+ redundantIneqsB.emplace_back(ineq);
else if (type == Simplex::IneqType::Cut)
- cuttingIneqsB.push_back(ineq);
+ cuttingIneqsB.emplace_back(ineq);
else
return failure();
return success();
@@ -940,7 +946,7 @@ LogicalResult SetCoalescer::typeEquality(ArrayRef<DynamicAPInt> eq,
Simplex &simp) {
if (typeInequality(eq, simp).failed())
return failure();
- negEqs.push_back(getNegatedCoeffs(eq));
+ negEqs.emplace_back(getNegatedCoeffs(eq));
ArrayRef<DynamicAPInt> inv(negEqs.back());
return typeInequality(inv, simp);
}
@@ -1038,7 +1044,7 @@ PresburgerRelation PresburgerRelation::simplify() const {
}
bool PresburgerRelation::isFullDim() const {
- return llvm::any_of(getAllDisjuncts(), [&](IntegerRelation disjunct) {
+ return llvm::any_of(getAllDisjuncts(), [](IntegerRelation disjunct) {
return disjunct.isFullDim();
});
}
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index 85cb56e8a1136..940a28f0ca006 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -14,8 +14,8 @@ using namespace mlir;
using namespace presburger;
QuasiPolynomial::QuasiPolynomial(
- unsigned numVars, SmallVector<Fraction> coeffs,
- std::vector<std::vector<SmallVector<Fraction>>> aff)
+ unsigned numVars, ArrayRef<Fraction> coeffs,
+ ArrayRef<std::vector<SmallVector<Fraction>>> aff)
: PresburgerSpace(/*numDomain=*/numVars, /*numRange=*/1, /*numSymbols=*/0,
/*numLocals=*/0),
coefficients(coeffs), affine(aff) {
@@ -36,7 +36,7 @@ QuasiPolynomial::QuasiPolynomial(
}
/// Define a quasipolynomial which is a single constant.
-QuasiPolynomial::QuasiPolynomial(unsigned numVars, Fraction constant)
+QuasiPolynomial::QuasiPolynomial(unsigned numVars, const Fraction &constant)
: PresburgerSpace(/*numDomain=*/numVars, /*numRange=*/1, /*numSymbols=*/0,
/*numLocals=*/0),
coefficients({constant}), affine({{}}) {}
@@ -71,7 +71,7 @@ QuasiPolynomial QuasiPolynomial::operator*(const QuasiPolynomial &x) const {
coeffs.reserve(coefficients.size() * x.coefficients.size());
for (const Fraction &coeff : coefficients)
for (const Fraction &xcoeff : x.coefficients)
- coeffs.push_back(coeff * xcoeff);
+ coeffs.emplace_back(coeff * xcoeff);
std::vector<SmallVector<Fraction>> product;
std::vector<std::vector<SmallVector<Fraction>>> aff;
@@ -81,14 +81,14 @@ QuasiPolynomial QuasiPolynomial::operator*(const QuasiPolynomial &x) const {
product.clear();
product.insert(product.end(), term.begin(), term.end());
product.insert(product.end(), xterm.begin(), xterm.end());
- aff.push_back(product);
+ aff...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/97897
More information about the Mlir-commits
mailing list