Internals: Add VNVisitorConst class.

This commit is contained in:
Wilson Snyder 2023-03-17 19:58:53 -04:00
parent 371b8310d9
commit d6c5d40f9b
14 changed files with 83 additions and 62 deletions

View File

@ -907,7 +907,7 @@ void AstNode::iterateChildren(VNVisitor& v) {
if (m_op4p) m_op4p->iterateAndNext(v); if (m_op4p) m_op4p->iterateAndNext(v);
} }
void AstNode::iterateChildrenConst(VNVisitor& v) { void AstNode::iterateChildrenConst(VNVisitorConst& v) {
// This is a very hot function // This is a very hot function
ASTNODE_PREFETCH(m_op1p); ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p); 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; AstNode* nodep = this;
while (nodep->m_nextp) nodep = nodep->m_nextp; while (nodep->m_nextp) nodep = nodep->m_nextp;
while (nodep) { while (nodep) {
@ -968,14 +968,14 @@ void AstNode::iterateListBackwards(VNVisitor& v) {
} }
} }
void AstNode::iterateChildrenBackwards(VNVisitor& v) { void AstNode::iterateChildrenBackwardsConst(VNVisitorConst& v) {
if (m_op1p) m_op1p->iterateListBackwards(v); if (m_op1p) m_op1p->iterateListBackwardsConst(v);
if (m_op2p) m_op2p->iterateListBackwards(v); if (m_op2p) m_op2p->iterateListBackwardsConst(v);
if (m_op3p) m_op3p->iterateListBackwards(v); if (m_op3p) m_op3p->iterateListBackwardsConst(v);
if (m_op4p) m_op4p->iterateListBackwards(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 // Keep following the current list even if edits change it
AstNode* nodep = this; AstNode* nodep = this;
do { do {

View File

@ -1373,13 +1373,38 @@ public:
virtual ~VNDeleter() { doDeletes(); } 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 // VNVisitor -- Allows new functions to be called on each node
// type without changing the base classes. See "Modern C++ Design". // type without changing the base classes. See "Modern C++ Design".
class VNVisitor VL_NOT_FINAL : public VNDeleter { class VNVisitor VL_NOT_FINAL : public VNVisitorConst {
friend class AstNode;
public: public:
/// Call visit()s on nodep /// Call visit()s on nodep
inline void iterate(AstNode* nodep); inline void iterate(AstNode* nodep);
@ -1387,21 +1412,10 @@ public:
inline void iterateNull(AstNode* nodep); inline void iterateNull(AstNode* nodep);
/// Call visit()s on nodep's children /// Call visit()s on nodep's children
inline void iterateChildren(AstNode* nodep); 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 /// Call visit()s on nodep (maybe nullptr) and nodep's nextp() list
inline void iterateAndNextNull(AstNode* nodep); 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 /// Return edited nodep; see comments in V3Ast.cpp
inline AstNode* iterateSubtreeReturnEdits(AstNode* nodep); 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 brokeExistsAbove() const { return brokeExists() && (m_brokenState >> 7); }
bool brokeExistsBelow() 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 // Note: brokeExistsBelow is not quite precise, as it is true for sibling nodes as well
bool brokeIterpp() const { return !!m_iterpp; }
// CONSTRUCTORS // CONSTRUCTORS
virtual ~AstNode() = default; virtual ~AstNode() = default;
@ -1964,26 +1979,27 @@ public:
virtual const char* broken() const { return nullptr; } virtual const char* broken() const { return nullptr; }
// INVOKERS // INVOKERS
virtual void accept(VNVisitor& v) = 0; virtual void accept(VNVisitorConst& v) = 0;
protected: protected:
// All VNVisitor related functions are called as methods off the visitor // All VNVisitor related functions are called as methods off the visitor
friend class VNVisitor; friend class VNVisitor;
friend class VNVisitorConst;
// Use instead VNVisitor::iterateChildren // Use instead VNVisitor::iterateChildren
void iterateChildren(VNVisitor& v); void iterateChildren(VNVisitor& v);
// Use instead VNVisitor::iterateChildrenBackwards // Use instead VNVisitor::iterateChildrenBackwardsConst
void iterateChildrenBackwards(VNVisitor& v); void iterateChildrenBackwardsConst(VNVisitorConst& v);
// Use instead VNVisitor::iterateChildrenConst // Use instead VNVisitor::iterateChildrenConst
void iterateChildrenConst(VNVisitor& v); void iterateChildrenConst(VNVisitorConst& v);
// Use instead VNVisitor::iterateAndNextNull // Use instead VNVisitor::iterateAndNextNull
void iterateAndNext(VNVisitor& v); void iterateAndNext(VNVisitor& v);
// Use instead VNVisitor::iterateAndNextConstNull // Use instead VNVisitor::iterateAndNextConstNull
void iterateAndNextConst(VNVisitor& v); void iterateAndNextConst(VNVisitorConst& v);
// Use instead VNVisitor::iterateSubtreeReturnEdits // Use instead VNVisitor::iterateSubtreeReturnEdits
AstNode* iterateSubtreeReturnEdits(VNVisitor& v); AstNode* iterateSubtreeReturnEdits(VNVisitor& v);
private: private:
void iterateListBackwards(VNVisitor& v); void iterateListBackwardsConst(VNVisitorConst& v);
// For internal use only. // For internal use only.
// Note: specializations for particular node types are provided by 'astgen' // Note: specializations for particular node types are provided by 'astgen'
@ -2483,24 +2499,29 @@ struct std::equal_to<VNRef<T_Node>> final {
//###################################################################### //######################################################################
// Inline VNVisitor METHODS // 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::iterate(AstNode* nodep) { nodep->accept(*this); }
void VNVisitor::iterateNull(AstNode* nodep) { void VNVisitor::iterateNull(AstNode* nodep) {
if (VL_LIKELY(nodep)) nodep->accept(*this); if (VL_LIKELY(nodep)) nodep->accept(*this);
} }
void VNVisitor::iterateChildren(AstNode* nodep) { nodep->iterateChildren(*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) { void VNVisitor::iterateAndNextNull(AstNode* nodep) {
if (VL_LIKELY(nodep)) nodep->iterateAndNext(*this); 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) { AstNode* VNVisitor::iterateSubtreeReturnEdits(AstNode* nodep) {
return nodep->iterateSubtreeReturnEdits(*this); return nodep->iterateSubtreeReturnEdits(*this);
} }

View File

@ -322,7 +322,7 @@ public:
ASTGEN_MEMBERS_AstNodeTermop; ASTGEN_MEMBERS_AstNodeTermop;
// Know no children, and hot function, so skip iterator for speed // Know no children, and hot function, so skip iterator for speed
// cppcheck-suppress functionConst // cppcheck-suppress functionConst
void iterateChildren(VNVisitor& v) {} void iterateChildren(VNVisitorConst& v) {}
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
}; };
class AstNodeTriop VL_NOT_FINAL : public AstNodeExpr { class AstNodeTriop VL_NOT_FINAL : public AstNodeExpr {
@ -492,7 +492,7 @@ public:
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
// Know no children, and hot function, so skip iterator for speed // Know no children, and hot function, so skip iterator for speed
// cppcheck-suppress functionConst // cppcheck-suppress functionConst
void iterateChildren(VNVisitor& v) {} void iterateChildren(VNVisitorConst& v) {}
}; };
// === Concrete node types ===================================================== // === Concrete node types =====================================================

View File

@ -144,7 +144,7 @@ bool V3Broken::isLinkable(const AstNode* nodep) { return s_linkableTable.isLinka
//###################################################################### //######################################################################
// Check every node in tree // Check every node in tree
class BrokenCheckVisitor final : public VNVisitor { class BrokenCheckVisitor final : public VNVisitorConst {
bool m_inScope = false; // Under AstScope bool m_inScope = false; // Under AstScope
// Constants for marking we are under/not under a node // Constants for marking we are under/not under a node
@ -312,7 +312,7 @@ private:
public: public:
// CONSTRUCTORS // CONSTRUCTORS
explicit BrokenCheckVisitor(AstNetlist* nodep) { iterate(nodep); } explicit BrokenCheckVisitor(AstNetlist* nodep) { iterateConstNull(nodep); }
~BrokenCheckVisitor() override = default; ~BrokenCheckVisitor() override = default;
}; };

View File

@ -2265,7 +2265,7 @@ private:
// VISITORS // VISITORS
void visit(AstNetlist* nodep) override { void visit(AstNetlist* nodep) override {
// Iterate modules backwards, in bottom-up order. That's faster // Iterate modules backwards, in bottom-up order. That's faster
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
} }
void visit(AstNodeModule* nodep) override { void visit(AstNodeModule* nodep) override {
VL_RESTORER(m_modp); VL_RESTORER(m_modp);

View File

@ -34,7 +34,7 @@ constexpr int EMITC_NUM_CONSTW = 8;
//###################################################################### //######################################################################
// Emit lazy forward declarations // Emit lazy forward declarations
class EmitCLazyDecls final : public VNVisitor { class EmitCLazyDecls final : public VNVisitorConst {
// NODE STATE/TYPES // NODE STATE/TYPES
// None allowed to support threaded emitting // None allowed to support threaded emitting
@ -72,12 +72,12 @@ class EmitCLazyDecls final : public VNVisitor {
// VISITORS // VISITORS
void visit(AstNodeCCall* nodep) override { void visit(AstNodeCCall* nodep) override {
lazyDeclare(nodep->funcp()); lazyDeclare(nodep->funcp());
iterateChildren(nodep); iterateChildrenConst(nodep);
} }
void visit(AstAddrOfCFunc* nodep) override { void visit(AstAddrOfCFunc* nodep) override {
lazyDeclare(nodep->funcp()); lazyDeclare(nodep->funcp());
iterateChildren(nodep); iterateChildrenConst(nodep);
} }
void visit(AstVarRef* nodep) override { void visit(AstVarRef* nodep) override {

View File

@ -33,7 +33,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
//###################################################################### //######################################################################
// Visitor that gathers the headers required by an AstCFunc // 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. // Ordered set, as it is used as a key in another map.
std::set<string> m_dependencies; // Header names to be included in output C++ file std::set<string> 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 // declaration of the receiver class, but their body very likely includes at least one
// relative reference, so we are probably not loosing much. // relative reference, so we are probably not loosing much.
addModDependency(EmitCParentModule::get(cfuncp)); addModDependency(EmitCParentModule::get(cfuncp));
iterate(cfuncp); iterateConst(cfuncp);
} }
public: public:

View File

@ -334,7 +334,7 @@ private:
// VISITORS // VISITORS
void visit(AstNetlist* nodep) override { void visit(AstNetlist* nodep) override {
// Children are iterated backwards to ensure correct compilation order // Children are iterated backwards to ensure correct compilation order
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
} }
void visit(AstNodeModule* nodep) override { void visit(AstNodeModule* nodep) override {
// Only list modules and interfaces // Only list modules and interfaces

View File

@ -780,7 +780,7 @@ class LinkDotFindVisitor final : public VNVisitor {
// First back iterate, to find all packages. Backward as must do base // First back iterate, to find all packages. Backward as must do base
// packages before using packages // packages before using packages
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
// The first modules in the list are always the top modules // The first modules in the list are always the top modules
// (sorted before this is called). // (sorted before this is called).
@ -1756,7 +1756,7 @@ class LinkDotScopeVisitor final : public VNVisitor {
// VISITs // VISITs
void visit(AstNetlist* nodep) override { void visit(AstNetlist* nodep) override {
// Recurse..., backward as must do packages before using packages // Recurse..., backward as must do packages before using packages
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
} }
void visit(AstConstPool*) override {} void visit(AstConstPool*) override {}
void visit(AstScope* nodep) override { void visit(AstScope* nodep) override {
@ -2238,7 +2238,7 @@ private:
// VISITs // VISITs
void visit(AstNetlist* nodep) override { void visit(AstNetlist* nodep) override {
// Recurse..., backward as must do packages before using packages // Recurse..., backward as must do packages before using packages
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
} }
void visit(AstTypeTable*) override {} void visit(AstTypeTable*) override {}
void visit(AstConstPool*) override {} void visit(AstConstPool*) override {}

View File

@ -454,7 +454,7 @@ private:
// VISITs // VISITs
void visit(AstNetlist* nodep) override { void visit(AstNetlist* nodep) override {
// Iterate modules backwards, in bottom-up order. // Iterate modules backwards, in bottom-up order.
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
} }
void visit(AstNodeModule* nodep) override { void visit(AstNodeModule* nodep) override {
VL_RESTORER(m_modp); VL_RESTORER(m_modp);

View File

@ -33,7 +33,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
//###################################################################### //######################################################################
// Stats class functions // Stats class functions
class StatsVisitor final : public VNVisitor { class StatsVisitor final : public VNVisitorConst {
private: private:
// NODE STATE/TYPES // NODE STATE/TYPES
@ -175,7 +175,7 @@ private:
if (m_fast && !nodep->funcp()->entryPoint()) { if (m_fast && !nodep->funcp()->entryPoint()) {
// Enter the function and trace it // Enter the function and trace it
m_tracingCall = true; m_tracingCall = true;
iterate(nodep->funcp()); iterateConst(nodep->funcp());
} }
} }
void visit(AstCFunc* nodep) override { void visit(AstCFunc* nodep) override {
@ -218,7 +218,7 @@ public:
// Initialize arrays // Initialize arrays
m_statTypeCount.resize(VNType::_ENUM_END); m_statTypeCount.resize(VNType::_ENUM_END);
// Process // Process
iterate(nodep); iterateConst(nodep);
} }
~StatsVisitor() override { ~StatsVisitor() override {
// Done. Publish statistics // Done. Publish statistics

View File

@ -1793,7 +1793,7 @@ class TristateVisitor final : public TristateBaseVisitor {
iterateChildren(nodep); iterateChildren(nodep);
} }
void visit(AstNetlist* nodep) override { iterateChildrenBackwards(nodep); } void visit(AstNetlist* nodep) override { iterateChildrenBackwardsConst(nodep); }
// Default: Just iterate // Default: Just iterate
void visit(AstNode* nodep) override { void visit(AstNode* nodep) override {

View File

@ -5608,7 +5608,7 @@ private:
} }
void visit(AstNetlist* nodep) override { void visit(AstNetlist* nodep) override {
// Iterate modules backwards, in bottom-up order. That's faster // Iterate modules backwards, in bottom-up order. That's faster
userIterateChildrenBackwards(nodep, nullptr); userIterateChildrenBackwardsConst(nodep, nullptr);
} }
//-------------------- //--------------------
@ -7351,12 +7351,12 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
} }
} }
void userIterateChildrenBackwards(AstNode* nodep, WidthVP* vup) { void userIterateChildrenBackwardsConst(AstNode* nodep, WidthVP* vup) {
if (!nodep) return; if (!nodep) return;
{ {
VL_RESTORER(m_vup); VL_RESTORER(m_vup);
m_vup = vup; m_vup = vup;
iterateChildrenBackwards(nodep); iterateChildrenBackwardsConst(nodep);
} }
} }

View File

@ -938,7 +938,7 @@ def write_ast_macros(filename):
if node.isLeaf: if node.isLeaf:
emitBlock('''\ 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); }} AstNode* clone() override {{ return new Ast{t}(*this); }}
''', ''',
t=node.name) t=node.name)
@ -1343,7 +1343,7 @@ if Args.classes:
# Write Ast code # Write Ast code
write_forward_class_decls("Ast", AstNodeList) write_forward_class_decls("Ast", AstNodeList)
write_visitor_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_enum("Ast", AstNodeList)
write_type_tests("Ast", AstNodeList) write_type_tests("Ast", AstNodeList)
write_ast_macros("V3Ast__gen_macros.h") write_ast_macros("V3Ast__gen_macros.h")