MLIR 23.0.0git
AffineOps.h
Go to the documentation of this file.
1//===- AffineOps.h - MLIR Affine Operations -------------------------------===//
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// This file defines convenience types for working with Affine operations
10// in the MLIR operation set.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_DIALECT_AFFINE_IR_AFFINEOPS_H
15#define MLIR_DIALECT_AFFINE_IR_AFFINEOPS_H
16
20#include "mlir/IR/AffineMap.h"
21#include "mlir/IR/Builders.h"
24namespace mlir {
25namespace affine {
26
27class AffineApplyOp;
28class AffineBound;
29class AffineMaxOp;
30class AffineMinOp;
31class AffineValueMap;
32
33/// A utility function to check if a value is defined at the top level of an
34/// op with trait `AffineScope` or is a region argument for such an op. A value
35/// of index type defined at the top level is always a valid symbol for all its
36/// uses.
37bool isTopLevelValue(Value value);
38
39/// A utility function to check if a value is defined at the top level of
40/// `region` or is an argument of `region`. A value of index type defined at the
41/// top level of a `AffineScope` region is always a valid symbol for all
42/// uses in that region.
43bool isTopLevelValue(Value value, Region *region);
44
45/// Returns the closest region enclosing `op` that is held by an operation with
46/// trait `AffineScope`; `nullptr` if there is no such region.
47Region *getAffineScope(Operation *op);
48
49/// Returns the closest region enclosing `op` that is held by a non-affine
50/// operation; `nullptr` if there is no such region. This method is meant to
51/// be used by affine analysis methods (e.g. dependence analysis) which are
52/// only meaningful when performed among/between operations from the same
53/// analysis scope.
54Region *getAffineAnalysisScope(Operation *op);
55
56/// Return the product of `terms`, creating an `affine.apply` if any of them are
57/// non-constant values. If any of `terms` is `nullptr`, return `nullptr`.
60
61/// Returns true if the given Value can be used as a dimension id in the region
62/// of the closest surrounding op that has the trait `AffineScope`.
63bool isValidDim(Value value);
64
65/// Returns true if the given Value can be used as a dimension id in `region`,
66/// i.e., for all its uses in `region`.
67bool isValidDim(Value value, Region *region);
68
69/// Returns true if the given value can be used as a symbol in the region of the
70/// closest surrounding op that has the trait `AffineScope`.
71bool isValidSymbol(Value value);
72
73/// Returns true if the given Value can be used as a symbol for `region`, i.e.,
74/// for all its uses in `region`.
75bool isValidSymbol(Value value, Region *region);
76
77/// Parses dimension and symbol list. `numDims` is set to the number of
78/// dimensions in the list parsed.
79ParseResult parseDimAndSymbolList(OpAsmParser &parser,
80 SmallVectorImpl<Value> &operands,
81 unsigned &numDims);
82
83/// Modifies both `map` and `operands` in-place so as to:
84/// 1. drop duplicate operands
85/// 2. drop unused dims and symbols from map
86/// 3. promote valid symbols to symbolic operands in case they appeared as
87/// dimensional operands
88/// 4. propagate constant operands and drop them
90 SmallVectorImpl<Value> *operands);
91
92/// Canonicalizes an integer set the same way canonicalizeMapAndOperands does
93/// for affine maps.
95 SmallVectorImpl<Value> *operands);
96
97/// Returns a composed AffineApplyOp by composing `map` and `operands` with
98/// other AffineApplyOps supplying those operands. The operands of the resulting
99/// AffineApplyOp do not change the length of AffineApplyOp chains.
100AffineApplyOp makeComposedAffineApply(OpBuilder &b, Location loc, AffineMap map,
101 ArrayRef<OpFoldResult> operands,
102 bool composeAffineMin = false);
104 ArrayRef<OpFoldResult> operands,
105 bool composeAffineMin = false);
106
107/// Constructs an AffineApplyOp that applies `map` to `operands` after composing
108/// the map with the maps of any other AffineApplyOp supplying the operands,
109/// then immediately attempts to fold it. If folding results in a constant
110/// value, no ops are actually created. The `map` must be a single-result affine
111/// map.
113 AffineMap map,
114 ArrayRef<OpFoldResult> operands,
115 bool composeAffineMin = false);
116/// Variant of `makeComposedFoldedAffineApply` that applies to an expression.
118 AffineExpr expr,
119 ArrayRef<OpFoldResult> operands,
120 bool composeAffineMin = false);
121/// Variant of `makeComposedFoldedAffineApply` suitable for multi-result maps.
122/// Note that this may create as many affine.apply operations as the map has
123/// results given that affine.apply must be single-result.
126 bool composeAffineMin = false);
127
128/// Returns an AffineMinOp obtained by composing `map` and `operands` with
129/// AffineApplyOps supplying those operands.
130AffineMinOp makeComposedAffineMin(OpBuilder &b, Location loc, AffineMap map,
131 ArrayRef<OpFoldResult> operands);
132
133/// Constructs an AffineMinOp that computes a minimum across the results of
134/// applying `map` to `operands`, then immediately attempts to fold it. If
135/// folding results in a constant value, no ops are actually created.
137 AffineMap map,
138 ArrayRef<OpFoldResult> operands);
139
140/// Constructs an AffineMinOp that computes a maximum across the results of
141/// applying `map` to `operands`, then immediately attempts to fold it. If
142/// folding results in a constant value, no ops are actually created.
144 AffineMap map,
145 ArrayRef<OpFoldResult> operands);
146
147/// Given an affine map `map` and its input `operands`, this method composes
148/// into `map`, maps of AffineApplyOps whose results are the values in
149/// `operands`, iteratively until no more of `operands` are the result of an
150/// AffineApplyOp. When this function returns, `map` becomes the composed affine
151/// map, and each Value in `operands` is guaranteed to be either a loop IV or a
152/// terminal symbol, i.e., a symbol defined at the top level or a block/function
153/// argument.
155 SmallVectorImpl<Value> *operands,
156 bool composeAffineMin = false);
157
158} // namespace affine
159} // namespace mlir
160
161#include "mlir/Dialect/Affine/IR/AffineOpsDialect.h.inc"
162
163#define GET_OP_CLASSES
164#include "mlir/Dialect/Affine/IR/AffineOps.h.inc"
165
166namespace mlir {
167namespace affine {
168
169/// Returns true if the provided value is the induction variable of an
170/// AffineForOp.
171bool isAffineForInductionVar(Value val);
172
173/// Returns true if `val` is the induction variable of an AffineParallelOp.
174bool isAffineParallelInductionVar(Value val);
175
176/// Returns true if the provided value is the induction variable of an
177/// AffineForOp or AffineParallelOp.
178bool isAffineInductionVar(Value val);
179
180/// Returns the loop parent of an induction variable. If the provided value is
181/// not an induction variable, then return nullptr.
182AffineForOp getForInductionVarOwner(Value val);
183
184/// Returns true if the provided value is among the induction variables of an
185/// AffineParallelOp.
186AffineParallelOp getAffineParallelInductionVarOwner(Value val);
187
188/// Extracts the induction variables from a list of AffineForOps and places them
189/// in the output argument `ivs`.
190void extractForInductionVars(ArrayRef<AffineForOp> forInsts,
191 SmallVectorImpl<Value> *ivs);
192
193/// Extracts the induction variables from a list of either AffineForOp or
194/// AffineParallelOp and places them in the output argument `ivs`.
195void extractInductionVars(ArrayRef<Operation *> affineOps,
196 SmallVectorImpl<Value> &ivs);
197
198/// Builds a perfect nest of affine.for loops, i.e., each loop except the
199/// innermost one contains only another loop and a terminator. The loops iterate
200/// from "lbs" to "ubs" with "steps". The body of the innermost loop is
201/// populated by calling "bodyBuilderFn" and providing it with an OpBuilder, a
202/// Location and a list of loop induction variables.
203void buildAffineLoopNest(OpBuilder &builder, Location loc,
204 ArrayRef<int64_t> lbs, ArrayRef<int64_t> ubs,
205 ArrayRef<int64_t> steps,
206 function_ref<void(OpBuilder &, Location, ValueRange)>
207 bodyBuilderFn = nullptr);
208void buildAffineLoopNest(OpBuilder &builder, Location loc, ValueRange lbs,
209 ValueRange ubs, ArrayRef<int64_t> steps,
210 function_ref<void(OpBuilder &, Location, ValueRange)>
211 bodyBuilderFn = nullptr);
212
213/// AffineBound represents a lower or upper bound in the for operation.
214/// This class does not own the underlying operands. Instead, it refers
215/// to the operands stored in the AffineForOp. Its life span should not exceed
216/// that of the for operation it refers to.
217class AffineBound {
218public:
220 AffineMap getMap() { return map; }
221
222 unsigned getNumOperands() { return operands.size(); }
223 Value getOperand(unsigned idx) {
224 return op.getOperand(operands.getBeginOperandIndex() + idx);
225 }
226
227 using operand_iterator = AffineForOp::operand_iterator;
228 using operand_range = AffineForOp::operand_range;
229
230 operand_iterator operandBegin() { return operands.begin(); }
231 operand_iterator operandEnd() { return operands.end(); }
233
234private:
235 // 'affine.for' operation that contains this bound.
236 AffineForOp op;
237 // Operands of the affine map.
238 OperandRange operands;
239 // Affine map for this bound.
240 AffineMap map;
241
242 AffineBound(AffineForOp op, OperandRange operands, AffineMap map)
243 : op(op), operands(operands), map(map) {}
244
245 friend class AffineForOp;
246};
247
248} // namespace affine
249} // namespace mlir
250
251#endif
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
Base type for affine expression.
Definition AffineExpr.h:68
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition IntegerSet.h:44
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This class helps build Operations.
Definition Builders.h:209
This class represents a single result from folding an operation.
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:43
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition Region.h:26
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
AffineBound represents a lower or upper bound in the for operation.
Definition AffineOps.h:217
Value getOperand(unsigned idx)
Definition AffineOps.h:223
operand_iterator operandBegin()
Definition AffineOps.h:230
AffineForOp::operand_iterator operand_iterator
Definition AffineOps.h:227
AffineForOp::operand_range operand_range
Definition AffineOps.h:228
AffineForOp getAffineForOp()
Definition AffineOps.h:219
operand_range getOperands()
Definition AffineOps.h:232
operand_iterator operandEnd()
Definition AffineOps.h:231
An AffineValueMap is an affine map plus its ML value operands and results for analysis purposes.
void buildAffineLoopNest(OpBuilder &builder, Location loc, ArrayRef< int64_t > lbs, ArrayRef< int64_t > ubs, ArrayRef< int64_t > steps, function_ref< void(OpBuilder &, Location, ValueRange)> bodyBuilderFn=nullptr)
Builds a perfect nest of affine.for loops, i.e., each loop except the innermost one contains only ano...
AffineApplyOp makeComposedAffineApply(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands, bool composeAffineMin=false)
Returns a composed AffineApplyOp by composing map and operands with other AffineApplyOps supplying th...
void extractForInductionVars(ArrayRef< AffineForOp > forInsts, SmallVectorImpl< Value > *ivs)
Extracts the induction variables from a list of AffineForOps and places them in the output argument i...
bool isValidDim(Value value)
Returns true if the given Value can be used as a dimension id in the region of the closest surroundin...
bool isAffineInductionVar(Value val)
Returns true if the provided value is the induction variable of an AffineForOp or AffineParallelOp.
SmallVector< OpFoldResult > makeComposedFoldedMultiResultAffineApply(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands, bool composeAffineMin=false)
Variant of makeComposedFoldedAffineApply suitable for multi-result maps.
OpFoldResult computeProduct(Location loc, OpBuilder &builder, ArrayRef< OpFoldResult > terms)
Return the product of terms, creating an affine.apply if any of them are non-constant values.
AffineForOp getForInductionVarOwner(Value val)
Returns the loop parent of an induction variable.
void canonicalizeMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands)
Modifies both map and operands in-place so as to:
OpFoldResult makeComposedFoldedAffineMax(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands)
Constructs an AffineMinOp that computes a maximum across the results of applying map to operands,...
bool isAffineForInductionVar(Value val)
Returns true if the provided value is the induction variable of an AffineForOp.
OpFoldResult makeComposedFoldedAffineApply(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands, bool composeAffineMin=false)
Constructs an AffineApplyOp that applies map to operands after composing the map with the maps of any...
OpFoldResult makeComposedFoldedAffineMin(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands)
Constructs an AffineMinOp that computes a minimum across the results of applying map to operands,...
bool isTopLevelValue(Value value)
A utility function to check if a value is defined at the top level of an op with trait AffineScope or...
Region * getAffineAnalysisScope(Operation *op)
Returns the closest region enclosing op that is held by a non-affine operation; nullptr if there is n...
void fullyComposeAffineMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands, bool composeAffineMin=false)
Given an affine map map and its input operands, this method composes into map, maps of AffineApplyOps...
void canonicalizeSetAndOperands(IntegerSet *set, SmallVectorImpl< Value > *operands)
Canonicalizes an integer set the same way canonicalizeMapAndOperands does for affine maps.
void extractInductionVars(ArrayRef< Operation * > affineOps, SmallVectorImpl< Value > &ivs)
Extracts the induction variables from a list of either AffineForOp or AffineParallelOp and places the...
bool isValidSymbol(Value value)
Returns true if the given value can be used as a symbol in the region of the closest surrounding op t...
AffineParallelOp getAffineParallelInductionVarOwner(Value val)
Returns true if the provided value is among the induction variables of an AffineParallelOp.
Region * getAffineScope(Operation *op)
Returns the closest region enclosing op that is held by an operation with trait AffineScope; nullptr ...
ParseResult parseDimAndSymbolList(OpAsmParser &parser, SmallVectorImpl< Value > &operands, unsigned &numDims)
Parses dimension and symbol list.
bool isAffineParallelInductionVar(Value val)
Returns true if val is the induction variable of an AffineParallelOp.
AffineMinOp makeComposedAffineMin(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands)
Returns an AffineMinOp obtained by composing map and operands with AffineApplyOps supplying those ope...
Include the generated interface declarations.
llvm::function_ref< Fn > function_ref
Definition LLVM.h:144