[Mlir-commits] [mlir] mlir/Presburger: optimize to avoid creating copies (PR #97897)

Ramkumar Ramachandra llvmlistbot at llvm.org
Sat Jul 6 06:45:24 PDT 2024


https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/97897

Optimize the Presburger library to avoid unnecessarily creating copies. While at it, fix some other minor issues in the codebase.

>From 29e9baac8ad52c5e0daaf5898447e2061cfde3f8 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Sat, 6 Jul 2024 14:26:05 +0100
Subject: [PATCH] mlir/Presburger: optimize to avoid creating copies

Optimize the Presburger library to avoid unnecessarily creating copies.
While at it, fix some other minor issues in the codebase.
---
 .../Analysis/Presburger/QuasiPolynomial.h     | 10 +--
 mlir/lib/Analysis/Presburger/Barvinok.cpp     | 41 +++++-----
 .../Analysis/Presburger/IntegerRelation.cpp   | 30 ++++----
 .../Analysis/Presburger/LinearTransform.cpp   |  4 +-
 mlir/lib/Analysis/Presburger/PWMAFunction.cpp |  6 +-
 .../Presburger/PresburgerRelation.cpp         | 34 +++++----
 .../Analysis/Presburger/QuasiPolynomial.cpp   | 26 +++----
 mlir/lib/Analysis/Presburger/Simplex.cpp      | 74 ++++++++++---------
 mlir/lib/Analysis/Presburger/Utils.cpp        |  9 +--
 9 files changed, 123 insertions(+), 111 deletions(-)

diff --git a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
index aeac19e827b44f..5a0962df89d37a 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 dae840e00ff2e2..fad4364391d569 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 095a7dcb287f3c..bdcb55251b1041 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 cccbf4c9991d3c..1e389ca69e4e8e 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 f78eb7d2d98ceb..beb9f3e82e22d3 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 e284ca82420bac..239ffe6aaaa764 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 85cb56e8a11366..940a28f0ca0068 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.emplace_back(product);
     }
   }
 
   return QuasiPolynomial(getNumInputs(), coeffs, aff);
 }
 
-QuasiPolynomial QuasiPolynomial::operator/(const Fraction x) const {
+QuasiPolynomial QuasiPolynomial::operator/(const Fraction &x) const {
   assert(x != 0 && "division by zero!");
   QuasiPolynomial qp(*this);
   for (Fraction &coeff : qp.coefficients)
@@ -130,15 +130,15 @@ QuasiPolynomial QuasiPolynomial::simplify() {
     newCoeff = coefficients[i];
     for (ArrayRef<Fraction> term : affine[i]) {
       bool allCoeffsZero = llvm::all_of(
-          term.slice(0, numParam), [](const Fraction c) { return c == 0; });
+          term.slice(0, numParam), [](const Fraction &c) { return c == 0; });
       if (allCoeffsZero)
         newCoeff *= term[numParam];
       else
-        newAffineTerm.push_back(SmallVector<Fraction>(term));
+        newAffineTerm.emplace_back(term);
     }
 
-    newCoeffs.push_back(newCoeff);
-    newAffine.push_back(newAffineTerm);
+    newCoeffs.emplace_back(newCoeff);
+    newAffine.emplace_back(newAffineTerm);
   }
   return QuasiPolynomial(getNumInputs(), newCoeffs, newAffine);
 }
@@ -157,8 +157,8 @@ QuasiPolynomial QuasiPolynomial::collectTerms() {
     }
     if (alreadyPresent)
       continue;
-    newCoeffs.push_back(coefficients[i]);
-    newAffine.push_back(affine[i]);
+    newCoeffs.emplace_back(coefficients[i]);
+    newAffine.emplace_back(affine[i]);
   }
 
   return QuasiPolynomial(getNumInputs(), newCoeffs, newAffine);
