MLIR  16.0.0git
Utils.h
Go to the documentation of this file.
1 //===- Utils.h - SCF dialect utilities --------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This header file defines prototypes for various SCF utilities.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef MLIR_DIALECT_SCF_UTILS_UTILS_H_
14 #define MLIR_DIALECT_SCF_UTILS_UTILS_H_
15
17 #include "mlir/IR/PatternMatch.h"
18 #include "mlir/Support/LLVM.h"
21
22 namespace mlir {
23 class Location;
24 class Operation;
25 class OpBuilder;
26 class Region;
27 class RewriterBase;
28 class ValueRange;
29 class Value;
30
31 namespace func {
32 class CallOp;
33 class FuncOp;
34 } // namespace func
35
36 /// Replace the loop with newIterOperands added as new initialization
37 /// values. newYieldValuesFn is a callback that can be used to specify
38 /// the additional values to be yielded by the loop. The number of
39 /// values returned by the callback should match the number of new
40 /// initialization values. This function
41 /// - Moves (i.e. doesnt clone) operations from the loop to the newly created
42 /// loop
43 /// - Replaces the uses of loop with the new loop.
44 /// - loop isnt erased, but is left in a "no-op" state where the body of the
45 /// loop just yields the basic block arguments that correspond to the
46 /// initialization values of a loop. The loop is dead after this method.
47 /// - All uses of the newIterOperands within the generated new loop
48 /// are replaced with the corresponding BlockArgument in the loop body.
49 using NewYieldValueFn = std::function<SmallVector<Value>(
51 scf::ForOp replaceLoopWithNewYields(OpBuilder &builder, scf::ForOp loop,
52  ValueRange newIterOperands,
53  const NewYieldValueFn &newYieldValuesFn);
54
55 /// Update a perfectly nested loop nest to yield new values from the innermost
56 /// loop and propagating it up through the loop nest. This function
57 /// - Expects loopNest to be a perfectly nested loop with outer most loop
58 /// first and innermost loop last.
59 /// - newIterOperands are the initialization values to be used for the
60 /// outermost loop
61 /// - newYielValueFn is the callback that generates the new values to be
62 /// yielded from within the innermost loop.
63 /// - The original loops are not erased, but are left in a "no-op" state where
64 /// the body of the loop just yields the basic block arguments that correspond
65 /// to the initialization values of a loop. The original loops are dead after
66 /// this method.
67 /// - All uses of the newIterOperands within the generated new loop
68 /// are replaced with the corresponding BlockArgument in the loop body.
71  ValueRange newIterOperands,
72  NewYieldValueFn newYieldValueFn);
73
74 /// Outline a region with a single block into a new FuncOp.
75 /// Assumes the FuncOp result types is the type of the yielded operands of the
76 /// single block. This constraint makes it easy to determine the result.
77 /// This method also clones the arith::ConstantIndexOp at the start of
78 /// outlinedFuncBody to alloc simple canonicalizations.
79 /// Creates a new FuncOp and thus cannot be used in a FuncOp pass.
80 /// The client is responsible for providing a unique funcName that will not
81 /// collide with another FuncOp name. If callOp is provided, it will be set
82 /// to point to the operation that calls the outlined function.
83 // TODO: support more than single-block regions.
84 // TODO: more flexible constant handling.
87  StringRef funcName, func::CallOp *callOp = nullptr);
88
89 /// Outline the then and/or else regions of ifOp as follows:
90 /// - if thenFn is not null, thenFnName must be specified and the then
91 /// region is inlined into a new FuncOp that is captured by the pointer.
92 /// - if elseFn is not null, elseFnName must be specified and the else
93 /// region is inlined into a new FuncOp that is captured by the pointer.
94 /// Creates new FuncOps and thus cannot be used in a FuncOp pass.
95 /// The client is responsible for providing a unique thenFnName/elseFnName
96 /// that will not collide with another FuncOp name.
97 LogicalResult outlineIfOp(RewriterBase &b, scf::IfOp ifOp, func::FuncOp *thenFn,
98  StringRef thenFnName, func::FuncOp *elseFn,
99  StringRef elseFnName);
100
101 /// Get a list of innermost parallel loops contained in rootOp. Innermost
102 /// parallel loops are those that do not contain further parallel loops
103 /// themselves.
106
107 /// Return the min/max expressions for value if it is an induction variable
108 /// from scf.for or scf.parallel loop.
109 /// if loopFilter is passed, the filter determines which loop to consider.
110 /// Other induction variables are ignored.
113  SmallVectorImpl<Value> &symbols,
114  llvm::function_ref<bool(Operation *)> loopFilter = nullptr);
115
116 /// Replace a perfect nest of "for" loops with a single linearized loop. Assumes
117 /// loops contains a list of perfectly nested loops with bounds and steps
118 /// independent of any loop induction variable involved in the nest.
120
121 /// Take the ParallelLoop and for each set of dimension indices, combine them
122 /// into a single dimension. combinedDimensions must contain each index into
123 /// loops exactly once.
124 void collapseParallelLoops(scf::ParallelOp loops,
125  ArrayRef<std::vector<unsigned>> combinedDimensions);
126
127 /// Promotes the loop body of a scf::ForOp to its containing block if the loop
128 /// was known to have a single iteration.
129 LogicalResult promoteIfSingleIteration(scf::ForOp forOp);
130
131 /// Unrolls this for operation by the specified unroll factor. Returns failure
132 /// if the loop cannot be unrolled either due to restrictions or due to invalid
133 /// unroll factors. Requires positive loop bounds and step. If specified,
134 /// annotates the Ops in each unrolled iteration by applying annotateFn.
136  scf::ForOp forOp, uint64_t unrollFactor,
137  function_ref<void(unsigned, Operation *, OpBuilder)> annotateFn = nullptr);
138
139 /// Tile a nest of standard for loops rooted at rootForOp by finding such
140 /// parametric tile sizes that the outer loops have a fixed number of iterations
141 /// as defined in sizes.
143 using TileLoops = std::pair<Loops, Loops>;
144 TileLoops extractFixedOuterLoops(scf::ForOp rootFOrOp, ArrayRef<int64_t> sizes);
145
146 /// Performs tiling fo imperfectly nested loops (with interchange) by
147 /// strip-mining the forOps by sizes and sinking them, in their order of
148 /// occurrence in forOps, under each of the targets.
149 /// Returns the new AffineForOps, one per each of (forOps, targets) pair,
150 /// nested immediately under each of targets.
152  ArrayRef<scf::ForOp> targets);
153
154 /// Performs tiling (with interchange) by strip-mining the forOps by sizes
155 /// and sinking them, in their order of occurrence in forOps, under target.
156 /// Returns the new AffineForOps, one per forOps, nested immediately under
157 /// target.
159  scf::ForOp target);
160
161 /// Tile a nest of scf::ForOp loops rooted at rootForOp with the given
162 /// (parametric) sizes. Sizes are expected to be strictly positive values at
163 /// runtime. If more sizes than loops are provided, discard the trailing values
164 /// in sizes. Assumes the loop nest is permutable.
165 /// Returns the newly created intra-tile loops.
166 Loops tilePerfectlyNested(scf::ForOp rootForOp, ArrayRef<Value> sizes);
167
168 /// Get perfectly nested sequence of loops starting at root of loop nest
169 /// (the first op being another AffineFor, and the second op - a terminator).
170 /// A loop is perfectly nested iff: the first op in the loop's body is another
171 /// AffineForOp, and the second op is a terminator).
173  scf::ForOp root);
174
175 } // namespace mlir
176
177 #endif // MLIR_DIALECT_SCF_UTILS_UTILS_H_
Include the generated interface declarations.
SmallVector< scf::ForOp > replaceLoopNestWithNewYields(OpBuilder &builder, ArrayRef< scf::ForOp > loopNest, ValueRange newIterOperands, NewYieldValueFn newYieldValueFn)
Update a perfectly nested loop nest to yield new values from the innermost loop and propagating it up...
Definition: Utils.cpp:105
FailureOr< func::FuncOp > outlineSingleBlockRegion(RewriterBase &rewriter, Location loc, Region &region, StringRef funcName, func::CallOp *callOp=nullptr)
Outline a region with a single block into a new FuncOp.
Definition: Utils.cpp:139
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
bool getInnermostParallelLoops(Operation *rootOp, SmallVectorImpl< scf::ParallelOp > &result)
Get a list of innermost parallel loops contained in rootOp.
Definition: Utils.cpp:266
std::pair< Loops, Loops > TileLoops
Definition: Utils.h:143
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
LogicalResult coalesceLoops(MutableArrayRef< AffineForOp > loops)
Replace a perfect nest of "for" loops with a single linearized loop.
Definition: LoopUtils.cpp:1715
LogicalResult promoteIfSingleIteration(AffineForOp forOp)
Promotes the loop body of a AffineForOp to its containing block if the loop was known to have a singl...
Definition: LoopUtils.cpp:131
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
LogicalResult tilePerfectlyNested(MutableArrayRef< AffineForOp > input, ArrayRef< unsigned > tileSizes, SmallVectorImpl< AffineForOp > *tiledNest=nullptr)
Tiles the specified band of perfectly nested loops creating tile-space loops and intra-tile loops...
Definition: LoopUtils.cpp:859
void collapseParallelLoops(scf::ParallelOp loops, ArrayRef< std::vector< unsigned >> combinedDimensions)
Take the ParallelLoop and for each set of dimension indices, combine them into a single dimension...
Definition: Utils.cpp:668
LogicalResult outlineIfOp(RewriterBase &b, scf::IfOp ifOp, func::FuncOp *thenFn, StringRef thenFnName, func::FuncOp *elseFn, StringRef elseFnName)
Outline the then and/or else regions of ifOp as follows:
Definition: Utils.cpp:243
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
This class provides support for representing a failure result, or a valid value of type T...
Definition: LogicalResult.h:78
SmallVector< SmallVector< AffineForOp, 8 >, 8 > tile(ArrayRef< AffineForOp > forOps, ArrayRef< uint64_t > sizes, ArrayRef< AffineForOp > targets)
Performs tiling fo imperfectly nested loops (with interchange) by strip-mining the forOps by sizes an...
Definition: LoopUtils.cpp:1692
LogicalResult loopUnrollByFactor(AffineForOp forOp, uint64_t unrollFactor, function_ref< void(unsigned, Operation *, OpBuilder)> annotateFn=nullptr)
Unrolls this for operation by the specified unroll factor.
Definition: LoopUtils.cpp:1091
void getPerfectlyNestedLoops(SmallVectorImpl< AffineForOp > &nestedLoops, AffineForOp root)
Get perfectly nested sequence of loops starting at root of loop nest (the first op being another Affi...
Definition: LoopUtils.cpp:945
scf::ForOp replaceLoopWithNewYields(OpBuilder &builder, scf::ForOp loop, ValueRange newIterOperands, const NewYieldValueFn &newYieldValuesFn)
Definition: Utils.cpp:41
TileLoops extractFixedOuterLoops(scf::ForOp rootFOrOp, ArrayRef< int64_t > sizes)
Definition: Utils.cpp:925
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
This class helps build Operations.
Definition: Builders.h:192
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:345
std::function< SmallVector< Value >(OpBuilder &b, Location loc, ArrayRef< BlockArgument > newBBArgs)> NewYieldValueFn
Replace the loop with newIterOperands added as new initialization values.
Definition: Utils.h:50
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
Definition: PatternMatch.h:398
Optional< std::pair< AffineExpr, AffineExpr > > getSCFMinMaxExpr(Value value, SmallVectorImpl< Value > &dims, SmallVectorImpl< Value > &symbols, llvm::function_ref< bool(Operation *)> loopFilter=nullptr)
Return the min/max expressions for value if it is an induction variable from scf.for or scf...