CIRCT 22.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
18void reduce::pruneUnusedOps(Operation *initialOp, Reduction &reduction) {
19 SmallVector<Operation *> worklist;
21 worklist.push_back(initialOp);
22 while (!worklist.empty()) {
23 auto *op = worklist.pop_back_val();
24 if (!op->use_empty() || op->hasAttr("inner_sym"))
25 continue;
26 for (auto arg : op->getOperands())
27 if (auto *argOp = arg.getDefiningOp())
28 if (handled.insert(argOp).second)
29 worklist.push_back(argOp);
30 reduction.notifyOpErased(op);
31 op->erase();
32 }
33}
34
35//===----------------------------------------------------------------------===//
36// InnerSymbolUses
37//===----------------------------------------------------------------------===//
38
39static StringAttr getSymbolName(Operation *op) {
40 return op->getAttrOfType<StringAttr>(SymbolTable::getSymbolAttrName());
41}
42
44 root->walk([&](Operation *op) {
45 auto collect = [&](Attribute attr) {
46 if (auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr))
47 symbolRefs.insert(symbolRef.getAttr());
48
49 if (auto innerRef = dyn_cast<hw::InnerRefAttr>(attr)) {
50 innerRefs.insert({innerRef.getModule(), innerRef.getName()});
51 innerRefModules.insert(innerRef.getModule());
52 }
53 };
54 for (auto namedAttr : op->getAttrs())
55 namedAttr.getValue().walk(collect);
56 for (auto result : op->getResults())
57 result.getType().walk(collect);
58 for (auto &region : op->getRegions())
59 for (auto &block : region)
60 for (auto arg : block.getArguments())
61 arg.getType().walk(collect);
62 });
63}
64
65bool InnerSymbolUses::hasInnerRef(Operation *op) const {
66 if (auto symbol = getSymbolName(op))
67 return hasInnerRef(symbol);
68
69 if (auto innerSym = hw::InnerSymbolTable::getInnerSymbol(op)) {
70 StringAttr symbol;
71 auto *parent = op->getParentOp();
72 while (parent && !(symbol = getSymbolName(parent)))
73 parent = parent->getParentOp();
74 if (symbol)
75 return hasInnerRef(symbol, innerSym);
76 }
77
78 return false;
79}
80
81bool InnerSymbolUses::hasInnerRef(hw::InnerRefAttr innerRef) const {
82 return innerRefs.contains({innerRef.getModule(), innerRef.getName()});
83}
84
85bool InnerSymbolUses::hasInnerRef(StringAttr symbol) const {
86 return innerRefModules.contains(symbol);
87}
88
89bool InnerSymbolUses::hasInnerRef(StringAttr symbol,
90 StringAttr innerSym) const {
91 return innerRefs.contains({symbol, innerSym});
92}
93
94bool InnerSymbolUses::hasSymbolRef(Operation *op) const {
95 return symbolRefs.contains(getSymbolName(op));
96}
97
98bool InnerSymbolUses::hasSymbolRef(StringAttr symbol) const {
99 return symbolRefs.contains(symbol);
100}
101
102bool InnerSymbolUses::hasRef(Operation *op) const {
103 return hasInnerRef(op) || hasSymbolRef(op);
104}
105
106bool InnerSymbolUses::hasRef(StringAttr symbol) const {
107 return hasInnerRef(symbol) || hasSymbolRef(symbol);
108}
static StringAttr getSymbolName(Operation *op)
static StringAttr getInnerSymbol(Operation *op)
Get InnerSymbol for an operation.
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.