21 #include "llvm/ADT/PostOrderIterator.h"
22 #include "llvm/Support/Debug.h"
25 #include "llvm/ADT/DepthFirstIterator.h"
28 #define DEBUG_TYPE "firrtl-analysis-instanceinfo"
30 using namespace circt;
31 using namespace firrtl;
55 if (kind < that.
kind) {
68 mergeIn(latticeValue);
72 if (isUnknown() || isMixed())
85 for (
auto *node : iGraph) {
86 auto moduleOp = node->getModule();
95 for (
auto *node : iGraph) {
99 auto moduleOp = node->getModule();
110 DenseSet<InstanceGraphNode *> visited;
111 for (
auto *root : iGraph) {
112 for (
auto *modIt : llvm::inverse_post_order_ext(root, visited)) {
113 visited.insert(modIt);
114 auto moduleOp = modIt->getModule();
134 for (
auto *useIt : modIt->uses()) {
135 auto parentOp = useIt->getParent()->getModule();
143 auto instanceOp = useIt->getInstance();
144 bool underLayer = (isa<InstanceOp>(instanceOp) &&
145 cast<InstanceOp>(instanceOp).getLowerToBind()) ||
146 instanceOp->getParentOfType<LayerBlockOp>();
147 if (!isGCCompanion) {
158 }
else if (!
isDut && !isGCCompanion) {
167 mlir::OpPrintingFlags flags;
171 << llvm::indent(2) <<
"circuit attributes:\n"
172 << llvm::indent(4) <<
"hasDut: " << (
hasDut() ?
"true" :
"false")
174 << llvm::indent(4) <<
"dut: ";
176 dut->print(llvm::dbgs(), flags);
178 llvm::dbgs() <<
"null";
179 llvm::dbgs() <<
"\n" << llvm::indent(4) <<
"effectiveDut: ";
181 llvm::dbgs() <<
"\n" << llvm::indent(2) <<
"module attributes:\n";
183 for (
auto *root : iGraph) {
184 for (
auto *modIt : llvm::inverse_post_order_ext(root, visited)) {
185 visited.insert(modIt);
186 auto moduleOp = modIt->getModule();
188 llvm::dbgs().indent(4)
189 <<
"- module: " << moduleOp.getModuleName() <<
"\n"
191 <<
"isDut: " << (
isDut(moduleOp) ?
"true" :
"false") <<
"\n"
192 << llvm::indent(6) <<
"isEffectiveDue: "
194 << llvm::indent(6) <<
"underDut: " << attributes.underDut <<
"\n"
195 << llvm::indent(6) <<
"underLayer: " << attributes.underLayer
197 << llvm::indent(6) <<
"inDesign: " << attributes.inDesign <<
"\n"
199 <<
"inEffectiveDesign: " << attributes.inEffectiveDesign <<
"\n";
239 return underDut.
isConstant() && underDut.getConstant();
257 return underLayer.
isConstant() && underLayer.getConstant();
267 return inDesign.
isConstant() && inDesign.getConstant();
277 return inEffectiveDesign.
isConstant() && inEffectiveDesign.getConstant();
assert(baseType &&"element must be base type")
static std::optional< APSInt > getConstant(Attribute operand)
Determine the value of a constant operand for the sake of constant folding.
This class provides a read-only projection over the MLIR attributes that represent a set of annotatio...
bool hasAnnotation(StringRef className) const
Return true if we have an annotation with the specified class name.
This graph tracks modules and where they are instantiated.
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.
bool isConstant(Operation *op)
Return true if the specified operation has a constant value.
constexpr const char * dutAnnoClass
constexpr const char * companionAnnoClass
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
llvm::raw_ostream & debugHeader(llvm::StringRef str, int width=80)
Write a "header"-like string to the debug stream with a certain width.
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.
Information about a 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.