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);
}
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 {

View File

@ -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<VNRef<T_Node>> 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);
}

View File

@ -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 =====================================================

View File

@ -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;
};

View File

@ -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);

View File

@ -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 {

View File

@ -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<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
// relative reference, so we are probably not loosing much.
addModDependency(EmitCParentModule::get(cfuncp));
iterate(cfuncp);
iterateConst(cfuncp);
}
public:

View File

@ -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

View File

@ -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 {}

View File

@ -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);

View File

@ -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

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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")