16#include "mlir/IR/BuiltinOps.h"
17#include "mlir/IR/Threading.h"
18#include "mlir/Pass/Pass.h"
19#include "llvm/Support/Debug.h"
21#define DEBUG_TYPE "firrtl-inner-symbol-dce"
25#define GEN_PASS_DEF_INNERSYMBOLDCE
26#include "circt/Dialect/FIRRTL/Passes.h.inc"
32using namespace firrtl;
45 auto mod = cast<FModuleLike>(target.
getOp());
47 auto base = mod.getPortSymbolAttr(target.
getPort());
48 cast<firrtl::FModuleLike>(*mod).setPortSymbolAttr(
53 auto symOp = cast<InnerSymbolOpInterface>(target.
getOp());
54 auto base = symOp.getInnerSymAttr();
55 symOp.setInnerSymbolAttr(base.erase(target.
getField()));
67 DenseSet<std::pair<StringAttr, StringAttr>>
innerRefs;
73 attr.walk([&](Attribute subAttr) {
74 if (
auto innerRef = dyn_cast<InnerRefAttr>(subAttr))
81 StringAttr moduleName = innerRef.getModule();
82 StringAttr symName = innerRef.getName();
87 auto [iter, inserted] =
innerRefs.insert({moduleName, symName});
91 LLVM_DEBUG(llvm::dbgs() <<
DEBUG_TYPE <<
": found reference to " << moduleName
92 <<
"::" << symName <<
'\n';);
97 auto moduleName = mod.getModuleNameAttr();
102 ++numInnerSymbolsFound;
105 if (
innerRefs.contains({moduleName, name}))
109 ++numInnerSymbolsRemoved;
111 LLVM_DEBUG(llvm::dbgs() <<
DEBUG_TYPE <<
": removed " << moduleName
112 <<
"::" << name <<
'\n';);
119 ModuleOp topModule = getOperation();
122 SmallVector<FModuleLike> modules;
123 topModule.walk([&](Operation *op) {
125 for (NamedAttribute namedAttr : op->getAttrs())
129 if (
auto mod = dyn_cast<FModuleLike>(op))
130 modules.push_back(mod);
135 parallelForEach(&getContext(), modules,
140 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.
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.
Operation * getOp() const
Return the target's base operation. For ports, this is the module.
static StringAttr getInnerSymbol(Operation *op)
Get InnerSymbol for an operation.
static RetTy walkSymbols(Operation *op, FuncTy &&callback)
Walk the given IST operation and invoke the callback for all encountered inner symbols.
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