1af5e83f5SUday Bondhugula //===- TestAffineLoopUnswitching.cpp - Test affine if/else hoisting -------===// 2af5e83f5SUday Bondhugula // 3af5e83f5SUday Bondhugula // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4af5e83f5SUday Bondhugula // See https://llvm.org/LICENSE.txt for license information. 5af5e83f5SUday Bondhugula // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6af5e83f5SUday Bondhugula // 7af5e83f5SUday Bondhugula //===----------------------------------------------------------------------===// 8af5e83f5SUday Bondhugula // 9af5e83f5SUday Bondhugula // This file implements a pass to hoist affine if/else structures. 10af5e83f5SUday Bondhugula // 11af5e83f5SUday Bondhugula //===----------------------------------------------------------------------===// 12af5e83f5SUday Bondhugula 13755dc07dSRiver Riddle #include "mlir/Dialect/Affine/Analysis/Utils.h" 14af5e83f5SUday Bondhugula #include "mlir/Dialect/Affine/IR/AffineOps.h" 15af5e83f5SUday Bondhugula #include "mlir/Dialect/Affine/Utils.h" 16af5e83f5SUday Bondhugula #include "mlir/Pass/Pass.h" 17af5e83f5SUday Bondhugula #include "mlir/Transforms/Passes.h" 18af5e83f5SUday Bondhugula 19af5e83f5SUday Bondhugula #define PASS_NAME "test-affine-loop-unswitch" 20af5e83f5SUday Bondhugula 21af5e83f5SUday Bondhugula using namespace mlir; 22af5e83f5SUday Bondhugula 23af5e83f5SUday Bondhugula namespace { 24af5e83f5SUday Bondhugula 25af5e83f5SUday Bondhugula /// This pass applies the permutation on the first maximal perfect nest. 26af5e83f5SUday Bondhugula struct TestAffineLoopUnswitching 2787d6bf37SRiver Riddle : public PassWrapper<TestAffineLoopUnswitching, OperationPass<>> { MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anon5bb0cbdb0111::TestAffineLoopUnswitching28*5e50dd04SRiver Riddle MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAffineLoopUnswitching) 29*5e50dd04SRiver Riddle 30b5e22e6dSMehdi Amini StringRef getArgument() const final { return PASS_NAME; } getDescription__anon5bb0cbdb0111::TestAffineLoopUnswitching31b5e22e6dSMehdi Amini StringRef getDescription() const final { 32b5e22e6dSMehdi Amini return "Tests affine loop unswitching / if/else hoisting"; 33b5e22e6dSMehdi Amini } 34af5e83f5SUday Bondhugula TestAffineLoopUnswitching() = default; 35322c8914SMehdi Amini TestAffineLoopUnswitching(const TestAffineLoopUnswitching &pass) = default; 36af5e83f5SUday Bondhugula 3741574554SRiver Riddle void runOnOperation() override; 38af5e83f5SUday Bondhugula 39af5e83f5SUday Bondhugula /// The maximum number of iterations to run this for. 40af5e83f5SUday Bondhugula constexpr static unsigned kMaxIterations = 5; 41af5e83f5SUday Bondhugula }; 42af5e83f5SUday Bondhugula 43be0a7e9fSMehdi Amini } // namespace 44af5e83f5SUday Bondhugula runOnOperation()4541574554SRiver Riddlevoid TestAffineLoopUnswitching::runOnOperation() { 46af5e83f5SUday Bondhugula // Each hoisting invalidates a lot of IR around. Just stop the walk after the 47af5e83f5SUday Bondhugula // first if/else hoisting, and repeat until no more hoisting can be done, or 48af5e83f5SUday Bondhugula // the maximum number of iterations have been run. 4987d6bf37SRiver Riddle Operation *op = getOperation(); 50af5e83f5SUday Bondhugula unsigned i = 0; 51af5e83f5SUday Bondhugula do { 52af5e83f5SUday Bondhugula auto walkFn = [](AffineIfOp op) { 53af5e83f5SUday Bondhugula return succeeded(hoistAffineIfOp(op)) ? WalkResult::interrupt() 54af5e83f5SUday Bondhugula : WalkResult::advance(); 55af5e83f5SUday Bondhugula }; 5687d6bf37SRiver Riddle if (op->walk(walkFn).wasInterrupted()) 57af5e83f5SUday Bondhugula break; 58af5e83f5SUday Bondhugula } while (++i < kMaxIterations); 59af5e83f5SUday Bondhugula } 60af5e83f5SUday Bondhugula 61af5e83f5SUday Bondhugula namespace mlir { registerTestAffineLoopUnswitchingPass()62af5e83f5SUday Bondhugulavoid registerTestAffineLoopUnswitchingPass() { 63b5e22e6dSMehdi Amini PassRegistration<TestAffineLoopUnswitching>(); 64af5e83f5SUday Bondhugula } 65af5e83f5SUday Bondhugula } // namespace mlir 66