6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
//
9
- // This file implements a pass to tile loop nests.
9
+ // This file implements a pass to tile affine loop nests.
10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
@@ -38,7 +38,7 @@ using namespace mlir::affine;
38
38
39
39
namespace {
40
40
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 .
42
42
struct LoopTiling : public affine ::impl::AffineLoopTilingBase<LoopTiling> {
43
43
LoopTiling () = default ;
44
44
explicit LoopTiling (uint64_t cacheSizeBytes, bool avoidMaxMinBounds = true )
@@ -59,6 +59,20 @@ struct LoopTiling : public affine::impl::AffineLoopTilingBase<LoopTiling> {
59
59
60
60
} // namespace
61
61
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
+
62
76
// / Creates a pass to perform loop tiling on all suitable loop nests of a
63
77
// / Function.
64
78
std::unique_ptr<OperationPass<func::FuncOp>>
@@ -122,10 +136,6 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
122
136
return ;
123
137
}
124
138
125
- // The first loop in the band.
126
- AffineForOp rootForOp = band[0 ];
127
- (void )rootForOp;
128
-
129
139
// Obtain memory footprint and set tile sizes so that a tile fits in
130
140
// the cache size. This is an approximation with the assumption that the
131
141
// footprint increases with the tile size linearly in that dimension (i.e.,
@@ -136,6 +146,9 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
136
146
llvm::fill (*tileSizes, LoopTiling::kDefaultTileSize );
137
147
if (avoidMaxMinBounds)
138
148
adjustToDivisorsOfTripCounts (band, tileSizes);
149
+ // The first loop in the band.
150
+ AffineForOp rootForOp = band[0 ];
151
+ (void )rootForOp;
139
152
LLVM_DEBUG (
140
153
rootForOp.emitWarning (" memory footprint unknown: using default tile "
141
154
" sizes adjusted to trip count divisors" ));
@@ -178,23 +191,17 @@ void LoopTiling::getTileSizes(ArrayRef<AffineForOp> band,
178
191
void LoopTiling::runOnOperation () {
179
192
// Bands of loops to tile.
180
193
std::vector<SmallVector<AffineForOp, 6 >> bands;
181
- getTileableBands (getOperation (), & bands);
194
+ getTopLevelTileableBands (getOperation (), bands);
182
195
183
196
// Tile each band.
184
197
for (auto &band : bands) {
185
- if (!isTilingValid (band)) {
186
- band.front ().emitRemark (" tiling nest is invalid due to dependences" );
187
- continue ;
188
- }
189
-
190
198
// Set up tile sizes; fill missing tile sizes at the end with default tile
191
199
// size or tileSize if one was provided.
192
200
SmallVector<unsigned , 6 > tileSizes;
193
201
getTileSizes (band, &tileSizes);
194
202
if (llvm::DebugFlag) {
195
203
auto diag = band[0 ].emitRemark (" using tile sizes [" );
196
- for (unsigned tSize : tileSizes)
197
- diag << tSize << ' ' ;
204
+ llvm::interleaveComma (tileSizes, llvm::dbgs ());
198
205
diag << " ]\n " ;
199
206
}
200
207
SmallVector<AffineForOp, 6 > tiledNest;
@@ -213,10 +220,8 @@ void LoopTiling::runOnOperation() {
213
220
assert (!intraTileLoops.empty () &&
214
221
" guaranteed to succeed on empty bands" );
215
222
LLVM_DEBUG (intraTileLoops.front ()->emitRemark (
216
- " separation post tiling failed!\n " ));
223
+ " separation post tiling failed!" ));
217
224
}
218
225
}
219
226
}
220
227
}
221
-
222
- constexpr unsigned LoopTiling::kDefaultTileSize ;
0 commit comments