[Mlir-commits] [mlir] ecddafd - [MLIR] NFC affine for op tiling cleanup / utility rename
Uday Bondhugula
llvmlistbot at llvm.org
Sat Apr 18 12:37:37 PDT 2020
Author: Uday Bondhugula
Date: 2020-04-19T00:53:34+05:30
New Revision: ecddafd84a7aa74fb8c4087926db16eb1c459028
URL: https://github.com/llvm/llvm-project/commit/ecddafd84a7aa74fb8c4087926db16eb1c459028
DIFF: https://github.com/llvm/llvm-project/commit/ecddafd84a7aa74fb8c4087926db16eb1c459028.diff
LOG: [MLIR] NFC affine for op tiling cleanup / utility rename
Rename mlir::tileCodeGen -> mlir::tilePerfectlyNested to be consistent.
NFC clean up tiling utility code, drop dead code, better comments.
Expose isPerfectlyNested and reuse.
Differential Revision: https://reviews.llvm.org/D78423
Added:
Modified:
mlir/include/mlir/Transforms/LoopUtils.h
mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
mlir/lib/Transforms/Utils/LoopUtils.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Transforms/LoopUtils.h b/mlir/include/mlir/Transforms/LoopUtils.h
index 1d0e8d39bd61..30f024e9f1b1 100644
--- a/mlir/include/mlir/Transforms/LoopUtils.h
+++ b/mlir/include/mlir/Transforms/LoopUtils.h
@@ -45,6 +45,10 @@ LogicalResult loopUnrollByFactor(AffineForOp forOp, uint64_t unrollFactor);
/// whichever is lower.
LogicalResult loopUnrollUpToFactor(AffineForOp forOp, uint64_t unrollFactor);
+/// Returns true if `loops` is a perfectly nested loop nest, where loops appear
+/// in it from outermost to innermost.
+bool LLVM_ATTRIBUTE_UNUSED isPerfectlyNested(ArrayRef<AffineForOp> loops);
+
/// Get perfectly nested sequence of loops starting at root of loop nest
/// (the first op being another AffineFor, and the second op - a terminator).
/// A loop is perfectly nested iff: the first op in the loop's body is another
@@ -84,10 +88,12 @@ LogicalResult affineForOpBodySkew(AffineForOp forOp, ArrayRef<uint64_t> shifts,
/// Tiles the specified band of perfectly nested loops creating tile-space loops
/// and intra-tile loops. A band is a contiguous set of loops. `tiledNest` when
/// non-null is set to the loops of the tiled nest from outermost to innermost.
+/// Loops in `input` are erased when the tiling is successful.
LLVM_NODISCARD
-LogicalResult tileCodeGen(MutableArrayRef<AffineForOp> band,
- ArrayRef<unsigned> tileSizes,
- SmallVectorImpl<AffineForOp> *tiledNest = nullptr);
+LogicalResult
+tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
+ ArrayRef<unsigned> tileSizes,
+ SmallVectorImpl<AffineForOp> *tiledNest = nullptr);
/// Performs loop interchange on 'forOpA' and 'forOpB'. Requires that 'forOpA'
/// and 'forOpB' are part of a perfectly nested sequence of loops.
diff --git a/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp b/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
index f6d1a5494be2..ce692e405ae1 100644
--- a/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
@@ -93,10 +93,8 @@ constructTiledIndexSetHyperRect(MutableArrayRef<AffineForOp> origLoops,
// Bounds for tile space loops.
for (unsigned i = 0; i < width; i++) {
- auto lbOperands = origLoops[i].getLowerBoundOperands();
- auto ubOperands = origLoops[i].getUpperBoundOperands();
- SmallVector<Value, 4> newLbOperands(lbOperands);
- SmallVector<Value, 4> newUbOperands(ubOperands);
+ OperandRange newLbOperands = origLoops[i].getLowerBoundOperands();
+ OperandRange newUbOperands = origLoops[i].getUpperBoundOperands();
newLoops[i].setLowerBound(newLbOperands, origLoops[i].getLowerBoundMap());
newLoops[i].setUpperBound(newUbOperands, origLoops[i].getUpperBoundMap());
newLoops[i].setStep(tileSizes[i]);
@@ -111,8 +109,7 @@ constructTiledIndexSetHyperRect(MutableArrayRef<AffineForOp> origLoops,
/*operands=*/newLoops[i].getInductionVar(), lbMap);
// Set the upper bound.
- if (mayBeConstantCount.hasValue() &&
- mayBeConstantCount.getValue() < tileSizes[i]) {
+ if (mayBeConstantCount && mayBeConstantCount.getValue() < tileSizes[i]) {
// Trip count is less than tile size; upper bound is the trip count.
auto ubMap = b.getConstantAffineMap(mayBeConstantCount.getValue());
newLoops[width + i].setUpperBoundMap(ubMap);
@@ -121,20 +118,22 @@ constructTiledIndexSetHyperRect(MutableArrayRef<AffineForOp> origLoops,
// Construct the upper bound map; the operands are the original operands
// with 'i' (tile-space loop) appended to it. The new upper bound map is
// the original one with an additional expression i + tileSize appended.
- auto ub = origLoops[i].getUpperBound();
+
+ // Add dim operands from original upper bound.
SmallVector<Value, 4> ubOperands;
+ auto ub = origLoops[i].getUpperBound();
ubOperands.reserve(ub.getNumOperands() + 1);
auto origUbMap = ub.getMap();
- // Add dim operands from original upper bound.
- for (unsigned j = 0, e = origUbMap.getNumDims(); j < e; ++j) {
+ for (unsigned j = 0, e = origUbMap.getNumDims(); j < e; ++j)
ubOperands.push_back(ub.getOperand(j));
- }
+
// Add dim operand for new loop upper bound.
ubOperands.push_back(newLoops[i].getInductionVar());
+
// Add symbol operands from original upper bound.
- for (unsigned j = 0, e = origUbMap.getNumSymbols(); j < e; ++j) {
+ for (unsigned j = 0, e = origUbMap.getNumSymbols(); j < e; ++j)
ubOperands.push_back(ub.getOperand(origUbMap.getNumDims() + j));
- }
+
SmallVector<AffineExpr, 4> boundExprs;
boundExprs.reserve(1 + origUbMap.getNumResults());
auto dim = b.getAffineDimExpr(origUbMap.getNumDims());
@@ -159,22 +158,22 @@ constructTiledIndexSetHyperRect(MutableArrayRef<AffineForOp> origLoops,
/// Tiles the specified band of perfectly nested loops creating tile-space loops
/// and intra-tile loops. A band is a contiguous set of loops.
// TODO(bondhugula): handle non hyper-rectangular spaces.
-LogicalResult mlir::tileCodeGen(MutableArrayRef<AffineForOp> band,
- ArrayRef<unsigned> tileSizes,
- SmallVectorImpl<AffineForOp> *tiledNest) {
+LogicalResult
+mlir::tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
+ ArrayRef<unsigned> tileSizes,
+ SmallVectorImpl<AffineForOp> *tiledNest) {
// Check if the supplied for op's are all successively nested.
- assert(!band.empty() && "no loops in band");
- assert(band.size() == tileSizes.size() && "Too few/many tile sizes");
+ assert(!input.empty() && "no loops in input band");
+ assert(input.size() == tileSizes.size() && "Too few/many tile sizes");
- for (unsigned i = 1, e = band.size(); i < e; i++)
- assert(band[i].getParentOp() == band[i - 1] && "not a perfect nest / band");
+ assert(isPerfectlyNested(input) && "input loops not perfectly nested");
- auto origLoops = band;
+ auto origLoops = input;
AffineForOp rootAffineForOp = origLoops[0];
auto loc = rootAffineForOp.getLoc();
// Note that width is at least one since band isn't empty.
- unsigned width = band.size();
+ unsigned width = input.size();
SmallVector<AffineForOp, 6> tiledLoops(2 * width);
@@ -209,14 +208,13 @@ LogicalResult mlir::tileCodeGen(MutableArrayRef<AffineForOp> band,
}
// Move the loop body of the original nest to the new one.
- moveLoopBody(origLoops[origLoops.size() - 1], innermostPointLoop);
+ moveLoopBody(origLoops.back(), innermostPointLoop);
SmallVector<Value, 8> origLoopIVs;
- extractForInductionVars(band, &origLoopIVs);
- SmallVector<Optional<Value>, 6> ids(origLoopIVs.begin(), origLoopIVs.end());
- FlatAffineConstraints cst;
- getIndexSet(band, &cst);
+ extractForInductionVars(input, &origLoopIVs);
+ FlatAffineConstraints cst;
+ getIndexSet(input, &cst);
if (!cst.isHyperRectangular(0, width)) {
llvm::dbgs() << "tiled code generation unimplemented for the "
"non-hyperrectangular case, op:"
@@ -258,15 +256,15 @@ static void getTileableBands(FuncOp f,
getMaximalPerfectLoopNest(forOp);
}
-// Reduce each tile size to the largest divisor of the corresponding trip count
-// (if the trip count is known).
+/// Reduces each tile size to the largest divisor of the corresponding trip
+/// count (if the trip count is known).
static void adjustToDivisorsOfTripCounts(ArrayRef<AffineForOp> band,
SmallVectorImpl<unsigned> *tileSizes) {
assert(band.size() == tileSizes->size() && "invalid tile size count");
for (unsigned i = 0, e = band.size(); i < e; i++) {
unsigned &tSizeAdjusted = (*tileSizes)[i];
auto mayConst = getConstantTripCount(band[i]);
- if (!mayConst.hasValue())
+ if (!mayConst)
continue;
// Adjust the tile size to largest factor of the trip count less than
// tSize.
@@ -289,8 +287,8 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
if (band.empty())
return;
- // Use tileSize for all loops if specified.
- if (tileSize.hasValue()) {
+ // Use command-line tileSize for all loops if specified.
+ if (tileSize) {
tileSizes->assign(band.size(), tileSize);
return;
}
@@ -312,7 +310,7 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
// footprint increases with the tile size linearly in that dimension (i.e.,
// assumes one-to-one access function).
auto fp = getMemoryFootprintBytes(band[0], 0);
- if (!fp.hasValue()) {
+ if (!fp) {
// Fill with default tile sizes if footprint is unknown.
std::fill(tileSizes->begin(), tileSizes->end(),
LoopTiling::kDefaultTileSize);
@@ -339,7 +337,7 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
// one possible approach. Or compute a polynomial in tile sizes and solve for
// it.
- // For an n-d tileable band, compute n^th root of the excess.
+ // For an n-d tileable band, compute the n^th root of the excess.
unsigned tSize =
static_cast<unsigned>(floorl(std::pow(excessFactor, 1.0 / band.size())));
// We'll keep a running product to determine the last tile size better.
@@ -375,7 +373,7 @@ void LoopTiling::runOnFunction() {
diag << "]\n";
}
SmallVector<AffineForOp, 6> tiledNest;
- if (failed(tileCodeGen(band, tileSizes, &tiledNest)))
+ if (failed(tilePerfectlyNested(band, tileSizes, &tiledNest)))
return signalPassFailure();
// Separate full and partial tiles.
diff --git a/mlir/lib/Transforms/Utils/LoopUtils.cpp b/mlir/lib/Transforms/Utils/LoopUtils.cpp
index 2175e6709f65..0161fbef621e 100644
--- a/mlir/lib/Transforms/Utils/LoopUtils.cpp
+++ b/mlir/lib/Transforms/Utils/LoopUtils.cpp
@@ -707,8 +707,8 @@ bool mlir::isValidLoopInterchangePermutation(ArrayRef<AffineForOp> loops,
/// Returns true if `loops` is a perfectly nested loop nest, where loops appear
/// in it from outermost to innermost.
-static bool LLVM_ATTRIBUTE_UNUSED
-isPerfectlyNested(ArrayRef<AffineForOp> loops) {
+bool LLVM_ATTRIBUTE_UNUSED
+mlir::isPerfectlyNested(ArrayRef<AffineForOp> loops) {
assert(!loops.empty() && "no loops provided");
// We already know that the block can't be empty.
More information about the Mlir-commits
mailing list