Fix queue element access (#5551)

This commit is contained in:
Ryszard Rozak
2024-10-24 09:40:54 -04:00
committed by GitHub
parent 4e5c7f4568
commit 4cd69f9feb
9 changed files with 126 additions and 26 deletions
+4
View File
@@ -4424,6 +4424,8 @@ class AstSelBit final : public AstNodePreSel {
// Single bit range extraction, perhaps with non-constant selection or array selection
// Gets replaced during link with AstArraySel or AstSel
// @astgen alias op2 := bitp
private:
VAccess m_access; // Left hand side assignment
public:
AstSelBit(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* bitp)
: ASTGEN_SUPER_SelBit(fl, fromp, bitp, nullptr) {
@@ -4431,6 +4433,8 @@ public:
"not coded to create after dtypes resolved");
}
ASTGEN_MEMBERS_AstSelBit;
VAccess access() const { return m_access; }
void access(const VAccess& flag) { m_access = flag; }
};
class AstSelExtract final : public AstNodePreSel {
// Range extraction, gets replaced with AstSel
+1
View File
@@ -311,6 +311,7 @@ class LinkLValueVisitor final : public VNVisitor {
}
}
void visit(AstNodePreSel* nodep) override {
if (AstSelBit* const selbitp = VN_CAST(nodep, SelBit)) selbitp->access(m_setRefLvalue);
VL_RESTORER(m_setRefLvalue);
{ // Only set lvalues on the from
iterateAndNextNull(nodep->fromp());
+4 -3
View File
@@ -493,10 +493,11 @@ class TaskVisitor final : public VNVisitor {
|| VN_IS(pinp, ArraySel)) {
refArgOk = true;
} else if (AstCMethodHard* const cMethodp = VN_CAST(pinp, CMethodHard)) {
refArgOk = cMethodp->name() == "at" || cMethodp->name() == "atBack";
if (VN_IS(cMethodp->fromp()->dtypep()->skipRefp(), QueueDType)) {
cMethodp->name(cMethodp->name() == "at" ? "atWriteAppend"
: "atWriteAppendBack");
refArgOk = cMethodp->name() == "atWriteAppend"
|| cMethodp->name() == "atWriteAppendBack";
} else {
refArgOk = cMethodp->name() == "at" || cMethodp->name() == "atBack";
}
}
if (refArgOk) {
+13 -3
View File
@@ -3520,9 +3520,19 @@ class WidthVisitor final : public VNVisitor {
return VN_AS(nodep->pinsp(), Arg)->exprp();
}
void methodCallLValueRecurse(AstMethodCall* nodep, AstNode* childp, const VAccess& access) {
if (const AstCMethodHard* const ichildp = VN_CAST(childp, CMethodHard)) {
if (ichildp->name() == "at" || ichildp->name() == "atWrite"
|| ichildp->name() == "atWriteAppend" || ichildp->name() == "atWriteAppendBack") {
if (AstCMethodHard* const ichildp = VN_CAST(childp, CMethodHard)) {
const std::string name = ichildp->name();
if (name == "at" || name == "atWrite" || name == "atBack" || name == "atWriteAppend"
|| name == "atWriteAppendBack") {
const AstNodeDType* const fromDtypep = ichildp->fromp()->dtypep()->skipRefp();
if (VN_IS(fromDtypep, QueueDType) || VN_IS(fromDtypep, DynArrayDType)) {
// Change access methods to writable ones
if (name == "at") {
ichildp->name("atWrite");
} else if (name == "atBack") {
ichildp->name("atWriteAppendBack");
}
}
methodCallLValueRecurse(nodep, ichildp->fromp(), access);
return;
}
+2 -20
View File
@@ -215,24 +215,6 @@ class WidthSelVisitor final : public VNVisitor {
}
}
static bool isPossibleWrite(AstNodeExpr* nodep) {
AstNode* abovep = nodep->firstAbovep();
if (AstNodeAssign* const assignp = VN_CAST(abovep, NodeAssign)) {
// On an assign LHS, assume a write
return assignp->lhsp() == nodep;
}
if (AstMethodCall* const methodCallp = VN_CAST(abovep, MethodCall)) {
// A method call can write
return methodCallp->fromp() == nodep;
}
if (AstNodePreSel* const preSelp = VN_CAST(abovep, NodePreSel)) {
// If we're not selected from, it's not a write (we're the index)
if (preSelp->fromp() != nodep) return false;
}
AstNodeExpr* exprp = VN_CAST(abovep, NodeExpr);
return exprp ? isPossibleWrite(exprp) : false;
}
// VISITORS
// If adding new visitors, ensure V3Width's visit(TYPE) calls into here
@@ -300,7 +282,7 @@ class WidthSelVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(nodep), nodep);
} else if (const AstDynArrayDType* const adtypep = VN_CAST(ddtypep, DynArrayDType)) {
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
const char* methodName = isPossibleWrite(nodep) ? "atWrite" : "at";
const char* methodName = nodep->access().isWriteOrRW() ? "atWrite" : "at";
AstCMethodHard* const newp
= new AstCMethodHard{nodep->fileline(), fromp, methodName, rhsp};
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
@@ -310,7 +292,7 @@ class WidthSelVisitor final : public VNVisitor {
} else if (const AstQueueDType* const adtypep = VN_CAST(ddtypep, QueueDType)) {
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
AstCMethodHard* newp;
const char* methodName = isPossibleWrite(nodep) ? "atWriteAppend" : "at";
const char* methodName = nodep->access().isWriteOrRW() ? "atWriteAppend" : "at";
if (AstNodeExpr* const backnessp = selQueueBackness(rhsp)) {
newp = new AstCMethodHard{nodep->fileline(), fromp,
std::string(methodName) + "Back", backnessp};