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(SmallVectorImpl<Operation *> &worklist,
33 Reduction &reduction) {
35 while (!worklist.empty()) {
36 auto *op = worklist.pop_back_val();
37 if (!op || handled.contains(op) || !op->use_empty() ||
38 op->hasAttr("inner_sym"))
39 continue;
40 handled.insert(op);
41 for (auto arg : op->getOperands())
42 if (auto *argOp = arg.getDefiningOp())
43 worklist.push_back(argOp);
44 reduction.notifyOpErased(op);
45 op->erase();
46 }
47}
48
49void reduce::pruneUnusedOps(Operation *initialOp, Reduction &reduction) {
50 SmallVector<Operation *> worklist({initialOp});
51 pruneUnusedOps(worklist, reduction);
52}
53
54//===----------------------------------------------------------------------===//
55// InnerSymbolUses
56//===----------------------------------------------------------------------===//
57
58static StringAttr getSymbolName(Operation *op) {
59 return op->getAttrOfType<StringAttr>(SymbolTable::getSymbolAttrName());
60}
61
63 root->walk([&](Operation *op) {
64 auto collect = [&](Attribute attr) {
65 if (auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr))
66 symbolRefs.insert(symbolRef.getAttr());
67
68 if (auto innerRef = dyn_cast<hw::InnerRefAttr>(attr)) {
69 innerRefs.insert({innerRef.getModule(), innerRef.getName()});
70 innerRefModules.insert(innerRef.getModule());
71 }
72 };
73 for (auto namedAttr : op->getAttrs())
74 namedAttr.getValue().walk(collect);
75 for (auto result : op->getResults())
76 result.getType().walk(collect);
77 for (auto &region : op->getRegions())
78 for (auto &block : region)
79 for (auto arg : block.getArguments())
80 arg.getType().walk(collect);
81 });
82}
83
84bool InnerSymbolUses::hasInnerRef(Operation *op) const {
85 if (auto symbol = getSymbolName(op))
86 return hasInnerRef(symbol);
87
88 if (auto innerSym = hw::InnerSymbolTable::getInnerSymbol(op)) {
89 StringAttr symbol;
90 auto *parent = op->getParentOp();
91 while (parent && !(symbol = getSymbolName(parent)))
92 parent = parent->getParentOp();
93 if (symbol)
94 return hasInnerRef(symbol, innerSym);
95 }
96
97 return false;
98}
99
100bool InnerSymbolUses::hasInnerRef(hw::InnerRefAttr innerRef) const {
101 return innerRefs.contains({innerRef.getModule(), innerRef.getName()});
102}
103
104bool InnerSymbolUses::hasInnerRef(StringAttr symbol) const {
105 return innerRefModules.contains(symbol);
106}
107
108bool InnerSymbolUses::hasInnerRef(StringAttr symbol,
109 StringAttr innerSym) const {
110 return innerRefs.contains({symbol, innerSym});
111}
112
113bool InnerSymbolUses::hasSymbolRef(Operation *op) const {
114 return symbolRefs.contains(getSymbolName(op));
115}
116
117bool InnerSymbolUses::hasSymbolRef(StringAttr symbol) const {
118 return symbolRefs.contains(symbol);
119}
120
121bool InnerSymbolUses::hasRef(Operation *op) const {
122 return hasInnerRef(op) || hasSymbolRef(op);
123}
124
125bool InnerSymbolUses::hasRef(StringAttr symbol) const {
126 return hasInnerRef(symbol) || hasSymbolRef(symbol);
127}
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(SmallVectorImpl< Operation * > &worklist, Reduction &reduction)
Starting from an initial worklist of operations, traverse through it and its operands and erase opera...
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.