CIRCT 24.0.0git
Loading...
Searching...
No Matches
NLATable.cpp
Go to the documentation of this file.
1//===- NLATable.cpp - Non-Local Anchor Table --------------------*- C++ -*-===//
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/BuiltinOps.h"
13
14using namespace circt;
15using namespace firrtl;
16
17NLATable::NLATable(Operation *operation) {
18 if (auto mod = dyn_cast<mlir::ModuleOp>(operation))
19 for (auto &op : *mod.getBody())
20 if ((operation = dyn_cast<CircuitOp>(&op)))
21 break;
22
23 auto circuit = cast<CircuitOp>(operation);
24 // We are assuming it's faster to iterate over the top level twice than cache
25 // a large number of options.
26 for (auto &op : *circuit.getBodyBlock()) {
27 if (auto module = dyn_cast<FModuleLike>(op))
28 symToOp[module.getModuleNameAttr()] = module;
29 if (auto nla = dyn_cast<hw::HierPathOp>(op))
30 addNLA(nla);
31 }
32}
33
34ArrayRef<hw::HierPathOp> NLATable::lookup(StringAttr name) {
35 auto iter = nodeMap.find(name);
36 if (iter == nodeMap.end())
37 return {};
38 return iter->second;
39}
40
41ArrayRef<hw::HierPathOp> NLATable::lookup(Operation *op) {
42 if (auto symOp = dyn_cast<mlir::SymbolOpInterface>(op))
43 return lookup(symOp.getNameAttr());
44 return {};
45}
46
47hw::HierPathOp NLATable::getNLA(StringAttr name) {
48 auto *n = symToOp.lookup(name);
49 return dyn_cast_or_null<hw::HierPathOp>(n);
50}
51
52FModuleLike NLATable::getModule(StringAttr name) {
53 auto *n = symToOp.lookup(name);
54 return dyn_cast_or_null<FModuleLike>(n);
55}
56
57void NLATable::addNLA(hw::HierPathOp nla) {
58 symToOp[nla.getSymNameAttr()] = nla;
59 for (auto ent : nla.getNamepath()) {
60 if (auto mod = dyn_cast<FlatSymbolRefAttr>(ent))
61 nodeMap[mod.getAttr()].push_back(nla);
62 else if (auto inr = dyn_cast<hw::InnerRefAttr>(ent))
63 nodeMap[inr.getModule()].push_back(nla);
64 }
65}
66
67void NLATable::erase(hw::HierPathOp nla, SymbolTable *symbolTable) {
68 symToOp.erase(nla.getSymNameAttr());
69 for (auto ent : nla.getNamepath())
70 if (auto mod = dyn_cast<FlatSymbolRefAttr>(ent))
71 llvm::erase(nodeMap[mod.getAttr()], nla);
72 else if (auto inr = dyn_cast<hw::InnerRefAttr>(ent))
73 llvm::erase(nodeMap[inr.getModule()], nla);
74 if (symbolTable)
75 symbolTable->erase(nla);
76}
77
78void NLATable::updateModuleInNLA(hw::HierPathOp nlaOp, StringAttr oldModule,
79 StringAttr newModule) {
80 nlaOp.updateModule(oldModule, newModule);
81 auto &nlas = nodeMap[oldModule];
82 auto *iter = std::find(nlas.begin(), nlas.end(), nlaOp);
83 if (iter != nlas.end()) {
84 nlas.erase(iter);
85 if (nlas.empty())
86 nodeMap.erase(oldModule);
87 nodeMap[newModule].push_back(nlaOp);
88 }
89}
90
91void NLATable::updateModuleInNLA(StringAttr name, StringAttr oldModule,
92 StringAttr newModule) {
93 auto nlaOp = getNLA(name);
94 if (!nlaOp)
95 return;
96 updateModuleInNLA(nlaOp, oldModule, newModule);
97}
98
99void NLATable::renameModule(StringAttr oldModName, StringAttr newModName) {
100 auto op = symToOp.find(oldModName);
101 if (op == symToOp.end())
102 return;
103 auto iter = nodeMap.find(oldModName);
104 if (iter == nodeMap.end())
105 return;
106 for (auto nla : iter->second)
107 nla.updateModule(oldModName, newModName);
108 nodeMap[newModName] = iter->second;
109 nodeMap.erase(oldModName);
110 symToOp[newModName] = op->second;
111 symToOp.erase(oldModName);
112}
113
115 StringAttr newModName, StringAttr oldModName,
116 const DenseMap<StringAttr, StringAttr> &innerSymRenameMap) {
117
118 if (newModName == oldModName)
119 return;
120 for (auto nla : lookup(oldModName)) {
121 nla.updateModuleAndInnerRef(oldModName, newModName, innerSymRenameMap);
122 nodeMap[newModName].push_back(nla);
123 }
124 nodeMap.erase(oldModName);
125 return;
126}
ArrayRef< hw::HierPathOp > lookup(Operation *op)
Lookup all NLAs an operation participates in.
Definition NLATable.cpp:41
void updateModuleInNLA(StringAttr nlaName, StringAttr oldModule, StringAttr newModule)
Replace the module oldModule with newModule in the namepath of the nla nlaName.
Definition NLATable.cpp:91
llvm::DenseMap< StringAttr, SmallVector< hw::HierPathOp, 4 > > nodeMap
Map modules to the NLA's that target them.
Definition NLATable.h:187
void renameModule(StringAttr oldModName, StringAttr newModName)
Rename a module, this updates the name to module tracking and the name to NLA tracking.
Definition NLATable.cpp:99
void addNLA(hw::HierPathOp nla)
Insert a new NLA.
Definition NLATable.cpp:57
void renameModuleAndInnerRef(StringAttr newModName, StringAttr oldModName, const DenseMap< StringAttr, StringAttr > &innerSymRenameMap)
Replace the module oldModName with newModName in the namepath of any NLA.
Definition NLATable.cpp:114
void erase(hw::HierPathOp nlaOp, SymbolTable *symbolTable=nullptr)
Remove the NLA from the analysis.
Definition NLATable.cpp:67
NLATable(Operation *operation)
Create a new NLA table of a circuit.
Definition NLATable.cpp:17
hw::HierPathOp getNLA(StringAttr name)
Resolve a symbol to an NLA.
Definition NLATable.cpp:47
llvm::DenseMap< StringAttr, Operation * > symToOp
Map symbol names to module and NLA operations.
Definition NLATable.h:190
FModuleLike getModule(StringAttr name)
Resolve a symbol to a Module.
Definition NLATable.cpp:52
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.