@@ -167,7 +167,7 @@ QuasiPolynomial QuasiPolynomial::collectTerms() {
 Fraction QuasiPolynomial::getConstantTerm() {
   Fraction constTerm = 0;
   for (unsigned i = 0, e = coefficients.size(); i < e; ++i)
-    if (affine[i].size() == 0)
+    if (affine[i].empty())
       constTerm += coefficients[i];
   return constTerm;
 }
diff --git a/mlir/lib/Analysis/Presburger/Simplex.cpp b/mlir/lib/Analysis/Presburger/Simplex.cpp
index bebbf0325f430c..7c8a019557132a 100644
--- a/mlir/lib/Analysis/Presburger/Simplex.cpp
+++ b/mlir/lib/Analysis/Presburger/Simplex.cpp
@@ -12,6 +12,7 @@
 #include "mlir/Analysis/Presburger/Matrix.h"
 #include "mlir/Analysis/Presburger/PresburgerSpace.h"
 #include "mlir/Analysis/Presburger/Utils.h"
+#include "llvm/ADT/DynamicAPInt.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
@@ -42,18 +43,20 @@ scaleAndAddForAssert(ArrayRef<DynamicAPInt> a, const DynamicAPInt &scale,
   SmallVector<DynamicAPInt, 8> res;
   res.reserve(a.size());
   for (unsigned i = 0, e = a.size(); i < e; ++i)
-    res.push_back(a[i] + scale * b[i]);
+    res.emplace_back(a[i] + scale * b[i]);
   return res;
 }
 
 SimplexBase::SimplexBase(unsigned nVar, bool mustUseBigM)
     : usingBigM(mustUseBigM), nRedundant(0), nSymbol(0),
       tableau(0, getNumFixedCols() + nVar), empty(false) {
+  var.reserve(nVar);
+  colUnknown.reserve(nVar + 1);
   colUnknown.insert(colUnknown.begin(), getNumFixedCols(), nullIndex);
   for (unsigned i = 0; i < nVar; ++i) {
     var.emplace_back(Orientation::Column, /*restricted=*/false,
                      /*pos=*/getNumFixedCols() + i);
-    colUnknown.push_back(i);
+    colUnknown.emplace_back(i);
   }
 }
 
@@ -105,9 +108,9 @@ unsigned SimplexBase::addZeroRow(bool makeRestricted) {
   // Resize the tableau to accommodate the extra row.
   unsigned newRow = tableau.appendExtraRow();
   assert(getNumRows() == getNumRows() && "Inconsistent tableau size");
-  rowUnknown.push_back(~con.size());
+  rowUnknown.emplace_back(~con.size());
   con.emplace_back(Orientation::Row, makeRestricted, newRow);
-  undoLog.push_back(UndoLogEntry::RemoveLastConstraint);
+  undoLog.emplace_back(UndoLogEntry::RemoveLastConstraint);
   tableau(newRow, 0) = 1;
   return newRow;
 }
@@ -346,8 +349,8 @@ SymbolicLexSimplex::getSymbolicSampleNumerator(unsigned row) const {
   SmallVector<DynamicAPInt, 8> sample;
   sample.reserve(nSymbol + 1);
   for (unsigned col = 3; col < 3 + nSymbol; ++col)
-    sample.push_back(tableau(row, col));
-  sample.push_back(tableau(row, 1));
+    sample.emplace_back(tableau(row, col));
+  sample.emplace_back(tableau(row, 1));
   return sample;
 }
 
@@ -426,8 +429,8 @@ LogicalResult SymbolicLexSimplex::addSymbolicCut(unsigned row) {
   divCoeffs.reserve(nSymbol + 1);
   DynamicAPInt divDenom = d;
   for (unsigned col = 3; col < 3 + nSymbol; ++col)
-    divCoeffs.push_back(mod(-tableau(row, col), divDenom)); // (-a_i%d)s_i
-  divCoeffs.push_back(mod(-tableau(row, 1), divDenom));     // -c%d.
+    divCoeffs.emplace_back(mod(-tableau(row, col), divDenom)); // (-a_i%d)s_i
+  divCoeffs.emplace_back(mod(-tableau(row, 1), divDenom));     // -c%d.
   normalizeDiv(divCoeffs, divDenom);
 
   domainSimplex.addDivisionVariable(divCoeffs, divDenom);
@@ -619,8 +622,8 @@ SymbolicLexOpt SymbolicLexSimplex::computeSymbolicIntegerLexMin() {
         // reallocated.
         int splitIndex = rowUnknown[splitRow];
         unsigned snapshot = getSnapshot();
-        stack.push_back(
-            {splitIndex, snapshot, domainSnapshot, domainPolyCounts});
+        stack.emplace_back(
+            StackFrame{splitIndex, snapshot, domainSnapshot, domainPolyCounts});
         ++level;
         continue;
       }
@@ -1093,7 +1096,7 @@ void SimplexBase::markEmpty() {
   // non-empty when rolling back past this point.
   if (empty)
     return;
-  undoLog.push_back(UndoLogEntry::UnmarkEmpty);
+  undoLog.emplace_back(UndoLogEntry::UnmarkEmpty);
   empty = true;
 }
 
@@ -1120,6 +1123,7 @@ void Simplex::addInequality(ArrayRef<DynamicAPInt> coeffs) {
 void SimplexBase::addEquality(ArrayRef<DynamicAPInt> coeffs) {
   addInequality(coeffs);
   SmallVector<DynamicAPInt, 8> negatedCoeffs;
+  negatedCoeffs.reserve(coeffs.size());
   for (const DynamicAPInt &coeff : coeffs)
     negatedCoeffs.emplace_back(-coeff);
   addInequality(negatedCoeffs);
@@ -1134,11 +1138,12 @@ unsigned SimplexBase::getSnapshot() const { return undoLog.size(); }
 
 unsigned SimplexBase::getSnapshotBasis() {
   SmallVector<int, 8> basis;
+  basis.reserve(colUnknown.size());
   for (int index : colUnknown) {
     if (index != nullIndex)
-      basis.push_back(index);
+      basis.emplace_back(index);
   }
-  savedBases.push_back(std::move(basis));
+  savedBases.emplace_back(std::move(basis));
 
   undoLog.emplace_back(UndoLogEntry::RestoreBasis);
   return undoLog.size() - 1;
@@ -1304,7 +1309,7 @@ void SimplexBase::addDivisionVariable(ArrayRef<DynamicAPInt> coeffs,
   SmallVector<DynamicAPInt, 8> ineq(coeffs.begin(), coeffs.end());
   DynamicAPInt constTerm = ineq.back();
   ineq.back() = -denom;
-  ineq.push_back(constTerm);
+  ineq.emplace_back(constTerm);
   addInequality(ineq);
 
   for (DynamicAPInt &coeff : ineq)
@@ -1321,7 +1326,7 @@ void SimplexBase::appendVariable(unsigned count) {
   for (unsigned i = 0; i < count; ++i) {
     var.emplace_back(Orientation::Column, /*restricted=*/false,
                      /*pos=*/getNumColumns() + i);
-    colUnknown.push_back(var.size() - 1);
+    colUnknown.emplace_back(var.size() - 1);
   }
   tableau.resizeHorizontally(getNumColumns() + count);
   undoLog.insert(undoLog.end(), count, UndoLogEntry::RemoveLastVariable);
@@ -1516,12 +1521,12 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
 
   result.colUnknown.assign(2, nullIndex);
   for (unsigned i = 2, e = a.getNumColumns(); i < e; ++i) {
-    result.colUnknown.push_back(a.colUnknown[i]);
+    result.colUnknown.emplace_back(a.colUnknown[i]);
     result.unknownFromIndex(result.colUnknown.back()).pos =
         result.colUnknown.size() - 1;
   }
   for (unsigned i = 2, e = b.getNumColumns(); i < e; ++i) {
-    result.colUnknown.push_back(indexFromBIndex(b.colUnknown[i]));
+    result.colUnknown.emplace_back(indexFromBIndex(b.colUnknown[i]));
     result.unknownFromIndex(result.colUnknown.back()).pos =
         result.colUnknown.size() - 1;
   }
@@ -1530,7 +1535,7 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
     unsigned resultRow = result.tableau.appendExtraRow();
     for (unsigned col = 0, e = a.getNumColumns(); col < e; ++col)
       result.tableau(resultRow, col) = a.tableau(row, col);
-    result.rowUnknown.push_back(a.rowUnknown[row]);
+    result.rowUnknown.emplace_back(a.rowUnknown[row]);
     result.unknownFromIndex(result.rowUnknown.back()).pos =
         result.rowUnknown.size() - 1;
   };
@@ -1545,7 +1550,7 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
     unsigned offset = a.getNumColumns() - 2;
     for (unsigned col = 2, e = b.getNumColumns(); col < e; ++col)
       result.tableau(resultRow, offset + col) = b.tableau(row, col);
-    result.rowUnknown.push_back(indexFromBIndex(b.rowUnknown[row]));
+    result.rowUnknown.emplace_back(indexFromBIndex(b.rowUnknown[row]));
     result.unknownFromIndex(result.rowUnknown.back()).pos =
         result.rowUnknown.size() - 1;
   };
@@ -1632,7 +1637,7 @@ Simplex::getSamplePointIfIntegral() const {
     // If the sample is non-integral, return std::nullopt.
     if (coord.num % coord.den != 0)
       return {};
-    integerSample.push_back(coord.num / coord.den);
+    integerSample.emplace_back(coord.num / coord.den);
   }
   return integerSample;
 }
@@ -1661,7 +1666,7 @@ class presburger::GBRSimplex {
   void addEqualityForDirection(ArrayRef<DynamicAPInt> dir) {
     assert(llvm::any_of(dir, [](const DynamicAPInt &x) { return x != 0; }) &&
            "Direction passed is the zero vector!");
-    snapshotStack.push_back(simplex.getSnapshot());
+    snapshotStack.emplace_back(simplex.getSnapshot());
     simplex.addEquality(getCoeffsForDirection(dir));
   }
   /// Compute max(dotProduct(dir, x - y)).
@@ -1691,6 +1696,7 @@ class presburger::GBRSimplex {
     assert(maybeWidth.isBounded() && "Width should be bounded!");
     dualDenom = simplex.tableau(row, 0);
     dual.clear();
+    dual.reserve((conIndex - simplexConstraintOffset) / 2);
 
     // The increment is i += 2 because equalities are added as two inequalities,
     // one positive and one negative. Each iteration processes one equality.
@@ -1715,14 +1721,14 @@ class presburger::GBRSimplex {
       // Note that it is NOT valid to perform pivots during the computation of
       // the duals. This entire dual computation must be performed on the same
       // tableau configuration.
-      assert(!(simplex.con[i].orientation == Orientation::Column &&
-               simplex.con[i + 1].orientation == Orientation::Column) &&
+      assert((simplex.con[i].orientation != Orientation::Column ||
+              simplex.con[i + 1].orientation != Orientation::Column) &&
              "Both inequalities for the equality cannot be in column "
              "orientation!");
       if (simplex.con[i].orientation == Orientation::Column)
-        dual.push_back(-simplex.tableau(row, simplex.con[i].pos));
+        dual.emplace_back(-simplex.tableau(row, simplex.con[i].pos));
       else if (simplex.con[i + 1].orientation == Orientation::Column)
-        dual.push_back(simplex.tableau(row, simplex.con[i + 1].pos));
+        dual.emplace_back(simplex.tableau(row, simplex.con[i + 1].pos));
       else
         dual.emplace_back(0);
     }
@@ -1749,9 +1755,9 @@ class presburger::GBRSimplex {
     assert(2 * dir.size() == simplex.getNumVariables() &&
            "Direction vector has wrong dimensionality");
     SmallVector<DynamicAPInt, 8> coeffs(dir.begin(), dir.end());
-    coeffs.reserve(2 * dir.size());
+    coeffs.reserve(dir.size() + 1);
     for (const DynamicAPInt &coeff : dir)
-      coeffs.push_back(-coeff);
+      coeffs.emplace_back(-coeff);
     coeffs.emplace_back(0); // constant term
     return coeffs;
   }
@@ -1921,7 +1927,7 @@ void Simplex::reduceBasis(IntMatrix &basis, unsigned level) {
       // because this case should only occur when i is level, and there are no
       // duals in that case anyway.
       assert(i == level && "This case should only occur when i == level");
-      width.push_back(
+      width.emplace_back(
           gbrSimplex.computeWidthAndDuals(basis.getRow(i), dual, dualDenom));
     }
 
@@ -1930,8 +1936,8 @@ void Simplex::reduceBasis(IntMatrix &basis, unsigned level) {
              "We don't know dual_i but we know width_{i+1}");
       // We don't know dual for our level, so let's find it.
       gbrSimplex.addEqualityForDirection(basis.getRow(i));
-      width.push_back(gbrSimplex.computeWidthAndDuals(basis.getRow(i + 1), dual,
-                                                      dualDenom));
+      width.emplace_back(gbrSimplex.computeWidthAndDuals(basis.getRow(i + 1),
+                                                         dual, dualDenom));
       gbrSimplex.removeLastEquality();
     }
 
@@ -2056,12 +2062,12 @@ std::optional<SmallVector<DynamicAPInt, 8>> Simplex::findIntegerSample() {
             computeIntegerBounds(basisCoeffs);
       }
 
-      snapshotStack.push_back(getSnapshot());
+      snapshotStack.emplace_back(getSnapshot());
       // The smallest value in the range is the next value to try.
       // The values in the optionals are guaranteed to exist since we know the
       // polytope is bounded.
-      nextValueStack.push_back(*minRoundedUp);
-      upperBoundStack.push_back(*maxRoundedDown);
+      nextValueStack.emplace_back(*minRoundedUp);
+      upperBoundStack.emplace_back(*maxRoundedDown);
     }
 
     assert((snapshotStack.size() - 1 == level &&
@@ -2088,7 +2094,7 @@ std::optional<SmallVector<DynamicAPInt, 8>> Simplex::findIntegerSample() {
     // Try the next value in the range and "recurse" into the next level.
     SmallVector<DynamicAPInt, 8> basisCoeffs(basis.getRow(level).begin(),
                                              basis.getRow(level).end());
-    basisCoeffs.push_back(-nextValue);
+    basisCoeffs.emplace_back(-nextValue);
     addEquality(basisCoeffs);
     level++;
   }
diff --git a/mlir/lib/Analysis/Presburger/Utils.cpp b/mlir/lib/Analysis/Presburger/Utils.cpp
index 9b32972de2e0a2..1a854e8805862b 100644
--- a/mlir/lib/Analysis/Presburger/Utils.cpp
+++ b/mlir/lib/Analysis/Presburger/Utils.cpp
@@ -33,7 +33,7 @@ using llvm::dynamicAPIntFromInt64;
 static void normalizeDivisionByGCD(MutableArrayRef<DynamicAPInt> dividend,
                                    DynamicAPInt &divisor) {
   assert(divisor > 0 && "divisor must be non-negative!");
-  if (divisor == 0 || dividend.empty())
+  if (dividend.empty())
     return;
   // We take the absolute value of dividend's coefficients to make sure that
   // `gcd` is positive.
@@ -554,8 +554,7 @@ std::vector<Fraction> presburger::multiplyPolynomials(ArrayRef<Fraction> a,
   auto getCoeff = [](ArrayRef<Fraction> arr, unsigned i) -> Fraction {
     if (i < arr.size())
       return arr[i];
-    else
-      return 0;
+    return 0;
   };
 
   std::vector<Fraction> convolution;
@@ -564,11 +563,11 @@ std::vector<Fraction> presburger::multiplyPolynomials(ArrayRef<Fraction> a,
     Fraction sum(0, 1);
     for (unsigned l = 0; l <= k; ++l)
       sum += getCoeff(a, l) * getCoeff(b, k - l);
-    convolution.push_back(sum);
+    convolution.emplace_back(sum);
   }
   return convolution;
 }
 
 bool presburger::isRangeZero(ArrayRef<Fraction> arr) {
-  return llvm::all_of(arr, [&](Fraction f) { return f == 0; });
+  return llvm::all_of(arr, [](const Fraction &f) { return f == 0; });
 }



More information about the Mlir-commits mailing list