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 layers. I.e.,
102  /// layers are not in the design.
104  };
105 
106  //===--------------------------------------------------------------------===//
107  // Circuit Attribute Queries
108  //===--------------------------------------------------------------------===//
109 
110  /// Return true if this circuit has a design-under-test.
111  bool hasDut();
112 
113  /// Return the design-under-test if one is defined for the circuit, otherwise
114  /// return null.
115  igraph::ModuleOpInterface getDut();
116 
117  /// Return the "effective" design-under-test. This will be the
118  /// design-under-test if one is defined. Otherwise, this will be the root
119  /// node of the instance graph.
120  igraph::ModuleOpInterface getEffectiveDut();
121 
122  //===--------------------------------------------------------------------===//
123  // Module Attribute Queries
124  //===--------------------------------------------------------------------===//
125 
126  /// Return true if this module is the design-under-test.
127  bool isDut(igraph::ModuleOpInterface op);
128 
129  /// Return true if this module is the design-under-test and the circuit has a
130  /// design-under-test. If the circuit has no design-under-test, then return
131  /// true if this is the top module.
132  bool isEffectiveDut(igraph::ModuleOpInterface op);
133 
134  /// Return true if at least one instance of this module is under (or
135  /// transitively under) the design-under-test. This is true if the module is
136  /// the design-under-test.
137  bool anyInstanceUnderDut(igraph::ModuleOpInterface op);
138 
139  /// Return true if all instances of this module are under (or transitively
140  /// under) the design-under-test. This is true if the module is the
141  /// design-under-test.
142  bool allInstancesUnderDut(igraph::ModuleOpInterface op);
143 
144  /// Return true if at least one instance is under (or transitively under) the
145  /// effective design-under-test. This is true if the module is the effective
146  /// design-under-test.
147  bool anyInstanceUnderEffectiveDut(igraph::ModuleOpInterface op);
148 
149  /// Return true if all instances are under (or transitively under) the
150  /// effective design-under-test. This is true if the module is the effective
151  /// design-under-test.
152  bool allInstancesUnderEffectiveDut(igraph::ModuleOpInterface op);
153 
154  /// Return true if at least one instance of this module is under (or
155  /// transitively under) a layer.
156  bool anyInstanceUnderLayer(igraph::ModuleOpInterface op);
157 
158  /// Return true if all instances of this module are under (or transitively
159  /// under) layer blocks.
160  bool allInstancesUnderLayer(igraph::ModuleOpInterface op);
161 
162  /// Return true if any instance of this module is within (or transitively
163  /// within) the design.
164  bool anyInstanceInDesign(igraph::ModuleOpInterface op);
165 
166  /// Return true if all instances of this module are within (or transitively
167  /// withiin) the design.
168  bool allInstancesInDesign(igraph::ModuleOpInterface op);
169 
170  /// Return true if any instance of this module is within (or transitively
171  /// within) the effective design
172  bool anyInstanceInEffectiveDesign(igraph::ModuleOpInterface op);
173 
174  /// Return true if all instances of this module are within (or transitively
175  /// withiin) the effective design.
176  bool allInstancesInEffectiveDesign(igraph::ModuleOpInterface op);
177 
178 private:
179  /// Stores circuit-level attributes.
181  /*effectiveDut=*/nullptr};
182 
183  /// Internal mapping of operations to module attributes.
184  DenseMap<Operation *, ModuleAttributes> moduleAttributes;
185 
186  /// Return the module attributes associated with a module.
187  const ModuleAttributes &getModuleAttributes(igraph::ModuleOpInterface op);
188 };
189 
190 #ifndef NDEBUG
191 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
192  const InstanceInfo::LatticeValue &value) {
193  if (value.isUnknown())
194  return os << "unknown";
195  if (value.isConstant())
196  return os << "constant<" << (value.getConstant() ? "true" : "false") << ">";
197  return os << "mixed";
198 }
199 #endif
200 
201 } // namespace firrtl
202 } // namespace circt
203 
204 #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 underLayer
Indicates if this module is instantiated under a layer.