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:
Geza Lore 2023-11-12 18:30:48 +00:00 committed by GitHub
parent 1c0af6c7bc
commit 47588f343b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 106 additions and 86 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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__", "",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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