1 //===- LoopInvariantCodeMotionUtils.h - LICM Utils --------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef MLIR_TRANSFORMS_LOOPINVARIANTCODEMOTIONUTILS_H 10 #define MLIR_TRANSFORMS_LOOPINVARIANTCODEMOTIONUTILS_H 11 12 #include "mlir/Support/LLVM.h" 13 14 namespace mlir { 15 16 class LoopLikeOpInterface; 17 class Operation; 18 class Region; 19 class RegionRange; 20 class Value; 21 22 /// Given a list of regions, perform loop-invariant code motion. An operation is 23 /// loop-invariant if it depends only of values defined outside of the loop. 24 /// LICM moves these operations out of the loop body so that they are not 25 /// computed more than once. 26 /// 27 /// Example: 28 /// 29 /// ```mlir 30 /// affine.for %arg0 = 0 to 10 { 31 /// affine.for %arg1 = 0 to 10 { 32 /// %v0 = arith.addi %arg0, %arg0 : i32 33 /// %v1 = arith.addi %v0, %arg1 : i32 34 /// } 35 /// } 36 /// ``` 37 /// 38 /// After LICM: 39 /// 40 /// ```mlir 41 /// affine.for %arg0 = 0 to 10 { 42 /// %v0 = arith.addi %arg0, %arg0 : i32 43 /// affine.for %arg1 = 0 to 10 { 44 /// %v1 = arith.addi %v0, %arg1 : i32 45 /// } 46 /// } 47 /// ``` 48 /// 49 /// Users must supply three callbacks. 50 /// 51 /// - `isDefinedOutsideRegion` returns true if the given value is invariant with 52 /// respect to the given region. A common implementation might be: 53 /// `value.getParentRegion()->isProperAncestor(region)`. 54 /// - `shouldMoveOutOfRegion` returns true if the provided operation can be 55 /// moved of the given region, e.g. if it is side-effect free. 56 /// - `moveOutOfRegion` moves the operation out of the given region. A common 57 /// implementation might be: `op->moveBefore(region->getParentOp())`. 58 /// 59 /// An operation is moved if all of its operands satisfy 60 /// `isDefinedOutsideRegion` and it satisfies `shouldMoveOutOfRegion`. 61 /// 62 /// Returns the number of operations moved. 63 size_t moveLoopInvariantCode( 64 RegionRange regions, 65 function_ref<bool(Value, Region *)> isDefinedOutsideRegion, 66 function_ref<bool(Operation *, Region *)> shouldMoveOutOfRegion, 67 function_ref<void(Operation *, Region *)> moveOutOfRegion); 68 69 /// Move side-effect free loop invariant code out of a loop-like op using 70 /// methods provided by the interface. 71 size_t moveLoopInvariantCode(LoopLikeOpInterface loopLike); 72 73 } // end namespace mlir 74 75 #endif // MLIR_TRANSFORMS_LOOPINVARIANTCODEMOTIONUTILS_H 76