MLIR 24.0.0git
SimplifyAffineStructures.cpp
Go to the documentation of this file.
1//===- SimplifyAffineStructures.cpp ---------------------------------------===//
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 implements a pass to simplify affine structures in operations.
10//
11//===----------------------------------------------------------------------===//
12
14
19#include "mlir/IR/IntegerSet.h"
21
22namespace mlir {
23namespace affine {
24#define GEN_PASS_DEF_SIMPLIFYAFFINESTRUCTURES
25#include "mlir/Dialect/Affine/Transforms/Passes.h.inc"
26} // namespace affine
27} // namespace mlir
28
29#define DEBUG_TYPE "simplify-affine-structure"
30
31using namespace mlir;
32using namespace mlir::affine;
33
34namespace {
35
36/// Simplifies affine maps and sets appearing in the operations of the Function.
37/// This part is mainly to test the simplifyAffineExpr method. In addition,
38/// all memrefs with non-trivial layout maps are converted to ones with trivial
39/// identity layout ones.
40struct SimplifyAffineStructures
41 : public affine::impl::SimplifyAffineStructuresBase<
42 SimplifyAffineStructures> {
43 void runOnOperation() override;
44
45 /// Utility to simplify an affine attribute and update its entry in the parent
46 /// operation if necessary.
47 template <typename AttributeT>
48 void simplifyAndUpdateAttribute(Operation *op, StringAttr name,
49 AttributeT attr) {
50 auto &simplified = simplifiedAttributes[attr];
51 if (simplified == attr)
52 return;
53
54 // This is a newly encountered attribute.
55 if (!simplified) {
56 // Try to simplify the value of the attribute.
57 auto value = attr.getValue();
58 auto simplifiedValue = simplify(value);
59 if (simplifiedValue == value) {
60 simplified = attr;
61 return;
62 }
63 simplified = AttributeT::get(simplifiedValue);
64 }
65
66 // Simplification was successful, so update the attribute.
67 if (op->getInherentAttr(name).has_value())
68 op->setInherentAttr(name, simplified);
69 else
70 op->setDiscardableAttr(name, simplified);
71 }
72
73 IntegerSet simplify(IntegerSet set) { return simplifyIntegerSet(set); }
74
75 /// Performs basic affine map simplifications.
76 AffineMap simplify(AffineMap map) {
77 MutableAffineMap mMap(map);
78 mMap.simplify();
79 return mMap.getAffineMap();
80 }
81
82 DenseMap<Attribute, Attribute> simplifiedAttributes;
83};
84
85} // namespace
86
87std::unique_ptr<OperationPass<func::FuncOp>>
89 return std::make_unique<SimplifyAffineStructures>();
90}
91
92void SimplifyAffineStructures::runOnOperation() {
93 auto func = getOperation();
94 simplifiedAttributes.clear();
95 RewritePatternSet patterns(func.getContext());
96 AffineApplyOp::getCanonicalizationPatterns(patterns, func.getContext());
97 AffineForOp::getCanonicalizationPatterns(patterns, func.getContext());
98 AffineIfOp::getCanonicalizationPatterns(patterns, func.getContext());
99 FrozenRewritePatternSet frozenPatterns(std::move(patterns));
100
101 // The simplification of affine attributes will likely simplify the op. Try to
102 // fold/apply canonicalization patterns when we have affine dialect ops.
103 SmallVector<Operation *> opsToSimplify;
104 func.walk([&](Operation *op) {
107 op, [&](StringRef name, Attribute &attr) { attrs.append(name, attr); });
108 for (auto attr : attrs) {
109 if (auto mapAttr = dyn_cast<AffineMapAttr>(attr.getValue()))
110 simplifyAndUpdateAttribute(op, attr.getName(), mapAttr);
111 else if (auto setAttr = dyn_cast<IntegerSetAttr>(attr.getValue()))
112 simplifyAndUpdateAttribute(op, attr.getName(), setAttr);
113 }
114
115 if (isa<AffineForOp, AffineIfOp, AffineApplyOp>(op))
116 opsToSimplify.push_back(op);
117 });
119 opsToSimplify, frozenPatterns,
120 GreedyRewriteConfig().setStrictness(
121 GreedyRewriteStrictness::ExistingAndNewOps));
122}
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
Attributes are known-constant values of operations.
Definition Attributes.h:25
This class represents a frozen set of patterns that can be processed by a pattern applicator.
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition IntegerSet.h:44
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
void walkInherentAttrs(Operation *op, InherentAttrVisitor visitor) const
Visit the inherent attributes stored in the properties of op.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
void setInherentAttr(StringAttr name, Attribute value)
Set an inherent attribute by name.
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Definition Operation.h:512
std::optional< Attribute > getInherentAttr(StringRef name)
Access an inherent attribute by name: returns an empty optional if there is no inherent attribute wit...
OperationName getName()
The name of an operation is the key identifier for it.
Definition Operation.h:115
DictionaryAttr getDiscardableAttrDictionary()
Return all of the discardable attributes on this operation as a DictionaryAttr.
Definition Operation.h:553
IntegerSet simplifyIntegerSet(IntegerSet set)
Simplify the integer set by simplifying the underlying affine expressions by flattening and some simp...
Definition Utils.cpp:2214
std::unique_ptr< OperationPass< func::FuncOp > > createSimplifyAffineStructuresPass()
Creates a simplification pass for affine structures (maps and sets).
Include the generated interface declarations.
LogicalResult applyOpPatternsGreedily(ArrayRef< Operation * > ops, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr, bool *allErased=nullptr)
Rewrite the specified ops by repeatedly applying the highest benefit patterns in a greedy worklist dr...
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
Definition LLVM.h:120
A mutable affine map. Its affine expressions are however unique.
Definition AffineMap.h:430
AffineMap getAffineMap() const
Get the AffineMap corresponding to this MutableAffineMap.
void simplify()
Simplify the (result) expressions in this map using analysis (used by.