From d6c5d40f9b73b531ee06bdc5f94667229a3e8d70 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 17 Mar 2023 19:58:53 -0400 Subject: [PATCH] Internals: Add VNVisitorConst class. --- src/V3Ast.cpp | 16 ++++----- src/V3Ast.h | 81 +++++++++++++++++++++++++++---------------- src/V3AstNodeExpr.h | 4 +-- src/V3Broken.cpp | 4 +-- src/V3Const.cpp | 2 +- src/V3EmitCFunc.h | 6 ++-- src/V3EmitCImp.cpp | 4 +-- src/V3EmitXml.cpp | 2 +- src/V3LinkDot.cpp | 6 ++-- src/V3LinkResolve.cpp | 2 +- src/V3Stats.cpp | 6 ++-- src/V3Tristate.cpp | 2 +- src/V3Width.cpp | 6 ++-- src/astgen | 4 +-- 14 files changed, 83 insertions(+), 62 deletions(-) diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 49d1a0434..86e89fac3 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -907,7 +907,7 @@ void AstNode::iterateChildren(VNVisitor& v) { if (m_op4p) m_op4p->iterateAndNext(v); } -void AstNode::iterateChildrenConst(VNVisitor& v) { +void AstNode::iterateChildrenConst(VNVisitorConst& v) { // This is a very hot function ASTNODE_PREFETCH(m_op1p); ASTNODE_PREFETCH(m_op2p); @@ -954,7 +954,7 @@ void AstNode::iterateAndNext(VNVisitor& v) { } } -void AstNode::iterateListBackwards(VNVisitor& v) { +void AstNode::iterateListBackwardsConst(VNVisitorConst& v) { AstNode* nodep = this; while (nodep->m_nextp) nodep = nodep->m_nextp; while (nodep) { @@ -968,14 +968,14 @@ void AstNode::iterateListBackwards(VNVisitor& v) { } } -void AstNode::iterateChildrenBackwards(VNVisitor& v) { - if (m_op1p) m_op1p->iterateListBackwards(v); - if (m_op2p) m_op2p->iterateListBackwards(v); - if (m_op3p) m_op3p->iterateListBackwards(v); - if (m_op4p) m_op4p->iterateListBackwards(v); +void AstNode::iterateChildrenBackwardsConst(VNVisitorConst& v) { + if (m_op1p) m_op1p->iterateListBackwardsConst(v); + if (m_op2p) m_op2p->iterateListBackwardsConst(v); + if (m_op3p) m_op3p->iterateListBackwardsConst(v); + if (m_op4p) m_op4p->iterateListBackwardsConst(v); } -void AstNode::iterateAndNextConst(VNVisitor& v) { +void AstNode::iterateAndNextConst(VNVisitorConst& v) { // Keep following the current list even if edits change it AstNode* nodep = this; do { diff --git a/src/V3Ast.h b/src/V3Ast.h index a325e5620..0d4ae58a7 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1373,13 +1373,38 @@ public: virtual ~VNDeleter() { doDeletes(); } }; +//###################################################################### +// VNVisitorConst -- Allows new functions to be called on each node +// type without changing the base classes. See "Modern C++ Design". +// This only has the constant fuctions for non-modifying visitors. +// For more typical usage see VNVisitor + +class VNVisitorConst VL_NOT_FINAL : public VNDeleter { + friend class AstNode; + +public: + /// Call visit()s on nodep + inline void iterateConst(AstNode* nodep); + /// Call visit()s on nodep + inline void iterateConstNull(AstNode* nodep); + /// Call visit()s on const nodep's children + inline void iterateChildrenConst(AstNode* nodep); + /// Call visit()s on nodep's children in backp() order + inline void iterateChildrenBackwardsConst(AstNode* nodep); + /// Call visit()s on const nodep (maybe nullptr) and nodep's nextp() list + inline void iterateAndNextConstNull(AstNode* nodep); + /// Call visit()s on const nodep (maybe nullptr) and nodep's nextp() list, in reverse order + inline void iterateAndNextConstNullBackwards(AstNode* nodep); + + virtual void visit(AstNode* nodep) = 0; +#include "V3Ast__gen_visitor_decls.h" // From ./astgen +}; + //###################################################################### // VNVisitor -- Allows new functions to be called on each node // type without changing the base classes. See "Modern C++ Design". -class VNVisitor VL_NOT_FINAL : public VNDeleter { - friend class AstNode; - +class VNVisitor VL_NOT_FINAL : public VNVisitorConst { public: /// Call visit()s on nodep inline void iterate(AstNode* nodep); @@ -1387,21 +1412,10 @@ public: inline void iterateNull(AstNode* nodep); /// Call visit()s on nodep's children inline void iterateChildren(AstNode* nodep); - /// Call visit()s on nodep's children in backp() order - inline void iterateChildrenBackwards(AstNode* nodep); - /// Call visit()s on const nodep's children - inline void iterateChildrenConst(AstNode* nodep); /// Call visit()s on nodep (maybe nullptr) and nodep's nextp() list inline void iterateAndNextNull(AstNode* nodep); - /// Call visit()s on const nodep (maybe nullptr) and nodep's nextp() list - inline void iterateAndNextConstNull(AstNode* nodep); - /// Call visit()s on const nodep (maybe nullptr) and nodep's nextp() list, in reverse order - inline void iterateAndNextConstNullBackwards(AstNode* nodep); /// Return edited nodep; see comments in V3Ast.cpp inline AstNode* iterateSubtreeReturnEdits(AstNode* nodep); - - virtual void visit(AstNode* nodep) = 0; -#include "V3Ast__gen_visitor_decls.h" // From ./astgen }; //###################################################################### @@ -1631,6 +1645,7 @@ public: bool brokeExistsAbove() const { return brokeExists() && (m_brokenState >> 7); } bool brokeExistsBelow() const { return brokeExists() && !(m_brokenState >> 7); } // Note: brokeExistsBelow is not quite precise, as it is true for sibling nodes as well + bool brokeIterpp() const { return !!m_iterpp; } // CONSTRUCTORS virtual ~AstNode() = default; @@ -1964,26 +1979,27 @@ public: virtual const char* broken() const { return nullptr; } // INVOKERS - virtual void accept(VNVisitor& v) = 0; + virtual void accept(VNVisitorConst& v) = 0; protected: // All VNVisitor related functions are called as methods off the visitor friend class VNVisitor; + friend class VNVisitorConst; // Use instead VNVisitor::iterateChildren void iterateChildren(VNVisitor& v); - // Use instead VNVisitor::iterateChildrenBackwards - void iterateChildrenBackwards(VNVisitor& v); + // Use instead VNVisitor::iterateChildrenBackwardsConst + void iterateChildrenBackwardsConst(VNVisitorConst& v); // Use instead VNVisitor::iterateChildrenConst - void iterateChildrenConst(VNVisitor& v); + void iterateChildrenConst(VNVisitorConst& v); // Use instead VNVisitor::iterateAndNextNull void iterateAndNext(VNVisitor& v); // Use instead VNVisitor::iterateAndNextConstNull - void iterateAndNextConst(VNVisitor& v); + void iterateAndNextConst(VNVisitorConst& v); // Use instead VNVisitor::iterateSubtreeReturnEdits AstNode* iterateSubtreeReturnEdits(VNVisitor& v); private: - void iterateListBackwards(VNVisitor& v); + void iterateListBackwardsConst(VNVisitorConst& v); // For internal use only. // Note: specializations for particular node types are provided by 'astgen' @@ -2483,24 +2499,29 @@ struct std::equal_to> final { //###################################################################### // Inline VNVisitor METHODS +void VNVisitorConst::iterateConst(AstNode* nodep) { nodep->accept(*this); } +void VNVisitorConst::iterateConstNull(AstNode* nodep) { + if (VL_LIKELY(nodep)) nodep->accept(*this); +} +void VNVisitorConst::iterateChildrenConst(AstNode* nodep) { nodep->iterateChildrenConst(*this); } +void VNVisitorConst::iterateChildrenBackwardsConst(AstNode* nodep) { + nodep->iterateChildrenBackwardsConst(*this); +} +void VNVisitorConst::iterateAndNextConstNullBackwards(AstNode* nodep) { + if (VL_LIKELY(nodep)) nodep->iterateListBackwardsConst(*this); +} +void VNVisitorConst::iterateAndNextConstNull(AstNode* nodep) { + if (VL_LIKELY(nodep)) nodep->iterateAndNextConst(*this); +} + void VNVisitor::iterate(AstNode* nodep) { nodep->accept(*this); } void VNVisitor::iterateNull(AstNode* nodep) { if (VL_LIKELY(nodep)) nodep->accept(*this); } void VNVisitor::iterateChildren(AstNode* nodep) { nodep->iterateChildren(*this); } -void VNVisitor::iterateChildrenBackwards(AstNode* nodep) { - nodep->iterateChildrenBackwards(*this); -} -void VNVisitor::iterateChildrenConst(AstNode* nodep) { nodep->iterateChildrenConst(*this); } void VNVisitor::iterateAndNextNull(AstNode* nodep) { if (VL_LIKELY(nodep)) nodep->iterateAndNext(*this); } -void VNVisitor::iterateAndNextConstNullBackwards(AstNode* nodep) { - if (VL_LIKELY(nodep)) nodep->iterateListBackwards(*this); -} -void VNVisitor::iterateAndNextConstNull(AstNode* nodep) { - if (VL_LIKELY(nodep)) nodep->iterateAndNextConst(*this); -} AstNode* VNVisitor::iterateSubtreeReturnEdits(AstNode* nodep) { return nodep->iterateSubtreeReturnEdits(*this); } diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index de4de290c..5e12b2bd1 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -322,7 +322,7 @@ public: ASTGEN_MEMBERS_AstNodeTermop; // Know no children, and hot function, so skip iterator for speed // cppcheck-suppress functionConst - void iterateChildren(VNVisitor& v) {} + void iterateChildren(VNVisitorConst& v) {} void dump(std::ostream& str) const override; }; class AstNodeTriop VL_NOT_FINAL : public AstNodeExpr { @@ -492,7 +492,7 @@ public: void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } // Know no children, and hot function, so skip iterator for speed // cppcheck-suppress functionConst - void iterateChildren(VNVisitor& v) {} + void iterateChildren(VNVisitorConst& v) {} }; // === Concrete node types ===================================================== diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index aa02b4dd3..09ab9b7ef 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -144,7 +144,7 @@ bool V3Broken::isLinkable(const AstNode* nodep) { return s_linkableTable.isLinka //###################################################################### // Check every node in tree -class BrokenCheckVisitor final : public VNVisitor { +class BrokenCheckVisitor final : public VNVisitorConst { bool m_inScope = false; // Under AstScope // Constants for marking we are under/not under a node @@ -312,7 +312,7 @@ private: public: // CONSTRUCTORS - explicit BrokenCheckVisitor(AstNetlist* nodep) { iterate(nodep); } + explicit BrokenCheckVisitor(AstNetlist* nodep) { iterateConstNull(nodep); } ~BrokenCheckVisitor() override = default; }; diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 8824aa2e1..6d7a9751c 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -2265,7 +2265,7 @@ private: // VISITORS void visit(AstNetlist* nodep) override { // Iterate modules backwards, in bottom-up order. That's faster - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); } void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 936196abc..a2bb47892 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -34,7 +34,7 @@ constexpr int EMITC_NUM_CONSTW = 8; //###################################################################### // Emit lazy forward declarations -class EmitCLazyDecls final : public VNVisitor { +class EmitCLazyDecls final : public VNVisitorConst { // NODE STATE/TYPES // None allowed to support threaded emitting @@ -72,12 +72,12 @@ class EmitCLazyDecls final : public VNVisitor { // VISITORS void visit(AstNodeCCall* nodep) override { lazyDeclare(nodep->funcp()); - iterateChildren(nodep); + iterateChildrenConst(nodep); } void visit(AstAddrOfCFunc* nodep) override { lazyDeclare(nodep->funcp()); - iterateChildren(nodep); + iterateChildrenConst(nodep); } void visit(AstVarRef* nodep) override { diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index 8bfc9fcfc..4a96fa118 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -33,7 +33,7 @@ VL_DEFINE_DEBUG_FUNCTIONS; //###################################################################### // Visitor that gathers the headers required by an AstCFunc -class EmitCGatherDependencies final : VNVisitor { +class EmitCGatherDependencies final : VNVisitorConst { // Ordered set, as it is used as a key in another map. std::set m_dependencies; // Header names to be included in output C++ file @@ -142,7 +142,7 @@ class EmitCGatherDependencies final : VNVisitor { // declaration of the receiver class, but their body very likely includes at least one // relative reference, so we are probably not loosing much. addModDependency(EmitCParentModule::get(cfuncp)); - iterate(cfuncp); + iterateConst(cfuncp); } public: diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index ef8071a20..d38df87ae 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -334,7 +334,7 @@ private: // VISITORS void visit(AstNetlist* nodep) override { // Children are iterated backwards to ensure correct compilation order - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); } void visit(AstNodeModule* nodep) override { // Only list modules and interfaces diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 113be442d..9a4cdffcd 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -780,7 +780,7 @@ class LinkDotFindVisitor final : public VNVisitor { // First back iterate, to find all packages. Backward as must do base // packages before using packages - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); // The first modules in the list are always the top modules // (sorted before this is called). @@ -1756,7 +1756,7 @@ class LinkDotScopeVisitor final : public VNVisitor { // VISITs void visit(AstNetlist* nodep) override { // Recurse..., backward as must do packages before using packages - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); } void visit(AstConstPool*) override {} void visit(AstScope* nodep) override { @@ -2238,7 +2238,7 @@ private: // VISITs void visit(AstNetlist* nodep) override { // Recurse..., backward as must do packages before using packages - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); } void visit(AstTypeTable*) override {} void visit(AstConstPool*) override {} diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 5f9bcbbef..6620c845d 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -454,7 +454,7 @@ private: // VISITs void visit(AstNetlist* nodep) override { // Iterate modules backwards, in bottom-up order. - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); } void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index df38e83ac..f79da45e4 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -33,7 +33,7 @@ VL_DEFINE_DEBUG_FUNCTIONS; //###################################################################### // Stats class functions -class StatsVisitor final : public VNVisitor { +class StatsVisitor final : public VNVisitorConst { private: // NODE STATE/TYPES @@ -175,7 +175,7 @@ private: if (m_fast && !nodep->funcp()->entryPoint()) { // Enter the function and trace it m_tracingCall = true; - iterate(nodep->funcp()); + iterateConst(nodep->funcp()); } } void visit(AstCFunc* nodep) override { @@ -218,7 +218,7 @@ public: // Initialize arrays m_statTypeCount.resize(VNType::_ENUM_END); // Process - iterate(nodep); + iterateConst(nodep); } ~StatsVisitor() override { // Done. Publish statistics diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 9837dbb92..26f2e0343 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -1793,7 +1793,7 @@ class TristateVisitor final : public TristateBaseVisitor { iterateChildren(nodep); } - void visit(AstNetlist* nodep) override { iterateChildrenBackwards(nodep); } + void visit(AstNetlist* nodep) override { iterateChildrenBackwardsConst(nodep); } // Default: Just iterate void visit(AstNode* nodep) override { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 7e556bca6..d6fde7ff4 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -5608,7 +5608,7 @@ private: } void visit(AstNetlist* nodep) override { // Iterate modules backwards, in bottom-up order. That's faster - userIterateChildrenBackwards(nodep, nullptr); + userIterateChildrenBackwardsConst(nodep, nullptr); } //-------------------- @@ -7351,12 +7351,12 @@ private: iterateChildren(nodep); } } - void userIterateChildrenBackwards(AstNode* nodep, WidthVP* vup) { + void userIterateChildrenBackwardsConst(AstNode* nodep, WidthVP* vup) { if (!nodep) return; { VL_RESTORER(m_vup); m_vup = vup; - iterateChildrenBackwards(nodep); + iterateChildrenBackwardsConst(nodep); } } diff --git a/src/astgen b/src/astgen index 9c30529f7..e567b4c21 100755 --- a/src/astgen +++ b/src/astgen @@ -938,7 +938,7 @@ def write_ast_macros(filename): if node.isLeaf: emitBlock('''\ - void accept(VNVisitor& v) override {{ v.visit(this); }} + void accept(VNVisitorConst& v) override {{ v.visit(this); }} AstNode* clone() override {{ return new Ast{t}(*this); }} ''', t=node.name) @@ -1343,7 +1343,7 @@ if Args.classes: # Write Ast code write_forward_class_decls("Ast", AstNodeList) write_visitor_decls("Ast", AstNodeList) - write_visitor_defns("Ast", AstNodeList, "VNVisitor") + write_visitor_defns("Ast", AstNodeList, "VNVisitorConst") write_type_enum("Ast", AstNodeList) write_type_tests("Ast", AstNodeList) write_ast_macros("V3Ast__gen_macros.h")