Internals: V3Slice style cleanup. No functional change; ignore whitespace

This commit is contained in:
Wilson Snyder 2024-11-28 13:33:59 -05:00
parent 7695687e87
commit e0ad430cd9
2 changed files with 79 additions and 82 deletions

View File

@ -50,8 +50,8 @@ protected:
m_inUnpacked = true; m_inUnpacked = true;
if (VN_IS(nodep->dtypep()->skipRefp(), AssocArrayDType)) { if (VN_IS(nodep->dtypep()->skipRefp(), AssocArrayDType)) {
// Note the double {{ initializer. The first { starts the initializer of the // Note the double {{ initializer. The first { starts the initializer of the
// VlUnpacked, and the second starts the initializer of m_storage within the // VlAssocArray, and the second starts the initializer of m_storage within the
// VlUnpacked. // VlAssocArray.
puts("{"); puts("{");
ofp()->putsNoTracking("{"); ofp()->putsNoTracking("{");
puts("\n"); puts("\n");

View File

@ -31,7 +31,7 @@
// ARRAYSEL // ARRAYSEL
// Modify bitp() for the new value and set ->length(1) // Modify bitp() for the new value and set ->length(1)
// //
// TODO: This code was written before SLICESEL was a type it might be // TODO: This code was written before SLICESEL was a type, it might be
// simplified to look primarily for SLICESELs. // simplified to look primarily for SLICESELs.
//************************************************************************* //*************************************************************************
@ -54,13 +54,12 @@ class SliceVisitor final : public VNVisitor {
// AstInitItem::user2() -> Corresponding first elemIdx // AstInitItem::user2() -> Corresponding first elemIdx
const VNUser2InUse m_inuser2; const VNUser2InUse m_inuser2;
// STATE // STATE - for current visit position (use VL_RESTORER)
AstNode* m_assignp = nullptr; // Assignment we are under AstNode* m_assignp = nullptr; // Assignment we are under
bool m_assignError = false; // True if the current assign already has an error bool m_assignError = false; // True if the current assign already has an error
bool m_okInitArray = false; // Allow InitArray children bool m_okInitArray = false; // Allow InitArray children
// METHODS // METHODS
AstNodeExpr* cloneAndSel(AstNode* nodep, int elements, int elemIdx) { AstNodeExpr* cloneAndSel(AstNode* nodep, int elements, int elemIdx) {
// Insert an ArraySel, except for a few special cases // Insert an ArraySel, except for a few special cases
const AstUnpackArrayDType* const arrayp const AstUnpackArrayDType* const arrayp
@ -221,40 +220,40 @@ class SliceVisitor final : public VNVisitor {
void visit(AstNodeAssign* nodep) override { void visit(AstNodeAssign* nodep) override {
// Called recursively on newly created assignments // Called recursively on newly created assignments
if (!nodep->user1() && !VN_IS(nodep, AssignAlias)) { if (nodep->user1SetOnce()) return; // Process once
nodep->user1(true); if (VN_IS(nodep, AssignAlias)) return;
m_assignError = false; if (debug() >= 9) nodep->dumpTree("- Deslice-In: ");
if (debug() >= 9) nodep->dumpTree("- Deslice-In: "); VL_RESTORER(m_assignError);
AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp(); VL_RESTORER(m_assignp);
AstNode* stp = nodep->rhsp(); m_assignError = false;
if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) { m_assignp = nodep;
if (!VN_IS(stp, CvtPackedToArray)) { AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp();
// Left and right could have different ascending/descending range, AstNode* stp = nodep->rhsp();
// but #elements is common and all variables are realigned to start at zero if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) {
// Assign of an ascending range slice to a descending range one must reverse if (!VN_IS(stp, CvtPackedToArray)) {
// the elements // Left and right could have different ascending/descending range,
AstNodeAssign* newlistp = nullptr; // but #elements is common and all variables are realigned to start at zero
const int elements = arrayp->rangep()->elementsConst(); // Assign of an ascending range slice to a descending range one must reverse
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { // the elements
AstNodeAssign* const newp AstNodeAssign* newlistp = nullptr;
= nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), const int elements = arrayp->rangep()->elementsConst();
cloneAndSel(nodep->rhsp(), elements, elemIdx)); for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
if (debug() >= 9) newp->dumpTree("- new: "); AstNodeAssign* const newp
newlistp = AstNode::addNext(newlistp, newp); = nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx),
} cloneAndSel(nodep->rhsp(), elements, elemIdx));
if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: "); if (debug() >= 9) newp->dumpTree("- new: ");
nodep->replaceWith(newlistp); newlistp = AstNode::addNext(newlistp, newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
// Normal edit iterator will now iterate on all of the expansion assignments
// This will potentially call this function again to resolve next level of
// slicing
return;
} }
if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: ");
nodep->replaceWith(newlistp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
// Normal edit iterator will now iterate on all of the expansion assignments
// This will potentially call this function again to resolve next level of
// slicing
return;
} }
VL_RESTORER(m_assignp);
m_assignp = nodep;
iterateChildren(nodep);
} }
iterateChildren(nodep);
} }
void visit(AstConsPackUOrStruct* nodep) override { void visit(AstConsPackUOrStruct* nodep) override {
@ -278,57 +277,55 @@ class SliceVisitor final : public VNVisitor {
} }
void expandBiOp(AstNodeBiop* nodep) { void expandBiOp(AstNodeBiop* nodep) {
if (!nodep->user1()) { if (nodep->user1SetOnce()) return; // Process once
nodep->user1(true); // If it's an unpacked array, blow it up into comparing each element
// If it's an unpacked array, blow it up into comparing each element AstNodeDType* const fromDtp = nodep->lhsp()->dtypep()->skipRefp();
AstNodeDType* const fromDtp = nodep->lhsp()->dtypep()->skipRefp(); UINFO(9, " Bi-Eq/Neq expansion " << nodep << endl);
UINFO(9, " Bi-Eq/Neq expansion " << nodep << endl); if (const AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
if (const AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType)) { AstNodeBiop* logp = nullptr;
AstNodeBiop* logp = nullptr; if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), NodeArrayDType)) {
if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), NodeArrayDType)) { nodep->lhsp()->v3error(
nodep->lhsp()->v3error( "Slice operator "
"Slice operator " << nodep->lhsp()->prettyTypeName()
<< nodep->lhsp()->prettyTypeName() << " on non-slicable (e.g. non-vector) left-hand-side operand");
<< " on non-slicable (e.g. non-vector) left-hand-side operand"); } else if (!VN_IS(nodep->rhsp()->dtypep()->skipRefp(), NodeArrayDType)) {
} else if (!VN_IS(nodep->rhsp()->dtypep()->skipRefp(), NodeArrayDType)) { nodep->rhsp()->v3error(
nodep->rhsp()->v3error( "Slice operator "
"Slice operator " << nodep->rhsp()->prettyTypeName()
<< nodep->rhsp()->prettyTypeName() << " on non-slicable (e.g. non-vector) right-hand-side operand");
<< " on non-slicable (e.g. non-vector) right-hand-side operand"); } else {
} else { const int elements = adtypep->rangep()->elementsConst();
const int elements = adtypep->rangep()->elementsConst(); for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { // EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1])
// EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1]) AstNodeBiop* const clonep
AstNodeBiop* const clonep = VN_AS( = VN_AS(nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx),
nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), cloneAndSel(nodep->rhsp(), elements, elemIdx)),
cloneAndSel(nodep->rhsp(), elements, elemIdx)), NodeBiop);
NodeBiop); if (!logp) {
if (!logp) { logp = clonep;
logp = clonep; } else {
} else { switch (nodep->type()) {
switch (nodep->type()) { case VNType::atEq: // FALLTHRU
case VNType::atEq: // FALLTHRU case VNType::atEqCase:
case VNType::atEqCase: logp = new AstLogAnd{nodep->fileline(), logp, clonep};
logp = new AstLogAnd{nodep->fileline(), logp, clonep}; break;
break; case VNType::atNeq: // FALLTHRU
case VNType::atNeq: // FALLTHRU case VNType::atNeqCase:
case VNType::atNeqCase: logp = new AstLogOr{nodep->fileline(), logp, clonep};
logp = new AstLogOr{nodep->fileline(), logp, clonep}; break;
break; default:
default: nodep->v3fatalSrc("Unknown node type processing array slice");
nodep->v3fatalSrc("Unknown node type processing array slice"); break;
break;
}
} }
} }
UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range");
nodep->replaceWith(logp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
nodep = logp;
} }
UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range");
nodep->replaceWith(logp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
nodep = logp;
} }
iterateChildren(nodep);
} }
iterateChildren(nodep);
} }
void visit(AstEq* nodep) override { expandBiOp(nodep); } void visit(AstEq* nodep) override { expandBiOp(nodep); }
void visit(AstNeq* nodep) override { expandBiOp(nodep); } void visit(AstNeq* nodep) override { expandBiOp(nodep); }