forked from github/verilator
Internals: Add VNVisitorConst class.
This commit is contained in:
parent
371b8310d9
commit
d6c5d40f9b
@ -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 {
|
||||
|
81
src/V3Ast.h
81
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<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);
|
||||
}
|
||||
|
@ -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 =====================================================
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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 {}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user