Skip to content

Commit 34526ed

Browse files
authored
[MLIR][Affine] Clean up outer logic of affine loop tiling pass (#149750)
Clean up outer logic of affine loop tiling pass. A wrongly named temporary method was exposed publicly; fix that. Remove unconditional emission of remarks.
1 parent a216702 commit 34526ed

File tree

5 files changed

+35
-44
lines changed

5 files changed

+35
-44
lines changed

mlir/include/mlir/Dialect/Affine/LoopUtils.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,6 @@ void promoteSingleIterationLoops(func::FuncOp f);
9898
LogicalResult affineForOpBodySkew(AffineForOp forOp, ArrayRef<uint64_t> shifts,
9999
bool unrollPrologueEpilogue = false);
100100

101-
/// Identify valid and profitable bands of loops to tile. This is currently just
102-
/// a temporary placeholder to test the mechanics of tiled code generation.
103-
/// Returns all maximal outermost perfect loop nests to tile.
104-
void getTileableBands(func::FuncOp f,
105-
std::vector<SmallVector<AffineForOp, 6>> *bands);
106-
107101
/// Tiles the specified band of perfectly nested loops creating tile-space loops
108102
/// and intra-tile loops. A band is a contiguous set of loops. This utility
109103
/// doesn't check for the validity of tiling itself, but just performs it.

mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file implements a pass to tile loop nests.
9+
// This file implements a pass to tile affine loop nests.
1010
//
1111
//===----------------------------------------------------------------------===//
1212

@@ -38,7 +38,7 @@ using namespace mlir::affine;
3838

3939
namespace {
4040

41-
/// A pass to perform loop tiling on all suitable loop nests of a Function.
41+
/// A pass to perform loop tiling on all suitable loop nests of a func op.
4242
struct LoopTiling : public affine::impl::AffineLoopTilingBase<LoopTiling> {
4343
LoopTiling() = default;
4444
explicit LoopTiling(uint64_t cacheSizeBytes, bool avoidMaxMinBounds = true)
@@ -59,6 +59,20 @@ struct LoopTiling : public affine::impl::AffineLoopTilingBase<LoopTiling> {
5959

6060
} // namespace
6161

62+
/// Get bands of loops that are valid to tile from the top-level of `f`.
63+
static void
64+
getTopLevelTileableBands(func::FuncOp f,
65+
std::vector<SmallVector<AffineForOp, 6>> &bands) {
66+
// Get maximal perfect nest of 'affine.for' ops starting from root
67+
// (inclusive).
68+
for (AffineForOp forOp : f.getOps<AffineForOp>()) {
69+
SmallVector<AffineForOp, 6> band;
70+
getPerfectlyNestedLoops(band, forOp);
71+
if (isTilingValid(band))
72+
bands.push_back(band);
73+
}
74+
}
75+
6276
/// Creates a pass to perform loop tiling on all suitable loop nests of a
6377
/// Function.
6478
std::unique_ptr<OperationPass<func::FuncOp>>
@@ -122,10 +136,6 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
122136
return;
123137
}
124138

125-
// The first loop in the band.
126-
AffineForOp rootForOp = band[0];
127-
(void)rootForOp;
128-
129139
// Obtain memory footprint and set tile sizes so that a tile fits in
130140
// the cache size. This is an approximation with the assumption that the
131141
// footprint increases with the tile size linearly in that dimension (i.e.,
@@ -136,6 +146,9 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
136146
llvm::fill(*tileSizes, LoopTiling::kDefaultTileSize);
137147
if (avoidMaxMinBounds)
138148
adjustToDivisorsOfTripCounts(band, tileSizes);
149+
// The first loop in the band.
150+
AffineForOp rootForOp = band[0];
151+
(void)rootForOp;
139152
LLVM_DEBUG(
140153
rootForOp.emitWarning("memory footprint unknown: using default tile "
141154
"sizes adjusted to trip count divisors"));
@@ -178,23 +191,17 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
178191
void LoopTiling::runOnOperation() {
179192
// Bands of loops to tile.
180193
std::vector<SmallVector<AffineForOp, 6>> bands;
181-
getTileableBands(getOperation(), &bands);
194+
getTopLevelTileableBands(getOperation(), bands);
182195

183196
// Tile each band.
184197
for (auto &band : bands) {
185-
if (!isTilingValid(band)) {
186-
band.front().emitRemark("tiling nest is invalid due to dependences");
187-
continue;
188-
}
189-
190198
// Set up tile sizes; fill missing tile sizes at the end with default tile
191199
// size or tileSize if one was provided.
192200
SmallVector<unsigned, 6> tileSizes;
193201
getTileSizes(band, &tileSizes);
194202
if (llvm::DebugFlag) {
195203
auto diag = band[0].emitRemark("using tile sizes [");
196-
for (unsigned tSize : tileSizes)
197-
diag << tSize << ' ';
204+
llvm::interleaveComma(tileSizes, llvm::dbgs());
198205
diag << "]\n";
199206
}
200207
SmallVector<AffineForOp, 6> tiledNest;
@@ -213,10 +220,8 @@ void LoopTiling::runOnOperation() {
213220
assert(!intraTileLoops.empty() &&
214221
"guaranteed to succeed on empty bands");
215222
LLVM_DEBUG(intraTileLoops.front()->emitRemark(
216-
"separation post tiling failed!\n"));
223+
"separation post tiling failed!"));
217224
}
218225
}
219226
}
220227
}
221-
222-
constexpr unsigned LoopTiling::kDefaultTileSize;

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -868,20 +868,6 @@ void mlir::affine::getPerfectlyNestedLoops(
868868
}
869869
}
870870

