15 #include "mlir/IR/BuiltinOps.h"
16 #include "mlir/IR/Threading.h"
17 #include "mlir/Pass/Pass.h"
18 #include "llvm/Support/Debug.h"
20 #define DEBUG_TYPE "firrtl-inner-symbol-dce"
24 #define GEN_PASS_DEF_INNERSYMBOLDCE
25 #include "circt/Dialect/FIRRTL/Passes.h.inc"
30 using namespace circt;
31 using namespace firrtl;
41 assert(InnerSymbolTable::getInnerSymbol(target));
44 auto mod = cast<FModuleLike>(target.
getOp());
46 auto base = mod.getPortSymbolAttr(target.
getPort());
47 cast<firrtl::FModuleLike>(*mod).setPortSymbolsAttr(
52 auto symOp = cast<InnerSymbolOpInterface>(target.
getOp());
53 auto base = symOp.getInnerSymAttr();
54 symOp.setInnerSymbolAttr(base.erase(target.
getField()));
59 void runOnOperation()
override;
62 void findInnerRefs(Attribute attr);
63 void insertInnerRef(InnerRefAttr innerRef);
64 void removeInnerSyms(FModuleLike mod);
66 DenseSet<std::pair<StringAttr, StringAttr>>
innerRefs;
72 attr.walk([&](Attribute subAttr) {
73 if (
auto innerRef = dyn_cast<InnerRefAttr>(subAttr))
74 insertInnerRef(innerRef);
80 StringAttr moduleName = innerRef.getModule();
81 StringAttr symName = innerRef.getName();
86 auto [iter, inserted] = innerRefs.insert({moduleName, symName});
90 LLVM_DEBUG(llvm::dbgs() <<
DEBUG_TYPE <<
": found reference to " << moduleName
91 <<
"::" << symName <<
'\n';);
96 auto moduleName = mod.getModuleNameAttr();
99 InnerSymbolTable::walkSymbols(
101 ++numInnerSymbolsFound;
104 if (innerRefs.contains({moduleName, name}))
108 ++numInnerSymbolsRemoved;
110 LLVM_DEBUG(llvm::dbgs() <<
DEBUG_TYPE <<
": removed " << moduleName
111 <<
"::" << name <<
'\n';);
118 ModuleOp topModule = getOperation();
121 SmallVector<FModuleLike> modules;
122 topModule.walk([&](Operation *op) {
124 for (NamedAttribute namedAttr : op->getAttrs())
125 findInnerRefs(namedAttr.getValue());
128 if (
auto mod = dyn_cast<FModuleLike>(op))
129 modules.push_back(mod);
134 parallelForEach(&getContext(), modules,
135 [&](FModuleLike mod) { removeInnerSyms(mod); });
139 return std::make_unique<InnerSymbolDCEPass>();
assert(baseType &&"element must be base type")
static void dropSymbol(const InnerSymTarget &target)
Drop the specified symbol.
The target of an inner symbol, the entity the symbol is a handle for.
Operation * getOp() const
Return the target's base operation. For ports, this is the module.
auto getField() const
Return the target's fieldID.
auto getPort() const
Return the target's port, if valid. Check "isPort()".
bool isPort() const
Return if this targets a port.
std::unique_ptr< mlir::Pass > createInnerSymbolDCEPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void removeInnerSyms(FModuleLike mod)
Remove all dead inner symbols from the specified module.
void findInnerRefs(Attribute attr)
Find all InnerRefAttrs inside a given Attribute.
void runOnOperation() override
void insertInnerRef(InnerRefAttr innerRef)
Add an InnerRefAttr to the set of all InnerRefAttrs.
DenseSet< std::pair< StringAttr, StringAttr > > innerRefs