Internals: Avoid passing vars from V3Const visitor; no functional change

This commit is contained in:
Wilson Snyder 2010-12-28 20:46:13 -05:00
parent 40f9d64973
commit 9f161b20ef
2 changed files with 52 additions and 33 deletions

View File

@ -93,7 +93,7 @@ public:
class ConstVisitor : public AstNVisitor {
private:
// NODE STATE
// ** only when m_warn/m_expensive is set. If state is needed other times,
// ** only when m_warn/m_doExpensive is set. If state is needed other times,
// ** must track down everywhere V3Const is called and make sure no overlaps.
// AstVar::user4p -> Used by ConstVarMarkVisitor/ConstVarFindVisitor
// AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label
@ -103,8 +103,8 @@ private:
bool m_required; // If true, must become a constant
bool m_wremove; // Inside scope, no assignw removal
bool m_warn; // Output warnings
bool m_cpp; // C++ conversions only
bool m_expensive; // Enable computationally expensive optimizations
bool m_doV; // Verilog, not C++ conversion
bool m_doExpensive; // Enable computationally expensive optimizations
AstNodeModule* m_modp; // Current module
AstNode* m_scopep; // Current scope
@ -289,7 +289,7 @@ private:
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
// Since select's return unsigned, this is always an extend
AstExtend* extendp = nodep->fromp()->castExtend();
return (!m_cpp
return (m_doV
&& extendp
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
@ -724,7 +724,7 @@ private:
return true;
}
}
else if (!m_cpp && nodep->lhsp()->castConcat()) {
else if (m_doV && nodep->lhsp()->castConcat()) {
bool need_temp = false;
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
// Note only do this (need user4) when m_warn, which is
@ -1064,12 +1064,13 @@ private:
nodep->iterateChildren(*this);
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
bool did=false;
if (!m_cpp && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
if (m_doV && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
//if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: ");
nodep->varp()->valuep()->iterateAndNext(*this);
if (operandConst(nodep->varp()->valuep())
&& !nodep->lvalue()
&& ((v3Global.opt.oConst() && !m_params // Can reduce constant wires into equations
&& ((!m_params // Can reduce constant wires into equations
&& v3Global.opt.oConst()
&& !nodep->varp()->isSigPublic())
|| nodep->varp()->isParam())) {
AstConst* constp = nodep->varp()->valuep()->castConst();
@ -1202,7 +1203,7 @@ private:
virtual void visit(AstSenTree* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_expensive) {
if (m_doExpensive) {
//cout<<endl; nodep->dumpTree(cout,"ssin: ");
// Optimize ideas for the future:
// SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b))
@ -1314,13 +1315,12 @@ private:
nodep->iterateChildren(*this);
if (replaceNodeAssign(nodep)) return;
AstNodeVarRef* varrefp = nodep->lhsp()->castVarRef(); // Not VarXRef, as different refs may set different values to each hierarchy
if (m_wremove
if (m_wremove && !m_params
&& m_modp && operandConst(nodep->rhsp())
&& !nodep->rhsp()->castConst()->num().isFourState()
&& varrefp // Don't do messes with BITREFs/ARRAYREFs
&& !varrefp->varp()->valuep() // Not already constified
&& !varrefp->varScopep() // Not scoped (or each scope may have different initial value)
&& !m_params) {
&& !varrefp->varScopep()) { // Not scoped (or each scope may have different initial value)
// ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) )
UINFO(4,"constAssignW "<<nodep<<endl);
// Make a initial assignment
@ -1506,7 +1506,7 @@ private:
virtual void visit(AstJumpGo* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_expensive) { nodep->labelp()->user4(true); }
if (m_doExpensive) { nodep->labelp()->user4(true); }
}
virtual void visit(AstJumpLabel* nodep, AstNUser*) {
@ -1515,7 +1515,7 @@ private:
// Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
nodep->iterateChildren(*this);
// AstJumpGo's below here that point to this node will set user4
if (m_expensive && !nodep->user4()) {
if (m_doExpensive && !nodep->user4()) {
UINFO(4,"JUMPLABEL => unused "<<nodep<<endl);
AstNode* underp = NULL;
if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext();
@ -1546,7 +1546,7 @@ private:
// Lint Checks
// v--- *1* These ops are always first, as we warn before replacing
// v--- *V* This op is a verilog op, ignore when in m_cpp mode
// v--- *V* This op is a verilog op, only in m_doV mode
TREEOP1("AstSel{warnSelect(nodep)}", "NEVER");
// Generic constants on both side. Do this first to avoid other replacements
TREEOP("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)");
@ -1781,15 +1781,34 @@ private:
}
public:
// Processing Mode Enum
enum ProcMode {
PROC_PARAMS,
PROC_V_WARN,
PROC_V_NOWARN,
PROC_V_EXPENSIVE,
PROC_CPP
};
// CONSTUCTORS
ConstVisitor(bool params, bool expensive, bool warn, bool cpp) {
m_params = params; m_required = params;
m_expensive = expensive;
m_warn = warn;
m_cpp = cpp;
m_wremove = true;
ConstVisitor(ProcMode pmode) {
m_params = false;
m_required = false;
m_doV = false;
m_doExpensive = false;
m_warn = false;
m_wremove = true; // Overridden in visitors
m_modp = NULL;
m_scopep = NULL;
//
switch (pmode) {
case PROC_PARAMS: m_doV = true; m_params = true; m_required = true; break;
case PROC_V_WARN: m_doV = true; m_warn = true; break;
case PROC_V_NOWARN: m_doV = true; break;
case PROC_V_EXPENSIVE: m_doV = true; m_doExpensive = true; break;
case PROC_CPP: m_doV = false; break;
default: v3fatalSrc("Bad case"); break;
}
}
virtual ~ConstVisitor() {}
AstNode* mainAcceptEdit(AstNode* nodep) {
@ -1806,7 +1825,7 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
// Resize even if the node already has a width, because burried in the treee we may
// have a node we just created with signing, etc, that isn't sized yet.
nodep = V3Width::widthParamsEdit(nodep); // Make sure we've sized everything first
ConstVisitor visitor (true,false,false,false);
ConstVisitor visitor (ConstVisitor::PROC_PARAMS);
if (AstVar* varp=nodep->castVar()) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
@ -1820,34 +1839,34 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
return nodep;
}
void V3Const::constifyAll(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,true,false,false);
(void)visitor.mainAcceptEdit(nodep);
}
void V3Const::constifyAllLint(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,false,true,false);
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
(void)visitor.mainAcceptEdit(nodep);
}
void V3Const::constifyCpp(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,false,false,true);
ConstVisitor visitor (ConstVisitor::PROC_CPP);
(void)visitor.mainAcceptEdit(nodep);
}
AstNode* V3Const::constifyEdit(AstNode* nodep) {
ConstVisitor visitor (false,false,false,false);
ConstVisitor visitor (ConstVisitor::PROC_V_NOWARN);
nodep = visitor.mainAcceptEdit(nodep);
return nodep;
}
void V3Const::constifyAll(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
(void)visitor.mainAcceptEdit(nodep);
}
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
ConstVisitor visitor (false,true,false,false);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
nodep = visitor.mainAcceptEdit(nodep);
return nodep;
}

View File

@ -285,7 +285,7 @@ sub tree_line {
(::subclasses_of($type)) or $self->error("Unknown AstNode type: $type: in $func");
my $mif = "";
$mif = "!m_cpp" if $cpp;
$mif = "m_doV" if $cpp;
$subnodes =~ s/,,/__ESCAPEDCOMMA__/g;
foreach my $subnode (split /\s*,\s*/, $subnodes) {
$subnode =~ s/__ESCAPEDCOMMA__/,/g;