CIRCT  20.0.0git
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 
11 #include "circt/Dialect/HW/HWOps.h"
12 #include "mlir/IR/BuiltinOps.h"
13 
14 using namespace circt;
15 using namespace firrtl;
16 
17 NLATable::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 
34 ArrayRef<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 
41 ArrayRef<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 
48 hw::HierPathOp NLATable::getNLA(StringAttr name) {
49  auto *n = symToOp.lookup(name);
50  return dyn_cast_or_null<hw::HierPathOp>(n);
51 }
52 
53 FModuleLike NLATable::getModule(StringAttr name) {
54  auto *n = symToOp.lookup(name);
55  return dyn_cast_or_null<FModuleLike>(n);
56 }
57 
58 void 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 
68 void 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 
79 void 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 
92 void 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 
100 void 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.
Definition: DebugAnalysis.h:21