Skip to content

Commit

Permalink
mlir/Presburger: optimize to avoid creating copies (#97897)
Browse files Browse the repository at this point in the history
Optimize the Presburger library to avoid unnecessarily creating copies.
While at it, fix some other minor issues in the codebase.
  • Loading branch information
artagnon authored Jul 15, 2024
1 parent 148d907 commit 266a5a9
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 111 deletions.
10 changes: 5 additions & 5 deletions mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -77,4 +77,4 @@ class QuasiPolynomial : public PresburgerSpace {
} // namespace presburger
} // namespace mlir

#endif // MLIR_ANALYSIS_PRESBURGER_QUASIPOLYNOMIAL_H
#endif // MLIR_ANALYSIS_PRESBURGER_QUASIPOLYNOMIAL_H
41 changes: 21 additions & 20 deletions mlir/lib/Analysis/Presburger/Barvinok.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand All @@ -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;
}
Expand All @@ -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).
Expand Down Expand Up @@ -573,15 +574,15 @@ 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.
ParamPoint vTranspose = v.transpose();
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();
Expand All @@ -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};
Expand Down Expand Up @@ -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());
Expand All @@ -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;
}

Expand Down Expand Up @@ -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
Expand Down
30 changes: 15 additions & 15 deletions mlir/lib/Analysis/Presburger/IntegerRelation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -528,7 +528,7 @@ void IntegerRelation::getLowerAndUpperBoundIndices(
continue;
if (containsConstraintDependentOnRange(r, /*isEq=*/true))
continue;
eqIndices->push_back(r);
eqIndices->emplace_back(r);
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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++) {
Expand All @@ -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);
}
}

Expand Down
4 changes: 2 additions & 2 deletions mlir/lib/Analysis/Presburger/LinearTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand Down
6 changes: 3 additions & 3 deletions mlir/lib/Analysis/Presburger/PWMAFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 266a5a9

Please sign in to comment.