Internals: Move dimension accessors from AstVar to AstNodeDType.

This commit is contained in:
Wilson Snyder 2012-02-28 21:33:17 -05:00
parent f540362e36
commit e6244ca204
11 changed files with 22 additions and 22 deletions

View File

@ -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<uint32_t,uint32_t> dimensions();
uint32_t arrayElements(); // 1, or total multiplication of all dimensions
};
struct AstNodeSel : public AstNodeBiop {

View File

@ -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<uint32_t,uint32_t> AstVar::dimensions() const {
pair<uint32_t,uint32_t> 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;

View File

@ -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<uint32_t,uint32_t> 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;

View File

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

View File

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

View File

@ -85,7 +85,7 @@ class SliceCloneVisitor : public AstNVisitor {
if (m_vecIdx == (int)m_selBits.size()) {
m_selBits.push_back(vector<unsigned>());
AstVar* varp = m_refp->varp();
pair<uint32_t,uint32_t> arrDim = varp->dimensions();
pair<uint32_t,uint32_t> 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<uint32_t,uint32_t> arrDim = nodep->varp()->dimensions();
pair<uint32_t,uint32_t> 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<uint32_t,uint32_t> arrDim = refp->varp()->dimensions();
pair<uint32_t,uint32_t> 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");

View File

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

View File

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

View File

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

View File

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

View File

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