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
3939namespace {
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 .
4242struct 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.
6478std::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,
178191void 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 ;
0 commit comments