astgen: Enforce the use of aliased operand accessors (#4688)
This patch enforces the use of the most specific accessors for operands which have an '@astgen alias' declaration, by making the superclass accessors of the same operands private. This ensures client code is cleaner as you can't use multiple different methods to reference the same operands (which we used to in some places). Also prep for some refactoring.
This commit is contained in:
parent
1c0af6c7bc
commit
47588f343b
|
|
@ -4311,7 +4311,7 @@ class AstSelMinus final : public AstNodePreSel {
|
|||
// -: range extraction, perhaps with non-constant selection
|
||||
// Gets replaced during link with AstSel
|
||||
// @astgen alias op2 := bitp
|
||||
// @astgen alias op3 := widtph
|
||||
// @astgen alias op3 := widthp
|
||||
public:
|
||||
AstSelMinus(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp, AstNodeExpr* widthp)
|
||||
: ASTGEN_SUPER_SelMinus(fl, fromp, bitp, widthp) {}
|
||||
|
|
@ -4321,7 +4321,7 @@ class AstSelPlus final : public AstNodePreSel {
|
|||
// +: range extraction, perhaps with non-constant selection
|
||||
// Gets replaced during link with AstSel
|
||||
// @astgen alias op2 := bitp
|
||||
// @astgen alias op3 := widtph
|
||||
// @astgen alias op3 := widthp
|
||||
public:
|
||||
AstSelPlus(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp, AstNodeExpr* widthp)
|
||||
: ASTGEN_SUPER_SelPlus(fl, fromp, bitp, widthp) {}
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst {
|
|||
void visit(AstWordSel* nodep) override {
|
||||
CONST_BITOP_RETURN_IF(!m_leafp, nodep);
|
||||
AstConst* const constp = VN_CAST(nodep->bitp(), Const);
|
||||
CONST_BITOP_RETURN_IF(!constp, nodep->rhsp());
|
||||
CONST_BITOP_RETURN_IF(!constp, nodep->bitp());
|
||||
UASSERT_OBJ(m_leafp->wordIdx() == -1, nodep, "Unexpected nested WordSel");
|
||||
m_leafp->wordIdx(constp->toSInt());
|
||||
iterateConst(nodep->fromp());
|
||||
|
|
@ -1269,9 +1269,9 @@ private:
|
|||
// V3Expand may make a arraysel that exceeds the bounds of the array
|
||||
// It was an expression, then got constified. In reality, the WordSel
|
||||
// must be wrapped in a Cond, that will be false.
|
||||
return (VN_IS(nodep->rhsp(), Const) && VN_IS(nodep->fromp(), NodeVarRef)
|
||||
return (VN_IS(nodep->bitp(), Const) && VN_IS(nodep->fromp(), NodeVarRef)
|
||||
&& VN_AS(nodep->fromp(), NodeVarRef)->access().isReadOnly()
|
||||
&& (static_cast<int>(VN_AS(nodep->rhsp(), Const)->toUInt())
|
||||
&& (static_cast<int>(VN_AS(nodep->bitp(), Const)->toUInt())
|
||||
>= VN_AS(nodep->fromp(), NodeVarRef)->varp()->widthWords()));
|
||||
}
|
||||
bool operandSelFull(const AstSel* nodep) {
|
||||
|
|
@ -2539,7 +2539,7 @@ private:
|
|||
// SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long
|
||||
// as SEL's width <= b's width
|
||||
AstReplicate* const repp = VN_AS(nodep->fromp(), Replicate);
|
||||
AstNodeExpr* const fromp = repp->lhsp();
|
||||
AstNodeExpr* const fromp = repp->srcp();
|
||||
AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const);
|
||||
if (!lsbp) return false;
|
||||
AstNodeExpr* const widthp = nodep->widthp();
|
||||
|
|
@ -2562,11 +2562,11 @@ private:
|
|||
}
|
||||
bool operandRepRep(AstReplicate* nodep) {
|
||||
// REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2))
|
||||
AstReplicate* const rep2p = VN_AS(nodep->lhsp(), Replicate);
|
||||
AstNodeExpr* const from2p = rep2p->lhsp();
|
||||
AstConst* const cnt1p = VN_CAST(nodep->rhsp(), Const);
|
||||
AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate);
|
||||
AstNodeExpr* const from2p = rep2p->srcp();
|
||||
AstConst* const cnt1p = VN_CAST(nodep->countp(), Const);
|
||||
if (!cnt1p) return false;
|
||||
AstConst* const cnt2p = VN_CAST(rep2p->rhsp(), Const);
|
||||
AstConst* const cnt2p = VN_CAST(rep2p->countp(), Const);
|
||||
if (!cnt2p) return false;
|
||||
//
|
||||
from2p->unlinkFrBack();
|
||||
|
|
@ -2589,15 +2589,15 @@ private:
|
|||
AstNodeExpr* from2p = nodep->rhsp();
|
||||
uint32_t cnt2 = 1;
|
||||
if (VN_IS(from1p, Replicate)) {
|
||||
AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->rhsp(), Const);
|
||||
AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const);
|
||||
if (!cnt1p) return false;
|
||||
from1p = VN_AS(from1p, Replicate)->lhsp();
|
||||
from1p = VN_AS(from1p, Replicate)->srcp();
|
||||
cnt1 = cnt1p->toUInt();
|
||||
}
|
||||
if (VN_IS(from2p, Replicate)) {
|
||||
AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->rhsp(), Const);
|
||||
AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const);
|
||||
if (!cnt2p) return false;
|
||||
from2p = VN_AS(from2p, Replicate)->lhsp();
|
||||
from2p = VN_AS(from2p, Replicate)->srcp();
|
||||
cnt2 = cnt2p->toUInt();
|
||||
}
|
||||
if (!operandsSame(from1p, from2p)) return false;
|
||||
|
|
@ -3488,8 +3488,8 @@ private:
|
|||
TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)");
|
||||
TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)");
|
||||
// This visit function here must allow for short-circuiting.
|
||||
TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)");
|
||||
TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)");
|
||||
TREEOPS("AstCond {$condp.isZero}", "replaceWIteratedThs(nodep)");
|
||||
TREEOPS("AstCond {$condp.isNeqZero}", "replaceWIteratedRhs(nodep)");
|
||||
TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->castNot()->lhsp(), $elsep, $thenp}");
|
||||
TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep}", "AstLogOr {$condp, $elsep}"); // a?1:b == a||b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isZero, !$elsep.isClassHandleValue}", "AstLogAnd{$condp, $thenp}"); // a?b:0 == a&&b
|
||||
|
|
@ -3670,9 +3670,9 @@ private:
|
|||
// bits end up in the wrong places
|
||||
TREEOPV("AstExtend {$lhsp.castExtend}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), Extend)->lhsp())");
|
||||
TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), ExtendS)->lhsp())");
|
||||
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
|
||||
TREEOPV("AstReplicate{$srcp, $countp.isOne, $srcp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
|
||||
TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
|
||||
TREEOPV("AstReplicate{$lhsp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}}
|
||||
TREEOPV("AstReplicate{$srcp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}}
|
||||
TREEOPV("AstConcat{operandConcatSame(nodep)}", "DONE"); // {a,a}->{2{a}}, {a,2{a}}->{3{a}, etc
|
||||
// Next rule because AUTOINST puts the width of bits in
|
||||
// to pins, even when the widths are exactly the same across the hierarchy.
|
||||
|
|
@ -3694,9 +3694,9 @@ private:
|
|||
// win if bit select is a constant (otherwise we may need to compute bit index several times)
|
||||
TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castAnd,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castOr,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castXor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castAnd,$fromp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castOr,$fromp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||
TREEOPV("AstSel{$fromp.castXor,$fromp.castConst}", "replaceSelIntoUniop(nodep)");
|
||||
// This visit function here must allow for short-circuiting.
|
||||
TREEOPS("AstLogIf{$lhsp.isZero}", "replaceNum(nodep, 1)");
|
||||
TREEOPV("AstLogIf{$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
|
||||
|
|
|
|||
|
|
@ -1184,25 +1184,25 @@ public:
|
|||
}
|
||||
void visit(AstSel* nodep) override {
|
||||
// Note ASSIGN checks for this on a LHS
|
||||
emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp());
|
||||
emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->widthp());
|
||||
}
|
||||
void visit(AstReplicate* nodep) override {
|
||||
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
UASSERT_OBJ((static_cast<int>(VN_AS(nodep->rhsp(), Const)->toUInt())
|
||||
* nodep->lhsp()->widthMin())
|
||||
if (nodep->srcp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
UASSERT_OBJ((static_cast<int>(VN_AS(nodep->countp(), Const)->toUInt())
|
||||
* nodep->srcp()->widthMin())
|
||||
== nodep->widthMin(),
|
||||
nodep, "Replicate non-constant or width miscomputed");
|
||||
puts("VL_REPLICATE_");
|
||||
emitIQW(nodep);
|
||||
puts("OI(");
|
||||
if (nodep->lhsp()) puts(cvtToStr(nodep->lhsp()->widthMin()));
|
||||
if (nodep->srcp()) puts(cvtToStr(nodep->srcp()->widthMin()));
|
||||
puts(",");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->srcp());
|
||||
puts(", ");
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
iterateAndNextConstNull(nodep->countp());
|
||||
puts(")");
|
||||
} else {
|
||||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nullptr);
|
||||
emitOpName(nodep, nodep->emitC(), nodep->srcp(), nodep->countp(), nullptr);
|
||||
}
|
||||
}
|
||||
void visit(AstStreamL* nodep) override {
|
||||
|
|
@ -1229,9 +1229,9 @@ public:
|
|||
}
|
||||
void visit(AstCastDynamic* nodep) override {
|
||||
putbs("VL_CAST_DYNAMIC(");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
puts(", ");
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
iterateAndNextConstNull(nodep->top());
|
||||
puts(")");
|
||||
}
|
||||
void visit(AstCountBits* nodep) override {
|
||||
|
|
|
|||
|
|
@ -731,7 +731,7 @@ private:
|
|||
} else {
|
||||
if (isImpure(nodep)) return;
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNodeExpr* lhsp = nodep->srcp()->unlinkFrBack();
|
||||
AstNodeExpr* newp;
|
||||
const int lhswidth = lhsp->widthMin();
|
||||
if (lhswidth == 1) {
|
||||
|
|
@ -739,7 +739,7 @@ private:
|
|||
newp = new AstNegate{fl, lhsp};
|
||||
} else {
|
||||
UINFO(8, " REPLICATE " << nodep << endl);
|
||||
const AstConst* const constp = VN_AS(nodep->rhsp(), Const);
|
||||
const AstConst* const constp = VN_AS(nodep->countp(), Const);
|
||||
UASSERT_OBJ(constp, nodep,
|
||||
"Replication value isn't a constant. Checked earlier!");
|
||||
const uint32_t times = constp->toUInt();
|
||||
|
|
@ -765,9 +765,9 @@ private:
|
|||
UINFO(8, " Wordize ASSIGN(REPLICATE) " << nodep << endl);
|
||||
if (!doExpandWide(rhsp)) return false;
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNodeExpr* const lhsp = rhsp->lhsp();
|
||||
AstNodeExpr* const lhsp = rhsp->srcp();
|
||||
const int lhswidth = lhsp->widthMin();
|
||||
const AstConst* const constp = VN_AS(rhsp->rhsp(), Const);
|
||||
const AstConst* const constp = VN_AS(rhsp->countp(), Const);
|
||||
UASSERT_OBJ(constp, rhsp, "Replication value isn't a constant. Checked earlier!");
|
||||
const uint32_t times = constp->toUInt();
|
||||
for (int w = 0; w < rhsp->widthWords(); ++w) {
|
||||
|
|
|
|||
|
|
@ -362,11 +362,11 @@ private:
|
|||
} // end expanding ranged cell
|
||||
else if (AstArraySel* const arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
|
||||
if (const AstUnpackArrayDType* const arrp
|
||||
= VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) {
|
||||
= VN_CAST(arrselp->fromp()->dtypep(), UnpackArrayDType)) {
|
||||
if (!VN_IS(arrp->subDTypep(), IfaceRefDType)) return;
|
||||
// Interface pin attaches to one element of arrayed interface
|
||||
V3Const::constifyParamsEdit(arrselp->rhsp());
|
||||
const AstConst* const constp = VN_CAST(arrselp->rhsp(), Const);
|
||||
V3Const::constifyParamsEdit(arrselp->bitp());
|
||||
const AstConst* const constp = VN_CAST(arrselp->bitp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
|
|
@ -374,9 +374,9 @@ private:
|
|||
return;
|
||||
}
|
||||
const string index = AstNode::encodeNumber(constp->toSInt());
|
||||
if (VN_IS(arrselp->lhsp(), SliceSel))
|
||||
arrselp->lhsp()->v3error("Unsupported: interface slices");
|
||||
const AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef);
|
||||
if (VN_IS(arrselp->fromp(), SliceSel))
|
||||
arrselp->fromp()->v3error("Unsupported: interface slices");
|
||||
const AstVarRef* const varrefp = VN_CAST(arrselp->fromp(), VarRef);
|
||||
UASSERT_OBJ(varrefp, arrselp, "No interface varref under array");
|
||||
AstVarXRef* const newp = new AstVarXRef{
|
||||
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
|
||||
|
|
|
|||
|
|
@ -238,19 +238,19 @@ private:
|
|||
void visit(AstSel* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
// Only set lvalues on the from
|
||||
m_setRefLvalue = VAccess::NOCHANGE;
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextNull(nodep->thsp());
|
||||
iterateAndNextNull(nodep->lsbp());
|
||||
iterateAndNextNull(nodep->widthp());
|
||||
}
|
||||
}
|
||||
void visit(AstNodeSel* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{ // Only set lvalues on the from
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
m_setRefLvalue = VAccess::NOCHANGE;
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextNull(nodep->bitp());
|
||||
}
|
||||
}
|
||||
void visit(AstCellArrayRef* nodep) override {
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ private:
|
|||
// Convert to AstSelLoopVars so V3LinkDot knows what's being defined
|
||||
AstNode* const newp
|
||||
= new AstSelLoopVars{selp->fileline(), selp->fromp()->unlinkFrBack(),
|
||||
selp->rhsp()->unlinkFrBackWithNext()};
|
||||
selp->bitp()->unlinkFrBackWithNext()};
|
||||
selp->replaceWith(newp);
|
||||
VL_DO_DANGLING(selp->deleteTree(), selp);
|
||||
} else if (VN_IS(bracketp, SelLoopVars)) {
|
||||
|
|
|
|||
|
|
@ -768,7 +768,7 @@ private:
|
|||
outVarrefpRef = varrefp;
|
||||
lsbRef = fetchConst(selp->lsbp())->num();
|
||||
return; // And presumably still optimizable()
|
||||
} else if (AstSel* const subselp = VN_CAST(selp->lhsp(), Sel)) {
|
||||
} else if (AstSel* const subselp = VN_CAST(selp->fromp(), Sel)) {
|
||||
V3Number sublsb{nodep};
|
||||
handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb /*ref*/, depth + 1);
|
||||
if (optimizable()) {
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ class SliceVisitor final : public VNVisitor {
|
|||
if (AstSliceSel* const slicep = VN_CAST(itemp, SliceSel)) {
|
||||
offset += slicep->declRange().lo();
|
||||
newp = new AstArraySel{nodep->fileline(),
|
||||
slicep->lhsp()->cloneTreePure(false), offset};
|
||||
slicep->fromp()->cloneTreePure(false), offset};
|
||||
} else {
|
||||
newp = new AstArraySel{nodep->fileline(), itemp->cloneTreePure(false),
|
||||
offset};
|
||||
|
|
|
|||
|
|
@ -267,9 +267,9 @@ private:
|
|||
}
|
||||
}
|
||||
} else if (const AstWordSel* const wordp = VN_CAST(nodep->lhsp(), WordSel)) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(wordp->lhsp(), VarRef)) {
|
||||
if (VN_IS(wordp->rhsp(), Const) && isSubstVar(varrefp->varp())) {
|
||||
const int word = VN_AS(wordp->rhsp(), Const)->toUInt();
|
||||
if (AstVarRef* const varrefp = VN_CAST(wordp->fromp(), VarRef)) {
|
||||
if (VN_IS(wordp->bitp(), Const) && isSubstVar(varrefp->varp())) {
|
||||
const int word = VN_AS(wordp->bitp(), Const)->toUInt();
|
||||
SubstVarEntry* const entryp = getEntryp(varrefp);
|
||||
hit = true;
|
||||
if (m_ops > SUBST_MAX_OPS_SUBST) {
|
||||
|
|
@ -297,9 +297,9 @@ private:
|
|||
}
|
||||
void visit(AstWordSel* nodep) override {
|
||||
if (!m_funcp) return;
|
||||
iterate(nodep->rhsp());
|
||||
AstVarRef* const varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
iterate(nodep->bitp());
|
||||
AstVarRef* const varrefp = VN_CAST(nodep->fromp(), VarRef);
|
||||
const AstConst* const constp = VN_CAST(nodep->bitp(), Const);
|
||||
if (varrefp && isSubstVar(varrefp->varp()) && varrefp->access().isReadOnly() && constp) {
|
||||
// Nicely formed lvalues handled in NodeAssign
|
||||
// Other lvalues handled as unknown mess in AstVarRef
|
||||
|
|
@ -318,7 +318,7 @@ private:
|
|||
entryp->consumeWord(word);
|
||||
}
|
||||
} else {
|
||||
iterate(nodep->lhsp());
|
||||
iterate(nodep->fromp());
|
||||
}
|
||||
}
|
||||
void visit(AstVarRef* nodep) override {
|
||||
|
|
|
|||
|
|
@ -730,12 +730,12 @@ private:
|
|||
// LHS, RHS is self-determined
|
||||
// width: value(LHS) * width(RHS)
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsNoWarnEdit(nodep->rhsp()); // rhsp may change
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->countp(), SELF, BOTH);
|
||||
V3Const::constifyParamsNoWarnEdit(nodep->countp()); // rhsp may change
|
||||
|
||||
uint32_t times = 1;
|
||||
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
const AstConst* const constp = VN_CAST(nodep->countp(), Const);
|
||||
if (constp) times = constp->toUInt();
|
||||
|
||||
AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp();
|
||||
|
|
@ -746,18 +746,18 @@ private:
|
|||
<< vdtypep->prettyDTypeNameQ()
|
||||
<< " data type");
|
||||
}
|
||||
if (VN_IS(nodep->lhsp(), Concat)) {
|
||||
if (VN_IS(nodep->srcp(), Concat)) {
|
||||
// Convert to concat directly, and visit(AstConst) will convert.
|
||||
// Don't iterate lhsp as SELF, the potential Concat below needs
|
||||
// the adtypep passed down to recognize the QueueDType
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP{vdtypep, BOTH}.p());
|
||||
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
|
||||
userIterateAndNext(nodep->srcp(), WidthVP{vdtypep, BOTH}.p());
|
||||
nodep->replaceWith(nodep->srcp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
} else { // int a[] = {lhs} -> same as '{lhs}
|
||||
auto* const newp = new AstPattern{
|
||||
nodep->fileline(),
|
||||
new AstPatMember{nodep->lhsp()->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
new AstPatMember{nodep->srcp()->fileline(), nodep->srcp()->unlinkFrBack(),
|
||||
nullptr, nullptr}};
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -769,11 +769,11 @@ private:
|
|||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Replication to form "
|
||||
<< vdtypep->prettyDTypeNameQ() << " data type");
|
||||
}
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
||||
if ((vdtypep && vdtypep->isString()) || nodep->lhsp()->isString()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->srcp(), SELF, BOTH);
|
||||
if ((vdtypep && vdtypep->isString()) || nodep->srcp()->isString()) {
|
||||
AstNode* const newp
|
||||
= new AstReplicateN{nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack()};
|
||||
= new AstReplicateN{nodep->fileline(), nodep->srcp()->unlinkFrBack(),
|
||||
nodep->countp()->unlinkFrBack()};
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
|
|
@ -785,8 +785,8 @@ private:
|
|||
" (IEEE 1800-2017 11.4.12.1)");
|
||||
times = 1; // Set to 1, so we can continue looking for errors
|
||||
}
|
||||
nodep->dtypeSetLogicUnsized((nodep->lhsp()->width() * times),
|
||||
(nodep->lhsp()->widthMin() * times),
|
||||
nodep->dtypeSetLogicUnsized((nodep->srcp()->width() * times),
|
||||
(nodep->srcp()->widthMin() * times),
|
||||
VSigning::UNSIGNED);
|
||||
}
|
||||
}
|
||||
|
|
@ -898,7 +898,7 @@ private:
|
|||
userIterateAndNext(nodep->lsbp(), WidthVP{SELF, PRELIM}.p());
|
||||
checkCvtUS(nodep->fromp());
|
||||
iterateCheckSizedSelf(nodep, "Select Width", nodep->widthp(), SELF, BOTH);
|
||||
iterateCheckSizedSelf(nodep, "Select LHS", nodep->lhsp(), SELF, BOTH);
|
||||
iterateCheckSizedSelf(nodep, "Select LHS", nodep->fromp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change
|
||||
const AstConst* const widthConstp = VN_CAST(nodep->widthp(), Const);
|
||||
if (!widthConstp) {
|
||||
|
|
@ -1141,7 +1141,7 @@ private:
|
|||
void visit(AstSelBit* nodep) override {
|
||||
// Just a quick check as after V3Param these nodes instead are AstSel's
|
||||
userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->bitp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p());
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
|
|
@ -1155,8 +1155,8 @@ private:
|
|||
void visit(AstSelExtract* nodep) override {
|
||||
// Just a quick check as after V3Param these nodes instead are AstSel's
|
||||
userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->leftp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->rightp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p());
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
|
|
@ -1168,8 +1168,8 @@ private:
|
|||
}
|
||||
void visit(AstSelPlus* nodep) override {
|
||||
userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->bitp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->widthp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p());
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
|
|
@ -1181,8 +1181,8 @@ private:
|
|||
}
|
||||
void visit(AstSelMinus* nodep) override {
|
||||
userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->rhsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->bitp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->widthp(), WidthVP{CONTEXT_DET, PRELIM}.p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP{SELF, BOTH}.p());
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ private:
|
|||
if (debug() >= 9) nodep->backp()->dumpTree("- SELBT0: ");
|
||||
// lhsp/rhsp do not need to be constant
|
||||
AstNodeExpr* const fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting
|
||||
AstNodeExpr* const rhsp = nodep->bitp()->unlinkFrBack(); // bit we're extracting
|
||||
if (debug() >= 9) nodep->dumpTree("- SELBT2: ");
|
||||
const FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* const ddtypep = fromdata.m_dtypep;
|
||||
|
|
@ -354,8 +354,8 @@ private:
|
|||
AstNodeDType* const ddtypep = fromdata.m_dtypep;
|
||||
const VNumRange fromRange = fromdata.m_fromRange;
|
||||
if (VN_IS(ddtypep, QueueDType)) {
|
||||
AstNodeExpr* const qleftp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNodeExpr* const qrightp = nodep->thsp()->unlinkFrBack();
|
||||
AstNodeExpr* const qleftp = nodep->leftp()->unlinkFrBack();
|
||||
AstNodeExpr* const qrightp = nodep->rightp()->unlinkFrBack();
|
||||
AstNodeExpr* const qleftBacknessp = selQueueBackness(qleftp);
|
||||
AstNodeExpr* const qrightBacknessp = selQueueBackness(qrightp);
|
||||
// Use special methods to refer to back rather than math using
|
||||
|
|
@ -381,8 +381,8 @@ private:
|
|||
"First value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
checkConstantOrReplace(nodep->rightp(),
|
||||
"Second value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
AstNodeExpr* const msbp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNodeExpr* const lsbp = nodep->thsp()->unlinkFrBack();
|
||||
AstNodeExpr* const msbp = nodep->leftp()->unlinkFrBack();
|
||||
AstNodeExpr* const lsbp = nodep->rightp()->unlinkFrBack();
|
||||
int32_t msb = VN_AS(msbp, Const)->toSInt();
|
||||
int32_t lsb = VN_AS(lsbp, Const)->toSInt();
|
||||
const int32_t elem = (msb > lsb) ? (msb - lsb + 1) : (lsb - msb + 1);
|
||||
|
|
|
|||
28
src/astgen
28
src/astgen
|
|
@ -503,13 +503,16 @@ class Cpt:
|
|||
" // Generated by astgen with short-circuiting\n" +
|
||||
" void visit(Ast" + node.name +
|
||||
"* nodep) override {\n" +
|
||||
" iterateAndNextNull(nodep->lhsp());\n" +
|
||||
"".join(out_for_type_sc))
|
||||
" iterateAndNextNull(nodep->{op1}());\n".format(
|
||||
op1=node.getOp(1)[0]) + "".join(out_for_type_sc))
|
||||
if out_for_type[0]:
|
||||
self.print(" iterateAndNextNull(nodep->rhsp());\n")
|
||||
self.print(
|
||||
" iterateAndNextNull(nodep->{op2}());\n".format(
|
||||
op2=node.getOp(2)[0]))
|
||||
if node.isSubClassOf(AstNodes["NodeTriop"]):
|
||||
self.print(
|
||||
" iterateAndNextNull(nodep->thsp());\n")
|
||||
" iterateAndNextNull(nodep->{op3}());\n".
|
||||
format(op3=node.getOp(3)[0]))
|
||||
self.print("".join(out_for_type) + " }\n")
|
||||
elif len(out_for_type) > 0: # Other types with something to print
|
||||
skip = node.name in self.tree_skip_visit
|
||||
|
|
@ -976,6 +979,8 @@ def write_ast_macros(filename):
|
|||
''',
|
||||
t=node.name)
|
||||
|
||||
hiddenMethods = []
|
||||
|
||||
for n in range(1, 5):
|
||||
op = node.getOp(n)
|
||||
if not op:
|
||||
|
|
@ -983,6 +988,11 @@ def write_ast_macros(filename):
|
|||
name, monad, kind = op
|
||||
retrieve = ("VN_DBG_AS(op{n}p(), {kind})" if kind != "Node"
|
||||
else "op{n}p()").format(n=n, kind=kind)
|
||||
superOp = node.superClass.getOp(n)
|
||||
superName = None
|
||||
if superOp:
|
||||
superName = superOp[0]
|
||||
hiddenMethods.append(superName)
|
||||
if monad == "List":
|
||||
emitBlock('''\
|
||||
Ast{kind}* {name}() const VL_MT_STABLE {{ return {retrieve}; }}
|
||||
|
|
@ -993,6 +1003,9 @@ def write_ast_macros(filename):
|
|||
Name=name[0].upper() + name[1:],
|
||||
n=n,
|
||||
retrieve=retrieve)
|
||||
if superOp:
|
||||
hiddenMethods.append("add" + superName[0].upper() +
|
||||
superName[1:])
|
||||
elif monad == "Optional":
|
||||
emitBlock('''\
|
||||
Ast{kind}* {name}() const VL_MT_STABLE {{ return {retrieve}; }}
|
||||
|
|
@ -1012,6 +1025,13 @@ def write_ast_macros(filename):
|
|||
n=n,
|
||||
retrieve=retrieve)
|
||||
|
||||
if hiddenMethods:
|
||||
fh.write("private: \\\n")
|
||||
for method in hiddenMethods:
|
||||
fh.write(" using Ast{sup}::{method}; \\\n".format(
|
||||
sup=node.superClass.name, method=method))
|
||||
fh.write("public: \\\n")
|
||||
|
||||
fh.write(
|
||||
" static_assert(true, \"\")\n") # Swallowing the semicolon
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue