mirror of
https://github.com/verilator/verilator.git
synced 2026-09-01 10:27:04 +02:00
Count non-empty always blocks in V3Split (#3337)
"Optimizations, Split always" in stats now means the number of newly added always. Co-authored-by: Wilson Snyder <[email protected]>
This commit is contained in:
+48
-13
@@ -791,21 +791,55 @@ private:
|
||||
};
|
||||
|
||||
class RemovePlaceholdersVisitor final : public VNVisitor {
|
||||
std::unordered_set<AstNode*> m_removeSet; // placeholders to be removed
|
||||
public:
|
||||
explicit RemovePlaceholdersVisitor(AstNode* nodep) {
|
||||
iterate(nodep);
|
||||
for (AstNode* np : m_removeSet) {
|
||||
np->unlinkFrBack(); // Without next
|
||||
VL_DO_DANGLING(np->deleteTree(), np);
|
||||
// MEMBERS
|
||||
bool m_isPure = true;
|
||||
int m_emptyAlways = 0;
|
||||
|
||||
// CONSTRUCTORS
|
||||
RemovePlaceholdersVisitor() = default;
|
||||
virtual ~RemovePlaceholdersVisitor() override = default;
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstSplitPlaceholder* nodep) override { pushDeletep(nodep->unlinkFrBack()); }
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
VL_RESTORER(m_isPure);
|
||||
m_isPure = true;
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->ifsp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack());
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
VL_RESTORER(m_isPure);
|
||||
m_isPure = true;
|
||||
iterateChildren(nodep);
|
||||
if (m_isPure) {
|
||||
bool emptyOrCommentOnly = true;
|
||||
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
// If this always block contains only AstComment, remove here.
|
||||
// V3Gate will remove anyway.
|
||||
if (!VN_IS(bodysp, Comment)) {
|
||||
emptyOrCommentOnly = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (emptyOrCommentOnly) {
|
||||
pushDeletep(nodep->unlinkFrBack());
|
||||
++m_emptyAlways;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~RemovePlaceholdersVisitor() override = default;
|
||||
virtual void visit(AstSplitPlaceholder* nodep) override { m_removeSet.insert(nodep); }
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
m_isPure &= nodep->isPure();
|
||||
iterateChildren(nodep); // must visit regardless of m_isPure to remove placeholders
|
||||
}
|
||||
|
||||
private:
|
||||
VL_UNCOPYABLE(RemovePlaceholdersVisitor);
|
||||
|
||||
public:
|
||||
static int exec(AstAlways* nodep) {
|
||||
RemovePlaceholdersVisitor visitor;
|
||||
visitor.iterate(nodep);
|
||||
return visitor.m_emptyAlways;
|
||||
}
|
||||
};
|
||||
|
||||
class SplitVisitor final : public SplitReorderBaseVisitor {
|
||||
@@ -832,7 +866,8 @@ public:
|
||||
for (AlwaysVec::iterator addme = it->second.begin(); addme != it->second.end();
|
||||
++addme) {
|
||||
origp->addNextHere(*addme);
|
||||
RemovePlaceholdersVisitor{*addme};
|
||||
const int numRemoved = RemovePlaceholdersVisitor::exec(*addme);
|
||||
m_statSplits -= numRemoved;
|
||||
}
|
||||
origp->unlinkFrBack(); // Without next
|
||||
VL_DO_DANGLING(origp->deleteTree(), origp);
|
||||
@@ -944,7 +979,7 @@ protected:
|
||||
// Counting original always blocks rather than newly-split
|
||||
// always blocks makes it a little easier to use this stat to
|
||||
// check the result of the t_alw_split test:
|
||||
++m_statSplits;
|
||||
m_statSplits += ifColor.colors().size() - 1; // -1 for the original always
|
||||
|
||||
// Visit through the original always block one more time,
|
||||
// and emit the split always blocks into m_replaceBlocks:
|
||||
|
||||
Reference in New Issue
Block a user