Skip to content

Commit 0a06ac7

Browse files
committed
[MLIR][Affine][Analysis] Merge FAC and FACV
With the introduction of IntegerPolyhedron and IntegerRelation in Presburger directory, the purpose of FlatAffineConstraints becomes redundant. For users requiring Presburger arithmetic without IR information, Presburger library can directly be used. For users requiring IR information, FlatAffineValueConstraints can be used. This patch merges FAC and FACV to remove redundancy of FAC. Reviewed By: arjunp Differential Revision: https://reviews.llvm.org/D122476
1 parent f99398f commit 0a06ac7

File tree

11 files changed

+225
-358
lines changed

11 files changed

+225
-358
lines changed

mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h

Lines changed: 107 additions & 206 deletions
Large diffs are not rendered by default.

mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#define DEBUG_TYPE "affine-analysis"
3030

3131
using namespace mlir;
32+
using namespace presburger;
3233

3334
/// Get the value that is being reduced by `pos`-th reduction in the loop if
3435
/// such a reduction can be performed by affine parallel loops. This assumes
@@ -445,12 +446,10 @@ static void computeDirectionVector(
445446
dependenceComponents->resize(numCommonLoops);
446447
for (unsigned j = 0; j < numCommonLoops; ++j) {
447448
(*dependenceComponents)[j].op = commonLoops[j].getOperation();
448-
auto lbConst =
449-
dependenceDomain->getConstantBound(FlatAffineConstraints::LB, j);
449+
auto lbConst = dependenceDomain->getConstantBound(IntegerPolyhedron::LB, j);
450450
(*dependenceComponents)[j].lb =
451451
lbConst.getValueOr(std::numeric_limits<int64_t>::min());
452-
auto ubConst =
453-
dependenceDomain->getConstantBound(FlatAffineConstraints::UB, j);
452+
auto ubConst = dependenceDomain->getConstantBound(IntegerPolyhedron::UB, j);
454453
(*dependenceComponents)[j].ub =
455454
ubConst.getValueOr(std::numeric_limits<int64_t>::max());
456455
}

mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp

Lines changed: 65 additions & 102 deletions
Large diffs are not rendered by default.

mlir/lib/Dialect/Affine/Analysis/Utils.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ ComputationSliceState::getAsConstraints(FlatAffineValueConstraints *cst) {
100100
if (isValidSymbol(value)) {
101101
// Check if the symbol is a constant.
102102
if (auto cOp = value.getDefiningOp<arith::ConstantIndexOp>())
103-
cst->addBound(FlatAffineConstraints::EQ, value, cOp.value());
103+
cst->addBound(FlatAffineValueConstraints::EQ, value, cOp.value());
104104
} else if (auto loop = getForInductionVarOwner(value)) {
105105
if (failed(cst->addAffineForOpDomain(loop)))
106106
return failure();
@@ -357,13 +357,13 @@ Optional<int64_t> MemRefRegion::getConstantBoundingSizeAndShape(
357357
// over-approximation from projection or union bounding box. We may not add
358358
// this on the region itself since they might just be redundant constraints
359359
// that will need non-trivials means to eliminate.
360-
FlatAffineConstraints cstWithShapeBounds(cst);
360+
FlatAffineValueConstraints cstWithShapeBounds(cst);
361361
for (unsigned r = 0; r < rank; r++) {
362-
cstWithShapeBounds.addBound(FlatAffineConstraints::LB, r, 0);
362+
cstWithShapeBounds.addBound(FlatAffineValueConstraints::LB, r, 0);
363363
int64_t dimSize = memRefType.getDimSize(r);
364364
if (ShapedType::isDynamic(dimSize))
365365
continue;
366-
cstWithShapeBounds.addBound(FlatAffineConstraints::UB, r, dimSize - 1);
366+
cstWithShapeBounds.addBound(FlatAffineValueConstraints::UB, r, dimSize - 1);
367367
}
368368

369369
// Find a constant upper bound on the extent of this memref region along each
@@ -440,7 +440,7 @@ LogicalResult MemRefRegion::unionBoundingBox(const MemRefRegion &other) {
440440
// }
441441
//
442442
// region: {memref = %A, write = false, {%i <= m0 <= %i + 7} }
443-
// The last field is a 2-d FlatAffineConstraints symbolic in %i.
443+
// The last field is a 2-d FlatAffineValueConstraints symbolic in %i.
444444
//
445445
// TODO: extend this to any other memref dereferencing ops
446446
// (dma_start, dma_wait).
@@ -520,7 +520,7 @@ LogicalResult MemRefRegion::compute(Operation *op, unsigned loopDepth,
520520
// Check if the symbol is a constant.
521521
if (auto *op = symbol.getDefiningOp()) {
522522
if (auto constOp = dyn_cast<arith::ConstantIndexOp>(op)) {
523-
cst.addBound(FlatAffineConstraints::EQ, symbol, constOp.value());
523+
cst.addBound(FlatAffineValueConstraints::EQ, symbol, constOp.value());
524524
}
525525
}
526526
}
@@ -585,10 +585,10 @@ LogicalResult MemRefRegion::compute(Operation *op, unsigned loopDepth,
585585
if (addMemRefDimBounds) {
586586
auto memRefType = memref.getType().cast<MemRefType>();
587587
for (unsigned r = 0; r < rank; r++) {
588-
cst.addBound(FlatAffineConstraints::LB, /*pos=*/r, /*value=*/0);
588+
cst.addBound(FlatAffineValueConstraints::LB, /*pos=*/r, /*value=*/0);
589589
if (memRefType.isDynamicDim(r))
590590
continue;
591-
cst.addBound(FlatAffineConstraints::UB, /*pos=*/r,
591+
cst.addBound(FlatAffineValueConstraints::UB, /*pos=*/r,
592592
memRefType.getDimSize(r) - 1);
593593
}
594594
}
@@ -677,7 +677,7 @@ LogicalResult mlir::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
677677

678678
// For each dimension, check for out of bounds.
679679
for (unsigned r = 0; r < rank; r++) {
680-
FlatAffineConstraints ucst(*region.getConstraints());
680+
FlatAffineValueConstraints ucst(*region.getConstraints());
681681

682682
// Intersect memory region with constraint capturing out of bounds (both out
683683
// of upper and out of lower), and check if the constraint system is
@@ -689,18 +689,18 @@ LogicalResult mlir::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
689689
continue;
690690

691691
// Check for overflow: d_i >= memref dim size.
692-
ucst.addBound(FlatAffineConstraints::LB, r, dimSize);
692+
ucst.addBound(FlatAffineValueConstraints::LB, r, dimSize);
693693
outOfBounds = !ucst.isEmpty();
694694
if (outOfBounds && emitError) {
695695
loadOrStoreOp.emitOpError()
696696
<< "memref out of upper bound access along dimension #" << (r + 1);
697697
}
698698

699699
// Check for a negative index.
700-
FlatAffineConstraints lcst(*region.getConstraints());
700+
FlatAffineValueConstraints lcst(*region.getConstraints());
701701
std::fill(ineq.begin(), ineq.end(), 0);
702702
// d_i <= -1;
703-
lcst.addBound(FlatAffineConstraints::UB, r, -1);
703+
lcst.addBound(FlatAffineValueConstraints::UB, r, -1);
704704
outOfBounds = !lcst.isEmpty();
705705
if (outOfBounds && emitError) {
706706
loadOrStoreOp.emitOpError()
@@ -1356,7 +1356,7 @@ void mlir::getSequentialLoops(AffineForOp forOp,
13561356
}
13571357

13581358
IntegerSet mlir::simplifyIntegerSet(IntegerSet set) {
1359-
FlatAffineConstraints fac(set);
1359+
FlatAffineValueConstraints fac(set);
13601360
if (fac.isEmpty())
13611361
return IntegerSet::getEmptySet(set.getNumDims(), set.getNumSymbols(),
13621362
set.getContext());

mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#define DEBUG_TYPE "LoopUtils"
3535

3636
using namespace mlir;
37+
using namespace presburger;
3738
using llvm::SmallMapVector;
3839

3940
namespace {
@@ -2364,8 +2365,8 @@ static bool getFullMemRefAsRegion(Operation *op, unsigned numParamLoopIVs,
23642365
for (unsigned d = 0; d < rank; d++) {
23652366
auto dimSize = memRefType.getDimSize(d);
23662367
assert(dimSize > 0 && "filtered dynamic shapes above");
2367-
regionCst->addBound(FlatAffineConstraints::LB, d, 0);
2368-
regionCst->addBound(FlatAffineConstraints::UB, d, dimSize - 1);
2368+
regionCst->addBound(IntegerPolyhedron::LB, d, 0);
2369+
regionCst->addBound(IntegerPolyhedron::UB, d, dimSize - 1);
23692370
}
23702371
return true;
23712372
}

mlir/lib/Dialect/Affine/Utils/Utils.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define DEBUG_TYPE "affine-utils"
2929

3030
using namespace mlir;
31+
using namespace presburger;
3132

3233
namespace {
3334
/// Visit affine expressions recursively and build the sequence of operations
@@ -1757,14 +1758,14 @@ MemRefType mlir::normalizeMemRefType(MemRefType memrefType, OpBuilder b,
17571758
// We have a single map that is not an identity map. Create a new memref
17581759
// with the right shape and an identity layout map.
17591760
ArrayRef<int64_t> shape = memrefType.getShape();
1760-
// FlatAffineConstraint may later on use symbolicOperands.
1761-
FlatAffineConstraints fac(rank, numSymbolicOperands);
1761+
// FlatAffineValueConstraint may later on use symbolicOperands.
1762+
FlatAffineValueConstraints fac(rank, numSymbolicOperands);
17621763
SmallVector<unsigned, 4> memrefTypeDynDims;
17631764
for (unsigned d = 0; d < rank; ++d) {
17641765
// Use constraint system only in static dimensions.
17651766
if (shape[d] > 0) {
1766-
fac.addBound(FlatAffineConstraints::LB, d, 0);
1767-
fac.addBound(FlatAffineConstraints::UB, d, shape[d] - 1);
1767+
fac.addBound(IntegerPolyhedron::LB, d, 0);
1768+
fac.addBound(IntegerPolyhedron::UB, d, shape[d] - 1);
17681769
} else {
17691770
memrefTypeDynDims.emplace_back(d);
17701771
}
@@ -1786,7 +1787,7 @@ MemRefType mlir::normalizeMemRefType(MemRefType memrefType, OpBuilder b,
17861787
newShape[d] = -1;
17871788
} else {
17881789
// The lower bound for the shape is always zero.
1789-
auto ubConst = fac.getConstantBound(FlatAffineConstraints::UB, d);
1790+
auto ubConst = fac.getConstantBound(IntegerPolyhedron::UB, d);
17901791
// For a static memref and an affine map with no symbols, this is
17911792
// always bounded.
17921793
assert(ubConst.hasValue() && "should always have an upper bound");

mlir/lib/Dialect/Linalg/Utils/Utils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define DEBUG_TYPE "linalg-utils"
3838

3939
using namespace mlir;
40+
using namespace presburger;
4041
using namespace mlir::linalg;
4142
using namespace mlir::scf;
4243

@@ -237,7 +238,7 @@ void getUpperBoundForIndex(Value value, AffineMap &boundMap,
237238
auto minOp = cast<AffineMinOp>(op);
238239
AffineMap map = constraints.computeAlignedMap(minOp.getAffineMap(),
239240
minOp.getOperands());
240-
if (failed(constraints.addBound(FlatAffineConstraints::UB,
241+
if (failed(constraints.addBound(IntegerPolyhedron::UB,
241242
getPosition(minOp.getResult()), map)))
242243
return;
243244
}

mlir/lib/Dialect/SCF/Utils/AffineCanonicalizationUtils.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define DEBUG_TYPE "mlir-scf-affine-utils"
2424

2525
using namespace mlir;
26+
using namespace presburger;
2627

2728
static void unpackOptionalValues(ArrayRef<Optional<Value>> source,
2829
SmallVector<Value> &target) {
@@ -38,7 +39,7 @@ static void unpackOptionalValues(ArrayRef<Optional<Value>> source,
3839
/// Note: This function adds a new symbol column to the `constraints` for each
3940
/// dimension/symbol that exists in the affine map but not in `constraints`.
4041
static LogicalResult alignAndAddBound(FlatAffineValueConstraints &constraints,
41-
FlatAffineConstraints::BoundType type,
42+
IntegerPolyhedron::BoundType type,
4243
unsigned pos, AffineMap map,
4344
ValueRange operands) {
4445
SmallVector<Value> dims, syms, newSyms;
@@ -113,8 +114,7 @@ canonicalizeMinMaxOp(RewriterBase &rewriter, Operation *op, AffineMap map,
113114

114115
// Add an inequality for each result expr_i of map:
115116
// isMin: op <= expr_i, !isMin: op >= expr_i
116-
auto boundType =
117-
isMin ? FlatAffineConstraints::UB : FlatAffineConstraints::LB;
117+
auto boundType = isMin ? IntegerPolyhedron::UB : IntegerPolyhedron::LB;
118118
// Upper bounds are exclusive, so add 1. (`affine.min` ops are inclusive.)
119119
AffineMap mapLbUb = isMin ? addConstToResults(map, 1) : map;
120120
if (failed(
@@ -136,7 +136,7 @@ canonicalizeMinMaxOp(RewriterBase &rewriter, Operation *op, AffineMap map,
136136
// Add an equality: Set dimOpBound to computed bound.
137137
// Add back dimension for op. (Was removed by `getSliceBounds`.)
138138
AffineMap alignedBoundMap = boundMap.shiftDims(/*shift=*/1, /*offset=*/dimOp);
139-
if (failed(constraints.addBound(FlatAffineConstraints::EQ, dimOpBound,
139+
if (failed(constraints.addBound(IntegerPolyhedron::EQ, dimOpBound,
140140
alignedBoundMap)))
141141
return failure();
142142

@@ -162,7 +162,7 @@ canonicalizeMinMaxOp(RewriterBase &rewriter, Operation *op, AffineMap map,
162162
// Note: These equalities could have been added earlier and used to express
163163
// minOp <= expr_i. However, then we run the risk that `getSliceBounds`
164164
// computes minOpUb in terms of r_i dims, which is not desired.
165-
if (failed(alignAndAddBound(newConstr, FlatAffineConstraints::EQ, i,
165+
if (failed(alignAndAddBound(newConstr, IntegerPolyhedron::EQ, i,
166166
map.getSubMap({i - resultDimStart}), operands)))
167167
return failure();
168168

@@ -189,7 +189,7 @@ canonicalizeMinMaxOp(RewriterBase &rewriter, Operation *op, AffineMap map,
189189
// Skip unused operands and operands that are already constants.
190190
if (!newOperands[i] || getConstantIntValue(newOperands[i]))
191191
continue;
192-
if (auto bound = constraints.getConstantBound(FlatAffineConstraints::EQ, i))
192+
if (auto bound = constraints.getConstantBound(IntegerPolyhedron::EQ, i))
193193
newOperands[i] =
194194
rewriter.create<arith::ConstantIndexOp>(op->getLoc(), *bound);
195195
}
@@ -203,7 +203,7 @@ static LogicalResult
203203
addLoopRangeConstraints(FlatAffineValueConstraints &constraints, Value iv,
204204
Value lb, Value ub, Value step,
205205
RewriterBase &rewriter) {
206-
// FlatAffineConstraints does not support semi-affine expressions.
206+
// IntegerPolyhedron does not support semi-affine expressions.
207207
// Therefore, only constant step values are supported.
208208
auto stepInt = getConstantIntValue(step);
209209
if (!stepInt)
@@ -217,9 +217,9 @@ addLoopRangeConstraints(FlatAffineValueConstraints &constraints, Value iv,
217217
Optional<int64_t> lbInt = getConstantIntValue(lb);
218218
Optional<int64_t> ubInt = getConstantIntValue(ub);
219219
if (lbInt)
220-
constraints.addBound(FlatAffineConstraints::EQ, dimLb, *lbInt);
220+
constraints.addBound(IntegerPolyhedron::EQ, dimLb, *lbInt);
221221
if (ubInt)
222-
constraints.addBound(FlatAffineConstraints::EQ, dimUb, *ubInt);
222+
constraints.addBound(IntegerPolyhedron::EQ, dimUb, *ubInt);
223223

224224
// Lower bound: iv >= lb (equiv.: iv - lb >= 0)
225225
SmallVector<int64_t> ineqLb(constraints.getNumCols(), 0);
@@ -248,7 +248,7 @@ addLoopRangeConstraints(FlatAffineValueConstraints &constraints, Value iv,
248248
/*dimCount=*/constraints.getNumDimIds(),
249249
/*symbolCount=*/constraints.getNumSymbolIds(), /*result=*/ivUb);
250250

251-
return constraints.addBound(FlatAffineConstraints::UB, dimIv, map);
251+
return constraints.addBound(IntegerPolyhedron::UB, dimIv, map);
252252
}
253253

254254
/// Canonicalize min/max operations in the context of for loops with a known
@@ -258,7 +258,7 @@ addLoopRangeConstraints(FlatAffineValueConstraints &constraints, Value iv,
258258
/// * iv >= lb
259259
/// * iv < lb + step * ((ub - lb - 1) floorDiv step) + 1
260260
///
261-
/// Note: Due to limitations of FlatAffineConstraints, only constant step sizes
261+
/// Note: Due to limitations of IntegerPolyhedron, only constant step sizes
262262
/// are currently supported.
263263
LogicalResult scf::canonicalizeMinMaxOpInLoop(RewriterBase &rewriter,
264264
Operation *op, AffineMap map,
@@ -321,9 +321,9 @@ LogicalResult scf::rewritePeeledMinMaxOp(RewriterBase &rewriter, Operation *op,
321321
FlatAffineValueConstraints constraints;
322322
constraints.appendDimId({iv, ub, step});
323323
if (auto constUb = getConstantIntValue(ub))
324-
constraints.addBound(FlatAffineConstraints::EQ, 1, *constUb);
324+
constraints.addBound(IntegerPolyhedron::EQ, 1, *constUb);
325325
if (auto constStep = getConstantIntValue(step))
326-
constraints.addBound(FlatAffineConstraints::EQ, 2, *constStep);
326+
constraints.addBound(IntegerPolyhedron::EQ, 2, *constStep);
327327

328328
// Add loop peeling invariant. This is the main piece of knowledge that
329329
// enables AffineMinOp simplification.

mlir/unittests/Dialect/Affine/Analysis/AffineStructuresParser.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
#include "mlir/Parser/Parser.h"
1212

1313
using namespace mlir;
14+
using namespace presburger;
1415

15-
FailureOr<FlatAffineConstraints>
16+
FailureOr<IntegerPolyhedron>
1617
mlir::parseIntegerSetToFAC(llvm::StringRef str, MLIRContext *context,
1718
bool printDiagnosticInfo) {
1819
IntegerSet set = parseIntegerSet(str, context, printDiagnosticInfo);
1920

2021
if (!set)
2122
return failure();
2223

23-
return FlatAffineConstraints(set);
24+
return FlatAffineValueConstraints(set);
2425
}

mlir/unittests/Dialect/Affine/Analysis/AffineStructuresParser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
namespace mlir {
2121

2222
/// This parses a single IntegerSet to an MLIR context and transforms it to
23-
/// FlatAffineConstraints if it was valid. If not, a failure is returned. If the
23+
/// IntegerPolyhedron if it was valid. If not, a failure is returned. If the
2424
/// passed `str` has additional tokens that were not part of the IntegerSet, a
2525
/// failure is returned. Diagnostics are printed on failure if
2626
/// `printDiagnosticInfo` is true.
2727

28-
FailureOr<FlatAffineConstraints>
28+
FailureOr<presburger::IntegerPolyhedron>
2929
parseIntegerSetToFAC(llvm::StringRef, MLIRContext *context,
3030
bool printDiagnosticInfo = true);
3131

0 commit comments

Comments
 (0)