[mlir][Analysis][NFC] Make BoundType a top-level enum
authorMatthias Springer <me@m-sp.org>
Thu, 23 Mar 2023 08:40:51 +0000 (09:40 +0100)
committerMatthias Springer <me@m-sp.org>
Thu, 23 Mar 2023 08:46:21 +0000 (09:46 +0100)
`BoundType` is no longer a nested member of `IntegerRelation` but a top-level enum in the `presburger` namespace.

This allows `BoundType` to be predeclared in header files. Nested members cannot be predeclared.

Differential Revision: https://reviews.llvm.org/D146210

13 files changed:
mlir/include/mlir/Analysis/FlatLinearValueConstraints.h
mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h
mlir/lib/Analysis/FlatLinearValueConstraints.cpp
mlir/lib/Analysis/Presburger/PWMAFunction.cpp
mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp
mlir/lib/Dialect/Affine/Analysis/Utils.cpp
mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp
mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp
mlir/lib/Dialect/Affine/Utils/Utils.cpp
mlir/lib/Dialect/Linalg/Utils/Utils.cpp
mlir/lib/Dialect/SCF/Utils/AffineCanonicalizationUtils.cpp
mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp

index a6900ab..abebd73 100644 (file)
@@ -87,8 +87,8 @@ public:
   ///
   /// 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 @@ public:
   /// 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 @@ public:
   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
index 8b0c2a5..9646894 100644 (file)
@@ -31,6 +31,9 @@ class PresburgerSet;
 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 @@ public:
   /// to None.
   DivisionRepr getLocalReprs(std::vector<MaybeLocalRepr> *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) {
index 6249428..e598364 100644 (file)
@@ -100,8 +100,8 @@ public:
   /// 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,
index b89b2d1..24c8d87 100644 (file)
@@ -308,8 +308,7 @@ static bool detectAsMod(const FlatLinearConstraints &cst, unsigned pos,
 
     // 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)
index 64b9ba6..ce9e810 100644 (file)
@@ -231,14 +231,14 @@ MultiAffineFunction::getLexSet(OrderingKind comp,
       //        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:
index d7720a0..da8f088 100644 (file)
@@ -445,12 +445,10 @@ static void computeDirectionVector(
   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<int64_t>::min());
-    auto ubConst =
-        dependenceDomain->getConstantBound64(IntegerPolyhedron::UB, j);
+    auto ubConst = dependenceDomain->getConstantBound64(BoundType::UB, j);
     (*dependenceComponents)[j].ub =
         ubConst.value_or(std::numeric_limits<int64_t>::max());
   }
index db4fa35..41a739d 100644 (file)
@@ -98,7 +98,7 @@ ComputationSliceState::getAsConstraints(FlatAffineValueConstraints *cst) {
     if (isValidSymbol(value)) {
       // Check if the symbol is a constant.
       if (auto cOp = value.getDefiningOp<arith::ConstantIndexOp>())
-        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 @@ std::optional<int64_t> MemRefRegion::getConstantBoundingSizeAndShape(
   // 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 @@ LogicalResult MemRefRegion::compute(Operation *op, unsigned loopDepth,
       // 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 @@ LogicalResult MemRefRegion::compute(Operation *op, unsigned loopDepth,
   if (addMemRefDimBounds) {
     auto memRefType = memref.getType().cast<MemRefType>();
     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();
@@ -695,7 +694,7 @@ LogicalResult mlir::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
       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()
@@ -706,7 +705,7 @@ LogicalResult mlir::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
     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()
@@ -1403,9 +1402,8 @@ static void unpackOptionalValues(ArrayRef<std::optional<Value>> source,
 /// 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<Value> dims, syms, newSyms;
   unpackOptionalValues(constraints.getMaybeValues(VarKind::SetDim), dims);
   unpackOptionalValues(constraints.getMaybeValues(VarKind::Symbol), syms);
@@ -1482,7 +1480,7 @@ mlir::simplifyConstrainedMinMaxOp(Operation *op,
 
   // 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(
@@ -1504,8 +1502,7 @@ mlir::simplifyConstrainedMinMaxOp(Operation *op,
   // 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
@@ -1530,7 +1527,7 @@ mlir::simplifyConstrainedMinMaxOp(Operation *op,
     // 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();
 
@@ -1557,7 +1554,7 @@ mlir::simplifyConstrainedMinMaxOp(Operation *op,
     // 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)
index 99dfaa9..999adfa 100644 (file)
@@ -97,11 +97,9 @@ SimplifyBoundedAffineOpsOp::apply(TransformResults &results,
     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.
index 1e567a6..a7f96dc 100644 (file)
@@ -2371,8 +2371,8 @@ static bool getFullMemRefAsRegion(Operation *op, unsigned numParamLoopIVs,
   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;
 }
index 5040595..d96b688 100644 (file)
@@ -1800,8 +1800,8 @@ MemRefType mlir::normalizeMemRefType(MemRefType memrefType,
   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 @@ MemRefType mlir::normalizeMemRefType(MemRefType memrefType,
       newShape[d] = ShapedType::kDynamic;
     } else {
       // The lower bound for the shape is always zero.
-      std::optional<int64_t> ubConst =
-          fac.getConstantBound64(IntegerPolyhedron::UB, d);
+      std::optional<int64_t> 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
index f3879f5..75f818b 100644 (file)
@@ -270,7 +270,7 @@ void getUpperBoundForIndex(Value value, AffineMap &boundMap,
     if (auto applyOp = dyn_cast<AffineApplyOp>(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 @@ void getUpperBoundForIndex(Value value, AffineMap &boundMap,
     auto minOp = cast<AffineMinOp>(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 @@ void getUpperBoundForIndex(Value value, AffineMap &boundMap,
   // 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;
 
index 6964747..1c458ee 100644 (file)
@@ -98,9 +98,9 @@ LogicalResult scf::addLoopRangeConstraints(FlatAffineValueConstraints &cstr,
   std::optional<int64_t> lbInt = getConstantIntValue(lb);
   std::optional<int64_t> 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<int64_t> ineqLb(cstr.getNumCols(), 0);
@@ -131,7 +131,7 @@ LogicalResult scf::addLoopRangeConstraints(FlatAffineValueConstraints &cstr,
       /*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 @@ LogicalResult scf::rewritePeeledMinMaxOp(RewriterBase &rewriter, Operation *op,
   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.
index cc55b96..6beb938 100644 (file)
@@ -594,12 +594,12 @@ TEST(IntegerPolyhedronTest, removeRedundantConstraintsTest) {
 
 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, addConstantUpperBound) {
 
 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);