CIRCT  19.0.0git
FieldRef.h
Go to the documentation of this file.
1 //===- FieldRef.h - Field References ---------------------------*- 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 header file defines FieldRefs and helpers for them.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef CIRCT_SUPPORT_FIELDREF_H
14 #define CIRCT_SUPPORT_FIELDREF_H
15 
16 #include "circt/Support/LLVM.h"
17 #include "mlir/IR/Value.h"
18 #include "llvm/ADT/DenseMapInfo.h"
19 
20 namespace circt {
21 
22 /// This class represents a reference to a specific field or element of an
23 /// aggregate value. Typically, the user will assign a unique field ID to each
24 /// field in an aggregate type by visiting them in a depth-first pre-order.
25 ///
26 /// This can be used as the key in a hashtable to store field specific
27 /// information.
28 class FieldRef {
29 public:
30  /// Get a null FieldRef.
31  FieldRef() {}
32 
33  /// Get a FieldRef location for the specified value.
34  FieldRef(Value value, unsigned id) : value(value), id(id) {}
35 
36  /// Get the Value which created this location.
37  Value getValue() const { return value; }
38 
39  /// Get the operation which defines this field. If the field is a block
40  /// argument it will return the operation which owns the block.
41  Operation *getDefiningOp() const;
42 
43  /// Get the operation which defines this field and cast it to the OpTy.
44  /// Returns null if the defining operation is of a different type.
45  template <typename OpTy>
46  OpTy getDefiningOp() const {
47  return llvm::dyn_cast<OpTy>(getDefiningOp());
48  }
49 
50  template <typename... Any>
51  bool isa() const {
52  auto *op = getDefiningOp();
53  assert(op && "isa<> used on a null type.");
54  return ::llvm::isa<Any...>(op);
55  }
56 
57  /// Get the field ID of this FieldRef, which is a unique identifier mapped to
58  /// a specific field in a bundle.
59  unsigned getFieldID() const { return id; }
60 
61  /// Get a reference to a subfield.
62  FieldRef getSubField(unsigned subFieldID) const {
63  return FieldRef(value, id + subFieldID);
64  }
65 
66  /// Get the location associated with the value of this field ref.
67  Location getLoc() const { return getValue().getLoc(); }
68 
69  bool operator==(const FieldRef &other) const {
70  return value == other.value && id == other.id;
71  }
72 
73  bool operator<(const FieldRef &other) const {
74  if (value.getImpl() < other.value.getImpl())
75  return true;
76  if (value.getImpl() > other.value.getImpl())
77  return false;
78  return id < other.id;
79  }
80 
81  operator bool() const { return bool(value); }
82 
83 private:
84  /// A pointer to the value which created this.
85  Value value;
86 
87  /// A unique field ID.
88  unsigned id = 0;
89 };
90 
91 /// Get a hash code for a FieldRef.
92 inline ::llvm::hash_code hash_value(const FieldRef &fieldRef) {
93  return llvm::hash_combine(fieldRef.getValue(), fieldRef.getFieldID());
94 }
95 
96 } // namespace circt
97 
98 namespace llvm {
99 /// Allow using FieldRef with DenseMaps. This hash is based on the Value
100 /// identity and field ID.
101 template <>
102 struct DenseMapInfo<circt::FieldRef> {
103  static inline circt::FieldRef getEmptyKey() {
104  return circt::FieldRef(DenseMapInfo<mlir::Value>::getEmptyKey(), 0);
105  }
107  return circt::FieldRef(DenseMapInfo<mlir::Value>::getTombstoneKey(), 0);
108  }
109  static unsigned getHashValue(const circt::FieldRef &val) {
110  return circt::hash_value(val);
111  }
112  static bool isEqual(const circt::FieldRef &lhs, const circt::FieldRef &rhs) {
113  return lhs == rhs;
114  }
115 };
116 } // namespace llvm
117 
118 #endif // CIRCT_SUPPORT_FIELDREF_H
assert(baseType &&"element must be base type")
This class represents a reference to a specific field or element of an aggregate value.
Definition: FieldRef.h:28
unsigned id
A unique field ID.
Definition: FieldRef.h:88
bool operator<(const FieldRef &other) const
Definition: FieldRef.h:73
FieldRef()
Get a null FieldRef.
Definition: FieldRef.h:31
FieldRef getSubField(unsigned subFieldID) const
Get a reference to a subfield.
Definition: FieldRef.h:62
unsigned getFieldID() const
Get the field ID of this FieldRef, which is a unique identifier mapped to a specific field in a bundl...
Definition: FieldRef.h:59
bool isa() const
Definition: FieldRef.h:51
Value getValue() const
Get the Value which created this location.
Definition: FieldRef.h:37
Location getLoc() const
Get the location associated with the value of this field ref.
Definition: FieldRef.h:67
Operation * getDefiningOp() const
Get the operation which defines this field.
Definition: FieldRef.cpp:19
OpTy getDefiningOp() const
Get the operation which defines this field and cast it to the OpTy.
Definition: FieldRef.h:46
FieldRef(Value value, unsigned id)
Get a FieldRef location for the specified value.
Definition: FieldRef.h:34
bool operator==(const FieldRef &other) const
Definition: FieldRef.h:69
Value value
A pointer to the value which created this.
Definition: FieldRef.h:85
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
inline ::llvm::hash_code hash_value(const FieldRef &fieldRef)
Get a hash code for a FieldRef.
Definition: FieldRef.h:92
static circt::FieldRef getTombstoneKey()
Definition: FieldRef.h:106
static circt::FieldRef getEmptyKey()
Definition: FieldRef.h:103
static unsigned getHashValue(const circt::FieldRef &val)
Definition: FieldRef.h:109
static bool isEqual(const circt::FieldRef &lhs, const circt::FieldRef &rhs)
Definition: FieldRef.h:112