CIRCT 20.0.0git
Loading...
Searching...
No Matches
NLATable.h
Go to the documentation of this file.
1//===- NLATable.h - 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//
9// This file defines the FIRRTL NLATable.
10//
11//===----------------------------------------------------------------------===//
12#ifndef CIRCT_DIALECT_FIRRTL_NLATABLE_H
13#define CIRCT_DIALECT_FIRRTL_NLATABLE_H
14
17#include "circt/Support/LLVM.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SetOperations.h"
20#include "llvm/ADT/iterator.h"
21
22namespace circt {
23namespace firrtl {
24
25/// This table tracks nlas and what modules participate in them.
26///
27/// To use this class, retrieve a cached copy from the analysis manager:
28/// auto &nlaTable = getAnalysis<NLATable>(getOperation());
29class NLATable {
30
31public:
32 /// Create a new NLA table of a circuit. This must be called on a FIRRTL
33 /// CircuitOp or MLIR ModuleOp. To ensure that the analysis does not return
34 /// stale data while a pass is running, it should be kept up-to-date when
35 /// modules are added or renamed and NLAs are updated.
36 explicit NLATable(Operation *operation);
37
38 /// Lookup all NLAs an operation participates in. This returns a reference to
39 /// the internal record, so make a copy before making any update to the
40 /// NLATable.
41 ArrayRef<hw::HierPathOp> lookup(Operation *op);
42
43 /// Lookup all NLAs an operation participates in. This returns a reference to
44 /// the internal record, so make a copy before making any update to the
45 /// NLATable.
46 ArrayRef<hw::HierPathOp> lookup(StringAttr name);
47
48 /// Resolve a symbol to an NLA.
49 hw::HierPathOp getNLA(StringAttr name);
50
51 /// Resolve a symbol to a Module.
52 FModuleLike getModule(StringAttr name);
53
54 /// Compute the NLAs that are common between the two modules, `mod1` and
55 /// `mod2` and insert them into the set `common`.
56 /// The set of NLAs that an instance op participates in is the set of common
57 /// NLAs between the parent module and the instance target. This can be used
58 /// to get the set of NLAs that an InstanceOp participates in, instead of
59 /// recording them on the op in the IR.
60 void commonNLAs(StringAttr mod1, StringAttr mod2,
61 DenseSet<hw::HierPathOp> &common) {
62 auto mod1NLAs = lookup(mod1);
63 auto mod2NLAs = lookup(mod2);
64 common.insert(mod1NLAs.begin(), mod1NLAs.end());
65 DenseSet<hw::HierPathOp> set2(mod2NLAs.begin(), mod2NLAs.end());
66 llvm::set_intersect(common, set2);
67 }
68
69 /// Get the NLAs that the InstanceOp participates in, insert it to the
70 /// DenseSet `nlas`.
71 void getInstanceNLAs(InstanceOp inst, DenseSet<hw::HierPathOp> &nlas) {
72 auto instSym = getInnerSymName(inst);
73 // If there is no inner sym on the InstanceOp, then it does not participate
74 // in any NLA.
75 if (!instSym)
76 return;
77 auto mod = inst->getParentOfType<FModuleOp>().getNameAttr();
78 // Get the NLAs that are common between the parent module and the target
79 // module. This should contain the NLAs that this InstanceOp participates
80 // in.
81 commonNLAs(inst->getParentOfType<FModuleOp>().getNameAttr(),
82 inst.getModuleNameAttr().getAttr(), nlas);
83 // Handle the case when there are more than one Instances for the same
84 // target module. Getting the `commonNLA`, in that case is not enough,
85 // remove the NLAs that donot have the InstanceOp as the innerSym.
86 for (auto nla : llvm::make_early_inc_range(nlas)) {
87 if (!nla.hasInnerSym(mod, instSym))
88 nlas.erase(nla);
89 }
90 }
91
92 /// Get the NLAs that the module `modName` particiaptes in, and insert them
93 /// into the DenseSet `nlas`.
94 void getNLAsInModule(StringAttr modName, DenseSet<hw::HierPathOp> &nlas) {
95 for (auto nla : lookup(modName))
96 nlas.insert(nla);
97 }
98
99 //===-------------------------------------------------------------------------
100 // Methods to keep an NLATable up to date.
101 //
102 // These methods are not thread safe. Make sure that modifications are
103 // properly synchronized or performed in a serial context. When the
104 // NLATable is used as an analysis, this is only safe when the pass is
105 // on a CircuitOp.
106
107 /// Insert a new NLA. This updates two internal records,
108 /// 1. Update the map for the `nlaOp` name to the Operation.
109 /// 2. For each module in the NLA namepath, insert the NLA into the list of
110 /// hwHierPathOps that participate in the corresponding module. This does
111 /// not update the module name to module op map, if any potentially new module
112 /// in the namepath does not already exist in the record.
113 void addNLA(hw::HierPathOp nla);
114
115 /// Remove the NLA from the analysis. This updates two internal records,
116 /// 1. Remove the NLA name to the operation map entry.
117 /// 2. For each module in the namepath of the NLA, remove the entry from the
118 /// list of NLAs that the module participates in.
119 /// Note that this invalidates any reference to the NLA list returned by
120 /// 'lookup'.
121 void erase(hw::HierPathOp nlaOp, SymbolTable *symbolTable = nullptr);
122
123 /// Record a new FModuleLike operation. This updates the Module name to Module
124 /// operation map.
125 void addModule(FModuleLike mod) { symToOp[mod.getModuleNameAttr()] = mod; }
126
127 /// Stop tracking a module. Remove the module from two internal records,
128 /// 1. Module name to Module op map.
129 /// 2. Module name to list of NLAs that the module participates in.
130 void eraseModule(StringAttr name) {
131 symToOp.erase(name);
132 nodeMap.erase(name);
133 }
134
135 /// Replace the module `oldModule` with `newModule` in the namepath of the nla
136 /// `nlaName`. This moves the nla from the list of `oldModule` to `newModule`.
137 /// Move `nlaName` from the list of NLAs that `oldModule` participates in to
138 /// `newModule`. This can delete and invalidate any reference returned by
139 /// `lookup`.
140 void updateModuleInNLA(StringAttr nlaName, StringAttr oldModule,
141 StringAttr newModule);
142
143 /// Replace the module `oldModule` with `newModule` in the namepath of the nla
144 /// `nlaOp`. This moves the nla from the list of `oldModule` to `newModule`.
145 /// Move `nlaOp` from the list of NLAs that `oldModule` participates in to
146 /// `newModule`. This can delete and invalidate any reference returned by
147 /// `lookup`.
148 void updateModuleInNLA(hw::HierPathOp nlaOp, StringAttr oldModule,
149 StringAttr newModule);
150
151 /// Rename a module, this updates the name to module tracking and the name to
152 /// NLA tracking. This moves all the NLAs that `oldModName` is participating
153 /// in to the `newModName`. The `oldModName` must exist in the name to module
154 /// record. This also removes all the entries for `oldModName`.
155 void renameModule(StringAttr oldModName, StringAttr newModName);
156
157 /// Replace the module `oldModName` with `newModName` in the namepath of any
158 /// NLA. Since the module is being updated, the symbols inside the module
159 /// should also be renamed. Use the rename map `innerSymRenameMap` to update
160 /// the inner_sym names in the namepath.
162 StringAttr newModName, StringAttr oldModName,
163 const DenseMap<StringAttr, StringAttr> &innerSymRenameMap);
164
165 /// Remove the NLA from the Module. This updates the module name to NLA
166 /// tracking.
167 void removeNLAfromModule(hw::HierPathOp nla, StringAttr mod) {
168 llvm::erase(nodeMap[mod], nla);
169 }
170
171 /// Remove all the nlas in the set `nlas` from the module. This updates the
172 /// module name to NLA tracking.
173 void removeNLAsfromModule(const DenseSet<hw::HierPathOp> &nlas,
174 StringAttr mod) {
175 llvm::erase_if(nodeMap[mod],
176 [&nlas](const auto &nla) { return nlas.count(nla); });
177 }
178
179 /// Add the nla to the module. This ensures that the list of NLAs that the
180 /// module participates in is updated. This will be required if `mod` is added
181 /// to the namepath of `nla`.
182 void addNLAtoModule(hw::HierPathOp nla, StringAttr mod) {
183 nodeMap[mod].push_back(nla);
184 }
185
186private:
187 NLATable(const NLATable &) = delete;
188
189 /// Map modules to the NLA's that target them.
190 llvm::DenseMap<StringAttr, SmallVector<hw::HierPathOp, 4>> nodeMap;
191
192 /// Map symbol names to module and NLA operations.
193 llvm::DenseMap<StringAttr, Operation *> symToOp;
194};
195
196} // namespace firrtl
197} // namespace circt
198#endif // CIRCT_DIALECT_FIRRTL_NLATABLE_H
This table tracks nlas and what modules participate in them.
Definition NLATable.h:29
ArrayRef< hw::HierPathOp > lookup(Operation *op)
Lookup all NLAs an operation participates in.
Definition NLATable.cpp:41
NLATable(const NLATable &)=delete
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
void removeNLAsfromModule(const DenseSet< hw::HierPathOp > &nlas, StringAttr mod)
Remove all the nlas in the set nlas from the module.
Definition NLATable.h:173
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 removeNLAfromModule(hw::HierPathOp nla, StringAttr mod)
Remove the NLA from the Module.
Definition NLATable.h:167
void addNLAtoModule(hw::HierPathOp nla, StringAttr mod)
Add the nla to the module.
Definition NLATable.h:182
void eraseModule(StringAttr name)
Stop tracking a module.
Definition NLATable.h:130
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 commonNLAs(StringAttr mod1, StringAttr mod2, DenseSet< hw::HierPathOp > &common)
Compute the NLAs that are common between the two modules, mod1 and mod2 and insert them into the set ...
Definition NLATable.h:60
void erase(hw::HierPathOp nlaOp, SymbolTable *symbolTable=nullptr)
Remove the NLA from the analysis.
Definition NLATable.cpp:68
void getNLAsInModule(StringAttr modName, DenseSet< hw::HierPathOp > &nlas)
Get the NLAs that the module modName particiaptes in, and insert them into the DenseSet nlas.
Definition NLATable.h:94
void addModule(FModuleLike mod)
Record a new FModuleLike operation.
Definition NLATable.h:125
void getInstanceNLAs(InstanceOp inst, DenseSet< hw::HierPathOp > &nlas)
Get the NLAs that the InstanceOp participates in, insert it to the DenseSet nlas.
Definition NLATable.h:71
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
StringAttr getInnerSymName(Operation *op)
Return the StringAttr for the inner_sym name, if it exists.
Definition FIRRTLOps.h:108
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.