CIRCT 23.0.0git
Loading...
Searching...
No Matches
ReductionUtils.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
12#include "mlir/IR/Operation.h"
13#include "llvm/ADT/SmallSet.h"
14
15using namespace circt;
16using namespace circt::reduce;
17
18//===----------------------------------------------------------------------===//
19// MetasyntacticNameGenerator
20//===----------------------------------------------------------------------===//
21
23 if (index >= std::size(names))
24 index = 0;
25 return names[index++];
26}
27
28//===----------------------------------------------------------------------===//
29// Utilities
30//===----------------------------------------------------------------------===//
31
32void reduce::pruneUnusedOps(Operation *initialOp, Reduction &reduction) {
33 SmallVector<Operation *> worklist;
35 worklist.push_back(initialOp);
36 while (!worklist.empty()) {
37 auto *op = worklist.pop_back_val();
38 if (!op->use_empty() || op->hasAttr("inner_sym"))
39 continue;
40 for (auto arg : op->getOperands())
41 if (auto *argOp = arg.getDefiningOp())
42 if (handled.insert(argOp).second)
43 worklist.push_back(argOp);
44 reduction.notifyOpErased(op);
45 op->erase();
46 }
47}
48
49//===----------------------------------------------------------------------===//
50// InnerSymbolUses
51//===----------------------------------------------------------------------===//
52
53static StringAttr getSymbolName(Operation *op) {
54 return op->getAttrOfType<StringAttr>(SymbolTable::getSymbolAttrName());
55}
56
58 root->walk([&](Operation *op) {
59 auto collect = [&](Attribute attr) {
60 if (auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr))
61 symbolRefs.insert(symbolRef.getAttr());
62
63 if (auto innerRef = dyn_cast<hw::InnerRefAttr>(attr)) {
64 innerRefs.insert({innerRef.getModule(), innerRef.getName()});
65 innerRefModules.insert(innerRef.getModule());
66 }
67 };
68 for (auto namedAttr : op->getAttrs())
69 namedAttr.getValue().walk(collect);
70 for (auto result : op->getResults())
71 result.getType().walk(collect);
72 for (auto &region : op->getRegions())
73 for (auto &block : region)
74 for (auto arg : block.getArguments())
75 arg.getType().walk(collect);
76 });
77}
78
79bool InnerSymbolUses::hasInnerRef(Operation *op) const {
80 if (auto symbol = getSymbolName(op))
81 return hasInnerRef(symbol);
82
83 if (auto innerSym = hw::InnerSymbolTable::getInnerSymbol(op)) {
84 StringAttr symbol;
85 auto *parent = op->getParentOp();
86 while (parent && !(symbol = getSymbolName(parent)))
87 parent = parent->getParentOp();
88 if (symbol)
89 return hasInnerRef(symbol, innerSym);
90 }
91
92 return false;
93}
94
95bool InnerSymbolUses::hasInnerRef(hw::InnerRefAttr innerRef) const {
96 return innerRefs.contains({innerRef.getModule(), innerRef.getName()});
97}
98
99bool InnerSymbolUses::hasInnerRef(StringAttr symbol) const {
100 return innerRefModules.contains(symbol);
101}
102
103bool InnerSymbolUses::hasInnerRef(StringAttr symbol,
104 StringAttr innerSym) const {
105 return innerRefs.contains({symbol, innerSym});
106}
107
108bool InnerSymbolUses::hasSymbolRef(Operation *op) const {
109 return symbolRefs.contains(getSymbolName(op));
110}
111
112bool InnerSymbolUses::hasSymbolRef(StringAttr symbol) const {
113 return symbolRefs.contains(symbol);
114}
115
116bool InnerSymbolUses::hasRef(Operation *op) const {
117 return hasInnerRef(op) || hasSymbolRef(op);
118}
119
120bool InnerSymbolUses::hasRef(StringAttr symbol) const {
121 return hasInnerRef(symbol) || hasSymbolRef(symbol);
122}
static StringAttr getSymbolName(Operation *op)
static StringAttr getInnerSymbol(Operation *op)
Get InnerSymbol for an operation.
const char * getNextName()
Get the next metasyntactic name in the sequence.
static constexpr const char * names[48]
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.
An abstract reduction pattern.
Definition Reduction.h:24
void notifyOpErased(Operation *op)
Definition Reduction.h:101
DenseSet< StringAttr > innerRefModules
Symbol names used in inner refs.
bool hasSymbolRef(Operation *op) const
Check whether the given symbol is targeted by a symbol ref.
bool hasInnerRef(Operation *op) const
Check whether an op is targeted by an inner ref.
DenseSet< StringAttr > symbolRefs
Symbol names used in symbol or inner refs.
bool hasRef(Operation *op) const
Check whether the given symbol is targeted by a symbol ref or inner ref.
DenseSet< std::pair< StringAttr, StringAttr > > innerRefs
Symbol and inner symbol name pairs used in inner refs.