871-
/// Identify valid and profitable bands of loops to tile. This is currently just
872-
/// a temporary placeholder to test the mechanics of tiled code generation.
873-
/// Returns all maximal outermost perfect loop nests to tile.
874-
void mlir::affine::getTileableBands(
875-
func::FuncOp f, std::vector<SmallVector<AffineForOp, 6>> *bands) {
876-
// Get maximal perfect nest of 'affine.for' insts starting from root
877-
// (inclusive).
878-
for (AffineForOp forOp : f.getOps<AffineForOp>()) {
879-
SmallVector<AffineForOp, 6> band;
880-
getPerfectlyNestedLoops(band, forOp);
881-
bands->push_back(band);
882-
}
883-
}
884-
885871
/// Unrolls this loop completely.
886872
LogicalResult mlir::affine::loopUnrollFull(AffineForOp forOp) {
887873
std::optional<uint64_t> mayBeConstantTripCount = getConstantTripCount(forOp);

mlir/test/Dialect/Affine/loop-tiling-validity.mlir

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
// CHECK-DAG: [[$LB:#map[0-9]*]] = affine_map<(d0) -> (d0)>
88
// CHECK-DAG: [[$UB:#map[0-9]*]] = affine_map<(d0) -> (d0 + 32)>
99

10-
// CHECK-LABEL: func @legal_loop()
11-
func.func @legal_loop() {
10+
// CHECK-LABEL: func @valid_to_tile()
11+
func.func @valid_to_tile() {
1212
%0 = memref.alloc() : memref<64xf32>
1313

1414
affine.for %i = 0 to 64 {
@@ -20,8 +20,8 @@ func.func @legal_loop() {
2020
return
2121
}
2222

23-
// CHECK: affine.for %{{.*}} = 0 to 64 step 32 {
24-
// CHECK-NEXT: affine.for %{{.*}} = [[$LB]](%{{.*}}) to [[$UB]](%{{.*}}) {
23+
// CHECK: affine.for %{{.*}} = 0 to 64 step 32 {
24+
// CHECK-NEXT: affine.for %{{.*}} = [[$LB]](%{{.*}}) to [[$UB]](%{{.*}}) {
2525

2626
// -----
2727

@@ -33,8 +33,10 @@ func.func @legal_loop() {
3333
func.func @illegal_loop_with_diag_dependence() {
3434
%A = memref.alloc() : memref<64x64xf32>
3535

36+
// No tiling here.
37+
// CHECK: affine.for %{{.*}} = 0 to 64 {
38+
// CHECK-NEXT: affine.for %{{.*}} = 0 to 64 {
3639
affine.for %i = 0 to 64 {
37-
// expected-remark@above {{tiling nest is invalid due to dependences}}
3840
affine.for %j = 0 to 64 {
3941
%0 = affine.load %A[%j, %i] : memref<64x64xf32>
4042
%1 = affine.load %A[%i, %j - 1] : memref<64x64xf32>

mlir/test/lib/Dialect/Affine/TestAffineLoopParametricTiling.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,13 @@ getTilingParameters(ArrayRef<AffineForOp> band,
7474
}
7575

7676
void TestAffineLoopParametricTiling::runOnOperation() {
77-
// Bands of loops to tile.
77+
// Get maximal perfect nest of 'affine.for' ops at the top-level.
7878
std::vector<SmallVector<AffineForOp, 6>> bands;
79-
getTileableBands(getOperation(), &bands);
79+
for (AffineForOp forOp : getOperation().getOps<AffineForOp>()) {
80+
SmallVector<AffineForOp, 6> band;
81+
getPerfectlyNestedLoops(band, forOp);
82+
bands.push_back(band);
83+
}
8084

8185
// Tile each band.
8286
for (MutableArrayRef<AffineForOp> band : bands) {

0 commit comments

Comments
 (0)