CIRCT 21.0.0git
Loading...
Searching...
No Matches
FIRRTLAnnotationHelper.h
Go to the documentation of this file.
1//===- FIRRTLAnnotationHelper.h - FIRRTL Annotation Lookup ------*- 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 declares helpers mapping annotations to operations.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef CIRCT_DIALECT_FIRRTL_FIRRTLANNOTATIONHELPER_H
14#define CIRCT_DIALECT_FIRRTL_FIRRTLANNOTATIONHELPER_H
15
21#include "llvm/ADT/TypeSwitch.h"
22
23namespace circt {
24namespace firrtl {
25
26/// Stores an index into an aggregate.
28 StringRef name;
29 bool isIndex;
30};
31
32/// The parsed annotation path.
34 StringRef circuit;
35 SmallVector<std::pair<StringRef, StringRef>> instances;
36 StringRef module;
37 // The final name of the target
38 StringRef name;
39 // Any aggregates indexed.
40 SmallVector<TargetToken> component;
41
42 /// Append the annotation path to the given `SmallString` or `SmallVector`.
43 void toVector(SmallVectorImpl<char> &out) const;
44
45 /// Convert the annotation path to a string.
46 std::string str() const {
47 SmallString<32> out;
48 toVector(out);
49 return std::string(out);
50 }
51};
52
53// The potentially non-local resolved annotation.
55 SmallVector<InstanceOp> instances;
57 unsigned fieldIdx = 0;
58
59 AnnoPathValue() = default;
60 AnnoPathValue(CircuitOp op) : ref(OpAnnoTarget(op)) {}
61 AnnoPathValue(Operation *op) : ref(OpAnnoTarget(op)) {}
62 AnnoPathValue(const SmallVectorImpl<InstanceOp> &insts, AnnoTarget b,
63 unsigned fieldIdx)
64 : instances(insts.begin(), insts.end()), ref(b), fieldIdx(fieldIdx) {}
65
66 bool isLocal() const { return instances.empty(); }
67
68 template <typename... T>
69 bool isOpOfType() const {
70 if (auto opRef = dyn_cast<OpAnnoTarget>(ref))
71 return isa<T...>(opRef.getOp());
72 return false;
73 }
74};
75
76template <typename T>
77static T &operator<<(T &os, const AnnoPathValue &path) {
78 os << "~" << path.ref.getModule()->getParentOfType<CircuitOp>().getName()
79 << "|";
80
81 if (path.isLocal()) {
82 os << path.ref.getModule().getModuleName();
83 } else {
84 os << path.instances.front()
85 ->getParentOfType<FModuleLike>()
86 .getModuleName();
87 }
88 for (auto inst : path.instances)
89 os << "/" << inst.getName() << ":" << inst.getModuleName();
90 if (!path.isOpOfType<FModuleOp, FExtModuleOp, InstanceOp>()) {
91 os << ">" << path.ref;
92 auto type = dyn_cast<FIRRTLBaseType>(path.ref.getType());
93 if (!type)
94 return os;
95 auto targetFieldID = path.fieldIdx;
96 while (targetFieldID) {
98 .Case<FVectorType>([&](FVectorType vector) {
99 auto index = vector.getIndexForFieldID(targetFieldID);
100 os << "[" << index << "]";
101 type = vector.getElementType();
102 targetFieldID -= vector.getFieldID(index);
103 })
104 .template Case<BundleType>([&](BundleType bundle) {
105 auto index = bundle.getIndexForFieldID(targetFieldID);
106 os << "." << bundle.getElementName(index);
107 type = bundle.getElementType(index);
108 targetFieldID -= bundle.getFieldID(index);
109 })
110 .Default([&](auto) { targetFieldID = 0; });
111 }
112 }
113 return os;
114}
115
116template <typename T>
117static T &operator<<(T &os, const OpAnnoTarget &target) {
118 os << target.getOp()->getAttrOfType<StringAttr>("name").getValue();
119 return os;
120}
121
122template <typename T>
123static T &operator<<(T &os, const PortAnnoTarget &target) {
124 os << target.getModule().getPortName(target.getPortNo());
125 return os;
126}
127
128template <typename T>
129static T &operator<<(T &os, const AnnoTarget &target) {
130 if (auto op = dyn_cast<OpAnnoTarget>(target))
131 os << op;
132 else if (auto port = dyn_cast<PortAnnoTarget>(target))
133 os << port;
134 else
135 os << "<<Unknown Anno Target>>";
136 return os;
137}
138
139/// Cache AnnoTargets for a module's named things.
141 AnnoTargetCache() = delete;
142 AnnoTargetCache(const AnnoTargetCache &other) = default;
144 : targets(std::move(other.targets)){};
145
146 AnnoTargetCache(FModuleLike mod) { gatherTargets(mod); };
147
148 /// Lookup the target for 'name', empty if not found.
149 /// (check for validity using operator bool()).
150 AnnoTarget getTargetForName(StringRef name) const {
151 return targets.lookup(name);
152 }
153
154 void insertOp(Operation *op) {
155 TypeSwitch<Operation *>(op)
156 .Case<InstanceOp, MemOp, NodeOp, RegOp, RegResetOp, WireOp,
157 chirrtl::CombMemOp, chirrtl::SeqMemOp, chirrtl::MemoryPortOp,
158 chirrtl::MemoryDebugPortOp, PrintFOp>([&](auto op) {
159 // To be safe, check attribute and non-empty name before adding.
160 if (auto name = op.getNameAttr(); name && !name.getValue().empty())
161 targets.insert({name, OpAnnoTarget(op)});
162 });
163 }
164
165 /// Replace `oldOp` with `newOp` in the target cache. The new and old ops can
166 /// have different names.
167 void replaceOp(Operation *oldOp, Operation *newOp) {
168 if (auto name = oldOp->getAttrOfType<StringAttr>("name");
169 name && !name.getValue().empty())
170 targets.erase(name);
171 insertOp(newOp);
172 }
173
174 /// Add a new module port to the target cache.
175 void insertPort(FModuleLike mod, size_t portNo) {
176 targets.insert({mod.getPortNameAttr(portNo), PortAnnoTarget(mod, portNo)});
177 }
178
179private:
180 /// Walk the module and add named things to 'targets'.
181 void gatherTargets(FModuleLike mod);
182
183 llvm::DenseMap<StringRef, AnnoTarget> targets;
184};
185
186/// Cache AnnoTargets for a circuit's modules, walked as needed.
188 /// Get cache for specified module, creating it as needed.
189 /// Returned reference may become invalidated by future calls.
190 const AnnoTargetCache &getOrCreateCacheFor(FModuleLike module) {
191 auto it = targetCaches.find(module);
192 if (it == targetCaches.end())
193 it = targetCaches.try_emplace(module, module).first;
194 return it->second;
195 }
196
197 /// Lookup the target for 'name' in 'module'.
198 AnnoTarget lookup(FModuleLike module, StringRef name) {
199 return getOrCreateCacheFor(module).getTargetForName(name);
200 }
201
202 /// Clear the cache completely.
203 void invalidate() { targetCaches.clear(); }
204
205 /// Replace `oldOp` with `newOp` in the target cache. The new and old ops can
206 /// have different names.
207 void replaceOp(Operation *oldOp, Operation *newOp) {
208 auto mod = newOp->getParentOfType<FModuleOp>();
209 auto it = targetCaches.find(mod);
210 if (it == targetCaches.end())
211 return;
212 it->getSecond().replaceOp(oldOp, newOp);
213 }
214
215 /// Add a new module port to the target cache.
216 void insertPort(FModuleLike mod, size_t portNo) {
217 auto it = targetCaches.find(mod);
218 if (it == targetCaches.end())
219 return;
220 it->getSecond().insertPort(mod, portNo);
221 }
222
223 /// Add a new op to the target cache.
224 void insertOp(Operation *op) {
225 auto mod = op->getParentOfType<FModuleOp>();
226 auto it = targetCaches.find(mod);
227 if (it == targetCaches.end())
228 return;
229 it->getSecond().insertOp(op);
230 }
231
232private:
233 DenseMap<Operation *, AnnoTargetCache> targetCaches;
234};
235
236/// Return an input \p target string in canonical form. This converts a Legacy
237/// Annotation (e.g., A.B.C) into a modern annotation (e.g., ~A|B>C). Trailing
238/// subfield/subindex references are preserved.
239std::string canonicalizeTarget(StringRef target);
240
241/// Parse a FIRRTL annotation path into its constituent parts.
242std::optional<TokenAnnoTarget> tokenizePath(StringRef origTarget);
243
244/// Convert a parsed target string to a resolved target structure. This
245/// resolves all names and aggregates from a parsed target.
246std::optional<AnnoPathValue> resolveEntities(TokenAnnoTarget path,
247 CircuitOp circuit,
248 SymbolTable &symTbl,
249 CircuitTargetCache &cache);
250
251/// Resolve a string path to a named item inside a circuit.
252std::optional<AnnoPathValue> resolvePath(StringRef rawPath, CircuitOp circuit,
253 SymbolTable &symTbl,
254 CircuitTargetCache &cache);
255
256/// A representation of a deferred Wiring problem consisting of a source that
257/// should be connected to a sink.
259 enum class RefTypeUsage { Prefer, Never };
260
261 /// A source to wire from.
262 Value source;
263
264 /// A sink to wire to.
265 Value sink;
266
267 /// A base name to use when generating new signals associated with this wiring
268 /// problem.
269 std::string newNameHint;
270
271 /// The usage of ref type ports when solving this problem.
273};
274
275/// A representation of a legacy Wiring problem consisting of a signal source
276/// that should be connected to one or many sinks.
278 /// A source to wire from.
279 Value source;
280
281 /// Sink(s) to wire to.
282 SmallVector<Value> sinks;
283};
284
285/// A store of pending modifications to a FIRRTL module associated with solving
286/// one or more WiringProblems.
288 /// A pair of Wiring Problem index and port information.
289 using portInfoPair = std::pair<size_t, PortInfo>;
290
291 /// A pair of Wiring Problem index and a U-turn Value that should be
292 /// connected.
293 using uturnPair = std::pair<size_t, Value>;
294
295 /// Ports that should be added to a module.
296 SmallVector<portInfoPair> portsToAdd;
297
298 /// A mapping of a Value that should be connected to either a new port or a
299 /// U-turn, for a specific Wiring Problem. This is pre-populated with the
300 /// source and sink.
301 DenseMap<size_t, Value> connectionMap;
302
303 /// A secondary value that _may_ need to be hooked up. This is always set
304 /// after the Value in the connectionMap.
305 SmallVector<uturnPair> uturns;
306};
307
308/// A cache of existing HierPathOps, mostly used to facilitate HierPathOp reuse.
310 HierPathCache(Operation *op, SymbolTable &symbolTable);
311
312 hw::HierPathOp getOpFor(ArrayAttr attr);
313
314 StringAttr getSymFor(ArrayAttr attr) {
315 return getOpFor(attr).getSymNameAttr();
316 }
317
318 FlatSymbolRefAttr getRefFor(ArrayAttr attr) {
319 return FlatSymbolRefAttr::get(getSymFor(attr));
320 }
321
322 const SymbolTable &getSymbolTable() const { return symbolTable; }
323
324private:
325 OpBuilder builder;
326 DenseMap<ArrayAttr, hw::HierPathOp> cache;
327 SymbolTable &symbolTable;
328};
329
330/// State threaded through functions for resolving and applying annotations.
332 using AddToWorklistFn = llvm::function_ref<void(DictionaryAttr)>;
333 ApplyState(CircuitOp circuit, SymbolTable &symTbl,
334 AddToWorklistFn addToWorklistFn,
335 InstancePathCache &instancePathCache, bool noRefTypePorts)
336 : circuit(circuit), symTbl(symTbl), addToWorklistFn(addToWorklistFn),
337 instancePathCache(instancePathCache), hierPathCache(circuit, symTbl),
338 noRefTypePorts(noRefTypePorts) {}
339
340 CircuitOp circuit;
341 SymbolTable &symTbl;
346 size_t numReusedHierPaths = 0;
347
348 // Options that control annotation lowering.
350
351 DenseSet<InstanceOp> wiringProblemInstRefs;
352 DenseMap<StringAttr, LegacyWiringProblem> legacyWiringProblems;
353 SmallVector<WiringProblem> wiringProblems;
354
356 return namespaces[module];
357 }
358
359 IntegerAttr newID() {
360 return IntegerAttr::get(IntegerType::get(circuit.getContext(), 64),
361 annotationID++);
362 };
363
364private:
366 unsigned annotationID = 0;
367};
368
369LogicalResult applyGCTView(const AnnoPathValue &target, DictionaryAttr anno,
370 ApplyState &state);
371
372LogicalResult applyGCTDataTaps(const AnnoPathValue &target, DictionaryAttr anno,
373 ApplyState &state);
374
375LogicalResult applyGCTMemTaps(const AnnoPathValue &target, DictionaryAttr anno,
376 ApplyState &state);
377
378LogicalResult applyTraceName(const AnnoPathValue &target, DictionaryAttr anno,
379 ApplyState &state);
380
381LogicalResult applyWiring(const AnnoPathValue &target, DictionaryAttr anno,
382 ApplyState &state);
383
384/// Implements the same behavior as DictionaryAttr::getAs<A> to return the
385/// value of a specific type associated with a key in a dictionary. However,
386/// this is specialized to print a useful error message, specific to custom
387/// processing, on failure.
388template <typename A>
389A tryGetAsBase(DictionaryAttr dict, Attribute root, StringRef key, Location loc,
390 Twine whatSpecific, Twine whatFull, Twine path = Twine()) {
391 SmallString<128> msg;
392 // Check that the key exists.
393 auto value = dict.get(key);
394 if (!value) {
395 if (path.isTriviallyEmpty())
396 (whatSpecific + " did not contain required key '" + key + "'.")
397 .toVector(msg);
398 else
399 (whatSpecific + " with path '" + path +
400 "' did not contain required key '" + key + "'.")
401 .toVector(msg);
402 mlir::emitError(loc, msg).attachNote()
403 << "The full " << whatFull << " is reproduced here: " << root;
404 return nullptr;
405 }
406 // Check that the value has the correct type.
407 auto valueA = dyn_cast<A>(value);
408 if (!valueA) {
409 if (path.isTriviallyEmpty())
410 (whatSpecific + " did not contain the correct type for key '" + key +
411 "'.")
412 .toVector(msg);
413 else
414 (whatSpecific + " with path '" + path +
415 "' did not contain the correct type for key '" + key + "'.")
416 .toVector(msg);
417 mlir::emitError(loc, msg).attachNote()
418 << "The full " << whatFull << " is reproduced here: " << root;
419 return nullptr;
420 }
421 return valueA;
422}
423
424/// Implements the same behavior as DictionaryAttr::getAs<A> to return the
425/// value of a specific type associated with a key in a dictionary. However,
426/// this is specialized to print a useful error message, specific to custom
427/// annotation process, on failure.
428template <typename A>
429A tryGetAs(DictionaryAttr dict, Attribute root, StringRef key, Location loc,
430 Twine clazz, Twine path = Twine()) {
431 return tryGetAsBase<A>(dict, root, key, loc, "Annotation '" + clazz + "'",
432 "Annotation", path);
433}
434
435/// Add ports to the module and all its instances and return the clone for
436/// `instOnPath`. This does not connect the new ports to anything. Replace
437/// the old instances with the new cloned instance in all the caches.
438InstanceOp addPortsToModule(FModuleLike mod, InstanceOp instOnPath,
439 FIRRTLType portType, Direction dir,
440 StringRef newName,
441 InstancePathCache &instancePathcache,
442 CircuitTargetCache *targetCaches = nullptr);
443
444///===----------------------------------------------------------------------===//
445/// LowerAnnotations
446///===----------------------------------------------------------------------===//
447
448/// Annotation resolver and handler.
450 llvm::function_ref<std::optional<AnnoPathValue>(DictionaryAttr, ApplyState &)>
452 llvm::function_ref<LogicalResult(const AnnoPathValue &, DictionaryAttr,
453 ApplyState &)>
455};
456
457/// Register external annotation records.
458LogicalResult registerAnnotationRecord(
459 StringRef annoClass, AnnoRecord annoRecord,
460 const std::function<void(llvm::Twine)> &errorHandler = {});
461
462///===----------------------------------------------------------------------===//
463/// Standard Utility Resolvers
464///===----------------------------------------------------------------------===//
465
466/// (SFC) FIRRTL SingleTargetAnnotation resolver. Uses the 'target' field of
467/// the annotation with standard parsing to resolve the path. This requires
468/// 'target' to exist and be normalized (per docs/FIRRTLAnnotations.md).
469std::optional<AnnoPathValue> stdResolve(DictionaryAttr anno, ApplyState &state);
470
471/// Resolves with target, if it exists. If not, resolves to the circuit.
472std::optional<AnnoPathValue> tryResolve(DictionaryAttr anno, ApplyState &state);
473
474///===----------------------------------------------------------------------===//
475/// Standard Utility Appliers
476///===----------------------------------------------------------------------===//
477
478/// An applier which puts the annotation on the target and drops the 'target'
479/// field from the annotation. Optionally handles non-local annotations.
480LogicalResult applyWithoutTargetImpl(const AnnoPathValue &target,
481 DictionaryAttr anno, ApplyState &state,
482 bool allowNonLocal);
483
484/// An applier which puts the annotation on the target and drops the 'target'
485/// field from the annotation. Optionally handles non-local annotations.
486/// Ensures the target resolves to an expected type of operation.
487template <bool allowNonLocal, bool allowPortAnnoTarget, typename T,
488 typename... Tr>
489static LogicalResult applyWithoutTarget(const AnnoPathValue &target,
490 DictionaryAttr anno,
491 ApplyState &state) {
492 if (isa<PortAnnoTarget>(target.ref)) {
493 if (!allowPortAnnoTarget)
494 return failure();
495 } else if (!target.isOpOfType<T, Tr...>())
496 return failure();
497
498 return applyWithoutTargetImpl(target, anno, state, allowNonLocal);
499}
500
501template <bool allowNonLocal, typename T, typename... Tr>
502static LogicalResult applyWithoutTarget(const AnnoPathValue &target,
503 DictionaryAttr anno,
504 ApplyState &state) {
505 return applyWithoutTarget<allowNonLocal, false, T, Tr...>(target, anno,
506 state);
507}
508
509/// An applier which puts the annotation on the target and drops the 'target'
510/// field from the annotaiton. Optionally handles non-local annotations.
511template <bool allowNonLocal = false>
512static LogicalResult applyWithoutTarget(const AnnoPathValue &target,
513 DictionaryAttr anno,
514 ApplyState &state) {
515 return applyWithoutTargetImpl(target, anno, state, allowNonLocal);
516}
517
518} // namespace firrtl
519} // namespace circt
520
521#endif // CIRCT_DIALECT_FIRRTL_FIRRTLANNOTATIONHELPER_H
static std::vector< mlir::Value > toVector(mlir::ValueRange range)
This class implements the same functionality as TypeSwitch except that it uses firrtl::type_dyn_cast ...
FIRRTLTypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
A tryGetAs(DictionaryAttr dict, Attribute root, StringRef key, Location loc, Twine clazz, Twine path=Twine())
Implements the same behavior as DictionaryAttr::getAs<A> to return the value of a specific type assoc...
std::optional< AnnoPathValue > resolveEntities(TokenAnnoTarget path, CircuitOp circuit, SymbolTable &symTbl, CircuitTargetCache &cache)
Convert a parsed target string to a resolved target structure.
std::string canonicalizeTarget(StringRef target)
Return an input target string in canonical form.
LogicalResult applyGCTMemTaps(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state)
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const InstanceInfo::LatticeValue &value)
static LogicalResult applyWithoutTarget(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state)
An applier which puts the annotation on the target and drops the 'target' field from the annotation.
LogicalResult applyWiring(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state)
Consume SourceAnnotation and SinkAnnotation, storing into state.
LogicalResult applyTraceName(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state)
Expand a TraceNameAnnotation (which has don't touch semantics) into a TraceAnnotation (which does NOT...
LogicalResult registerAnnotationRecord(StringRef annoClass, AnnoRecord annoRecord, const std::function< void(llvm::Twine)> &errorHandler={})
Register external annotation records.
LogicalResult applyGCTDataTaps(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state)
std::optional< AnnoPathValue > resolvePath(StringRef rawPath, CircuitOp circuit, SymbolTable &symTbl, CircuitTargetCache &cache)
Resolve a string path to a named item inside a circuit.
LogicalResult applyGCTView(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state)
std::optional< TokenAnnoTarget > tokenizePath(StringRef origTarget)
Parse a FIRRTL annotation path into its constituent parts.
LogicalResult applyWithoutTargetImpl(const AnnoPathValue &target, DictionaryAttr anno, ApplyState &state, bool allowNonLocal)
===-------------------------------------------------------------------—===// Standard Utility Applier...
A tryGetAsBase(DictionaryAttr dict, Attribute root, StringRef key, Location loc, Twine whatSpecific, Twine whatFull, Twine path=Twine())
Implements the same behavior as DictionaryAttr::getAs<A> to return the value of a specific type assoc...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
SmallVector< InstanceOp > instances
AnnoPathValue(const SmallVectorImpl< InstanceOp > &insts, AnnoTarget b, unsigned fieldIdx)
===-------------------------------------------------------------------—===// LowerAnnotations ===----...
llvm::function_ref< std::optional< AnnoPathValue >(DictionaryAttr, ApplyState &)> resolver
llvm::function_ref< LogicalResult(const AnnoPathValue &, DictionaryAttr, ApplyState &)> applier
Cache AnnoTargets for a module's named things.
AnnoTarget getTargetForName(StringRef name) const
Lookup the target for 'name', empty if not found.
AnnoTargetCache(AnnoTargetCache &&other)
void gatherTargets(FModuleLike mod)
Walk the module and add named things to 'targets'.
AnnoTargetCache(const AnnoTargetCache &other)=default
void replaceOp(Operation *oldOp, Operation *newOp)
Replace oldOp with newOp in the target cache.
void insertPort(FModuleLike mod, size_t portNo)
Add a new module port to the target cache.
llvm::DenseMap< StringRef, AnnoTarget > targets
An annotation target is used to keep track of something that is targeted by an Annotation.
FIRRTLType getType() const
Get the type of the target.
FModuleLike getModule() const
Get the parent module of the target.
State threaded through functions for resolving and applying annotations.
DenseSet< InstanceOp > wiringProblemInstRefs
DenseMap< StringAttr, LegacyWiringProblem > legacyWiringProblems
ApplyState(CircuitOp circuit, SymbolTable &symTbl, AddToWorklistFn addToWorklistFn, InstancePathCache &instancePathCache, bool noRefTypePorts)
SmallVector< WiringProblem > wiringProblems
InstancePathCache & instancePathCache
hw::InnerSymbolNamespaceCollection namespaces
hw::InnerSymbolNamespace & getNamespace(FModuleLike module)
llvm::function_ref< void(DictionaryAttr)> AddToWorklistFn
Cache AnnoTargets for a circuit's modules, walked as needed.
const AnnoTargetCache & getOrCreateCacheFor(FModuleLike module)
Get cache for specified module, creating it as needed.
DenseMap< Operation *, AnnoTargetCache > targetCaches
void replaceOp(Operation *oldOp, Operation *newOp)
Replace oldOp with newOp in the target cache.
void invalidate()
Clear the cache completely.
void insertPort(FModuleLike mod, size_t portNo)
Add a new module port to the target cache.
void insertOp(Operation *op)
Add a new op to the target cache.
AnnoTarget lookup(FModuleLike module, StringRef name)
Lookup the target for 'name' in 'module'.
A cache of existing HierPathOps, mostly used to facilitate HierPathOp reuse.
DenseMap< ArrayAttr, hw::HierPathOp > cache
StringAttr getSymFor(ArrayAttr attr)
FlatSymbolRefAttr getRefFor(ArrayAttr attr)
const SymbolTable & getSymbolTable() const
A representation of a legacy Wiring problem consisting of a signal source that should be connected to...
SmallVector< Value > sinks
Sink(s) to wire to.
A store of pending modifications to a FIRRTL module associated with solving one or more WiringProblem...
SmallVector< portInfoPair > portsToAdd
Ports that should be added to a module.
std::pair< size_t, PortInfo > portInfoPair
A pair of Wiring Problem index and port information.
SmallVector< uturnPair > uturns
A secondary value that may need to be hooked up.
DenseMap< size_t, Value > connectionMap
A mapping of a Value that should be connected to either a new port or a U-turn, for a specific Wiring...
std::pair< size_t, Value > uturnPair
A pair of Wiring Problem index and a U-turn Value that should be connected.
This represents an annotation targeting a specific operation.
This represents an annotation targeting a specific port of a module, memory, or instance.
Stores an index into an aggregate.
The parsed annotation path.
SmallVector< TargetToken > component
std::string str() const
Convert the annotation path to a string.
void toVector(SmallVectorImpl< char > &out) const
Append the annotation path to the given SmallString or SmallVector.
SmallVector< std::pair< StringRef, StringRef > > instances
A representation of a deferred Wiring problem consisting of a source that should be connected to a si...
Value source
A source to wire from.
RefTypeUsage refTypeUsage
The usage of ref type ports when solving this problem.
std::string newNameHint
A base name to use when generating new signals associated with this wiring problem.
A data structure that caches and provides absolute paths to module instances in the IR.