CIRCT  20.0.0git
FIRRTLInstanceInfo.h
Go to the documentation of this file.
1 //===- FIRRTLInstanceInfo.h - Instance info analysis ------------*- 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 InstanceInfo analysis. This is an analysis that
10 // depends on the InstanceGraph analysis, but provides additional information
11 // about FIRRTL operations. This is useful if you find yourself needing to
12 // selectively iterate over parts of the design.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef CIRCT_DIALECT_FIRRTL_FIRRTLINSTANCEINFO_H
17 #define CIRCT_DIALECT_FIRRTL_FIRRTLINSTANCEINFO_H
18 
20 #include "circt/Support/LLVM.h"
21 #include "mlir/Pass/AnalysisManager.h"
22 
23 namespace circt {
24 namespace firrtl {
25 
26 class InstanceInfo {
27 
28 public:
29  explicit InstanceInfo(Operation *op, mlir::AnalysisManager &am);
30 
31  /// A lattice value to record the value of a property.
32  class LatticeValue {
33 
34  public:
35  enum Kind {
36  // Indicates that we have no information about this property. Properties
37  // start in this state and then are changed to Constant or Mixed.
38  Unknown = 0,
39 
40  // Indicates that the property has a true or false value.
42 
43  // Indicates that the property was found to be both true and false.
44  Mixed
45  };
46 
47  private:
48  /// Whether or not the property holds.
49  Kind kind = Kind::Unknown;
50 
51  /// The value of the property if `kind` is `Constant`.
52  bool value = false;
53 
54  public:
55  /// Return true if the kind is Unknown.
56  bool isUnknown() const;
57 
58  /// Return true if the kind is Constant.
59  bool isConstant() const;
60 
61  /// Return true if the kind is Mixed.
62  bool isMixed() const;
63 
64  /// Return the value. This should only be used if the kind is Constant.
65  bool getConstant() const;
66 
67  /// Set this LatticeValue to a constant.
68  void markConstant(bool constant);
69 
70  /// Set this LatticeValue to mixed.
71  void markMixed();
72 
73  /// Merge attributes from another LatticeValue into this one.
74  void mergeIn(LatticeValue that);
75 
76  /// Merge a constant value into this one.
77  void mergeIn(bool value);
78 
79  /// Invert the lattice value.
81  };
82 
83  /// Information about a circuit
85  /// The design-under-test if one is defined.
86  igraph::ModuleOpInterface dut;
87 
88  /// The design-under-test if one is defined or the top module.
89  igraph::ModuleOpInterface effectiveDut;
90  };
91 
92  /// Information about a module
94  /// Indicates if this module is instantiated under the design-under-test.
96 
97  /// Indicates if this module is instantiated under a layer.
99 
100  /// Indicates if this module is instantiated in the design. The "design" is
101  /// defined as being under the design-under-test, excluding verification
102  /// code (e.g., layers).
104 
105  /// Indicates if this modules is instantiated in the effective design. The
106  /// "effective design" is defined as the design-under-test (DUT), excluding
107  /// verification code (e.g., layers). If a DUT is specified, then this is
108  /// the same as `inDesign`. However, if there is no DUT, then every module
109  /// is deemed to be in the design except those which are explicitly
110  /// verification code.
112  };
113 
114  //===--------------------------------------------------------------------===//
115  // Circuit Attribute Queries
116  //===--------------------------------------------------------------------===//
117 
118  /// Return true if this circuit has a design-under-test.
119  bool hasDut();
120 
121  /// Return the design-under-test if one is defined for the circuit, otherwise
122  /// return null.
123  igraph::ModuleOpInterface getDut();
124 
125  /// Return the "effective" design-under-test. This will be the
126  /// design-under-test if one is defined. Otherwise, this will be the root
127  /// node of the instance graph.
128  igraph::ModuleOpInterface getEffectiveDut();
129 
130  //===--------------------------------------------------------------------===//
131  // Module Attribute Queries
132  //===--------------------------------------------------------------------===//
133 
134  /// Return true if this module is the design-under-test.
135  bool isDut(igraph::ModuleOpInterface op);
136 
137  /// Return true if this module is the design-under-test and the circuit has a
138  /// design-under-test. If the circuit has no design-under-test, then return
139  /// true if this is the top module.
140  bool isEffectiveDut(igraph::ModuleOpInterface op);
141 
142  /// Return true if at least one instance of this module is under (or
143  /// transitively under) the design-under-test. This is true if the module is
144  /// the design-under-test.
145  bool anyInstanceUnderDut(igraph::ModuleOpInterface op);
146 
147  /// Return true if all instances of this module are under (or transitively
148  /// under) the design-under-test. This is true if the module is the
149  /// design-under-test.
150  bool allInstancesUnderDut(igraph::ModuleOpInterface op);
151 
152  /// Return true if at least one instance is under (or transitively under) the
153  /// effective design-under-test. This is true if the module is the effective
154  /// design-under-test.
155  bool anyInstanceUnderEffectiveDut(igraph::ModuleOpInterface op);
156 
157  /// Return true if all instances are under (or transitively under) the
158  /// effective design-under-test. This is true if the module is the effective
159  /// design-under-test.
160  bool allInstancesUnderEffectiveDut(igraph::ModuleOpInterface op);
161 
162  /// Return true if at least one instance of this module is under (or
163  /// transitively under) a layer.
164  bool anyInstanceUnderLayer(igraph::ModuleOpInterface op);
165 
166  /// Return true if all instances of this module are under (or transitively
167  /// under) layer blocks.
168  bool allInstancesUnderLayer(igraph::ModuleOpInterface op);
169 
170  /// Return true if any instance of this module is within (or transitively
171  /// within) the design.
172  bool anyInstanceInDesign(igraph::ModuleOpInterface op);
173 
174  /// Return true if all instances of this module are within (or transitively
175  /// withiin) the design.
176  bool allInstancesInDesign(igraph::ModuleOpInterface op);
177 
178  /// Return true if any instance of this module is within (or transitively
179  /// within) the effective design
180  bool anyInstanceInEffectiveDesign(igraph::ModuleOpInterface op);
181 
182  /// Return true if all instances of this module are within (or transitively
183  /// withiin) the effective design.
184  bool allInstancesInEffectiveDesign(igraph::ModuleOpInterface op);
185 
186 private:
187  /// Stores circuit-level attributes.
189  /*effectiveDut=*/nullptr};
190 
191  /// Internal mapping of operations to module attributes.
192  DenseMap<Operation *, ModuleAttributes> moduleAttributes;
193 
194  /// Return the module attributes associated with a module.
195  const ModuleAttributes &getModuleAttributes(igraph::ModuleOpInterface op);
196 };
197 
198 #ifndef NDEBUG
199 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
200  const InstanceInfo::LatticeValue &value) {
201  if (value.isUnknown())
202  return os << "unknown";
203  if (value.isConstant())
204  return os << "constant<" << (value.getConstant() ? "true" : "false") << ">";
205  return os << "mixed";
206 }
207 #endif
208 
209 } // namespace firrtl
210 } // namespace circt
211 
212 #endif // CIRCT_DIALECT_FIRRTL_FIRRTLINSTANCEINFO_H
A lattice value to record the value of a property.
LatticeValue operator!()
Invert the lattice value.
void mergeIn(LatticeValue that)
Merge attributes from another LatticeValue into this one.
bool value
The value of the property if kind is Constant.
Kind kind
Whether or not the property holds.
bool getConstant() const
Return the value. This should only be used if the kind is Constant.
void markMixed()
Set this LatticeValue to mixed.
bool isConstant() const
Return true if the kind is Constant.
bool isUnknown() const
Return true if the kind is Unknown.
void markConstant(bool constant)
Set this LatticeValue to a constant.
bool isMixed() const
Return true if the kind is Mixed.
bool allInstancesUnderLayer(igraph::ModuleOpInterface op)
Return true if all instances of this module are under (or transitively under) layer blocks.
igraph::ModuleOpInterface getDut()
Return the design-under-test if one is defined for the circuit, otherwise return null.
bool isEffectiveDut(igraph::ModuleOpInterface op)
Return true if this module is the design-under-test and the circuit has a design-under-test.
CircuitAttributes circuitAttributes
Stores circuit-level attributes.
bool hasDut()
Return true if this circuit has a design-under-test.
bool allInstancesInEffectiveDesign(igraph::ModuleOpInterface op)
Return true if all instances of this module are within (or transitively withiin) the effective design...
bool isDut(igraph::ModuleOpInterface op)
Return true if this module is the design-under-test.
bool anyInstanceUnderDut(igraph::ModuleOpInterface op)
Return true if at least one instance of this module is under (or transitively under) the design-under...
bool anyInstanceUnderEffectiveDut(igraph::ModuleOpInterface op)
Return true if at least one instance is under (or transitively under) the effective design-under-test...
bool allInstancesUnderEffectiveDut(igraph::ModuleOpInterface op)
Return true if all instances are under (or transitively under) the effective design-under-test.
DenseMap< Operation *, ModuleAttributes > moduleAttributes
Internal mapping of operations to module attributes.
igraph::ModuleOpInterface getEffectiveDut()
Return the "effective" design-under-test.
InstanceInfo(Operation *op, mlir::AnalysisManager &am)
bool allInstancesUnderDut(igraph::ModuleOpInterface op)
Return true if all instances of this module are under (or transitively under) the design-under-test.
const ModuleAttributes & getModuleAttributes(igraph::ModuleOpInterface op)
Return the module attributes associated with a module.
bool anyInstanceInEffectiveDesign(igraph::ModuleOpInterface op)
Return true if any instance of this module is within (or transitively within) the effective design.
bool allInstancesInDesign(igraph::ModuleOpInterface op)
Return true if all instances of this module are within (or transitively withiin) the design.
bool anyInstanceUnderLayer(igraph::ModuleOpInterface op)
Return true if at least one instance of this module is under (or transitively under) a layer.
bool anyInstanceInDesign(igraph::ModuleOpInterface op)
Return true if any instance of this module is within (or transitively within) the design.
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const InstanceInfo::LatticeValue &value)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
igraph::ModuleOpInterface dut
The design-under-test if one is defined.
igraph::ModuleOpInterface effectiveDut
The design-under-test if one is defined or the top module.
InstanceInfo::LatticeValue inDesign
Indicates if this module is instantiated in the design.
InstanceInfo::LatticeValue underDut
Indicates if this module is instantiated under the design-under-test.
InstanceInfo::LatticeValue inEffectiveDesign
Indicates if this modules is instantiated in the effective design.
InstanceInfo::LatticeValue underLayer
Indicates if this module is instantiated under a layer.