1e7084713SRob Suderman //===- SimplifyAffineStructures.cpp ---------------------------------------===//
2e7084713SRob Suderman //
3e7084713SRob Suderman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e7084713SRob Suderman // See https://llvm.org/LICENSE.txt for license information.
5e7084713SRob Suderman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e7084713SRob Suderman //
7e7084713SRob Suderman //===----------------------------------------------------------------------===//
8e7084713SRob Suderman //
904b5274eSUday Bondhugula // This file implements a pass to simplify affine structures in operations.
10e7084713SRob Suderman //
11e7084713SRob Suderman //===----------------------------------------------------------------------===//
12e7084713SRob Suderman
131834ad4aSRiver Riddle #include "PassDetail.h"
14755dc07dSRiver Riddle #include "mlir/Dialect/Affine/Analysis/Utils.h"
1504b5274eSUday Bondhugula #include "mlir/Dialect/Affine/IR/AffineOps.h"
16e7084713SRob Suderman #include "mlir/Dialect/Affine/Passes.h"
17a70aa7bbSRiver Riddle #include "mlir/Dialect/Affine/Utils.h"
1892744f62SUday Bondhugula #include "mlir/IR/IntegerSet.h"
19b6eb26fdSRiver Riddle #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
20e7084713SRob Suderman
21e7084713SRob Suderman #define DEBUG_TYPE "simplify-affine-structure"
22e7084713SRob Suderman
23e7084713SRob Suderman using namespace mlir;
24e7084713SRob Suderman
25e7084713SRob Suderman namespace {
26e7084713SRob Suderman
27e7084713SRob Suderman /// Simplifies affine maps and sets appearing in the operations of the Function.
28e7084713SRob Suderman /// This part is mainly to test the simplifyAffineExpr method. In addition,
29e7084713SRob Suderman /// all memrefs with non-trivial layout maps are converted to ones with trivial
30e7084713SRob Suderman /// identity layout ones.
31e7084713SRob Suderman struct SimplifyAffineStructures
321834ad4aSRiver Riddle : public SimplifyAffineStructuresBase<SimplifyAffineStructures> {
3341574554SRiver Riddle void runOnOperation() override;
34e7084713SRob Suderman
35e7084713SRob Suderman /// Utility to simplify an affine attribute and update its entry in the parent
36e7084713SRob Suderman /// operation if necessary.
37e7084713SRob Suderman template <typename AttributeT>
simplifyAndUpdateAttribute__anonfe12588e0111::SimplifyAffineStructures38195730a6SRiver Riddle void simplifyAndUpdateAttribute(Operation *op, StringAttr name,
39e7084713SRob Suderman AttributeT attr) {
40e7084713SRob Suderman auto &simplified = simplifiedAttributes[attr];
41e7084713SRob Suderman if (simplified == attr)
42e7084713SRob Suderman return;
43e7084713SRob Suderman
44e7084713SRob Suderman // This is a newly encountered attribute.
45e7084713SRob Suderman if (!simplified) {
46e7084713SRob Suderman // Try to simplify the value of the attribute.
47e7084713SRob Suderman auto value = attr.getValue();
48e7084713SRob Suderman auto simplifiedValue = simplify(value);
49e7084713SRob Suderman if (simplifiedValue == value) {
50e7084713SRob Suderman simplified = attr;
51e7084713SRob Suderman return;
52e7084713SRob Suderman }
53e7084713SRob Suderman simplified = AttributeT::get(simplifiedValue);
54e7084713SRob Suderman }
55e7084713SRob Suderman
56e7084713SRob Suderman // Simplification was successful, so update the attribute.
57e7084713SRob Suderman op->setAttr(name, simplified);
58e7084713SRob Suderman }
59e7084713SRob Suderman
simplify__anonfe12588e0111::SimplifyAffineStructures6092744f62SUday Bondhugula IntegerSet simplify(IntegerSet set) { return simplifyIntegerSet(set); }
61e7084713SRob Suderman
62e7084713SRob Suderman /// Performs basic affine map simplifications.
simplify__anonfe12588e0111::SimplifyAffineStructures63e7084713SRob Suderman AffineMap simplify(AffineMap map) {
64e7084713SRob Suderman MutableAffineMap mMap(map);
65e7084713SRob Suderman mMap.simplify();
66e7084713SRob Suderman return mMap.getAffineMap();
67e7084713SRob Suderman }
68e7084713SRob Suderman
69e7084713SRob Suderman DenseMap<Attribute, Attribute> simplifiedAttributes;
70e7084713SRob Suderman };
71e7084713SRob Suderman
72be0a7e9fSMehdi Amini } // namespace
73e7084713SRob Suderman
74*58ceae95SRiver Riddle std::unique_ptr<OperationPass<func::FuncOp>>
createSimplifyAffineStructuresPass()7580aca1eaSRiver Riddle mlir::createSimplifyAffineStructuresPass() {
76e7084713SRob Suderman return std::make_unique<SimplifyAffineStructures>();
77e7084713SRob Suderman }
78e7084713SRob Suderman
runOnOperation()7941574554SRiver Riddle void SimplifyAffineStructures::runOnOperation() {
8041574554SRiver Riddle auto func = getOperation();
81e7084713SRob Suderman simplifiedAttributes.clear();
82dc4e913bSChris Lattner RewritePatternSet patterns(func.getContext());
837932d21fSUday Bondhugula AffineApplyOp::getCanonicalizationPatterns(patterns, func.getContext());
8404b5274eSUday Bondhugula AffineForOp::getCanonicalizationPatterns(patterns, func.getContext());
8504b5274eSUday Bondhugula AffineIfOp::getCanonicalizationPatterns(patterns, func.getContext());
8679d7f618SChris Lattner FrozenRewritePatternSet frozenPatterns(std::move(patterns));
877932d21fSUday Bondhugula
887932d21fSUday Bondhugula // The simplification of affine attributes will likely simplify the op. Try to
897932d21fSUday Bondhugula // fold/apply canonicalization patterns when we have affine dialect ops.
907932d21fSUday Bondhugula SmallVector<Operation *> opsToSimplify;
9104b5274eSUday Bondhugula func.walk([&](Operation *op) {
9204b5274eSUday Bondhugula for (auto attr : op->getAttrs()) {
930c7890c8SRiver Riddle if (auto mapAttr = attr.getValue().dyn_cast<AffineMapAttr>())
940c7890c8SRiver Riddle simplifyAndUpdateAttribute(op, attr.getName(), mapAttr);
950c7890c8SRiver Riddle else if (auto setAttr = attr.getValue().dyn_cast<IntegerSetAttr>())
960c7890c8SRiver Riddle simplifyAndUpdateAttribute(op, attr.getName(), setAttr);
97e7084713SRob Suderman }
9804b5274eSUday Bondhugula
99d891d738SRahul Joshi if (isa<AffineForOp, AffineIfOp, AffineApplyOp>(op))
1007932d21fSUday Bondhugula opsToSimplify.push_back(op);
101e7084713SRob Suderman });
1027932d21fSUday Bondhugula (void)applyOpPatternsAndFold(opsToSimplify, frozenPatterns, /*strict=*/true);
103e7084713SRob Suderman }
104