MLIR  20.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 
22 namespace mlir {
23 namespace affine {
24 #define GEN_PASS_DEF_SIMPLIFYAFFINESTRUCTURES
25 #include "mlir/Dialect/Affine/Passes.h.inc"
26 } // namespace affine
27 } // namespace mlir
28 
29 #define DEBUG_TYPE "simplify-affine-structure"
30 
31 using namespace mlir;
32 using namespace mlir::affine;
33 
34 namespace {
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.
40 struct 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  op->setAttr(name, simplified);
68  }
69 
70  IntegerSet simplify(IntegerSet set) { return simplifyIntegerSet(set); }
71 
72  /// Performs basic affine map simplifications.
73  AffineMap simplify(AffineMap map) {
74  MutableAffineMap mMap(map);
75  mMap.simplify();
76  return mMap.getAffineMap();
77  }
78 
79  DenseMap<Attribute, Attribute> simplifiedAttributes;
80 };
81 
82 } // namespace
83 
84 std::unique_ptr<OperationPass<func::FuncOp>>
86  return std::make_unique<SimplifyAffineStructures>();
87 }
88 
89 void SimplifyAffineStructures::runOnOperation() {
90  auto func = getOperation();
91  simplifiedAttributes.clear();
92  RewritePatternSet patterns(func.getContext());
93  AffineApplyOp::getCanonicalizationPatterns(patterns, func.getContext());
94  AffineForOp::getCanonicalizationPatterns(patterns, func.getContext());
95  AffineIfOp::getCanonicalizationPatterns(patterns, func.getContext());
96  FrozenRewritePatternSet frozenPatterns(std::move(patterns));
97 
98  // The simplification of affine attributes will likely simplify the op. Try to
99  // fold/apply canonicalization patterns when we have affine dialect ops.
100  SmallVector<Operation *> opsToSimplify;
101  func.walk([&](Operation *op) {
102  for (auto attr : op->getAttrs()) {
103  if (auto mapAttr = dyn_cast<AffineMapAttr>(attr.getValue()))
104  simplifyAndUpdateAttribute(op, attr.getName(), mapAttr);
105  else if (auto setAttr = dyn_cast<IntegerSetAttr>(attr.getValue()))
106  simplifyAndUpdateAttribute(op, attr.getName(), setAttr);
107  }
108 
109  if (isa<AffineForOp, AffineIfOp, AffineApplyOp>(op))
110  opsToSimplify.push_back(op);
111  });
114  (void)applyOpPatternsGreedily(opsToSimplify, frozenPatterns, config);
115 }
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition: AffineMap.h:46
This class represents a frozen set of patterns that can be processed by a pattern applicator.
This class allows control over how the GreedyPatternRewriteDriver works.
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition: IntegerSet.h:44
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Definition: Operation.h:512
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:582
IntegerSet simplifyIntegerSet(IntegerSet set)
Simplify the integer set by simplifying the underlying affine expressions by flattening and some simp...
Definition: Utils.cpp:1980
std::unique_ptr< OperationPass< func::FuncOp > > createSimplifyAffineStructuresPass()
Creates a simplification pass for affine structures (maps and sets).
Include the generated interface declarations.
const FrozenRewritePatternSet GreedyRewriteConfig config
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...
const FrozenRewritePatternSet & patterns
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
@ ExistingAndNewOps
Only pre-existing and newly created ops are processed.
A mutable affine map. Its affine expressions are however unique.
Definition: AffineMap.h:430
AffineMap getAffineMap() const
Get the AffineMap corresponding to this MutableAffineMap.
Definition: AffineMap.cpp:992
void simplify()
Simplify the (result) expressions in this map using analysis (used by.
Definition: AffineMap.cpp:984