CIRCT  20.0.0git
FIRRTLAnnotations.h
Go to the documentation of this file.
1 //===- FIRRTLAnnotations.h - Code for working with Annotations --*- 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 for working with FIRRTL annotations.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef CIRCT_DIALECT_FIRRTL_ANNOTATIONS_H
14 #define CIRCT_DIALECT_FIRRTL_ANNOTATIONS_H
15 
16 #include "circt/Support/LLVM.h"
17 #include "mlir/IR/BuiltinAttributes.h"
18 #include "mlir/IR/BuiltinTypes.h"
19 #include "mlir/IR/Operation.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/Support/PointerLikeTypeTraits.h"
22 
23 namespace circt {
24 namespace hw {
25 struct InnerSymbolNamespace;
26 } // namespace hw
27 namespace firrtl {
28 
29 class AnnotationSetIterator;
30 class FModuleOp;
31 class FModuleLike;
32 class MemOp;
33 class InstanceOp;
34 class FIRRTLType;
35 
36 /// Return the name of the attribute used for annotations on FIRRTL ops.
37 inline StringRef getAnnotationAttrName() { return "annotations"; }
38 
39 /// Return the name of the attribute used for port annotations on FIRRTL ops.
40 inline StringRef getPortAnnotationAttrName() { return "portAnnotations"; }
41 
42 inline ArrayAttr getAnnotationsIfPresent(Operation *op) {
43  return op->getAttrOfType<ArrayAttr>(getAnnotationAttrName());
44 }
45 
46 /// This class provides a read-only projection of an annotation.
47 class Annotation {
48 public:
49  Annotation() = default;
50 
51  explicit Annotation(Attribute attr) : attr(attr) {
52  assert(attr && "null attributes not allowed");
53  }
54 
55  // Make a new annotation which is a clone of anno with a new fieldID.
56  Annotation(Annotation anno, uint64_t fieldID) : attr(anno.attr) {
57  auto oldFieldID = anno.getMember<IntegerAttr>("circt.fieldID");
58  if (oldFieldID && !fieldID) {
59  removeMember("circt.fieldID");
60  return;
61  }
62  if (fieldID)
63  setMember("circt.fieldID",
64  IntegerAttr::get(IntegerType::get(anno.attr.getContext(), 32),
65  APInt(32, fieldID)));
66  }
67 
68  /// Get the data dictionary of this attribute.
69  DictionaryAttr getDict() const;
70 
71  /// Set the data dictionary of this attribute.
72  void setDict(DictionaryAttr dict);
73 
74  /// Get the field id this attribute targets.
75  unsigned getFieldID() const;
76 
77  /// Get the underlying attribute.
78  Attribute getAttr() const { return attr; }
79 
80  /// Return the 'class' that this annotation is representing.
81  StringAttr getClassAttr() const;
82  StringRef getClass() const;
83 
84  /// Return true if this annotation matches any of the specified class names.
85  template <typename... Args>
86  bool isClass(Args... names) const {
87  return ClassIsa{getClassAttr()}(names...);
88  }
89 
90  /// Return a member of the annotation.
91  template <typename AttrClass = Attribute>
92  AttrClass getMember(StringAttr name) const {
93  return getDict().getAs<AttrClass>(name);
94  }
95  template <typename AttrClass = Attribute>
96  AttrClass getMember(StringRef name) const {
97  return getDict().getAs<AttrClass>(name);
98  }
99 
100  /// Add or set a member of the annotation to a value.
101  void setMember(StringAttr name, Attribute value);
102  void setMember(StringRef name, Attribute value);
103 
104  /// Remove a member of the annotation.
105  void removeMember(StringAttr name);
106  void removeMember(StringRef name);
107 
108  using iterator = llvm::ArrayRef<NamedAttribute>::iterator;
109  iterator begin() const { return getDict().begin(); }
110  iterator end() const { return getDict().end(); }
111 
112  bool operator==(const Annotation &other) const { return attr == other.attr; }
113  bool operator!=(const Annotation &other) const { return !(*this == other); }
114  explicit operator bool() const { return bool(attr); }
115  bool operator!() const { return attr == nullptr; }
116 
117  void dump();
118 
119 private:
120  Attribute attr;
121 
122  /// Helper struct to perform variadic class equality check.
123  struct ClassIsa {
124  StringAttr cls;
125 
126  bool operator()() const { return false; }
127  template <typename T, typename... Rest>
128  bool operator()(T name, Rest... rest) const {
129  return compare(name) || (*this)(rest...);
130  }
131 
132  private:
133  bool compare(StringAttr name) const { return cls == name; }
134  bool compare(StringRef name) const { return cls && cls.getValue() == name; }
135  };
136 };
137 
138 /// This class provides a read-only projection over the MLIR attributes that
139 /// represent a set of annotations. It is intended to make this work less
140 /// stringly typed and fiddly for clients.
141 ///
143 public:
145 
146  /// Form an empty annotation set.
147  explicit AnnotationSet(MLIRContext *context)
148  : annotations(ArrayAttr::get(context, {})) {}
149 
150  /// Form an annotation set from an array of annotation attributes.
151  explicit AnnotationSet(ArrayRef<Attribute> annotations, MLIRContext *context);
152 
153  /// Form an annotation set from an array of annotations.
154  explicit AnnotationSet(ArrayRef<Annotation> annotations,
155  MLIRContext *context);
156 
157  /// Form an annotation set with a non-null ArrayAttr.
159  assert(annotations && "Cannot use null attribute set");
160  }
161 
162  /// Form an annotation set with a possibly-null ArrayAttr.
163  explicit AnnotationSet(ArrayAttr annotations, MLIRContext *context);
164 
165  /// Get an annotation set for the specified operation.
166  explicit AnnotationSet(Operation *op);
167 
168  /// Get an annotation set for the specified port.
169  static AnnotationSet forPort(FModuleLike op, size_t portNo);
170  static AnnotationSet forPort(MemOp op, size_t portNo);
171 
172  /// Get an annotation set for the specified value.
173  static AnnotationSet get(Value v);
174 
175  /// Return all the raw annotations that exist.
176  ArrayRef<Attribute> getArray() const { return annotations.getValue(); }
177 
178  /// Return this annotation set as an ArrayAttr.
179  ArrayAttr getArrayAttr() const {
180  assert(annotations && "Cannot use null attribute set");
181  return annotations;
182  }
183 
184  /// Store the annotations in this set in an operation's `annotations`
185  /// attribute, overwriting any existing annotations. Removes the `annotations`
186  /// attribute if the set is empty. Returns true if the operation was modified,
187  /// false otherwise.
188  bool applyToOperation(Operation *op) const;
189 
190  /// Store the annotations in this set in an operation's `portAnnotations`
191  /// attribute, overwriting any existing annotations for this port. Returns
192  /// true if the operation was modified, false otherwise.
193  bool applyToPort(FModuleLike op, size_t portNo) const;
194  bool applyToPort(MemOp op, size_t portNo) const;
195 
196  /// Return true if we have an annotation with the specified class name.
197  bool hasAnnotation(StringRef className) const {
198  return !annotations.empty() && hasAnnotationImpl(className);
199  }
200  bool hasAnnotation(StringAttr className) const {
201  return !annotations.empty() && hasAnnotationImpl(className);
202  }
203 
204  /// Return true if we have an annotation with the specified class name.
205  template <typename... Args>
206  static bool hasAnnotation(Operation *op, Args... args) {
207  auto annosArray = getAnnotationsIfPresent(op);
208  if (!annosArray)
209  return false;
210  AnnotationSet annotations(annosArray);
211  return !annotations.empty() && (... || annotations.hasAnnotationImpl(args));
212  }
213 
214  /// If this annotation set has an annotation with the specified class name,
215  /// return it. Otherwise return a null DictionaryAttr.
216  Annotation getAnnotation(StringRef className) const {
217  if (annotations.empty())
218  return {};
219  return getAnnotationImpl(className);
220  }
221  Annotation getAnnotation(StringAttr className) const {
222  if (annotations.empty())
223  return {};
224  return getAnnotationImpl(className);
225  }
226 
228  iterator begin() const;
229  iterator end() const;
230 
231  /// Return the MLIRContext corresponding to this AnnotationSet.
232  MLIRContext *getContext() const { return annotations.getContext(); }
233 
234  // Support for widely used annotations.
235 
236  /// firrtl.transforms.DontTouchAnnotation
237  bool hasDontTouch() const;
238  bool setDontTouch(bool dontTouch);
239  bool addDontTouch();
240  bool removeDontTouch();
241  static bool hasDontTouch(Operation *op);
242  static bool setDontTouch(Operation *op, bool dontTouch);
243  static bool addDontTouch(Operation *op);
244  static bool removeDontTouch(Operation *op);
245 
246  bool operator==(const AnnotationSet &other) const {
247  return annotations == other.annotations;
248  }
249  bool operator!=(const AnnotationSet &other) const {
250  return !(*this == other);
251  }
252 
253  bool empty() const { return annotations.empty(); }
254 
255  size_t size() const { return annotations.size(); }
256 
257  /// Add more annotations to this annotation set.
258  void addAnnotations(ArrayRef<Annotation> annotations);
259  void addAnnotations(ArrayRef<Attribute> annotations);
260  void addAnnotations(ArrayAttr annotations);
261 
262  /// Remove an annotation from this annotation set. Returns true if any were
263  /// removed, false otherwise.
264  bool removeAnnotation(Annotation anno);
265  bool removeAnnotation(Attribute anno);
266  bool removeAnnotation(StringRef className);
267 
268  /// Remove all annotations from this annotation set for which `predicate`
269  /// returns true. The predicate is guaranteed to be called on every
270  /// annotation, such that this method can be used to partition the set by
271  /// extracting and removing annotations at the same time. Returns true if any
272  /// annotations were removed, false otherwise.
273  bool removeAnnotations(llvm::function_ref<bool(Annotation)> predicate);
274 
275  /// Remove all annotations with one of the given classes from this annotation
276  /// set.
277  template <typename... Args>
278  bool removeAnnotationsWithClass(Args... names) {
279  return removeAnnotations(
280  [&](Annotation anno) { return anno.isClass(names...); });
281  }
282 
283  /// Remove all annotations from an operation for which `predicate` returns
284  /// true. The predicate is guaranteed to be called on every annotation, such
285  /// that this method can be used to partition the set by extracting and
286  /// removing annotations at the same time. Returns true if any annotations
287  /// were removed, false otherwise.
288  static bool removeAnnotations(Operation *op,
289  llvm::function_ref<bool(Annotation)> predicate);
290  static bool removeAnnotations(Operation *op, StringRef className);
291 
292  /// Remove all port annotations from a module or extmodule for which
293  /// `predicate` returns true. The predicate is guaranteed to be called on
294  /// every annotation, such that this method can be used to partition a
295  /// module's port annotations by extracting and removing annotations at the
296  /// same time. Returns true if any annotations were removed, false otherwise.
297  static bool removePortAnnotations(
298  Operation *module,
299  llvm::function_ref<bool(unsigned, Annotation)> predicate);
300 
301 private:
302  bool hasAnnotationImpl(StringAttr className) const;
303  bool hasAnnotationImpl(StringRef className) const;
304  Annotation getAnnotationImpl(StringAttr className) const;
305  Annotation getAnnotationImpl(StringRef className) const;
306 
307  ArrayAttr annotations;
308 };
309 
310 // Iteration over the annotation set.
312  : public llvm::indexed_accessor_iterator<AnnotationSetIterator,
313  AnnotationSet, Annotation,
314  Annotation, Annotation> {
315 public:
316  // Index into this iterator.
317  Annotation operator*() const;
318 
319 private:
320  AnnotationSetIterator(AnnotationSet owner, ptrdiff_t curIndex)
321  : llvm::indexed_accessor_iterator<AnnotationSetIterator, AnnotationSet,
323  owner, curIndex) {}
324  friend llvm::indexed_accessor_iterator<AnnotationSetIterator, AnnotationSet,
326  friend class AnnotationSet;
327 };
328 
329 inline auto AnnotationSet::begin() const -> iterator {
330  return AnnotationSetIterator(*this, 0);
331 }
332 inline auto AnnotationSet::end() const -> iterator {
333  return iterator(*this, annotations.size());
334 }
335 
336 //===----------------------------------------------------------------------===//
337 // AnnoTarget
338 //===----------------------------------------------------------------------===//
339 
340 namespace detail {
342  /* implicit */ AnnoTargetImpl(Operation *op) : op(op), portNo(~0UL) {}
343 
344  AnnoTargetImpl(Operation *op, unsigned portNo) : op(op), portNo(portNo) {}
345 
346  operator bool() const { return getOp(); }
347  bool operator==(const AnnoTargetImpl &other) const {
348  return op == other.op && portNo == other.portNo;
349  }
350  bool operator!=(const AnnoTargetImpl &other) const {
351  return !(*this == other);
352  }
353 
354  bool isPort() const { return op && portNo != ~0UL; }
355  bool isOp() const { return op && portNo == ~0UL; }
356 
357  Operation *getOp() const { return op; }
358  void setOp(Operation *op) { this->op = op; }
359 
360  unsigned getPortNo() const { return portNo; }
361  void setPortNo(unsigned portNo) { this->portNo = portNo; }
362 
363 protected:
364  Operation *op;
365  size_t portNo;
366 };
367 } // namespace detail
368 
369 /// An annotation target is used to keep track of something that is targeted by
370 /// an Annotation.
371 struct AnnoTarget {
373 
374  operator bool() const { return impl; }
375  bool operator==(const AnnoTarget &other) const { return impl == other.impl; }
376  bool operator!=(const AnnoTarget &other) const { return !(*this == other); }
377 
378  Operation *getOp() const { return getImpl().getOp(); }
379  void setOp(Operation *op) { getImpl().setOp(op); }
380 
381  /// Get the annotations associated with the target.
383 
384  /// Set the annotations associated with the target.
385  void setAnnotations(AnnotationSet annotations) const;
386 
387  /// Get the parent module of the target.
388  FModuleLike getModule() const;
389 
390  /// Get a reference to this target suitable for use in an NLA.
391  Attribute getNLAReference(hw::InnerSymbolNamespace &moduleNamespace) const;
392 
393  /// Get the type of the target.
394  FIRRTLType getType() const;
395 
396  detail::AnnoTargetImpl getImpl() const { return impl; }
397 
398 protected:
400 };
401 
402 /// This represents an annotation targeting a specific operation.
403 struct OpAnnoTarget : public AnnoTarget {
405 
406  OpAnnoTarget(Operation *op) : AnnoTarget(op) {}
407 
409  void setAnnotations(AnnotationSet annotations) const;
410  Attribute getNLAReference(hw::InnerSymbolNamespace &moduleNamespace) const;
411  FIRRTLType getType() const;
412 
413  static bool classof(const AnnoTarget &annoTarget) {
414  return annoTarget.getImpl().isOp();
415  }
416 };
417 
418 /// This represents an annotation targeting a specific port of a module, memory,
419 /// or instance.
420 struct PortAnnoTarget : public AnnoTarget {
422 
423  PortAnnoTarget(FModuleLike op, unsigned portNo);
424  PortAnnoTarget(MemOp op, unsigned portNo);
425 
426  unsigned getPortNo() const { return getImpl().getPortNo(); }
427  void setPortNo(unsigned portNo) { getImpl().setPortNo(portNo); }
428 
430  void setAnnotations(AnnotationSet annotations) const;
431  Attribute getNLAReference(hw::InnerSymbolNamespace &moduleNamespace) const;
432  FIRRTLType getType() const;
433 
434  static bool classof(const AnnoTarget &annoTarget) {
435  return annoTarget.getImpl().isPort();
436  }
437 };
438 
439 //===----------------------------------------------------------------------===//
440 // Utilities for Specific Annotations
441 //
442 // TODO: Remove these in favor of first-class annotations.
443 //===----------------------------------------------------------------------===//
444 
445 /// Utility that searches for a MarkDUTAnnotation on a specific module, `mod`,
446 /// and tries to update a design-under-test (DUT), `dut`, with this module if
447 /// the module is the DUT. This function returns success if either no DUT was
448 /// found or if the DUT was found and a previous DUT was not set (if `dut` is
449 /// null). This returns failure if a DUT was found and a previous DUT was set.
450 /// This function generates an error message in the failure case.
451 LogicalResult extractDUT(FModuleLike mod, FModuleLike &dut);
452 
453 } // namespace firrtl
454 } // namespace circt
455 
456 //===----------------------------------------------------------------------===//
457 // Traits
458 //===----------------------------------------------------------------------===//
459 
460 namespace llvm {
461 
462 /// Add support for llvm style casts to AnnoTarget.
463 template <typename To, typename From>
464 struct CastInfo<
465  To, From,
466  std::enable_if_t<std::is_base_of_v<::circt::firrtl::AnnoTarget, From>>>
468  DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
469  static inline bool isPossible(From target) {
470  // Allow constant upcasting. This also gets around the fact that AnnoTarget
471  // does not implement classof.
472  if constexpr (std::is_base_of_v<To, From>)
473  return true;
474  else
475  return To::classof(target);
476  }
477  static inline To doCast(From target) { return To(target.getImpl()); }
478 };
479 
480 /// Make `Annotation` behave like a `Attribute` in terms of pointer-likeness.
481 template <>
482 struct PointerLikeTypeTraits<circt::firrtl::Annotation>
483  : PointerLikeTypeTraits<mlir::Attribute> {
485  static inline void *getAsVoidPointer(Annotation v) {
486  return const_cast<void *>(v.getAttr().getAsOpaquePointer());
487  }
488  static inline Annotation getFromVoidPointer(void *p) {
489  return Annotation(mlir::DictionaryAttr::getFromOpaquePointer(p));
490  }
491 };
492 
493 /// Make `Annotation` hash just like `Attribute`.
494 template <>
495 struct DenseMapInfo<circt::firrtl::Annotation> {
498  return Annotation(
499  mlir::DictionaryAttr(static_cast<mlir::Attribute::ImplType *>(
501  }
503  return Annotation(
504  mlir::DictionaryAttr(static_cast<mlir::Attribute::ImplType *>(
506  }
507  static unsigned getHashValue(Annotation val) {
508  return mlir::hash_value(val.getAttr());
509  }
510  static bool isEqual(Annotation lhs, Annotation rhs) { return lhs == rhs; }
511 };
512 
513 /// Make `AnnoTarget` hash.
514 template <>
515 struct DenseMapInfo<circt::firrtl::AnnoTarget> {
521  return AnnoTarget(AnnoTargetImpl(o, i));
522  }
526  return AnnoTarget(AnnoTargetImpl(o, i));
527  }
528  static unsigned getHashValue(AnnoTarget val) {
529  auto impl = val.getImpl();
530  return hash_combine(impl.getOp(), impl.getPortNo());
531  }
532  static bool isEqual(AnnoTarget lhs, AnnoTarget rhs) { return lhs == rhs; }
533 };
534 
535 } // namespace llvm
536 
537 #endif // CIRCT_DIALECT_FIRRTL_ANNOTATIONS_H
assert(baseType &&"element must be base type")
AnnotationSetIterator(AnnotationSet owner, ptrdiff_t curIndex)
This class provides a read-only projection over the MLIR attributes that represent a set of annotatio...
bool hasDontTouch() const
firrtl.transforms.DontTouchAnnotation
bool hasAnnotationImpl(StringAttr className) const
bool removeAnnotations(llvm::function_ref< bool(Annotation)> predicate)
Remove all annotations from this annotation set for which predicate returns true.
Annotation getAnnotationImpl(StringAttr className) const
bool applyToPort(FModuleLike op, size_t portNo) const
Store the annotations in this set in an operation's portAnnotations attribute, overwriting any existi...
ArrayAttr getArrayAttr() const
Return this annotation set as an ArrayAttr.
AnnotationSet(ArrayAttr annotations)
Form an annotation set with a non-null ArrayAttr.
bool removeAnnotation(Annotation anno)
Remove an annotation from this annotation set.
static bool hasAnnotation(Operation *op, Args... args)
Return true if we have an annotation with the specified class name.
bool removeAnnotationsWithClass(Args... names)
Remove all annotations with one of the given classes from this annotation set.
static AnnotationSet get(Value v)
Get an annotation set for the specified value.
Annotation getAnnotation(StringAttr className) const
bool hasAnnotation(StringAttr className) const
bool operator!=(const AnnotationSet &other) const
bool applyToOperation(Operation *op) const
Store the annotations in this set in an operation's annotations attribute, overwriting any existing a...
void addAnnotations(ArrayRef< Annotation > annotations)
Add more annotations to this annotation set.
bool hasAnnotation(StringRef className) const
Return true if we have an annotation with the specified class name.
AnnotationSet(MLIRContext *context)
Form an empty annotation set.
static bool removePortAnnotations(Operation *module, llvm::function_ref< bool(unsigned, Annotation)> predicate)
Remove all port annotations from a module or extmodule for which predicate returns true.
static AnnotationSet forPort(FModuleLike op, size_t portNo)
Get an annotation set for the specified port.
Annotation getAnnotation(StringRef className) const
If this annotation set has an annotation with the specified class name, return it.
bool operator==(const AnnotationSet &other) const
bool setDontTouch(bool dontTouch)
ArrayRef< Attribute > getArray() const
Return all the raw annotations that exist.
AnnotationSetIterator iterator
MLIRContext * getContext() const
Return the MLIRContext corresponding to this AnnotationSet.
This class provides a read-only projection of an annotation.
Attribute getAttr() const
Get the underlying attribute.
DictionaryAttr getDict() const
Get the data dictionary of this attribute.
void setDict(DictionaryAttr dict)
Set the data dictionary of this attribute.
bool operator==(const Annotation &other) const
unsigned getFieldID() const
Get the field id this attribute targets.
AttrClass getMember(StringAttr name) const
Return a member of the annotation.
void setMember(StringAttr name, Attribute value)
Add or set a member of the annotation to a value.
Annotation(Annotation anno, uint64_t fieldID)
void removeMember(StringAttr name)
Remove a member of the annotation.
bool operator!=(const Annotation &other) const
AttrClass getMember(StringRef name) const
StringRef getClass() const
Return the 'class' that this annotation is representing.
StringAttr getClassAttr() const
Return the 'class' that this annotation is representing.
llvm::ArrayRef< NamedAttribute >::iterator iterator
bool isClass(Args... names) const
Return true if this annotation matches any of the specified class names.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
StringRef getAnnotationAttrName()
Return the name of the attribute used for annotations on FIRRTL ops.
LogicalResult extractDUT(FModuleLike mod, FModuleLike &dut)
Utility that searches for a MarkDUTAnnotation on a specific module, mod, and tries to update a design...
StringRef getPortAnnotationAttrName()
Return the name of the attribute used for port annotations on FIRRTL ops.
ArrayAttr getAnnotationsIfPresent(Operation *op)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
size_t hash_combine(size_t h1, size_t h2)
C++'s stdlib doesn't have a hash_combine function. This is a simple one.
Definition: Utils.h:32
Definition: hw.py:1
llvm::hash_code hash_value(const T &e)
An annotation target is used to keep track of something that is targeted by an Annotation.
void setOp(Operation *op)
FIRRTLType getType() const
Get the type of the target.
bool operator!=(const AnnoTarget &other) const
Attribute getNLAReference(hw::InnerSymbolNamespace &moduleNamespace) const
Get a reference to this target suitable for use in an NLA.
detail::AnnoTargetImpl getImpl() const
detail::AnnoTargetImpl impl
Operation * getOp() const
FModuleLike getModule() const
Get the parent module of the target.
AnnotationSet getAnnotations() const
Get the annotations associated with the target.
void setAnnotations(AnnotationSet annotations) const
Set the annotations associated with the target.
bool operator==(const AnnoTarget &other) const
AnnoTarget(detail::AnnoTargetImpl impl=nullptr)
Helper struct to perform variadic class equality check.
bool compare(StringRef name) const
bool compare(StringAttr name) const
bool operator()(T name, Rest... rest) const
This represents an annotation targeting a specific operation.
Attribute getNLAReference(hw::InnerSymbolNamespace &moduleNamespace) const
void setAnnotations(AnnotationSet annotations) const
static bool classof(const AnnoTarget &annoTarget)
AnnotationSet getAnnotations() const
This represents an annotation targeting a specific port of a module, memory, or instance.
static bool classof(const AnnoTarget &annoTarget)
void setPortNo(unsigned portNo)
AnnotationSet getAnnotations() const
void setAnnotations(AnnotationSet annotations) const
Attribute getNLAReference(hw::InnerSymbolNamespace &moduleNamespace) const
PortAnnoTarget(FModuleLike op, unsigned portNo)
bool operator!=(const AnnoTargetImpl &other) const
bool operator==(const AnnoTargetImpl &other) const
AnnoTargetImpl(Operation *op, unsigned portNo)
static bool isEqual(AnnoTarget lhs, AnnoTarget rhs)
static unsigned getHashValue(AnnoTarget val)
static unsigned getHashValue(Annotation val)
static bool isEqual(Annotation lhs, Annotation rhs)