diff --git a/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h b/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h --- a/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h +++ b/mlir/include/mlir/Analysis/FlatLinearValueConstraints.h @@ -87,8 +87,8 @@ /// /// Note: The dimensions/symbols of this FlatLinearConstraints must match the /// dimensions/symbols of the affine map. - LogicalResult addBound(BoundType type, unsigned pos, AffineMap boundMap, - bool isClosedBound); + LogicalResult addBound(presburger::BoundType type, unsigned pos, + AffineMap boundMap, bool isClosedBound); /// Adds a bound for the variable at the specified position with constraints /// being drawn from the specified bound map. In case of an EQ bound, the @@ -98,7 +98,8 @@ /// Note: The dimensions/symbols of this FlatLinearConstraints must match the /// dimensions/symbols of the affine map. By default the lower bound is closed /// and the upper bound is open. - LogicalResult addBound(BoundType type, unsigned pos, AffineMap boundMap); + LogicalResult addBound(presburger::BoundType type, unsigned pos, + AffineMap boundMap); /// The `addBound` overload above hides the inherited overloads by default, so /// we explicitly introduce them here. @@ -315,7 +316,7 @@ void clearAndCopyFrom(const IntegerRelation &other) override; /// Adds a constant bound for the variable associated with the given Value. - void addBound(BoundType type, Value val, int64_t value); + void addBound(presburger::BoundType type, Value val, int64_t value); using FlatLinearConstraints::addBound; /// Returns the Value associated with the pos^th variable. Asserts if diff --git a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h --- a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h +++ b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h @@ -31,6 +31,9 @@ class PresburgerRelation; struct SymbolicLexMin; +/// The type of bound: equal, lower bound or upper bound. +enum class BoundType { EQ, LB, UB }; + /// An IntegerRelation represents the set of points from a PresburgerSpace that /// satisfy a list of affine constraints. Affine constraints can be inequalities /// or equalities in the form: @@ -397,9 +400,6 @@ /// to None. DivisionRepr getLocalReprs(std::vector *repr = nullptr) const; - /// The type of bound: equal, lower bound or upper bound. - enum BoundType { EQ, LB, UB }; - /// Adds a constant bound for the specified variable. void addBound(BoundType type, unsigned pos, const MPInt &value); void addBound(BoundType type, unsigned pos, int64_t value) { diff --git a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h --- a/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h +++ b/mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h @@ -100,8 +100,8 @@ /// EQ bound, the bound map is expected to have exactly one result. In case /// of a LB/UB, the bound map may have more than one result, for each of which /// an inequality is added. - LogicalResult addBound(BoundType type, unsigned pos, AffineMap boundMap, - ValueRange operands); + LogicalResult addBound(presburger::BoundType type, unsigned pos, + AffineMap boundMap, ValueRange operands); using FlatLinearValueConstraints::addBound; /// Add the specified values as a dim or symbol var depending on its nature, diff --git a/mlir/lib/Analysis/FlatLinearValueConstraints.cpp b/mlir/lib/Analysis/FlatLinearValueConstraints.cpp --- a/mlir/lib/Analysis/FlatLinearValueConstraints.cpp +++ b/mlir/lib/Analysis/FlatLinearValueConstraints.cpp @@ -308,8 +308,7 @@ // Express `var_r` as `var_n % divisor` and store the expression in `memo`. if (quotientCount >= 1) { - auto ub = cst.getConstantBound64(FlatLinearConstraints::BoundType::UB, - dimExpr.getPosition()); + auto ub = cst.getConstantBound64(BoundType::UB, dimExpr.getPosition()); // If `var_n` has an upperbound that is less than the divisor, mod can be // eliminated altogether. if (ub && *ub < divisor) diff --git a/mlir/lib/Analysis/Presburger/PWMAFunction.cpp b/mlir/lib/Analysis/Presburger/PWMAFunction.cpp --- a/mlir/lib/Analysis/Presburger/PWMAFunction.cpp +++ b/mlir/lib/Analysis/Presburger/PWMAFunction.cpp @@ -231,14 +231,14 @@ // outA - outB <= -1 // outA <= outB - 1 // outA < outB - levelSet.addBound(IntegerPolyhedron::BoundType::UB, subExpr, MPInt(-1)); + levelSet.addBound(BoundType::UB, subExpr, MPInt(-1)); break; case OrderingKind::GT: // For greater than, we add a lower bound of 1: // outA - outB >= 1 // outA > outB + 1 // outA > outB - levelSet.addBound(IntegerPolyhedron::BoundType::LB, subExpr, MPInt(1)); + levelSet.addBound(BoundType::LB, subExpr, MPInt(1)); break; case OrderingKind::GE: case OrderingKind::LE: diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp --- a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp @@ -445,12 +445,10 @@ dependenceComponents->resize(numCommonLoops); for (unsigned j = 0; j < numCommonLoops; ++j) { (*dependenceComponents)[j].op = commonLoops[j].getOperation(); - auto lbConst = - dependenceDomain->getConstantBound64(IntegerPolyhedron::LB, j); + auto lbConst = dependenceDomain->getConstantBound64(BoundType::LB, j); (*dependenceComponents)[j].lb = lbConst.value_or(std::numeric_limits::min()); - auto ubConst = - dependenceDomain->getConstantBound64(IntegerPolyhedron::UB, j); + auto ubConst = dependenceDomain->getConstantBound64(BoundType::UB, j); (*dependenceComponents)[j].ub = ubConst.value_or(std::numeric_limits::max()); } diff --git a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp --- a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp @@ -98,7 +98,7 @@ if (isValidSymbol(value)) { // Check if the symbol is a constant. if (auto cOp = value.getDefiningOp()) - cst->addBound(FlatAffineValueConstraints::EQ, value, cOp.value()); + cst->addBound(BoundType::EQ, value, cOp.value()); } else if (auto loop = getForInductionVarOwner(value)) { if (failed(cst->addAffineForOpDomain(loop))) return failure(); @@ -357,11 +357,11 @@ // that will need non-trivials means to eliminate. FlatAffineValueConstraints cstWithShapeBounds(cst); for (unsigned r = 0; r < rank; r++) { - cstWithShapeBounds.addBound(FlatAffineValueConstraints::LB, r, 0); + cstWithShapeBounds.addBound(BoundType::LB, r, 0); int64_t dimSize = memRefType.getDimSize(r); if (ShapedType::isDynamic(dimSize)) continue; - cstWithShapeBounds.addBound(FlatAffineValueConstraints::UB, r, dimSize - 1); + cstWithShapeBounds.addBound(BoundType::UB, r, dimSize - 1); } // Find a constant upper bound on the extent of this memref region along each @@ -516,7 +516,7 @@ // Check if the symbol is a constant. Value symbol = operand; if (auto constVal = getConstantIntValue(symbol)) - cst.addBound(FlatAffineValueConstraints::EQ, symbol, constVal.value()); + cst.addBound(BoundType::EQ, symbol, constVal.value()); } else { LLVM_DEBUG(llvm::dbgs() << "unknown affine dimensional value"); return failure(); @@ -580,11 +580,10 @@ if (addMemRefDimBounds) { auto memRefType = memref.getType().cast(); for (unsigned r = 0; r < rank; r++) { - cst.addBound(FlatAffineValueConstraints::LB, /*pos=*/r, /*value=*/0); + cst.addBound(BoundType::LB, /*pos=*/r, /*value=*/0); if (memRefType.isDynamicDim(r)) continue; - cst.addBound(FlatAffineValueConstraints::UB, /*pos=*/r, - memRefType.getDimSize(r) - 1); + cst.addBound(BoundType::UB, /*pos=*/r, memRefType.getDimSize(r) - 1); } } cst.removeTrivialRedundancy(); @@ -684,7 +683,7 @@ continue; // Check for overflow: d_i >= memref dim size. - ucst.addBound(FlatAffineValueConstraints::LB, r, dimSize); + ucst.addBound(BoundType::LB, r, dimSize); outOfBounds = !ucst.isEmpty(); if (outOfBounds && emitError) { loadOrStoreOp.emitOpError() @@ -695,7 +694,7 @@ FlatAffineValueConstraints lcst(*region.getConstraints()); std::fill(ineq.begin(), ineq.end(), 0); // d_i <= -1; - lcst.addBound(FlatAffineValueConstraints::UB, r, -1); + lcst.addBound(BoundType::UB, r, -1); outOfBounds = !lcst.isEmpty(); if (outOfBounds && emitError) { loadOrStoreOp.emitOpError() @@ -1392,9 +1391,8 @@ /// Note: This function adds a new symbol column to the `constraints` for each /// dimension/symbol that exists in the affine map but not in `constraints`. static LogicalResult alignAndAddBound(FlatAffineValueConstraints &constraints, - IntegerPolyhedron::BoundType type, - unsigned pos, AffineMap map, - ValueRange operands) { + BoundType type, unsigned pos, + AffineMap map, ValueRange operands) { SmallVector dims, syms, newSyms; unpackOptionalValues(constraints.getMaybeValues(VarKind::SetDim), dims); unpackOptionalValues(constraints.getMaybeValues(VarKind::Symbol), syms); @@ -1471,7 +1469,7 @@ // Add an inequality for each result expr_i of map: // isMin: op <= expr_i, !isMin: op >= expr_i - auto boundType = isMin ? IntegerPolyhedron::UB : IntegerPolyhedron::LB; + auto boundType = isMin ? BoundType::UB : BoundType::LB; // Upper bounds are exclusive, so add 1. (`affine.min` ops are inclusive.) AffineMap mapLbUb = isMin ? addConstToResults(map, 1) : map; if (failed( @@ -1493,8 +1491,7 @@ // Add an equality: Set dimOpBound to computed bound. // Add back dimension for op. (Was removed by `getSliceBounds`.) AffineMap alignedBoundMap = boundMap.shiftDims(/*shift=*/1, /*offset=*/dimOp); - if (failed(constraints.addBound(IntegerPolyhedron::EQ, dimOpBound, - alignedBoundMap))) + if (failed(constraints.addBound(BoundType::EQ, dimOpBound, alignedBoundMap))) return failure(); // If the constraint system is empty, there is an inconsistency. (E.g., this @@ -1519,7 +1516,7 @@ // Note: These equalities could have been added earlier and used to express // minOp <= expr_i. However, then we run the risk that `getSliceBounds` // computes minOpUb in terms of r_i dims, which is not desired. - if (failed(alignAndAddBound(newConstr, IntegerPolyhedron::EQ, i, + if (failed(alignAndAddBound(newConstr, BoundType::EQ, i, map.getSubMap({i - resultDimStart}), operands))) return failure(); @@ -1546,7 +1543,7 @@ // Skip unused operands and operands that are already constants. if (!newOperands[i] || getConstantIntValue(newOperands[i])) continue; - if (auto bound = constraints.getConstantBound64(IntegerPolyhedron::EQ, i)) { + if (auto bound = constraints.getConstantBound64(BoundType::EQ, i)) { AffineExpr expr = i < newMap.getNumDims() ? builder.getAffineDimExpr(i) diff --git a/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp b/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp --- a/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp +++ b/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp @@ -97,11 +97,9 @@ unsigned pos; if (!cstr.findVar(std::get<0>(it), &pos)) pos = cstr.appendSymbolVar(std::get<0>(it)); - cstr.addBound(FlatAffineValueConstraints::BoundType::LB, pos, - std::get<1>(it)); + cstr.addBound(presburger::BoundType::LB, pos, std::get<1>(it)); // Note: addBound bounds are inclusive, but specified UB is exclusive. - cstr.addBound(FlatAffineValueConstraints::BoundType::UB, pos, - std::get<2>(it) - 1); + cstr.addBound(presburger::BoundType::UB, pos, std::get<2>(it) - 1); } // Transform all targets. diff --git a/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp b/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp --- a/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp +++ b/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp @@ -2368,8 +2368,8 @@ for (unsigned d = 0; d < rank; d++) { auto dimSize = memRefType.getDimSize(d); assert(dimSize > 0 && "filtered dynamic shapes above"); - regionCst->addBound(IntegerPolyhedron::LB, d, 0); - regionCst->addBound(IntegerPolyhedron::UB, d, dimSize - 1); + regionCst->addBound(BoundType::LB, d, 0); + regionCst->addBound(BoundType::UB, d, dimSize - 1); } return true; } diff --git a/mlir/lib/Dialect/Affine/Utils/Utils.cpp b/mlir/lib/Dialect/Affine/Utils/Utils.cpp --- a/mlir/lib/Dialect/Affine/Utils/Utils.cpp +++ b/mlir/lib/Dialect/Affine/Utils/Utils.cpp @@ -1800,8 +1800,8 @@ for (unsigned d = 0; d < rank; ++d) { // Use constraint system only in static dimensions. if (shape[d] > 0) { - fac.addBound(IntegerPolyhedron::LB, d, 0); - fac.addBound(IntegerPolyhedron::UB, d, shape[d] - 1); + fac.addBound(BoundType::LB, d, 0); + fac.addBound(BoundType::UB, d, shape[d] - 1); } else { memrefTypeDynDims.emplace_back(d); } @@ -1824,8 +1824,7 @@ newShape[d] = ShapedType::kDynamic; } else { // The lower bound for the shape is always zero. - std::optional ubConst = - fac.getConstantBound64(IntegerPolyhedron::UB, d); + std::optional ubConst = fac.getConstantBound64(BoundType::UB, d); // For a static memref and an affine map with no symbols, this is // always bounded. However, when we have symbols, we may not be able to // obtain a constant upper bound. Also, mapping to a negative space is diff --git a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp --- a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp +++ b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp @@ -270,7 +270,7 @@ if (auto applyOp = dyn_cast(op)) { AffineMap map = constraints.computeAlignedMap(applyOp.getAffineMap(), applyOp.getOperands()); - if (failed(constraints.addBound(IntegerPolyhedron::EQ, + if (failed(constraints.addBound(BoundType::EQ, getPosition(applyOp.getResult()), map))) return; continue; @@ -279,7 +279,7 @@ auto minOp = cast(op); AffineMap map = constraints.computeAlignedMap(minOp.getAffineMap(), minOp.getOperands()); - if (failed(constraints.addBound(IntegerPolyhedron::UB, + if (failed(constraints.addBound(BoundType::UB, getPosition(minOp.getResult()), map, /*isClosedBound=*/true))) return; @@ -290,8 +290,7 @@ // of the terminals of the index computation. unsigned pos = getPosition(value); if (constantRequired) { - auto ubConst = constraints.getConstantBound64( - FlatAffineValueConstraints::BoundType::UB, pos); + auto ubConst = constraints.getConstantBound64(BoundType::UB, pos); if (!ubConst) return; diff --git a/mlir/lib/Dialect/SCF/Utils/AffineCanonicalizationUtils.cpp b/mlir/lib/Dialect/SCF/Utils/AffineCanonicalizationUtils.cpp --- a/mlir/lib/Dialect/SCF/Utils/AffineCanonicalizationUtils.cpp +++ b/mlir/lib/Dialect/SCF/Utils/AffineCanonicalizationUtils.cpp @@ -98,9 +98,9 @@ std::optional lbInt = getConstantIntValue(lb); std::optional ubInt = getConstantIntValue(ub); if (lbInt) - cstr.addBound(IntegerPolyhedron::EQ, symLb, *lbInt); + cstr.addBound(BoundType::EQ, symLb, *lbInt); if (ubInt) - cstr.addBound(IntegerPolyhedron::EQ, symUb, *ubInt); + cstr.addBound(BoundType::EQ, symUb, *ubInt); // Lower bound: iv >= lb (equiv.: iv - lb >= 0) SmallVector ineqLb(cstr.getNumCols(), 0); @@ -131,7 +131,7 @@ /*dimCount=*/cstr.getNumDimVars(), /*symbolCount=*/cstr.getNumSymbolVars(), /*result=*/ivUb); - return cstr.addBound(IntegerPolyhedron::UB, dimIv, map); + return cstr.addBound(BoundType::UB, dimIv, map); } /// Canonicalize min/max operations in the context of for loops with a known @@ -202,9 +202,9 @@ constraints.appendDimVar({iv}); constraints.appendSymbolVar({ub, step}); if (auto constUb = getConstantIntValue(ub)) - constraints.addBound(IntegerPolyhedron::EQ, 1, *constUb); + constraints.addBound(BoundType::EQ, 1, *constUb); if (auto constStep = getConstantIntValue(step)) - constraints.addBound(IntegerPolyhedron::EQ, 2, *constStep); + constraints.addBound(BoundType::EQ, 2, *constStep); // Add loop peeling invariant. This is the main piece of knowledge that // enables AffineMinOp simplification. diff --git a/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp --- a/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp +++ b/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp @@ -594,12 +594,12 @@ TEST(IntegerPolyhedronTest, addConstantUpperBound) { IntegerPolyhedron poly(PresburgerSpace::getSetSpace(2)); - poly.addBound(IntegerPolyhedron::UB, 0, 1); + poly.addBound(BoundType::UB, 0, 1); EXPECT_EQ(poly.atIneq(0, 0), -1); EXPECT_EQ(poly.atIneq(0, 1), 0); EXPECT_EQ(poly.atIneq(0, 2), 1); - poly.addBound(IntegerPolyhedron::UB, {1, 2, 3}, 1); + poly.addBound(BoundType::UB, {1, 2, 3}, 1); EXPECT_EQ(poly.atIneq(1, 0), -1); EXPECT_EQ(poly.atIneq(1, 1), -2); EXPECT_EQ(poly.atIneq(1, 2), -2); @@ -607,12 +607,12 @@ TEST(IntegerPolyhedronTest, addConstantLowerBound) { IntegerPolyhedron poly(PresburgerSpace::getSetSpace(2)); - poly.addBound(IntegerPolyhedron::LB, 0, 1); + poly.addBound(BoundType::LB, 0, 1); EXPECT_EQ(poly.atIneq(0, 0), 1); EXPECT_EQ(poly.atIneq(0, 1), 0); EXPECT_EQ(poly.atIneq(0, 2), -1); - poly.addBound(IntegerPolyhedron::LB, {1, 2, 3}, 1); + poly.addBound(BoundType::LB, {1, 2, 3}, 1); EXPECT_EQ(poly.atIneq(1, 0), 1); EXPECT_EQ(poly.atIneq(1, 1), 2); EXPECT_EQ(poly.atIneq(1, 2), 2);