CIRCT 20.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 auto name = op->getAttrOfType<StringAttr>("sym_name");
43 if (!name)
44 return {};
45 return lookup(name);
46}
47
48hw::HierPathOp NLATable::getNLA(StringAttr name) {
49 auto *n = symToOp.lookup(name);
50 return dyn_cast_or_null<hw::HierPathOp>(n);
51}
52
53FModuleLike NLATable::getModule(StringAttr name) {
54 auto *n = symToOp.lookup(name);
55 return dyn_cast_or_null<FModuleLike>(n);
56}
57
58void NLATable::addNLA(hw::HierPathOp nla) {
59 symToOp[nla.getSymNameAttr()] = nla;
60 for (auto ent : nla.getNamepath()) {
61 if (auto mod = dyn_cast<FlatSymbolRefAttr>(ent))
62 nodeMap[mod.getAttr()].push_back(nla);
63 else if (auto inr = dyn_cast<hw::InnerRefAttr>(ent))
64 nodeMap[inr.getModule()].push_back(nla);
65 }
66}
67
68void NLATable::erase(hw::HierPathOp nla, SymbolTable *symbolTable) {
69 symToOp.erase(nla.getSymNameAttr());
70 for (auto ent : nla.getNamepath())
71 if (auto mod = dyn_cast<FlatSymbolRefAttr>(ent))
72 llvm::erase(nodeMap[mod.getAttr()], nla);
73 else if (auto inr = dyn_cast<hw::InnerRefAttr>(ent))
74 llvm::erase(nodeMap[inr.getModule()], nla);
75 if (symbolTable)
76 symbolTable->erase(nla);
77}
78
79void NLATable::updateModuleInNLA(hw::HierPathOp nlaOp, StringAttr oldModule,
80 StringAttr newModule) {
81 nlaOp.updateModule(oldModule, newModule);
82 auto &nlas = nodeMap[oldModule];
83 auto *iter = std::find(nlas.begin(), nlas.end(), nlaOp);
84 if (iter != nlas.end()) {
85 nlas.erase(iter);
86 if (nlas.empty())
87 nodeMap.erase(oldModule);
88 nodeMap[newModule].push_back(nlaOp);
89 }
90}
91
92void NLATable::updateModuleInNLA(StringAttr name, StringAttr oldModule,
93 StringAttr newModule) {
94 auto nlaOp = getNLA(name);
95 if (!nlaOp)
96 return;
97 updateModuleInNLA(nlaOp, oldModule, newModule);
98}
99
100void NLATable::renameModule(StringAttr oldModName, StringAttr newModName) {
101 auto op = symToOp.find(oldModName);
102 if (op == symToOp.end())
103 return;
104 auto iter = nodeMap.find(oldModName);
105 if (iter == nodeMap.end())
106 return;
107 for (auto nla : iter->second)
108 nla.updateModule(oldModName, newModName);
109 nodeMap[newModName] = iter->second;
110 nodeMap.erase(oldModName);
111 symToOp[newModName] = op->second;
112 symToOp.erase(oldModName);
113}
114
116 StringAttr newModName, StringAttr oldModName,
117 const DenseMap<StringAttr, StringAttr> &innerSymRenameMap) {
118
119 if (newModName == oldModName)
120 return;
121 for (auto nla : lookup(oldModName)) {
122 nla.updateModuleAndInnerRef(oldModName, newModName, innerSymRenameMap);
123 nodeMap[newModName].push_back(nla);
124 }
125 nodeMap.erase(oldModName);
126 return;
127}
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:92
llvm::DenseMap< StringAttr, SmallVector< hw::HierPathOp, 4 > > nodeMap
Map modules to the NLA's that target them.
Definition NLATable.h:190
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:100
void addNLA(hw::HierPathOp nla)
Insert a new NLA.
Definition NLATable.cpp:58
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:115
void erase(hw::HierPathOp nlaOp, SymbolTable *symbolTable=nullptr)
Remove the NLA from the analysis.
Definition NLATable.cpp:68
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:48
llvm::DenseMap< StringAttr, Operation * > symToOp
Map symbol names to module and NLA operations.
Definition NLATable.h:193
FModuleLike getModule(StringAttr name)
Resolve a symbol to a Module.
Definition NLATable.cpp:53
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.