Skip to content

Commit 3fbec15

Browse files
committed
[FIRRTL] Switch to IPO instead of RPO
Change FIRRTL's `InstanceInfo` analysis to use `llvm::inverse_post_order` instead of `ReversePostOrderTraversal`. This may be slightly faster/more efficient as it doesn't build a vector of what to visit in a post order walk and this will visit all modules, not just those under the top module. h/t @youngar for the pattern and the reasoning behind why to favor this pattern. Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
1 parent dc28bc5 commit 3fbec15

File tree

1 file changed

+35
-33
lines changed

1 file changed

+35
-33
lines changed

lib/Analysis/FIRRTLInstanceInfo.cpp

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -74,39 +74,41 @@ InstanceInfo::InstanceInfo(Operation *op, mlir::AnalysisManager &am) {
7474
// Visit modules in reverse post-order (visit parents before children) because
7575
// information flows in this direction---the attributes of modules are
7676
// determinend by their instantiations.
77-
llvm::ReversePostOrderTraversal<InstanceGraph *> rpo(&iGraph);
78-
for (auto *modIt : rpo) {
79-
auto moduleOp = modIt->getModule();
80-
ModuleAttributes &attributes = moduleAttributes[moduleOp];
81-
82-
// Set DUT-related attributes.
83-
auto isDut = AnnotationSet(moduleOp).hasAnnotation(dutAnnoClass);
84-
if (isDut) {
85-
circuitAttributes.dutNode = modIt;
86-
circuitAttributes.effectiveDutNode = modIt;
87-
}
88-
89-
// If the module is not instantiated, then set attributes and early exit.
90-
if (modIt->noUses()) {
91-
attributes.underDut.markConstant(false);
92-
attributes.underLayer.markConstant(false);
93-
continue;
94-
}
95-
96-
// Merge in attributes from modules that instantiate this module.
97-
for (auto *useIt : modIt->uses()) {
98-
auto parentOp = useIt->getParent()->getModule();
99-
auto parentAttrs = moduleAttributes.find(parentOp)->getSecond();
100-
// Merge underDut.
101-
if (this->isDut(parentOp) || isDut)
102-
attributes.underDut.mergeIn(true);
103-
else
104-
attributes.underDut.mergeIn(parentAttrs.underDut);
105-
// Merge underLayer.
106-
if (useIt->getInstance()->getParentOfType<LayerBlockOp>())
107-
attributes.underLayer.mergeIn(true);
108-
else
109-
attributes.underLayer.mergeIn(parentAttrs.underLayer);
77+
DenseSet<InstanceGraphNode *> visited;
78+
for (auto *root : iGraph) {
79+
for (auto *modIt : llvm::inverse_post_order_ext(root, visited)) {
80+
auto moduleOp = modIt->getModule();
81+
ModuleAttributes &attributes = moduleAttributes[moduleOp];
82+
83+
// Set DUT-related attributes.
84+
auto isDut = AnnotationSet(moduleOp).hasAnnotation(dutAnnoClass);
85+
if (isDut) {
86+
circuitAttributes.dutNode = modIt;
87+
circuitAttributes.effectiveDutNode = modIt;
88+
}
89+
90+
// If the module is not instantiated, then set attributes and early exit.
91+
if (modIt->noUses()) {
92+
attributes.underDut.markConstant(false);
93+
attributes.underLayer.markConstant(false);
94+
continue;
95+
}
96+
97+
// Merge in attributes from modules that instantiate this module.
98+
for (auto *useIt : modIt->uses()) {
99+
auto parentOp = useIt->getParent()->getModule();
100+
auto parentAttrs = moduleAttributes.find(parentOp)->getSecond();
101+
// Merge underDut.
102+
if (this->isDut(parentOp) || isDut)
103+
attributes.underDut.mergeIn(true);
104+
else
105+
attributes.underDut.mergeIn(parentAttrs.underDut);
106+
// Merge underLayer.
107+
if (useIt->getInstance()->getParentOfType<LayerBlockOp>())
108+
attributes.underLayer.mergeIn(true);
109+
else
110+
attributes.underLayer.mergeIn(parentAttrs.underLayer);
111+
}
110112
}
111113
}
112114

0 commit comments

Comments
 (0)