CIRCT 22.0.0git
Loading...
Searching...
No Matches
GenericReductions.cpp
Go to the documentation of this file.
1//===- GenericReductions.cpp - Generic Reduction patterns -----------------===//
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
11#include "mlir/IR/SymbolTable.h"
12#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
13#include "mlir/Transforms/Passes.h"
14
15using namespace mlir;
16using namespace circt;
17
18//===----------------------------------------------------------------------===//
19// Reduction Patterns
20//===----------------------------------------------------------------------===//
21
22namespace {
23
24/// A sample reduction pattern that removes operations which either produce no
25/// results or their results have no users.
26struct OperationPruner : public Reduction {
27 void beforeReduction(mlir::ModuleOp op) override {
28 symbolUses = reduce::InnerSymbolUses(op);
29 }
30 uint64_t match(Operation *op) override {
31 if (op->hasTrait<OpTrait::IsTerminator>())
32 return 0;
33 if (isa<ModuleOp>(op))
34 return 0;
35 if (op->getNumResults() > 0 && !op->use_empty())
36 return 0;
37 if (symbolUses.hasRef(op))
38 return 0;
39 return 1;
40 }
41 LogicalResult rewrite(Operation *op) override {
42 reduce::pruneUnusedOps(op, *this);
43 return success();
44 }
45 std::string getName() const override { return "operation-pruner"; }
46
47 reduce::InnerSymbolUses symbolUses;
48};
49
50/// Remove unused symbol ops.
51struct UnusedSymbolPruner : public Reduction {
52 void beforeReduction(mlir::ModuleOp op) override {
53 symbolUses = reduce::InnerSymbolUses(op);
54 }
55
56 uint64_t match(Operation *op) override {
57 if (op->hasAttr(SymbolTable::getSymbolAttrName()))
58 if (!symbolUses.hasRef(op))
59 return 1;
60 return 0;
61 }
62
63 LogicalResult rewrite(Operation *op) override {
64 op->erase();
65 return success();
66 }
67
68 std::string getName() const override { return "unused-symbol-pruner"; }
69
70 reduce::InnerSymbolUses symbolUses;
71};
72
73/// A reduction pattern that changes symbol visibility from "public" to
74/// "private".
75struct MakeSymbolsPrivate : public Reduction {
76 uint64_t match(Operation *op) override {
77 if (!op->getParentOp() || !isa<SymbolOpInterface>(op))
78 return 0;
79 return SymbolTable::getSymbolVisibility(op) !=
80 SymbolTable::Visibility::Private;
81 }
82
83 LogicalResult rewrite(Operation *op) override {
84 // Change the visibility from public to private
85 SymbolTable::setSymbolVisibility(op, SymbolTable::Visibility::Private);
86 return success();
87 }
88
89 std::string getName() const override { return "make-symbols-private"; }
90 bool acceptSizeIncrease() const override { return true; }
91};
92
93} // namespace
94
95//===----------------------------------------------------------------------===//
96// Reduction Registration
97//===----------------------------------------------------------------------===//
98
99static std::unique_ptr<Pass>
100createSimpleCanonicalizerPass(std::optional<int64_t> maxNumRewrites) {
101 GreedyRewriteConfig config;
102 config.setUseTopDownTraversal(true);
103 config.setRegionSimplificationLevel(
104 mlir::GreedySimplifyRegionLevel::Disabled);
105 if (maxNumRewrites)
106 config.setMaxNumRewrites(*maxNumRewrites);
107 return createCanonicalizerPass(config);
108}
109
111 MLIRContext *context, ReducePatternSet &patterns,
112 std::optional<int64_t> maxNumRewrites) {
113 patterns.add<PassReduction, 103>(context, createSymbolDCEPass());
114 patterns.add<PassReduction, 102>(
115 context, createSimpleCanonicalizerPass(maxNumRewrites));
116 patterns.add<PassReduction, 101>(context, createCSEPass());
117 patterns.add<MakeSymbolsPrivate, 100>();
118 patterns.add<UnusedSymbolPruner, 99>();
119 patterns.add<OperationPruner, 1>();
120}
void pruneUnusedOps(Operation *initialOp, Reduction &reduction)
Starting at the given op, traverse through it and its operands and erase operations that have no more...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void populateGenericReducePatterns(MLIRContext *context, ReducePatternSet &patterns, std::optional< int64_t > maxNumRewrites=std::nullopt)
Populate reduction patterns that are not specific to certain operations or dialects.
std::unique_ptr< Pass > createSimpleCanonicalizerPass()
Create a simple canonicalizer pass.
Definition Passes.cpp:15
A reduction pattern that applies an mlir::Pass.
Definition Reduction.h:142
An abstract reduction pattern.
Definition Reduction.h:24
virtual LogicalResult rewrite(Operation *op)
Apply the reduction to a specific operation.
Definition Reduction.h:58
virtual bool acceptSizeIncrease() const
Return true if the tool should accept the transformation this reduction performs on the module even i...
Definition Reduction.h:79
virtual uint64_t match(Operation *op)
Check if the reduction can apply to a specific operation.
Definition Reduction.h:41
virtual std::string getName() const =0
Return a human-readable name for this reduction pattern.
virtual void beforeReduction(mlir::ModuleOp)
Called before the reduction is applied to a new subset of operations.
Definition Reduction.h:30
A helper struct that scans a root operation and all its nested operations for InnerRefAttrs.