Internals: Fix invalid use of user1 in V3Const (#7157)
This commit is contained in:
parent
1e6c1ab106
commit
1716423d07
|
|
@ -3343,58 +3343,54 @@ class ConstVisitor final : public VNVisitor {
|
||||||
void visit(AstCvtArrayToArray* nodep) override {
|
void visit(AstCvtArrayToArray* nodep) override {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
// Handle the case where we have a stream operation inside a cast conversion
|
// Handle the case where we have a stream operation inside a cast conversion
|
||||||
// To avoid infinite recursion, mark the node as processed by setting user1.
|
// Check for both StreamL and StreamR operations
|
||||||
if (!nodep->user1()) {
|
AstNodeStream* streamp = nullptr;
|
||||||
nodep->user1(true);
|
bool isReverse = false;
|
||||||
// Check for both StreamL and StreamR operations
|
if (AstStreamL* const streamLp = VN_CAST(nodep->fromp(), StreamL)) {
|
||||||
AstNodeStream* streamp = nullptr;
|
streamp = streamLp;
|
||||||
bool isReverse = false;
|
isReverse = true; // StreamL reverses the operation
|
||||||
if (AstStreamL* const streamLp = VN_CAST(nodep->fromp(), StreamL)) {
|
} else if (AstStreamR* const streamRp = VN_CAST(nodep->fromp(), StreamR)) {
|
||||||
streamp = streamLp;
|
streamp = streamRp;
|
||||||
isReverse = true; // StreamL reverses the operation
|
isReverse = false; // StreamR doesn't reverse the operation
|
||||||
} else if (AstStreamR* const streamRp = VN_CAST(nodep->fromp(), StreamR)) {
|
}
|
||||||
streamp = streamRp;
|
if (streamp) {
|
||||||
isReverse = false; // StreamR doesn't reverse the operation
|
AstNodeExpr* srcp = streamp->lhsp();
|
||||||
}
|
const AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp();
|
||||||
if (streamp) {
|
AstNodeDType* const dstDTypep = nodep->dtypep()->skipRefp();
|
||||||
AstNodeExpr* srcp = streamp->lhsp();
|
if (VN_IS(srcDTypep, QueueDType) && VN_IS(dstDTypep, QueueDType)) {
|
||||||
const AstNodeDType* const srcDTypep = srcp->dtypep()->skipRefp();
|
int blockSize = 1;
|
||||||
AstNodeDType* const dstDTypep = nodep->dtypep()->skipRefp();
|
if (const AstConst* const constp = VN_CAST(streamp->rhsp(), Const)) {
|
||||||
if (VN_IS(srcDTypep, QueueDType) && VN_IS(dstDTypep, QueueDType)) {
|
blockSize = constp->toSInt();
|
||||||
int blockSize = 1;
|
if (VL_UNLIKELY(blockSize <= 0)) {
|
||||||
if (const AstConst* const constp = VN_CAST(streamp->rhsp(), Const)) {
|
// Not reachable due to higher level checks when parsing stream
|
||||||
blockSize = constp->toSInt();
|
// operators commented out to not fail v3error-coverage-checks.
|
||||||
if (VL_UNLIKELY(blockSize <= 0)) {
|
// nodep->v3error("Stream block size must be positive, got " <<
|
||||||
// Not reachable due to higher level checks when parsing stream
|
// blockSize);
|
||||||
// operators commented out to not fail v3error-coverage-checks.
|
blockSize = 1;
|
||||||
// nodep->v3error("Stream block size must be positive, got " <<
|
|
||||||
// blockSize);
|
|
||||||
blockSize = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Not reachable due to higher level checks when parsing stream operators
|
|
||||||
// commented out to not fail v3error-coverage-checks.
|
|
||||||
// else {
|
|
||||||
// nodep->v3error("Stream block size must be constant (got " <<
|
|
||||||
// streamp->rhsp()->prettyTypeName() << ")");
|
|
||||||
// }
|
|
||||||
int srcElementBits = 0;
|
|
||||||
if (const AstNodeDType* const elemDtp = srcDTypep->subDTypep()) {
|
|
||||||
srcElementBits = elemDtp->width();
|
|
||||||
}
|
|
||||||
int dstElementBits = 0;
|
|
||||||
if (const AstNodeDType* const elemDtp = dstDTypep->subDTypep()) {
|
|
||||||
dstElementBits = elemDtp->width();
|
|
||||||
}
|
|
||||||
streamp->unlinkFrBack();
|
|
||||||
AstNodeExpr* newp = new AstCvtArrayToArray{
|
|
||||||
srcp->fileline(), srcp->unlinkFrBack(), dstDTypep, isReverse,
|
|
||||||
blockSize, dstElementBits, srcElementBits};
|
|
||||||
nodep->replaceWith(newp);
|
|
||||||
VL_DO_DANGLING(pushDeletep(streamp), streamp);
|
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
// Not reachable due to higher level checks when parsing stream operators
|
||||||
|
// commented out to not fail v3error-coverage-checks.
|
||||||
|
// else {
|
||||||
|
// nodep->v3error("Stream block size must be constant (got " <<
|
||||||
|
// streamp->rhsp()->prettyTypeName() << ")");
|
||||||
|
// }
|
||||||
|
int srcElementBits = 0;
|
||||||
|
if (const AstNodeDType* const elemDtp = srcDTypep->subDTypep()) {
|
||||||
|
srcElementBits = elemDtp->width();
|
||||||
|
}
|
||||||
|
int dstElementBits = 0;
|
||||||
|
if (const AstNodeDType* const elemDtp = dstDTypep->subDTypep()) {
|
||||||
|
dstElementBits = elemDtp->width();
|
||||||
|
}
|
||||||
|
streamp->unlinkFrBack();
|
||||||
|
AstNodeExpr* newp = new AstCvtArrayToArray{
|
||||||
|
srcp->fileline(), srcp->unlinkFrBack(), dstDTypep, isReverse,
|
||||||
|
blockSize, dstElementBits, srcElementBits};
|
||||||
|
nodep->replaceWith(newp);
|
||||||
|
VL_DO_DANGLING(pushDeletep(streamp), streamp);
|
||||||
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue