MLIR 22.0.0git
Transforms.h
Go to the documentation of this file.
1//===- Transforms.h - Transforms Entrypoints --------------------*- 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// This header file defines a set of transforms specific for the AffineOps
10// dialect.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_DIALECT_AFFINE_TRANSFORMS_TRANSFORMS_H
15#define MLIR_DIALECT_AFFINE_TRANSFORMS_TRANSFORMS_H
16
18#include "mlir/Support/LLVM.h"
19
20namespace mlir {
21class AffineMap;
22class Location;
23class OpBuilder;
24class OpFoldResult;
26class RewriterBase;
27class Value;
28
29namespace presburger {
30enum class BoundType;
31} // namespace presburger
32
33namespace affine {
34class AffineApplyOp;
35class AffineDelinearizeIndexOp;
36class AffineLinearizeIndexOp;
37class AffineMaxOp;
38class AffineMinOp;
39
40/// Lowers `affine.delinearize_index` into a sequence of division and remainder
41/// operations.
42LogicalResult lowerAffineDelinearizeIndexOp(RewriterBase &rewriter,
43 AffineDelinearizeIndexOp op);
44
45/// Lowers `affine.linearize_index` into a sequence of multiplications and
46/// additions. Make a best effort to sort the input indices so that
47/// the most loop-invariant terms are at the left of the additions
48/// to enable loop-invariant code motion.
49LogicalResult lowerAffineLinearizeIndexOp(RewriterBase &rewriter,
50 AffineLinearizeIndexOp op);
51
52/// Populate patterns that expand affine index operations into more fundamental
53/// operations (not necessarily restricted to Affine dialect).
54void populateAffineExpandIndexOpsPatterns(RewritePatternSet &patterns);
55
56/// Populate patterns that expand affine index operations into their equivalent
57/// `affine.apply` representations.
59
60/// Helper function to rewrite `op`'s affine map and reorder its operands such
61/// that they are in increasing order of hoistability (i.e. the least hoistable)
62/// operands come first in the operand list.
63void reorderOperandsByHoistability(RewriterBase &rewriter, AffineApplyOp op);
64
65/// Split an "affine.apply" operation into smaller ops.
66/// This reassociates a large AffineApplyOp into an ordered list of smaller
67/// AffineApplyOps. This can be used right before lowering affine ops to arith
68/// to exhibit more opportunities for CSE and LICM.
69/// Return the sink AffineApplyOp on success or failure if `op` does not
70/// decompose into smaller AffineApplyOps.
71/// Note that this can be undone by canonicalization which tries to
72/// maximally compose chains of AffineApplyOps.
73FailureOr<AffineApplyOp> decompose(RewriterBase &rewriter, AffineApplyOp op);
74
75/// Reify a bound for the given variable in terms of SSA values for which
76/// `stopCondition` is met.
77///
78/// By default, lower/equal bounds are closed and upper bounds are open. If
79/// `closedUB` is set to "true", upper bounds are also closed.
80FailureOr<OpFoldResult>
81reifyValueBound(OpBuilder &b, Location loc, presburger::BoundType type,
82 const ValueBoundsConstraintSet::Variable &var,
84 bool closedUB = false);
85
86/// Reify a bound for the given index-typed value in terms of SSA values for
87/// which `stopCondition` is met. If no stop condition is specified, reify in
88/// terms of the operands of the owner op.
89///
90/// By default, lower/equal bounds are closed and upper bounds are open. If
91/// `closedUB` is set to "true", upper bounds are also closed.
92///
93/// Example:
94/// %0 = arith.addi %a, %b : index
95/// %1 = arith.addi %0, %c : index
96///
97/// * If `stopCondition` evaluates to "true" for %0 and %c, "%0 + %c" is an EQ
98/// bound for %1.
99/// * If `stopCondition` evaluates to "true" for %a, %b and %c, "%a + %b + %c"
100/// is an EQ bound for %1.
101/// * Otherwise, if the owners of %a, %b or %c do not implement the
102/// ValueBoundsOpInterface, no bound can be computed.
103FailureOr<OpFoldResult> reifyIndexValueBound(
104 OpBuilder &b, Location loc, presburger::BoundType type, Value value,
105 ValueBoundsConstraintSet::StopConditionFn stopCondition = nullptr,
106 bool closedUB = false);
107
108/// Reify a bound for the specified dimension of the given shaped value in terms
109/// of SSA values for which `stopCondition` is met. If no stop condition is
110/// specified, reify in terms of the operands of the owner op.
111///
112/// By default, lower/equal bounds are closed and upper bounds are open. If
113/// `closedUB` is set to "true", upper bounds are also closed.
114FailureOr<OpFoldResult> reifyShapedValueDimBound(
115 OpBuilder &b, Location loc, presburger::BoundType type, Value value,
116 int64_t dim,
117 ValueBoundsConstraintSet::StopConditionFn stopCondition = nullptr,
118 bool closedUB = false);
119
120/// Materialize an already computed bound with Affine dialect ops.
121///
122/// * `ValueBoundsOpInterface::computeBound` computes bounds but does not
123/// create IR. It is dialect independent.
124/// * `materializeComputedBound` materializes computed bounds with Affine
125/// dialect ops.
126/// * `reifyIndexValueBound`/`reifyShapedValueDimBound` are a combination of
127/// the two functions mentioned above.
128OpFoldResult materializeComputedBound(
129 OpBuilder &b, Location loc, AffineMap boundMap,
130 ArrayRef<std::pair<Value, std::optional<int64_t>>> mapOperands);
131
132/// This transform tries to simplify the affine min operation `op`, by finding a
133/// common lower bound for a set of expressions in the affine map results. It
134/// returns whether the transform updated `op`'s affine map.
135///
136/// In concrete terms, given an operation like:
137/// `affine.min affine_map<(d0)[s0, s1] -> (d0, s1, s0, 128)>(%i)[%s0, %s1]`
138/// If `d0 < 128` and `128 < s1 < s0`, the transform will update `op` to:
139/// `affine.min affine_map<(d0)[s0, s1] -> (d0, 128)>(%i)[%s0, %s1]`.
140bool simplifyAffineMinOp(RewriterBase &rewriter, AffineMinOp op);
141
142/// This transform tries to simplify the affine max operation `op`, by finding a
143/// common upper bound for a set of expressions in the affine map results. It
144/// returns whether the transform updated `op`'s affine map.
145///
146/// In concrete terms, given an operation like:
147/// `affine.max affine_map<(d0)[s0, s1] -> (d0, s1, s0, 128)>(%i)[%s0, %s1]`
148/// If `d0 > 128` and `s0 > s1 > 128`, the transform will update `op` to:
149/// `affine.max affine_map<(d0)[s0, s1] -> (d0, s0)>(%i)[%s0, %s1]`.
150bool simplifyAffineMaxOp(RewriterBase &rewriter, AffineMaxOp op);
151
152/// This transform applies `simplifyAffineMinOp` and `simplifyAffineMaxOp` to
153/// all the `affine.min` or `affine.max` operations in `ops`. After
154/// simplification, it invokes the `affine.min/max` canonicalization patterns on
155/// `ops`.
156///
157/// This transform returns failure if the greedy pattern rewriter failed to
158/// converge during canonicalization, otherwise it returns success. If provided,
159/// `modified` is set to `true` if the IR was modified in any way.
160LogicalResult simplifyAffineMinMaxOps(RewriterBase &rewriter,
161 ArrayRef<Operation *> ops,
162 bool *modified = nullptr);
163} // namespace affine
164} // namespace mlir
165
166#endif // MLIR_DIALECT_AFFINE_TRANSFORMS_TRANSFORMS_H
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
This class helps build Operations.
Definition Builders.h:207
This class represents a single result from folding an operation.
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
std::function< bool( Value, std::optional< int64_t >, ValueBoundsConstraintSet &cstr)> StopConditionFn
The stop condition when traversing the backward slice of a shaped value/ index-type value.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
bool simplifyAffineMaxOp(RewriterBase &rewriter, AffineMaxOp op)
This transform tries to simplify the affine max operation op, by finding a common upper bound for a s...
FailureOr< OpFoldResult > reifyValueBound(OpBuilder &b, Location loc, presburger::BoundType type, const ValueBoundsConstraintSet::Variable &var, ValueBoundsConstraintSet::StopConditionFn stopCondition, bool closedUB=false)
Reify a bound for the given variable in terms of SSA values for which stopCondition is met.
LogicalResult lowerAffineDelinearizeIndexOp(RewriterBase &rewriter, AffineDelinearizeIndexOp op)
Lowers affine.delinearize_index into a sequence of division and remainder operations.
FailureOr< OpFoldResult > reifyIndexValueBound(OpBuilder &b, Location loc, presburger::BoundType type, Value value, ValueBoundsConstraintSet::StopConditionFn stopCondition=nullptr, bool closedUB=false)
Reify a bound for the given index-typed value in terms of SSA values for which stopCondition is met.
FailureOr< AffineApplyOp > decompose(RewriterBase &rewriter, AffineApplyOp op)
Split an "affine.apply" operation into smaller ops.
LogicalResult lowerAffineLinearizeIndexOp(RewriterBase &rewriter, AffineLinearizeIndexOp op)
Lowers affine.linearize_index into a sequence of multiplications and additions.
OpFoldResult materializeComputedBound(OpBuilder &b, Location loc, AffineMap boundMap, ArrayRef< std::pair< Value, std::optional< int64_t > > > mapOperands)
Materialize an already computed bound with Affine dialect ops.
bool simplifyAffineMinOp(RewriterBase &rewriter, AffineMinOp op)
This transform tries to simplify the affine min operation op, by finding a common lower bound for a s...
LogicalResult simplifyAffineMinMaxOps(RewriterBase &rewriter, ArrayRef< Operation * > ops, bool *modified=nullptr)
This transform applies simplifyAffineMinOp and simplifyAffineMaxOp to all the affine....
void populateAffineExpandIndexOpsPatterns(RewritePatternSet &patterns)
Populate patterns that expand affine index operations into more fundamental operations (not necessari...
FailureOr< OpFoldResult > reifyShapedValueDimBound(OpBuilder &b, Location loc, presburger::BoundType type, Value value, int64_t dim, ValueBoundsConstraintSet::StopConditionFn stopCondition=nullptr, bool closedUB=false)
Reify a bound for the specified dimension of the given shaped value in terms of SSA values for which ...
void reorderOperandsByHoistability(RewriterBase &rewriter, AffineApplyOp op)
Helper function to rewrite op's affine map and reorder its operands such that they are in increasing ...
void populateAffineExpandIndexOpsAsAffinePatterns(RewritePatternSet &patterns)
Populate patterns that expand affine index operations into their equivalent affine....
BoundType
The type of bound: equal, lower bound or upper bound.
Include the generated interface declarations.
const FrozenRewritePatternSet & patterns