MLIR 24.0.0git
AffineStructures.h
Go to the documentation of this file.
1//===- AffineStructures.h - MLIR Affine Structures Class --------*- 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// Structures for affine/polyhedral analysis of ML functions.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_DIALECT_AFFINE_ANALYSIS_AFFINESTRUCTURES_H
14#define MLIR_DIALECT_AFFINE_ANALYSIS_AFFINESTRUCTURES_H
15
19#include "mlir/IR/AffineExpr.h"
21#include <optional>
22
23namespace mlir {
24class AffineMap;
25class IntegerSet;
26class MemRefType;
27class MLIRContext;
28struct MutableAffineMap;
29class Value;
30
31namespace presburger {
33} // namespace presburger
34
35namespace affine {
36class AffineCondition;
37class AffineForOp;
38class AffineIfOp;
39class AffineParallelOp;
40class AffineValueMap;
41
42/// FlatAffineValueConstraints is an extension of FlatLinearValueConstraints
43/// with helper functions for Affine dialect ops.
45public:
47
48 /// Creates an affine constraint system from an IntegerSet. Returns failure
49 /// if `set` is semi-affine, as flattening is not implemented for those.
50 static FailureOr<FlatAffineValueConstraints>
51 create(IntegerSet set, ValueRange operands = {});
52
53 /// Return the kind of this object.
54 Kind getKind() const override { return Kind::FlatAffineValueConstraints; }
55
56 static bool classof(const IntegerRelation *cst) {
57 return cst->getKind() >= Kind::FlatAffineValueConstraints &&
58 cst->getKind() <= Kind::FlatAffineRelation;
59 }
60
61 /// Adds constraints (lower and upper bounds) for the specified 'affine.for'
62 /// operation's Value using IR information stored in its bound maps. The
63 /// right variable is first looked up using `forOp`'s Value. Asserts if the
64 /// Value corresponding to the 'affine.for' operation isn't found in the
65 /// constraint system. Returns failure for the yet unimplemented/unsupported
66 /// cases. Any new variables that are found in the bound operands of the
67 /// 'affine.for' operation are added as trailing variables (either
68 /// dimensional or symbolic depending on whether the operand is a valid
69 /// symbol).
70 LogicalResult addAffineForOpDomain(AffineForOp forOp);
71
72 /// Add constraints (lower and upper bounds) for the specified
73 /// 'affine.parallel' operation's Value using IR information stored in its
74 /// bound maps. Returns failure for the yet unimplemented/unsupported cases.
75 /// Asserts if the Value corresponding to the 'affine.parallel' operation
76 /// isn't found in the constraint system.
77 LogicalResult addAffineParallelOpDomain(AffineParallelOp parallelOp);
78
79 /// Adds constraints (lower and upper bounds) for each loop in the loop nest
80 /// described by the bound maps `lbMaps` and `ubMaps` of a computation slice.
81 /// Every pair (`lbMaps[i]`, `ubMaps[i]`) describes the bounds of a loop in
82 /// the nest, sorted outer-to-inner. `operands` contains the bound operands
83 /// for a single bound map. All the bound maps will use the same bound
84 /// operands. Note that some loops described by a computation slice might not
85 /// exist yet in the IR so the Value attached to those dimension variables
86 /// might be empty. For that reason, this method doesn't perform Value
87 /// look-ups to retrieve the dimension variable positions. Instead, it
88 /// assumes the position of the dim variables in the constraint system is
89 /// the same as the position of the loop in the loop nest.
92 ArrayRef<Value> operands);
93
94 /// Adds constraints imposed by the `affine.if` operation. These constraints
95 /// are collected from the IntegerSet attached to the given `affine.if`
96 /// instance argument (`ifOp`). It is asserted that:
97 /// 1) The IntegerSet of the given `affine.if` instance should not contain
98 /// semi-affine expressions,
99 /// 2) The columns of the constraint system created from `ifOp` should match
100 /// the columns in the current one regarding numbers and values.
101 void addAffineIfOpDomain(AffineIfOp ifOp);
102
103 /// Adds a bound for the variable at the specified position with constraints
104 /// being drawn from the specified bound map and operands. In case of an
105 /// EQ bound, the bound map is expected to have exactly one result. In case
106 /// of a LB/UB, the bound map may have more than one result, for each of which
107 /// an inequality is added.
108 LogicalResult addBound(presburger::BoundType type, unsigned pos,
109 AffineMap boundMap, ValueRange operands);
111
112 /// Add the specified values as a dim or symbol var depending on its nature,
113 /// if it already doesn't exist in the system. `val` has to be either a
114 /// terminal symbol or a loop IV, i.e., it cannot be the result of an
115 /// affine.apply of any symbols or loop IVs. Return failure if the addition
116 /// wasn't possible due to the above conditions not being met. This method can
117 /// also fail if the addition of the domain of an affine IV fails. The
118 /// variable is added to the end of the existing dims or symbols. Additional
119 /// information on the variable is extracted from the IR and added to the
120 /// constraint system.
121 LogicalResult addInductionVarOrTerminalSymbol(Value val);
122
123 /// Adds slice lower bounds represented by lower bounds in `lbMaps` and upper
124 /// bounds in `ubMaps` to each variable in the constraint system which has
125 /// a value in `values`. Note that both lower/upper bounds share the same
126 /// operand list `operands`.
127 /// This function assumes `values.size` == `lbMaps.size` == `ubMaps.size`.
128 /// Note that both lower/upper bounds use operands from `operands`.
129 LogicalResult addSliceBounds(ArrayRef<Value> values,
130 ArrayRef<AffineMap> lbMaps,
131 ArrayRef<AffineMap> ubMaps,
132 ArrayRef<Value> operands);
133
134 /// Changes all symbol variables which are loop IVs to dim variables.
136
137 /// Returns the bound for the variable at `pos` from the inequality at
138 /// `ineqPos` as a 1-d affine value map (affine map + operands). The returned
139 /// affine value map can either be a lower bound or an upper bound depending
140 /// on the sign of atIneq(ineqPos, pos). Asserts if the row at `ineqPos` does
141 /// not involve the `pos`th variable.
142 void getIneqAsAffineValueMap(unsigned pos, unsigned ineqPos,
143 AffineValueMap &vmap,
144 MLIRContext *context) const;
145
146 /// Composes the affine value map with this FlatAffineValueConstrains, adding
147 /// the results of the map as dimensions at the front
148 /// [0, vMap->getNumResults()) and with the dimensions set to the equalities
149 /// specified by the value map.
150 ///
151 /// Returns failure if the composition fails (when vMap is a semi-affine map).
152 /// The vMap's operand Value's are used to look up the right positions in
153 /// the FlatAffineValueConstraints with which to associate. Every operand of
154 /// vMap should have a matching dim/symbol column in this constraint system
155 /// (with the same associated Value).
156 LogicalResult composeMap(const AffineValueMap *vMap);
157};
158
159/// A FlatAffineRelation represents a set of ordered pairs (domain -> range)
160/// where "domain" and "range" are tuples of variables. The relation is
161/// represented as a FlatAffineValueConstraints with separation of dimension
162/// variables into domain and range. The variables are stored as:
163/// [domainVars, rangeVars, symbolVars, localVars, constant].
164///
165/// Deprecated: use IntegerRelation and store SSA Values in the PresburgerSpace
166/// of the relation using PresburgerSpace::identifiers. Note that
167/// FlatAffineRelation::numDomainDims and FlatAffineRelation::numRangeDims are
168/// independent of numDomain and numRange of the relation's space. In
169/// particular, operations such as FlatAffineRelation::compose do not ensure
170/// consistency between numDomainDims/numRangeDims and numDomain/numRange which
171/// may lead to unexpected behaviour.
173public:
174 FlatAffineRelation(unsigned numReservedInequalities,
175 unsigned numReservedEqualities, unsigned numReservedCols,
176 unsigned numDomainDims, unsigned numRangeDims,
177 unsigned numSymbols, unsigned numLocals,
178 ArrayRef<std::optional<Value>> valArgs = {})
180 numReservedInequalities, numReservedEqualities, numReservedCols,
181 numDomainDims + numRangeDims, numSymbols, numLocals, valArgs),
183
185 unsigned numSymbols = 0, unsigned numLocals = 0)
187 numLocals),
189
194
199
200 /// Return the kind of this object.
201 Kind getKind() const override { return Kind::FlatAffineRelation; }
202
203 static bool classof(const IntegerRelation *cst) {
204 return cst->getKind() == Kind::FlatAffineRelation;
205 }
206
207 /// Returns a set corresponding to the domain/range of the affine relation.
210
211 /// Returns the number of variables corresponding to domain/range of
212 /// relation.
213 inline unsigned getNumDomainDims() const { return numDomainDims; }
214 inline unsigned getNumRangeDims() const { return numRangeDims; }
215
216 /// Given affine relation `other: (domainOther -> rangeOther)`, this operation
217 /// takes the composition of `other` on `this: (domainThis -> rangeThis)`.
218 /// The resulting relation represents tuples of the form: `domainOther ->
219 /// rangeThis`.
220 void compose(const FlatAffineRelation &other);
221
222 /// Swap domain and range of the relation.
223 /// `(domain -> range)` is converted to `(range -> domain)`.
224 void inverse();
225
226 /// Insert `num` variables of the specified kind after the `pos` variable
227 /// of that kind. The coefficient columns corresponding to the added
228 /// variables are initialized to zero.
229 void insertDomainVar(unsigned pos, unsigned num = 1);
230 void insertRangeVar(unsigned pos, unsigned num = 1);
231
232 /// Append `num` variables of the specified kind after the last variable
233 /// of that kind. The coefficient columns corresponding to the added
234 /// variables are initialized to zero.
235 void appendDomainVar(unsigned num = 1);
236 void appendRangeVar(unsigned num = 1);
237
238 /// Removes variables in the column range [varStart, varLimit), and copies any
239 /// remaining valid data into place, updates member variables, and resizes
240 /// arrays as needed.
241 void removeVarRange(VarKind kind, unsigned varStart,
242 unsigned varLimit) override;
243 using IntegerRelation::removeVarRange;
244
245protected:
246 // Number of dimension variables corresponding to domain variables.
248
249 // Number of dimension variables corresponding to range variables.
250 unsigned numRangeDims;
251};
252
253/// Builds a relation from the given AffineMap/AffineValueMap `map`, containing
254/// all pairs of the form `operands -> result` that satisfy `map`. `rel` is set
255/// to the relation built. For example, give the AffineMap:
256///
257/// (d0, d1)[s0] -> (d0 + s0, d0 - s0)
258///
259/// the resulting relation formed is:
260///
261/// (d0, d1) -> (r1, r2)
262/// [d0 d1 r1 r2 s0 const]
263/// 1 0 -1 0 1 0 = 0
264/// 0 1 0 -1 -1 0 = 0
265///
266/// For AffineValueMap, the domain and symbols have Value set corresponding to
267/// the Value in `map`. Returns failure if the AffineMap could not be flattened
268/// (i.e., semi-affine is not yet handled).
269LogicalResult getRelationFromMap(AffineMap &map,
271LogicalResult getRelationFromMap(const AffineValueMap &map,
273
274} // namespace affine
275} // namespace mlir
276
277#endif // MLIR_DIALECT_AFFINE_ANALYSIS_AFFINESTRUCTURES_H
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
void addBound(presburger::BoundType type, Value val, int64_t value)
Adds a constant bound for the variable associated with the given Value.
FlatLinearValueConstraints(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, unsigned numDims, unsigned numSymbols, unsigned numLocals, ArrayRef< std::optional< Value > > valArgs)
Constructs a constraint system reserving memory for the specified number of constraints and variables...
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition IntegerSet.h:44
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
An AffineValueMap is an affine map plus its ML value operands and results for analysis purposes.
A FlatAffineRelation represents a set of ordered pairs (domain -> range) where "domain" and "range" a...
FlatAffineRelation(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, unsigned numDomainDims, unsigned numRangeDims, unsigned numSymbols, unsigned numLocals, ArrayRef< std::optional< Value > > valArgs={})
static bool classof(const IntegerRelation *cst)
void appendDomainVar(unsigned num=1)
Append num variables of the specified kind after the last variable of that kind.
void compose(const FlatAffineRelation &other)
Given affine relation other: (domainOther -> rangeOther), this operation takes the composition of oth...
unsigned getNumDomainDims() const
Returns the number of variables corresponding to domain/range of relation.
void inverse()
Swap domain and range of the relation.
FlatAffineValueConstraints getDomainSet() const
Returns a set corresponding to the domain/range of the affine relation.
FlatAffineRelation(unsigned numDomainDims=0, unsigned numRangeDims=0, unsigned numSymbols=0, unsigned numLocals=0)
Kind getKind() const override
Return the kind of this object.
void removeVarRange(VarKind kind, unsigned varStart, unsigned varLimit) override
Removes variables in the column range [varStart, varLimit), and copies any remaining valid data into ...
FlatAffineValueConstraints getRangeSet() const
void insertRangeVar(unsigned pos, unsigned num=1)
FlatAffineRelation(unsigned numDomainDims, unsigned numRangeDims, FlatAffineValueConstraints &fac)
FlatAffineRelation(unsigned numDomainDims, unsigned numRangeDims, IntegerPolyhedron &fac)
void insertDomainVar(unsigned pos, unsigned num=1)
Insert num variables of the specified kind after the pos variable of that kind.
FlatAffineValueConstraints is an extension of FlatLinearValueConstraints with helper functions for Af...
LogicalResult addBound(presburger::BoundType type, unsigned pos, AffineMap boundMap, ValueRange operands)
Adds a bound for the variable at the specified position with constraints being drawn from the specifi...
void addAffineIfOpDomain(AffineIfOp ifOp)
Adds constraints imposed by the affine.if operation.
void convertLoopIVSymbolsToDims()
Changes all symbol variables which are loop IVs to dim variables.
LogicalResult addDomainFromSliceMaps(ArrayRef< AffineMap > lbMaps, ArrayRef< AffineMap > ubMaps, ArrayRef< Value > operands)
Adds constraints (lower and upper bounds) for each loop in the loop nest described by the bound maps ...
LogicalResult addAffineParallelOpDomain(AffineParallelOp parallelOp)
Add constraints (lower and upper bounds) for the specified 'affine.parallel' operation's Value using ...
Kind getKind() const override
Return the kind of this object.
LogicalResult addAffineForOpDomain(AffineForOp forOp)
Adds constraints (lower and upper bounds) for the specified 'affine.for' operation's Value using IR i...
static FailureOr< FlatAffineValueConstraints > create(IntegerSet set, ValueRange operands={})
Creates an affine constraint system from an IntegerSet.
FlatLinearValueConstraints(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, unsigned numDims, unsigned numSymbols, unsigned numLocals, ArrayRef< std::optional< Value > > valArgs)
Constructs a constraint system reserving memory for the specified number of constraints and variables...
void getIneqAsAffineValueMap(unsigned pos, unsigned ineqPos, AffineValueMap &vmap, MLIRContext *context) const
Returns the bound for the variable at pos from the inequality at ineqPos as a 1-d affine value map (a...
LogicalResult addSliceBounds(ArrayRef< Value > values, ArrayRef< AffineMap > lbMaps, ArrayRef< AffineMap > ubMaps, ArrayRef< Value > operands)
Adds slice lower bounds represented by lower bounds in lbMaps and upper bounds in ubMaps to each vari...
LogicalResult composeMap(const AffineValueMap *vMap)
Composes the affine value map with this FlatAffineValueConstrains, adding the results of the map as d...
LogicalResult addInductionVarOrTerminalSymbol(Value val)
Add the specified values as a dim or symbol var depending on its nature, if it already doesn't exist ...
static bool classof(const IntegerRelation *cst)
IntegerPolyhedron(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, const PresburgerSpace &space)
Constructs a set reserving memory for the specified number of constraints and variables.
An IntegerRelation represents the set of points from a PresburgerSpace that satisfy a list of affine ...
Kind
All derived classes of IntegerRelation.
IntegerRelation(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, const PresburgerSpace &space)
Constructs a relation reserving memory for the specified number of constraints and variables.
This class represents a multi-affine function with the domain as Z^d, where d is the number of domain...
LogicalResult getRelationFromMap(AffineMap &map, presburger::IntegerRelation &rel)
Builds a relation from the given AffineMap/AffineValueMap map, containing all pairs of the form opera...
BoundType
The type of bound: equal, lower bound or upper bound.
Include the generated interface declarations.
A mutable affine map. Its affine expressions are however unique.
Definition AffineMap.h:430