Skip to content
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

mlir/Presburger: optimize to avoid creating copies #97897

Merged
merged 1 commit into from
Jul 15, 2024

Conversation

artagnon
Copy link
Contributor

@artagnon artagnon commented Jul 6, 2024

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

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

llvmbot commented Jul 6, 2024

@llvm/pr-subscribers-mlir-presburger

Author: Ramkumar Ramachandra (artagnon)

Changes

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 --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]

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 6, 2024

@llvm/pr-subscribers-mlir

Author: Ramkumar Ramachandra (artagnon)

Changes

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 --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]

@artagnon artagnon merged commit 266a5a9 into llvm:main Jul 15, 2024
10 checks passed
@artagnon artagnon deleted the presburger-copyoptz branch July 15, 2024 18:42
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
Optimize the Presburger library to avoid unnecessarily creating copies.
While at it, fix some other minor issues in the codebase.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251672
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants