13fef2d26SRiver Riddle //= TestAffineLoopParametricTiling.cpp -- Parametric Affine loop tiling pass =//
23fef2d26SRiver Riddle //
33fef2d26SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43fef2d26SRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
53fef2d26SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63fef2d26SRiver Riddle //
73fef2d26SRiver Riddle //===----------------------------------------------------------------------===//
83fef2d26SRiver Riddle //
93fef2d26SRiver Riddle // This file implements a test pass to test parametric tiling of perfectly
103fef2d26SRiver Riddle // nested affine for loops.
113fef2d26SRiver Riddle //
123fef2d26SRiver Riddle //===----------------------------------------------------------------------===//
133fef2d26SRiver Riddle 
143fef2d26SRiver Riddle #include "mlir/Dialect/Affine/IR/AffineOps.h"
15a70aa7bbSRiver Riddle #include "mlir/Dialect/Affine/LoopUtils.h"
163fef2d26SRiver Riddle #include "mlir/Dialect/Affine/Passes.h"
1736550692SRiver Riddle #include "mlir/Dialect/Func/IR/FuncOps.h"
183fef2d26SRiver Riddle 
193fef2d26SRiver Riddle using namespace mlir;
203fef2d26SRiver Riddle 
213fef2d26SRiver Riddle #define DEBUG_TYPE "test-affine-parametric-tile"
223fef2d26SRiver Riddle 
233fef2d26SRiver Riddle namespace {
243fef2d26SRiver Riddle struct TestAffineLoopParametricTiling
2541574554SRiver Riddle     : public PassWrapper<TestAffineLoopParametricTiling,
26*58ceae95SRiver Riddle                          OperationPass<func::FuncOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anondad0e7f70111::TestAffineLoopParametricTiling275e50dd04SRiver Riddle   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAffineLoopParametricTiling)
285e50dd04SRiver Riddle 
29b5e22e6dSMehdi Amini   StringRef getArgument() const final { return "test-affine-parametric-tile"; }
getDescription__anondad0e7f70111::TestAffineLoopParametricTiling30b5e22e6dSMehdi Amini   StringRef getDescription() const final {
31b5e22e6dSMehdi Amini     return "Tile affine loops using SSA values as tile sizes";
32b5e22e6dSMehdi Amini   }
3341574554SRiver Riddle   void runOnOperation() override;
343fef2d26SRiver Riddle };
35be0a7e9fSMehdi Amini } // namespace
363fef2d26SRiver Riddle 
373fef2d26SRiver Riddle /// Checks if the function enclosing the loop nest has any arguments passed to
383fef2d26SRiver Riddle /// it, which can be used as tiling parameters. Assumes that atleast 'n'
393fef2d26SRiver Riddle /// arguments are passed, where 'n' is the number of loops in the loop nest.
checkIfTilingParametersExist(ArrayRef<AffineForOp> band)403fef2d26SRiver Riddle static void checkIfTilingParametersExist(ArrayRef<AffineForOp> band) {
413fef2d26SRiver Riddle   assert(!band.empty() && "no loops in input band");
423fef2d26SRiver Riddle   AffineForOp topLoop = band[0];
433fef2d26SRiver Riddle 
44*58ceae95SRiver Riddle   if (func::FuncOp funcOp = dyn_cast<func::FuncOp>(topLoop->getParentOp()))
453fef2d26SRiver Riddle     assert(funcOp.getNumArguments() >= band.size() && "Too few tile sizes");
463fef2d26SRiver Riddle }
473fef2d26SRiver Riddle 
483fef2d26SRiver Riddle /// Captures tiling parameters, which are expected to be passed as arguments
493fef2d26SRiver Riddle /// to the function enclosing the loop nest. Also checks if the required
503fef2d26SRiver Riddle /// parameters are of index type. This approach is temporary for testing
513fef2d26SRiver Riddle /// purposes.
getTilingParameters(ArrayRef<AffineForOp> band,SmallVectorImpl<Value> & tilingParameters)523fef2d26SRiver Riddle static void getTilingParameters(ArrayRef<AffineForOp> band,
533fef2d26SRiver Riddle                                 SmallVectorImpl<Value> &tilingParameters) {
543fef2d26SRiver Riddle   AffineForOp topLoop = band[0];
553fef2d26SRiver Riddle   Region *funcOpRegion = topLoop->getParentRegion();
563fef2d26SRiver Riddle   unsigned nestDepth = band.size();
573fef2d26SRiver Riddle 
583fef2d26SRiver Riddle   for (BlockArgument blockArgument :
593fef2d26SRiver Riddle        funcOpRegion->getArguments().take_front(nestDepth)) {
603fef2d26SRiver Riddle     if (blockArgument.getArgNumber() < nestDepth) {
613fef2d26SRiver Riddle       assert(blockArgument.getType().isIndex() &&
623fef2d26SRiver Riddle              "expected tiling parameters to be of index type.");
633fef2d26SRiver Riddle       tilingParameters.push_back(blockArgument);
643fef2d26SRiver Riddle     }
653fef2d26SRiver Riddle   }
663fef2d26SRiver Riddle }
673fef2d26SRiver Riddle 
runOnOperation()6841574554SRiver Riddle void TestAffineLoopParametricTiling::runOnOperation() {
693fef2d26SRiver Riddle   // Bands of loops to tile.
703fef2d26SRiver Riddle   std::vector<SmallVector<AffineForOp, 6>> bands;
7141574554SRiver Riddle   getTileableBands(getOperation(), &bands);
723fef2d26SRiver Riddle 
733fef2d26SRiver Riddle   // Tile each band.
749cf9ed94SUday Bondhugula   for (MutableArrayRef<AffineForOp> band : bands) {
753fef2d26SRiver Riddle     // Capture the tiling parameters from the arguments to the function
763fef2d26SRiver Riddle     // enclosing this loop nest.
773fef2d26SRiver Riddle     SmallVector<AffineForOp, 6> tiledNest;
783fef2d26SRiver Riddle     SmallVector<Value, 6> tilingParameters;
793fef2d26SRiver Riddle     // Check if tiling parameters are present.
803fef2d26SRiver Riddle     checkIfTilingParametersExist(band);
813fef2d26SRiver Riddle 
823fef2d26SRiver Riddle     // Get function arguments as tiling parameters.
833fef2d26SRiver Riddle     getTilingParameters(band, tilingParameters);
843fef2d26SRiver Riddle 
859cf9ed94SUday Bondhugula     (void)tilePerfectlyNestedParametric(band, tilingParameters, &tiledNest);
863fef2d26SRiver Riddle   }
873fef2d26SRiver Riddle }
883fef2d26SRiver Riddle 
893fef2d26SRiver Riddle namespace mlir {
903fef2d26SRiver Riddle namespace test {
registerTestAffineLoopParametricTilingPass()913fef2d26SRiver Riddle void registerTestAffineLoopParametricTilingPass() {
92b5e22e6dSMehdi Amini   PassRegistration<TestAffineLoopParametricTiling>();
933fef2d26SRiver Riddle }
943fef2d26SRiver Riddle } // namespace test
953fef2d26SRiver Riddle } // namespace mlir
96