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