diff --git a/src/V3Ast.h b/src/V3Ast.h index 1fa35e9a0..82a08fc01 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1334,6 +1334,9 @@ struct AstNodeDType : public AstNode { virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... virtual bool maybePointedTo() const { return true; } + AstNodeDType* dtypeDimensionp(int depth); + pair dimensions(); + uint32_t arrayElements(); // 1, or total multiplication of all dimensions }; struct AstNodeSel : public AstNodeBiop { diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 0a4a17a81..6e04aa9a5 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -245,7 +245,7 @@ string AstVar::scType() const { } } -AstNodeDType* AstVar::dtypeDimensionp(int dimension) const { +AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) { // dimension passed from AstArraySel::dimension // Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar, // which is the lowest in the dtype list. @@ -258,7 +258,7 @@ AstNodeDType* AstVar::dtypeDimensionp(int dimension) const { // *or* VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (ARRAYSEL3 (DT)))) // SEL1 needs to select from entire variable which is a pointer to ARRAYSEL0 int dim = 0; - for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) { + for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstArrayDType* adtypep = dtypep->castArrayDType()) { if ((dim++)==dimension) { @@ -282,9 +282,9 @@ AstNodeDType* AstVar::dtypeDimensionp(int dimension) const { return NULL; } -uint32_t AstVar::arrayElements() const { +uint32_t AstNodeDType::arrayElements() { uint32_t entries=1; - for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) { + for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstArrayDType* adtypep = dtypep->castArrayDType()) { entries *= adtypep->elementsConst(); @@ -298,11 +298,11 @@ uint32_t AstVar::arrayElements() const { return entries; } -pair AstVar::dimensions() const { +pair AstNodeDType::dimensions() { // How many array dimensions (packed,unpacked) does this Var have? uint32_t packed = 0; uint32_t unpacked = 0; - for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) { + for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstArrayDType* adtypep = dtypep->castArrayDType()) { if (adtypep->isPacked()) packed += 1; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 2577a8d11..ea331c5b4 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -683,8 +683,6 @@ public: AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType) AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) - AstNodeDType* dtypeDimensionp(int depth) const; - pair dimensions() const; AstNode* valuep() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const) void valuep(AstNode* nodep) { setOp3p(nodep); } // It's valuep, not constp, as may be more complicated than an AstConst void addAttrsp(AstNode* nodep) { addNOp4p(nodep); } @@ -760,7 +758,6 @@ public: bool attrScClocked() const { return m_scClocked; } bool attrSFormat() const { return m_attrSFormat; } bool attrIsolateAssign() const { return m_attrIsolateAssign; } - uint32_t arrayElements() const; // 1, or total multiplication of all dimensions virtual string verilogKwd() const; void propagateAttrFrom(AstVar* fromp) { // This is getting connected to fromp; keep attributes @@ -2347,7 +2344,7 @@ public: , m_showname(showname) { widthSignedFrom(varp); m_code = 0; - m_codeInc = varp->arrayElements() * varp->widthWords(); + m_codeInc = varp->dtypep()->arrayElements() * varp->widthWords(); AstBasicDType* bdtypep = varp->basicp(); m_msb = bdtypep ? bdtypep->msbEndianed() : 0; m_lsb = bdtypep ? bdtypep->lsbEndianed() : 0; diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 2e29ec776..8b0e94620 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -87,7 +87,7 @@ private: if (prettyName.find("._") != string::npos) return "Inlined leading underscore"; } - if ((nodep->width()*nodep->arrayElements()) > 256) return "Wide bus/array > 256 bits"; + if ((nodep->width()*nodep->dtypep()->arrayElements()) > 256) return "Wide bus/array > 256 bits"; // We allow this, though tracing doesn't // if (nodep->arrayp(1)) return "Unsupported: Multi-dimensional array"; return NULL; diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index de8e49791..301e8a74b 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -322,7 +322,7 @@ public: AstVarRef* varrefp = nodep->memp()->castVarRef(); if (!varrefp) { nodep->v3error("Readmem loading non-variable"); } else if (AstArrayDType* adtypep = varrefp->varp()->dtypeSkipRefp()->castArrayDType()) { - puts(cvtToStr(varrefp->varp()->arrayElements())); + puts(cvtToStr(varrefp->varp()->dtypep()->arrayElements())); array_lsb = adtypep->lsb(); } else { diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 0186b0101..475594fa2 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -85,7 +85,7 @@ class SliceCloneVisitor : public AstNVisitor { if (m_vecIdx == (int)m_selBits.size()) { m_selBits.push_back(vector()); AstVar* varp = m_refp->varp(); - pair arrDim = varp->dimensions(); + pair arrDim = varp->dtypep()->dimensions(); uint32_t dimensions = arrDim.first + arrDim.second; for (uint32_t i = 0; i < dimensions; ++i) { m_selBits[m_vecIdx].push_back(0); @@ -267,7 +267,7 @@ class SliceVisitor : public AstNVisitor { AstVar* varp = refp->varp(); AstNode* topp = nodep; for (unsigned i = start; i < start + count; ++i) { - AstNodeDType* dtypep = varp->dtypeDimensionp(i-1); + AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1); AstArrayDType* adtypep = dtypep->castArrayDType(); if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType"); vlsint32_t msb = adtypep->msb(); @@ -303,7 +303,7 @@ class SliceVisitor : public AstNVisitor { // The LHS/RHS of an Assign may be to a Var that is an array. In this // case we need to create a slice accross the entire Var if (m_assignp && !nodep->backp()->castArraySel()) { - pair arrDim = nodep->varp()->dimensions(); + pair arrDim = nodep->varp()->dtypep()->dimensions(); uint32_t dimensions = arrDim.first + arrDim.second; if (dimensions > 0) { AstVarRef* clonep = nodep->cloneTree(false); @@ -337,7 +337,7 @@ class SliceVisitor : public AstNVisitor { if (nodep->user3()) return; // Prevent recursion on just created nodes unsigned dim = explicitDimensions(nodep); AstVarRef* refp = nodep->user1p()->castNode()->castVarRef(); - pair arrDim = refp->varp()->dimensions(); + pair arrDim = refp->varp()->dtypep()->dimensions(); uint32_t implicit = (arrDim.first + arrDim.second) - dim; if (implicit > 0) { AstArraySel* newp = insertImplicit(nodep->cloneTree(false), dim+1, implicit); @@ -439,7 +439,7 @@ class SliceVisitor : public AstNVisitor { nodep->iterateChildren(*this); } else { AstVarRef* refp = findVarRefRecurse(nodep->lhsp()); - ArrayDimensions varDim = refp->varp()->dimensions(); + ArrayDimensions varDim = refp->varp()->dtypep()->dimensions(); if ((int)(dim - varDim.second) < 0) { // Unpacked dimensions are referenced first, make sure we have them all nodep->v3error("Unary operator used across unpacked dimensions"); diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 79cdde9c9..547b79df4 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -345,7 +345,7 @@ private: AstVarScope* vsc2p= *it; AstVar* var2p = vsc2p->varp(); if (var1p->width() == var2p->width() - && var1p->arrayElements() == var2p->arrayElements()) { + && var1p->dtypep()->arrayElements() == var2p->dtypep()->arrayElements()) { AstNode* init1p = var1p->valuep()->castInitArray(); AstNode* init2p = var2p->valuep()->castInitArray(); if (init1p->sameTree(init2p)) { diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index c4ef69c17..7902c20a5 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -76,7 +76,7 @@ private: return "Inlined leading underscore"; } if ((int)nodep->width() > v3Global.opt.traceMaxWidth()) return "Wide bus > --trace-max-width bits"; - if ((int)nodep->arrayElements() > v3Global.opt.traceMaxArray()) return "Wide memory > --trace-max-array ents"; + if ((int)nodep->dtypep()->arrayElements() > v3Global.opt.traceMaxArray()) return "Wide memory > --trace-max-array ents"; if (!(nodep->dtypeSkipRefp()->castBasicDType() || (nodep->dtypeSkipRefp()->castArrayDType() && nodep->dtypeSkipRefp()->castArrayDType()->dtypeSkipRefp()->castBasicDType()))) { diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 741127df8..817462da8 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -380,7 +380,7 @@ private: int maxmsb = 0; bool lvalue = false; if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { - AstArrayDType* adtypep = varrefp->varp()->dtypeDimensionp(dimension)->castArrayDType(); + AstArrayDType* adtypep = varrefp->varp()->dtypep()->dtypeDimensionp(dimension)->castArrayDType(); if (!adtypep) nodep->v3fatalSrc("ArraySel to type without array at same depth"); lvalue = varrefp->lvalue(); maxmsb = adtypep->elementsConst()-1; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 8ccfd3efc..bd6fa289c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -457,7 +457,7 @@ private: // int frommsb; int fromlsb; - AstNodeDType* ddtypep = varrp->varp()->dtypeDimensionp(dimension); + AstNodeDType* ddtypep = varrp->varp()->dtypep()->dtypeDimensionp(dimension); if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { int outwidth = varrp->width(); // Width of variable frommsb = adtypep->msb(); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index d32812ded..0c69da1ed 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -78,7 +78,7 @@ private: // Perform error checks on the node AstVar* varp = varFromBasefrom(basefromp); //UINFO(9,"SCD\n"); if (debug()>=9) nodep->backp()->dumpTree(cout,"-selcheck: "); - AstNodeDType* ddtypep = varp->dtypeDimensionp(dimension); + AstNodeDType* ddtypep = varp->dtypep()->dtypeDimensionp(dimension); if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { return adtypep; }