[Mlir-commits] [mlir] [WIP][MLIR][Presburger] Fix a bunch of minor style choices etc. (PR #82782)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Feb 23 08:12:20 PST 2024


https://github.com/Abhinav271828 created https://github.com/llvm/llvm-project/pull/82782

* Use range-style for-loops
* Use `int` instead of `unsigned`
* Define and use `+=` for QuasiPolynomials
* Use "numSymbols" instead of "numParams"

>From 2036fca61ef57c39db2e2aebe1d0c3d2d86bfb8d Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Fri, 16 Feb 2024 22:54:44 +0530
Subject: [PATCH 1/6] Change loop format

---
 .../Analysis/Presburger/GeneratingFunction.h  | 11 ++--
 mlir/lib/Analysis/Presburger/Barvinok.cpp     | 53 +++++++++----------
 mlir/lib/Analysis/Presburger/Matrix.cpp       | 43 +++++++--------
 .../Analysis/Presburger/QuasiPolynomial.cpp   |  9 ++--
 mlir/lib/Analysis/Presburger/Utils.cpp        |  7 +--
 .../Analysis/Presburger/BarvinokTest.cpp      | 12 ++---
 .../Analysis/Presburger/MatrixTest.cpp        | 18 +++----
 mlir/unittests/Analysis/Presburger/Utils.h    | 36 ++++++-------
 8 files changed, 96 insertions(+), 93 deletions(-)

diff --git a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
index db5b6b6a959186..e90a991d5c4809 100644
--- a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
+++ b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
@@ -16,6 +16,7 @@
 
 #include "mlir/Analysis/Presburger/Fraction.h"
 #include "mlir/Analysis/Presburger/Matrix.h"
+#include "llvm/ADT/Sequence.h"
 
 namespace mlir {
 namespace presburger {
@@ -91,7 +92,7 @@ class GeneratingFunction {
   }
 
   llvm::raw_ostream &print(llvm::raw_ostream &os) const {
-    for (unsigned i = 0, e = signs.size(); i < e; i++) {
+    for (int i : llvm::seq<int>(0, signs.size())) {
       if (i == 0) {
         if (signs[i] == -1)
           os << "- ";
@@ -104,20 +105,20 @@ class GeneratingFunction {
 
       os << "x^[";
       unsigned r = numerators[i].getNumRows();
-      for (unsigned j = 0; j < r - 1; j++) {
+      for (unsigned j = 0; j < r - 1; ++j) {
         os << "[";
-        for (unsigned k = 0, c = numerators[i].getNumColumns(); k < c - 1; k++)
+        for (int k : llvm::seq<int>(0, numerators[i].getNumColumns() - 1))
           os << numerators[i].at(j, k) << ",";
         os << numerators[i].getRow(j).back() << "],";
       }
       os << "[";
-      for (unsigned k = 0, c = numerators[i].getNumColumns(); k < c - 1; k++)
+      for (int k : llvm::seq<int>(0, numerators[i].getNumColumns() - 1))
         os << numerators[i].at(r - 1, k) << ",";
       os << numerators[i].getRow(r - 1).back() << "]]/";
 
       for (const Point &den : denominators[i]) {
         os << "(x^[";
-        for (unsigned j = 0, e = den.size(); j < e - 1; j++)
+        for (int j : llvm::seq<int>(0, den.size() - 1))
           os << den[j] << ",";
         os << den.back() << "])";
       }
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index b6d1f99df8ba55..c483b9a4b81f37 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -28,12 +28,10 @@ ConeV mlir::presburger::detail::getDual(ConeH cone) {
   // is represented as a row [a1, ..., an, b]
   // and that b = 0.
 
-  for (auto i : llvm::seq<int>(0, numIneq)) {
+  for (int i : llvm::seq<int>(0, numIneq)) {
     assert(cone.atIneq(i, numVar) == 0 &&
            "H-representation of cone is not centred at the origin!");
-    for (unsigned j = 0; j < numVar; ++j) {
-      dual.at(i, j) = cone.atIneq(i, j);
-    }
+    dual.setRow(i, cone.getInequality(i).take_front(numVar));
   }
 
   // Now dual is of the form [ [a1, ..., an] , ... ]
@@ -130,8 +128,8 @@ mlir::presburger::detail::computeUnimodularConeGeneratingFunction(
   unsigned numRows = vertex.getNumRows();
   ParamPoint numerator(numColumns, numRows);
   SmallVector<Fraction> ithCol(numRows);
-  for (auto i : llvm::seq<int>(0, numColumns)) {
-    for (auto j : llvm::seq<int>(0, numRows))
+  for (int i : llvm::seq<int>(0, numColumns)) {
+    for (int j : llvm::seq<int>(0, numRows))
       ithCol[j] = vertex(j, i);
     numerator.setRow(i, transp.preMultiplyWithRow(ithCol));
     numerator.negateRow(i);
@@ -176,12 +174,12 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
 
   // Perform row operations to make each column all zeros except for the
   // diagonal element, which is made to be one.
-  for (unsigned i = 0; i < d; ++i) {
+  for (int i : llvm::seq<int>(0, d)) {
     // First ensure that the diagonal element is nonzero, by swapping
     // it with a row that is non-zero at column i.
     if (equations(i, i) != 0)
       continue;
-    for (unsigned j = i + 1; j < d; ++j) {
+    for (int j : llvm::seq<int>(i + 1, d)) {
       if (equations(j, i) == 0)
         continue;
       equations.swapRows(j, i);
@@ -191,7 +189,7 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
     Fraction diagElement = equations(i, i);
 
     // Apply row operations to make all elements except the diagonal to zero.
-    for (unsigned j = 0; j < d; ++j) {
+    for (int j : llvm::seq<int>(0, d)) {
       if (i == j)
         continue;
       if (equations(j, i) == 0)
@@ -205,7 +203,7 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
   }
 
   // Rescale diagonal elements to 1.
-  for (unsigned i = 0; i < d; ++i)
+  for (int i : llvm::seq<int>(0, d))
     equations.scaleRow(i, 1 / equations(i, i));
 
   // Now we have reduced the equations to the form
@@ -332,7 +330,7 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
   //
   // We start with the permutation that takes the last numVars inequalities.
   SmallVector<int> indicator(numIneqs);
-  for (unsigned i = numIneqs - numVars; i < numIneqs; ++i)
+  for (int i : llvm::seq<int>(numIneqs - numVars, numIneqs))
     indicator[i] = 1;
 
   do {
@@ -393,7 +391,7 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
     // Thus we premultiply [X | y] with each row of A2
     // and add each row of [B2 | c2].
     FracMatrix activeRegion(numIneqs - numVars, numSymbols + 1);
-    for (unsigned i = 0; i < numIneqs - numVars; i++) {
+    for (int i : llvm::seq<int>(0, numIneqs - numVars)) {
       activeRegion.setRow(i, vertex->preMultiplyWithRow(a2.getRow(i)));
       activeRegion.addToRow(i, b2c2.getRow(i), 1);
     }
@@ -412,9 +410,9 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
     // We translate the cones to be pointed at the origin by making the
     // constant terms zero.
     ConeH tangentCone = defineHRep(numVars);
-    for (unsigned j = 0, e = subset.getNumRows(); j < e; ++j) {
+    for (int j : llvm::seq<int>(0, subset.getNumRows())) {
       SmallVector<MPInt> ineq(numVars + 1);
-      for (unsigned k = 0; k < numVars; ++k)
+      for (int k : llvm::seq<int>(0, numVars))
         ineq[k] = subset(j, k);
       tangentCone.addInequality(ineq);
     }
@@ -482,7 +480,7 @@ Point mlir::presburger::detail::getNonOrthogonalVector(
   Fraction maxDisallowedValue = -Fraction(1, 0),
            disallowedValue = Fraction(0, 1);
 
-  for (unsigned d = 1; d < dim; ++d) {
+  for (int d : llvm::seq<int>(1, dim)) {
     // Compute the disallowed values  - <x_i[:d-1], vs> / x_i[d] for each i.
     maxDisallowedValue = -Fraction(1, 0);
     for (const Point &vector : vectors) {
@@ -530,7 +528,7 @@ QuasiPolynomial mlir::presburger::detail::getCoefficientInRationalFunction(
   coefficients.reserve(power + 1);
 
   coefficients.push_back(num[0] / den[0]);
-  for (unsigned i = 1; i <= power; ++i) {
+  for (unsigned i : llvm::seq<int>(1, power + 1)) {
     // If the power is not there in the numerator, the coefficient is zero.
     coefficients.push_back(i < num.size() ? num[i]
                                           : QuasiPolynomial(numParam, 0));
@@ -538,7 +536,7 @@ QuasiPolynomial mlir::presburger::detail::getCoefficientInRationalFunction(
     // After den.size(), the coefficients are zero, so we stop
     // subtracting at that point (if it is less than i).
     unsigned limit = std::min<unsigned long>(i, den.size() - 1);
-    for (unsigned j = 1; j <= limit; ++j)
+    for (int j : llvm::seq<int>(1, limit + 1))
       coefficients[i] = coefficients[i] -
                         coefficients[i - j] * QuasiPolynomial(numParam, den[j]);
 
@@ -582,7 +580,7 @@ substituteMuInTerm(unsigned numParams, ParamPoint v, std::vector<Point> ds,
   ParamPoint vTranspose = v.transpose();
   std::vector<std::vector<SmallVector<Fraction>>> affine;
   affine.reserve(numDims);
-  for (unsigned j = 0; j < numDims; ++j)
+  for (int j : llvm::seq<int>(0, numDims))
     affine.push_back({SmallVector<Fraction>(vTranspose.getRow(j))});
 
   QuasiPolynomial num(numParams, coefficients, affine);
@@ -613,10 +611,10 @@ void normalizeDenominatorExponents(int &sign, QuasiPolynomial &num,
   // denominator, and convert them to their absolute values.
   unsigned numNegExps = 0;
   Fraction sumNegExps(0, 1);
-  for (unsigned j = 0, e = dens.size(); j < e; ++j) {
-    if (dens[j] < 0) {
+  for (const Fraction &den : dens) {
+    if (den < 0) {
       numNegExps += 1;
-      sumNegExps += dens[j];
+      sumNegExps += den;
     }
   }
 
@@ -641,7 +639,7 @@ std::vector<QuasiPolynomial> getBinomialCoefficients(QuasiPolynomial n,
   std::vector<QuasiPolynomial> coefficients;
   coefficients.reserve(r + 1);
   coefficients.push_back(QuasiPolynomial(numParams, 1));
-  for (unsigned j = 1; j <= r; ++j)
+  for (int j : llvm::seq<int>(1, r + 1))
     // We use the recursive formula for binomial coefficients here and below.
     coefficients.push_back(
         (coefficients[j - 1] * (n - QuasiPolynomial(numParams, j - 1)) /
@@ -701,7 +699,7 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
   unsigned numParams = gf.getNumParams();
   const std::vector<std::vector<Point>> &ds = gf.getDenominators();
   QuasiPolynomial totalTerm(numParams, 0);
-  for (unsigned i = 0, e = ds.size(); i < e; ++i) {
+  for (int i : llvm::seq<int>(0, ds.size())) {
     int sign = gf.getSigns()[i];
 
     // Compute the new exponents of (s+1) for the numerator and the
@@ -722,7 +720,7 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
     // Then, using the formula for geometric series, we replace each (1 -
     // (s+1)^(dens[j])) with
     // (-s)(\sum_{0 ≤ k < dens[j]} (s+1)^k).
-    for (unsigned j = 0, e = dens.size(); j < e; ++j)
+    for (int j : llvm::seq<int>(0, dens.size()))
       dens[j] = abs(dens[j]) - 1;
     // Note that at this point, the semantics of `dens[j]` changes to mean
     // a term (\sum_{0 ≤ k ≤ dens[j]} (s+1)^k). The denominator is, as before,
@@ -774,9 +772,10 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
     // of all the terms.
     std::vector<Fraction> denominatorCoefficients;
     denominatorCoefficients = eachTermDenCoefficients[0];
-    for (unsigned j = 1, e = eachTermDenCoefficients.size(); j < e; ++j)
-      denominatorCoefficients = multiplyPolynomials(denominatorCoefficients,
-                                                    eachTermDenCoefficients[j]);
+    for (const std::vector<Fraction> &eachTermDenCoefficient :
+         eachTermDenCoefficients)
+      denominatorCoefficients =
+          multiplyPolynomials(denominatorCoefficients, eachTermDenCoefficient);
 
     totalTerm =
         totalTerm + getCoefficientInRationalFunction(r, numeratorCoefficients,
diff --git a/mlir/lib/Analysis/Presburger/Matrix.cpp b/mlir/lib/Analysis/Presburger/Matrix.cpp
index 4cb6e6b16bc878..76d4f61d1c0c2a 100644
--- a/mlir/lib/Analysis/Presburger/Matrix.cpp
+++ b/mlir/lib/Analysis/Presburger/Matrix.cpp
@@ -11,6 +11,7 @@
 #include "mlir/Analysis/Presburger/MPInt.h"
 #include "mlir/Analysis/Presburger/Utils.h"
 #include "mlir/Support/LLVM.h"
+#include "llvm/ADT/Sequence.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -38,7 +39,7 @@ bool Matrix<T>::operator==(const Matrix<T> &m) const {
   if (nColumns != m.getNumColumns())
     return false;
 
-  for (unsigned i = 0; i < nRows; i++)
+  for (int i : llvm::seq<int>(0, nRows))
     if (getRow(i) != m.getRow(i))
       return false;
 
@@ -392,8 +393,8 @@ Matrix<T> Matrix<T>::getSubMatrix(unsigned fromRow, unsigned toRow,
          "end of column range must be after beginning!");
   assert(toColumn < nColumns && "end of column range out of bounds!");
   Matrix<T> subMatrix(toRow - fromRow + 1, toColumn - fromColumn + 1);
-  for (unsigned i = fromRow; i <= toRow; ++i)
-    for (unsigned j = fromColumn; j <= toColumn; ++j)
+  for (int i : llvm::seq<int>(fromRow, toRow + 1))
+    for (int j : llvm::seq<int>(fromColumn, toColumn + 1))
       subMatrix(i - fromRow, j - fromColumn) = at(i, j);
   return subMatrix;
 }
@@ -413,7 +414,7 @@ template <typename T>
 std::pair<Matrix<T>, Matrix<T>>
 Matrix<T>::splitByBitset(ArrayRef<int> indicator) {
   Matrix<T> rowsForOne(0, nColumns), rowsForZero(0, nColumns);
-  for (unsigned i = 0; i < nRows; i++) {
+  for (int i : llvm::seq<int>(0, nRows)) {
     if (indicator[i] == 1)
       rowsForOne.appendExtraRow(getRow(i));
     else
@@ -566,8 +567,8 @@ MPInt IntMatrix::determinant(IntMatrix *inverse) const {
     return detM;
 
   *inverse = IntMatrix(nRows, nColumns);
-  for (unsigned i = 0; i < nRows; i++)
-    for (unsigned j = 0; j < nColumns; j++)
+  for (int i : llvm::seq<int>(0, nRows))
+    for (int j : llvm::seq<int>(0, nColumns))
       inverse->at(i, j) = (fracInverse.at(i, j) * detM).getAsInteger();
 
   return detM;
@@ -579,8 +580,8 @@ FracMatrix FracMatrix::identity(unsigned dimension) {
 
 FracMatrix::FracMatrix(IntMatrix m)
     : FracMatrix(m.getNumRows(), m.getNumColumns()) {
-  for (unsigned i = 0, r = m.getNumRows(); i < r; i++)
-    for (unsigned j = 0, c = m.getNumColumns(); j < c; j++)
+  for (int i : llvm::seq<int>(0, m.getNumRows()))
+    for (int j : llvm::seq<int>(0, m.getNumColumns()))
       this->at(i, j) = m.at(i, j);
 }
 
@@ -602,12 +603,12 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
   // which is initially identity.
   // Either way, the product of the diagonal elements
   // is then the determinant.
-  for (unsigned i = 0; i < nRows; i++) {
+  for (int i : llvm::seq<int>(0, nRows)) {
     if (m(i, i) == 0)
       // First ensure that the diagonal
       // element is nonzero, by swapping
       // it with a nonzero row.
-      for (unsigned j = i + 1; j < nRows; j++) {
+      for (int j : llvm::seq<int>(i + 1, nRows)) {
         if (m(j, i) != 0) {
           m.swapRows(j, i);
           if (inverse)
@@ -623,7 +624,7 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
     // Set all elements above the
     // diagonal to zero.
     if (inverse) {
-      for (unsigned j = 0; j < i; j++) {
+      for (int j : llvm::seq<int>(0, i)) {
         if (m.at(j, i) == 0)
           continue;
         a = m.at(j, i);
@@ -637,7 +638,7 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
 
     // Set all elements below the
     // diagonal to zero.
-    for (unsigned j = i + 1; j < nRows; j++) {
+    for (int j : llvm::seq<int>(i + 1, nRows)) {
       if (m.at(j, i) == 0)
         continue;
       a = m.at(j, i);
@@ -655,15 +656,15 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
   // normalize them and apply the same scale to the inverse matrix.
   // For efficiency we skip scaling m and just scale tempInv appropriately.
   if (inverse) {
-    for (unsigned i = 0; i < nRows; i++)
-      for (unsigned j = 0; j < nRows; j++)
+    for (int i : llvm::seq<int>(0, nRows))
+      for (int j : llvm::seq<int>(0, nRows))
         tempInv.at(i, j) = tempInv.at(i, j) / m(i, i);
 
     *inverse = std::move(tempInv);
   }
 
   Fraction determinant = 1;
-  for (unsigned i = 0; i < nRows; i++)
+  for (int i : llvm::seq<int>(0, nRows))
     determinant *= m.at(i, i);
 
   return determinant;
@@ -678,8 +679,8 @@ FracMatrix FracMatrix::gramSchmidt() const {
   // projection along each of the previous vectors.
   // This ensures that it has no component in the direction
   // of any of the previous vectors.
-  for (unsigned i = 1, e = getNumRows(); i < e; i++) {
-    for (unsigned j = 0; j < i; j++) {
+  for (int i : llvm::seq<int>(1, getNumRows())) {
+    for (int j : llvm::seq<int>(0, i)) {
       Fraction jNormSquared = dotProduct(orth.getRow(j), orth.getRow(j));
       assert(jNormSquared != 0 && "some row became zero! Inputs to this "
                                   "function must be linearly independent.");
@@ -730,7 +731,7 @@ void FracMatrix::LLL(Fraction delta) {
   // We start from the second row.
   unsigned k = 1;
   while (k < getNumRows()) {
-    for (unsigned j = k - 1; j < k; j--) {
+    for (int j : llvm::reverse(llvm::seq<int>(0, k))) {
       // Compute the Gram-Schmidt coefficient μ_jk.
       mu = dotProduct(getRow(k), gsOrth.getRow(j)) /
            dotProduct(gsOrth.getRow(j), gsOrth.getRow(j));
@@ -763,12 +764,12 @@ IntMatrix FracMatrix::normalizeRows() const {
   IntMatrix normalized(numRows, numColumns);
 
   MPInt lcmDenoms = MPInt(1);
-  for (unsigned i = 0; i < numRows; i++) {
+  for (int i : llvm::seq<int>(0, numRows)) {
     // For a row, first compute the LCM of the denominators.
-    for (unsigned j = 0; j < numColumns; j++)
+    for (int j : llvm::seq<int>(0, numColumns))
       lcmDenoms = lcm(lcmDenoms, at(i, j).den);
     // Then, multiply by it throughout and convert to integers.
-    for (unsigned j = 0; j < numColumns; j++)
+    for (int j : llvm::seq<int>(0, numColumns))
       normalized(i, j) = (at(i, j) * lcmDenoms).getAsInteger();
   }
   return normalized;
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index 4fd4886d22536d..673adba4fc8d61 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -10,6 +10,7 @@
 #include "mlir/Analysis/Presburger/Fraction.h"
 #include "mlir/Analysis/Presburger/PresburgerSpace.h"
 #include "mlir/Analysis/Presburger/Utils.h"
+#include "llvm/ADT/Sequence.h"
 
 using namespace mlir;
 using namespace presburger;
@@ -109,7 +110,7 @@ QuasiPolynomial QuasiPolynomial::simplify() {
 
   unsigned numParam = getNumInputs();
 
-  for (unsigned i = 0, e = coefficients.size(); i < e; i++) {
+  for (int i : llvm::seq<int>(0, coefficients.size())) {
     // A term is zero if its coefficient is zero, or
     if (coefficients[i] == Fraction(0, 1))
       continue;
@@ -148,9 +149,9 @@ QuasiPolynomial QuasiPolynomial::collectTerms() {
   SmallVector<Fraction> newCoeffs({});
   std::vector<std::vector<SmallVector<Fraction>>> newAffine({});
 
-  for (unsigned i = 0, e = affine.size(); i < e; i++) {
+  for (int i : llvm::seq<int>(0, affine.size())) {
     bool alreadyPresent = false;
-    for (unsigned j = 0, f = newAffine.size(); j < f; j++) {
+    for (int j : llvm::seq<int>(0, newAffine.size())) {
       if (affine[i] == newAffine[j]) {
         newCoeffs[j] += coefficients[i];
         alreadyPresent = true;
@@ -167,7 +168,7 @@ QuasiPolynomial QuasiPolynomial::collectTerms() {
 
 Fraction QuasiPolynomial::getConstantTerm() {
   Fraction constTerm = 0;
-  for (unsigned i = 0, e = coefficients.size(); i < e; ++i)
+  for (int i : llvm::seq<int>(0, coefficients.size()))
     if (affine[i].size() == 0)
       constTerm += coefficients[i];
   return constTerm;
diff --git a/mlir/lib/Analysis/Presburger/Utils.cpp b/mlir/lib/Analysis/Presburger/Utils.cpp
index f717a4de5d7283..ae4602f2690fb0 100644
--- a/mlir/lib/Analysis/Presburger/Utils.cpp
+++ b/mlir/lib/Analysis/Presburger/Utils.cpp
@@ -17,6 +17,7 @@
 #include "mlir/Support/LLVM.h"
 #include "mlir/Support/LogicalResult.h"
 #include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -534,7 +535,7 @@ Fraction presburger::dotProduct(ArrayRef<Fraction> a, ArrayRef<Fraction> b) {
   assert(a.size() == b.size() &&
          "dot product is only valid for vectors of equal sizes!");
   Fraction sum = 0;
-  for (unsigned i = 0, e = a.size(); i < e; i++)
+  for (int i : llvm::seq<int>(0, a.size()))
     sum += a[i] * b[i];
   return sum;
 }
@@ -557,9 +558,9 @@ std::vector<Fraction> presburger::multiplyPolynomials(ArrayRef<Fraction> a,
 
   std::vector<Fraction> convolution;
   convolution.reserve(len);
-  for (unsigned k = 0; k < len; ++k) {
+  for (int k : llvm::seq<int>(0, len)) {
     Fraction sum(0, 1);
-    for (unsigned l = 0; l <= k; ++l)
+    for (int l : llvm::seq<int>(0, k + 1))
       sum += getCoeff(a, l) * getCoeff(b, k - l);
     convolution.push_back(sum);
   }
diff --git a/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp b/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp
index 5e279b542fdf95..e3b081da85a0dd 100644
--- a/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp
@@ -93,7 +93,7 @@ TEST(BarvinokTest, getNonOrthogonalVector) {
                                 Point({2, 7, 0, 0}), Point({0, 0, 0, 0})};
   Point nonOrth = getNonOrthogonalVector(vectors);
 
-  for (unsigned i = 0; i < 3; i++)
+  for (unsigned i = 0; i < 3; ++i)
     EXPECT_NE(dotProduct(nonOrth, vectors[i]), 0);
 
   vectors = {Point({0, 1, 3}), Point({-2, -1, 1}), Point({6, 3, 0}),
@@ -160,7 +160,7 @@ TEST(BarvinokTest, computeNumTermsCone) {
   // terms with 1 affine function,
   Fraction pSquaredCoeff = 0, pCoeff = 0, constantTerm = 0;
   SmallVector<Fraction> coefficients = numPoints.getCoefficients();
-  for (unsigned i = 0; i < numPoints.getCoefficients().size(); i++)
+  for (int i : llvm::seq<int>(0, numPoints.getCoefficients().size()))
     if (numPoints.getAffine()[i].size() == 2)
       pSquaredCoeff = pSquaredCoeff + coefficients[i];
     else if (numPoints.getAffine()[i].size() == 1)
@@ -214,7 +214,7 @@ TEST(BarvinokTest, computeNumTermsCone) {
   // We store the coefficients of M, N and P in this array.
   Fraction count[2][2][2];
   coefficients = numPoints.getCoefficients();
-  for (unsigned i = 0, e = coefficients.size(); i < e; i++) {
+  for (int i : llvm::seq<int>(0, coefficients.size())) {
     unsigned mIndex = 0, nIndex = 0, pIndex = 0;
     for (const SmallVector<Fraction> &aff : numPoints.getAffine()[i]) {
       if (aff[0] == 1)
@@ -231,9 +231,9 @@ TEST(BarvinokTest, computeNumTermsCone) {
   // We expect the answer to be
   // (⌊M⌋ + 1)(⌊N⌋ + 1)(⌊P⌋ + 1) =
   // ⌊M⌋⌊N⌋⌊P⌋ + ⌊M⌋⌊N⌋ + ⌊N⌋⌊P⌋ + ⌊M⌋⌊P⌋ + ⌊M⌋ + ⌊N⌋ + ⌊P⌋ + 1.
-  for (unsigned i = 0; i < 2; i++)
-    for (unsigned j = 0; j < 2; j++)
-      for (unsigned k = 0; k < 2; k++)
+  for (unsigned i = 0; i < 2; ++i)
+    for (unsigned j = 0; j < 2; ++j)
+      for (unsigned k = 0; k < 2; ++k)
         EXPECT_EQ(count[i][j][k], 1);
 }
 
diff --git a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
index fa1f32970b1463..feda98d0b1817a 100644
--- a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
@@ -344,8 +344,8 @@ TEST(MatrixTest, gramSchmidt) {
   FracMatrix gs = mat.gramSchmidt();
 
   EXPECT_EQ_FRAC_MATRIX(gs, gramSchmidt);
-  for (unsigned i = 0; i < 3u; i++)
-    for (unsigned j = i + 1; j < 3u; j++)
+  for (unsigned i = 0; i < 3u; ++i)
+    for (unsigned j = i + 1; j < 3u; ++j)
       EXPECT_EQ(dotProduct(gs.getRow(i), gs.getRow(j)), 0);
 
   mat = makeFracMatrix(3, 3,
@@ -362,8 +362,8 @@ TEST(MatrixTest, gramSchmidt) {
   gs = mat.gramSchmidt();
 
   EXPECT_EQ_FRAC_MATRIX(gs, gramSchmidt);
-  for (unsigned i = 0; i < 3u; i++)
-    for (unsigned j = i + 1; j < 3u; j++)
+  for (unsigned i = 0; i < 3u; ++i)
+    for (unsigned j = i + 1; j < 3u; ++j)
       EXPECT_EQ(dotProduct(gs.getRow(i), gs.getRow(j)), 0);
 
   mat = makeFracMatrix(
@@ -379,8 +379,8 @@ TEST(MatrixTest, gramSchmidt) {
   // but we can check that the result is linearly independent.
   ASSERT_FALSE(mat.determinant(nullptr) == 0);
 
-  for (unsigned i = 0; i < 4u; i++)
-    for (unsigned j = i + 1; j < 4u; j++)
+  for (unsigned i = 0; i < 4u; ++i)
+    for (unsigned j = i + 1; j < 4u; ++j)
       EXPECT_EQ(dotProduct(gs.getRow(i), gs.getRow(j)), 0);
 
   mat = FracMatrix::identity(/*dim=*/10);
@@ -394,8 +394,8 @@ void checkReducedBasis(FracMatrix mat, Fraction delta) {
   FracMatrix gsOrth = mat.gramSchmidt();
 
   // Size-reduced check.
-  for (unsigned i = 0, e = mat.getNumRows(); i < e; i++) {
-    for (unsigned j = 0; j < i; j++) {
+  for (int i : llvm::seq<int>(0, mat.getNumRows())) {
+    for (int j : llvm::seq<int>(0, i)) {
       Fraction mu = dotProduct(mat.getRow(i), gsOrth.getRow(j)) /
                     dotProduct(gsOrth.getRow(j), gsOrth.getRow(j));
       EXPECT_TRUE(abs(mu) <= Fraction(1, 2));
@@ -403,7 +403,7 @@ void checkReducedBasis(FracMatrix mat, Fraction delta) {
   }
 
   // Lovasz condition check.
-  for (unsigned i = 1, e = mat.getNumRows(); i < e; i++) {
+  for (int i : llvm::seq<int>(1, mat.getNumRows())) {
     Fraction mu = dotProduct(mat.getRow(i), gsOrth.getRow(i - 1)) /
                   dotProduct(gsOrth.getRow(i - 1), gsOrth.getRow(i - 1));
     EXPECT_TRUE(dotProduct(mat.getRow(i), mat.getRow(i)) >
diff --git a/mlir/unittests/Analysis/Presburger/Utils.h b/mlir/unittests/Analysis/Presburger/Utils.h
index 6b00898a7e2749..26970b798953af 100644
--- a/mlir/unittests/Analysis/Presburger/Utils.h
+++ b/mlir/unittests/Analysis/Presburger/Utils.h
@@ -22,6 +22,7 @@
 #include "mlir/Analysis/Presburger/Simplex.h"
 #include "mlir/IR/MLIRContext.h"
 #include "mlir/Support/LLVM.h"
+#include "llvm/ADT/Sequence.h"
 
 #include <gtest/gtest.h>
 #include <optional>
@@ -33,10 +34,10 @@ inline IntMatrix makeIntMatrix(unsigned numRow, unsigned numColumns,
                                ArrayRef<SmallVector<int, 8>> matrix) {
   IntMatrix results(numRow, numColumns);
   assert(matrix.size() == numRow);
-  for (unsigned i = 0; i < numRow; ++i) {
+  for (int i : llvm::seq<int>(0, numRow)) {
     assert(matrix[i].size() == numColumns &&
            "Output expression has incorrect dimensionality!");
-    for (unsigned j = 0; j < numColumns; ++j)
+    for (int j : llvm::seq<int>(0, numColumns))
       results(i, j) = MPInt(matrix[i][j]);
   }
   return results;
@@ -46,10 +47,10 @@ inline FracMatrix makeFracMatrix(unsigned numRow, unsigned numColumns,
                                  ArrayRef<SmallVector<Fraction, 8>> matrix) {
   FracMatrix results(numRow, numColumns);
   assert(matrix.size() == numRow);
-  for (unsigned i = 0; i < numRow; ++i) {
+  for (int i : llvm::seq<int>(0, numRow)) {
     assert(matrix[i].size() == numColumns &&
            "Output expression has incorrect dimensionality!");
-    for (unsigned j = 0; j < numColumns; ++j)
+    for (int j : llvm::seq<int>(0, numColumns))
       results(i, j) = matrix[i][j];
   }
   return results;
@@ -59,8 +60,8 @@ inline void EXPECT_EQ_INT_MATRIX(IntMatrix a, IntMatrix b) {
   EXPECT_EQ(a.getNumRows(), b.getNumRows());
   EXPECT_EQ(a.getNumColumns(), b.getNumColumns());
 
-  for (unsigned row = 0; row < a.getNumRows(); row++)
-    for (unsigned col = 0; col < a.getNumColumns(); col++)
+  for (int row : llvm::seq<int>(0, a.getNumRows()))
+    for (int col : llvm::seq<int>(0, a.getNumColumns()))
       EXPECT_EQ(a(row, col), b(row, col));
 }
 
@@ -68,8 +69,8 @@ inline void EXPECT_EQ_FRAC_MATRIX(FracMatrix a, FracMatrix b) {
   EXPECT_EQ(a.getNumRows(), b.getNumRows());
   EXPECT_EQ(a.getNumColumns(), b.getNumColumns());
 
-  for (unsigned row = 0; row < a.getNumRows(); row++)
-    for (unsigned col = 0; col < a.getNumColumns(); col++)
+  for (int row : llvm::seq<int>(0, a.getNumRows()))
+    for (int col : llvm::seq<int>(0, a.getNumColumns()))
       EXPECT_EQ(a(row, col), b(row, col));
 }
 
@@ -82,25 +83,24 @@ inline void EXPECT_EQ_REPR_GENERATINGFUNCTION(detail::GeneratingFunction a,
   SmallVector<int> aSigns = a.getSigns();
   SmallVector<int> bSigns = b.getSigns();
   EXPECT_EQ(aSigns.size(), bSigns.size());
-  for (unsigned i = 0, e = aSigns.size(); i < e; i++)
+  for (int i : llvm::seq<int>(0, aSigns.size()))
     EXPECT_EQ(aSigns[i], bSigns[i]);
 
   std::vector<detail::ParamPoint> aNums = a.getNumerators();
   std::vector<detail::ParamPoint> bNums = b.getNumerators();
   EXPECT_EQ(aNums.size(), bNums.size());
-  for (unsigned i = 0, e = aNums.size(); i < e; i++)
+  for (int i : llvm::seq<int>(0, aNums.size()))
     EXPECT_EQ_FRAC_MATRIX(aNums[i], bNums[i]);
 
   std::vector<std::vector<detail::Point>> aDens = a.getDenominators();
   std::vector<std::vector<detail::Point>> bDens = b.getDenominators();
   EXPECT_EQ(aDens.size(), bDens.size());
-  for (unsigned i = 0, e = aDens.size(); i < e; i++) {
+  for (int i : llvm::seq<int>(0, aDens.size())) {
     EXPECT_EQ(aDens[i].size(), bDens[i].size());
-    for (unsigned j = 0, f = aDens[i].size(); j < f; j++) {
+    for (int j : llvm::seq<int>(0, aDens[i].size())) {
       EXPECT_EQ(aDens[i][j].size(), bDens[i][j].size());
-      for (unsigned k = 0, g = aDens[i][j].size(); k < g; k++) {
+      for (int k : llvm::seq<int>(0, aDens[i][j].size()))
         EXPECT_EQ(aDens[i][j][k], bDens[i][j][k]);
-      }
     }
   }
 }
@@ -114,16 +114,16 @@ inline void EXPECT_EQ_REPR_QUASIPOLYNOMIAL(QuasiPolynomial a,
   SmallVector<Fraction> aCoeffs = a.getCoefficients(),
                         bCoeffs = b.getCoefficients();
   EXPECT_EQ(aCoeffs.size(), bCoeffs.size());
-  for (unsigned i = 0, e = aCoeffs.size(); i < e; i++)
+  for (int i : llvm::seq<int>(0, aCoeffs.size()))
     EXPECT_EQ(aCoeffs[i], bCoeffs[i]);
 
   std::vector<std::vector<SmallVector<Fraction>>> aAff = a.getAffine(),
                                                   bAff = b.getAffine();
   EXPECT_EQ(aAff.size(), bAff.size());
-  for (unsigned i = 0, e = aAff.size(); i < e; i++) {
+  for (int i : llvm::seq<int>(0, aAff.size())) {
     EXPECT_EQ(aAff[i].size(), bAff[i].size());
-    for (unsigned j = 0, f = aAff[i].size(); j < f; j++)
-      for (unsigned k = 0, g = a.getNumInputs(); k <= g; k++)
+    for (int j : llvm::seq<int>(0, aAff[i].size()))
+      for (int k : llvm::seq<int>(0, a.getNumInputs()))
         EXPECT_EQ(aAff[i][j][k], bAff[i][j][k]);
   }
 }

>From 13a2411303ac6a67a8f24b6bc85f95a4235b320e Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Mon, 19 Feb 2024 23:14:43 +0530
Subject: [PATCH 2/6] Define and use increment operator for quasipolynomials

---
 mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h | 1 +
 mlir/lib/Analysis/Presburger/Barvinok.cpp               | 7 +++----
 mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp        | 4 ++++
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
index aeac19e827b44f..2518a0a4908120 100644
--- a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
+++ b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
@@ -58,6 +58,7 @@ class QuasiPolynomial : public PresburgerSpace {
   QuasiPolynomial operator-(const QuasiPolynomial &x) const;
   QuasiPolynomial operator*(const QuasiPolynomial &x) const;
   QuasiPolynomial operator/(const Fraction x) const;
+  void operator+=(const QuasiPolynomial &x);
 
   // Removes terms which evaluate to zero from the expression
   // and folds affine functions which are constant into the
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index c483b9a4b81f37..d5b6d6024a6a56 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -777,10 +777,9 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
       denominatorCoefficients =
           multiplyPolynomials(denominatorCoefficients, eachTermDenCoefficient);
 
-    totalTerm =
-        totalTerm + getCoefficientInRationalFunction(r, numeratorCoefficients,
-                                                     denominatorCoefficients) *
-                        QuasiPolynomial(numParams, sign);
+    totalTerm += getCoefficientInRationalFunction(r, numeratorCoefficients,
+                                                  denominatorCoefficients) *
+                 QuasiPolynomial(numParams, sign);
   }
 
   return totalTerm.simplify();
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index 673adba4fc8d61..edb4c091e15547 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -98,6 +98,10 @@ QuasiPolynomial QuasiPolynomial::operator/(const Fraction x) const {
   return qp;
 }
 
+void QuasiPolynomial::operator+=(const QuasiPolynomial &x) {
+  *this = *this + x;
+}
+
 // Removes terms which evaluate to zero from the expression and
 // integrate affine functions which are constants into the
 // coefficients.

>From 73702af15fa291d4951aaa6ad6aa43326fa6727a Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Mon, 19 Feb 2024 23:19:08 +0530
Subject: [PATCH 3/6] Use EXPECT_NE

---
 mlir/unittests/Analysis/Presburger/MatrixTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
index feda98d0b1817a..a3b898c529c77d 100644
--- a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
@@ -377,7 +377,7 @@ TEST(MatrixTest, gramSchmidt) {
 
   // The integers involved are too big to construct the actual matrix.
   // but we can check that the result is linearly independent.
-  ASSERT_FALSE(mat.determinant(nullptr) == 0);
+  EXPECT_NE(mat.determinant(nullptr), 0);
 
   for (unsigned i = 0; i < 4u; ++i)
     for (unsigned j = i + 1; j < 4u; ++j)

>From da73e0ceea9af13f7a88170aa036ceceb1e6ecb7 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Mon, 19 Feb 2024 23:38:16 +0530
Subject: [PATCH 4/6] Change terminology to symbols in GF

---
 .../mlir/Analysis/Presburger/GeneratingFunction.h | 15 ++++++++-------
 mlir/lib/Analysis/Presburger/Barvinok.cpp         |  2 +-
 mlir/unittests/Analysis/Presburger/Utils.h        |  2 +-
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
index e90a991d5c4809..d19945d2c5266d 100644
--- a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
+++ b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
@@ -51,19 +51,20 @@ using Point = SmallVector<Fraction>;
 // g_{ij} \in Q^n are vectors.
 class GeneratingFunction {
 public:
-  GeneratingFunction(unsigned numParam, SmallVector<int> signs,
+  GeneratingFunction(unsigned numSymbols, SmallVector<int> signs,
                      std::vector<ParamPoint> nums,
                      std::vector<std::vector<Point>> dens)
-      : numParam(numParam), signs(signs), numerators(nums), denominators(dens) {
+      : numSymbols(numSymbols), signs(signs), numerators(nums),
+        denominators(dens) {
 #ifndef NDEBUG
     for (const ParamPoint &term : numerators)
-      assert(term.getNumRows() == numParam + 1 &&
+      assert(term.getNumRows() == numSymbols + 1 &&
              "dimensionality of numerator exponents does not match number of "
              "parameters!");
 #endif // NDEBUG
   }
 
-  unsigned getNumParams() const { return numParam; }
+  unsigned getNumSymbols() const { return numSymbols; }
 
   SmallVector<int> getSigns() const { return signs; }
 
@@ -74,7 +75,7 @@ class GeneratingFunction {
   }
 
   GeneratingFunction operator+(const GeneratingFunction &gf) const {
-    assert(numParam == gf.getNumParams() &&
+    assert(numSymbols == gf.getNumSymbols() &&
            "two generating functions with different numbers of parameters "
            "cannot be added!");
     SmallVector<int> sumSigns = signs;
@@ -87,7 +88,7 @@ class GeneratingFunction {
     std::vector<std::vector<Point>> sumDenominators = denominators;
     sumDenominators.insert(sumDenominators.end(), gf.denominators.begin(),
                            gf.denominators.end());
-    return GeneratingFunction(numParam, sumSigns, sumNumerators,
+    return GeneratingFunction(numSymbols, sumSigns, sumNumerators,
                               sumDenominators);
   }
 
@@ -127,7 +128,7 @@ class GeneratingFunction {
   }
 
 private:
-  unsigned numParam;
+  unsigned numSymbols;
   SmallVector<int> signs;
   std::vector<ParamPoint> numerators;
   std::vector<std::vector<Point>> denominators;
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index d5b6d6024a6a56..1803b751a06838 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -696,7 +696,7 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
     allDenominators.insert(allDenominators.end(), den.begin(), den.end());
   Point mu = getNonOrthogonalVector(allDenominators);
 
-  unsigned numParams = gf.getNumParams();
+  unsigned numParams = gf.getNumSymbols();
   const std::vector<std::vector<Point>> &ds = gf.getDenominators();
   QuasiPolynomial totalTerm(numParams, 0);
   for (int i : llvm::seq<int>(0, ds.size())) {
diff --git a/mlir/unittests/Analysis/Presburger/Utils.h b/mlir/unittests/Analysis/Presburger/Utils.h
index 26970b798953af..ed4b04cb7880e6 100644
--- a/mlir/unittests/Analysis/Presburger/Utils.h
+++ b/mlir/unittests/Analysis/Presburger/Utils.h
@@ -78,7 +78,7 @@ inline void EXPECT_EQ_FRAC_MATRIX(FracMatrix a, FracMatrix b) {
 // Note that this is not a true equality check.
 inline void EXPECT_EQ_REPR_GENERATINGFUNCTION(detail::GeneratingFunction a,
                                               detail::GeneratingFunction b) {
-  EXPECT_EQ(a.getNumParams(), b.getNumParams());
+  EXPECT_EQ(a.getNumSymbols(), b.getNumSymbols());
 
   SmallVector<int> aSigns = a.getSigns();
   SmallVector<int> bSigns = b.getSigns();

>From 50d826db2d076375d4e377cfc04deefad91422d9 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Fri, 23 Feb 2024 17:26:54 +0530
Subject: [PATCH 5/6] Proof for intersection case

---
 mlir/lib/Analysis/Presburger/Barvinok.cpp | 28 +++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index 1803b751a06838..e5a81230fede7f 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -235,6 +235,34 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
 /// generating functions the region that (the sum of) precisely this subset is
 /// in, is the intersection of the regions that these are active in,
 /// intersected with the complements of the remaining regions.
+///
+/// If the parameter values lie in the intersection of two chambers with
+/// differing vertex sets, the answer is given by considering either one.
+/// Assume that the chambers differ in that one has k+1 vertices and the other
+/// only k – we can then show that the same vertex is counted twice in the
+/// former, and so the sets are in fact the same. This is proved below.
+/// Consider a parametric polyhedron D in n variables and m parameters. We want
+/// to show that if two vertices' chambers intersect, then the vertices collapse
+/// in this region.
+///
+/// Let D' be the polyhedron in combined data-and-parameter space (R^{n+m}).
+/// Then we have from [1] that:
+///
+/// * a vertex is a 0-dimensional face of D, which is equivalent to an m-face
+/// F_i^m of D'.
+/// * a vertex v_i(p) is obtained from F_i^m(D') by projecting down to n-space
+/// (see Fig. 1).
+/// * the region a vertex exists in is given by projecting F_i^m(D') down to
+/// m-space.
+///
+/// Thus, if two chambers intersect, this means that the corresponding faces
+/// (say F_i^m(D') and F_j^m(D')) also have some intersection. Since the
+/// vertices v_i and v_j correspond to the projections of F_i^m(D') and
+/// F_j^m(D'), they must collapse in the intersection.
+///
+/// [1]: Parameterized Polyhedra and Their Vertices (Loechner & Wilde, 1997)
+/// https://link.springer.com/article/10.1023/A:1025117523902
+
 std::vector<std::pair<PresburgerSet, GeneratingFunction>>
 mlir::presburger::detail::computeChamberDecomposition(
     unsigned numSymbols, ArrayRef<std::pair<PresburgerSet, GeneratingFunction>>

>From b5fae3fb76a92165eb17039ce6fb63afe51c5967 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Fri, 23 Feb 2024 18:01:30 +0530
Subject: [PATCH 6/6] Implement evaluation of QPs

---
 .../Analysis/Presburger/QuasiPolynomial.h     |  2 ++
 .../Analysis/Presburger/QuasiPolynomial.cpp   | 24 +++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
index 2518a0a4908120..a3af219192fbe1 100644
--- a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
+++ b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
@@ -70,6 +70,8 @@ class QuasiPolynomial : public PresburgerSpace {
 
   Fraction getConstantTerm();
 
+  Fraction evaluateAt(const SmallVector<Fraction> &parameters);
+
 private:
   SmallVector<Fraction> coefficients;
   std::vector<std::vector<SmallVector<Fraction>>> affine;
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index edb4c091e15547..816e5ac72f66c1 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -177,3 +177,27 @@ Fraction QuasiPolynomial::getConstantTerm() {
       constTerm += coefficients[i];
   return constTerm;
 }
+
+Fraction QuasiPolynomial::evaluateAt(const SmallVector<Fraction> &parameters) {
+  assert(parameters.size() == getNumInputs() &&
+         "the size of the input vector does not match the dimensionality of "
+         "the polynomial!");
+
+  unsigned numParams = parameters.size();
+  Fraction sum = 0;
+  // The value of the function is given by a sum of terms,
+  for (int i : llvm::seq<int>(0, coefficients.size())) {
+    // each of which is a coefficient, multiplied by the product of
+    Fraction product = coefficients[i];
+    for (int j : llvm::seq<int>(0, affine[i].size())) {
+      ArrayRef<Fraction> affineFunction(affine[i][j]);
+      // the floors of some affine functions.
+      Fraction value =
+          floor(dotProduct(affineFunction.slice(numParams), parameters) +
+                affineFunction.back());
+      product *= value;
+    }
+    sum += coefficients[i] * product;
+  }
+  return sum;
+}
\ No newline at end of file



More information about the Mlir-commits mailing list