Internals: Remove AstWhile::precondsp() (#6219). No functional change intended.
This commit is contained in:
parent
2958a5aaae
commit
763183f067
|
|
@ -3737,10 +3737,9 @@ public:
|
||||||
bool isTimingControl() const override { return true; }
|
bool isTimingControl() const override { return true; }
|
||||||
};
|
};
|
||||||
class AstWhile final : public AstNodeStmt {
|
class AstWhile final : public AstNodeStmt {
|
||||||
// @astgen op1 := precondsp : List[AstNode]
|
// @astgen op1 := condp : AstNodeExpr
|
||||||
// @astgen op2 := condp : AstNodeExpr
|
// @astgen op2 := stmtsp : List[AstNode]
|
||||||
// @astgen op3 := stmtsp : List[AstNode]
|
// @astgen op3 := incsp : List[AstNode]
|
||||||
// @astgen op4 := incsp : List[AstNode]
|
|
||||||
VOptionBool m_unrollFull; // Full, disable, or default unrolling
|
VOptionBool m_unrollFull; // Full, disable, or default unrolling
|
||||||
public:
|
public:
|
||||||
AstWhile(FileLine* fl, AstNodeExpr* condp, AstNode* stmtsp = nullptr, AstNode* incsp = nullptr)
|
AstWhile(FileLine* fl, AstNodeExpr* condp, AstNode* stmtsp = nullptr, AstNode* incsp = nullptr)
|
||||||
|
|
|
||||||
|
|
@ -1518,12 +1518,7 @@ void AstNodeStmt::addNextStmt(AstNode* newp, AstNode*) {
|
||||||
void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
|
void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
|
||||||
// Special, as statements need to be put in different places
|
// Special, as statements need to be put in different places
|
||||||
// Belowp is how we came to recurse up to this point
|
// Belowp is how we came to recurse up to this point
|
||||||
// Preconditions insert first just before themselves (the normal rule
|
if (belowp == condp()) {
|
||||||
// for other statement types)
|
|
||||||
if (belowp == precondsp()) {
|
|
||||||
// Next in precond list
|
|
||||||
belowp->addNextHere(newp);
|
|
||||||
} else if (belowp == condp()) {
|
|
||||||
// Becomes first statement in body, body may have been empty
|
// Becomes first statement in body, body may have been empty
|
||||||
if (stmtsp()) {
|
if (stmtsp()) {
|
||||||
stmtsp()->addHereThisAsNext(newp);
|
stmtsp()->addHereThisAsNext(newp);
|
||||||
|
|
|
||||||
|
|
@ -3352,14 +3352,10 @@ class ConstVisitor final : public VNVisitor {
|
||||||
if (m_doNConst) {
|
if (m_doNConst) {
|
||||||
if (nodep->condp()->isZero()) {
|
if (nodep->condp()->isZero()) {
|
||||||
UINFO(4, "WHILE(0) => nop " << nodep);
|
UINFO(4, "WHILE(0) => nop " << nodep);
|
||||||
if (nodep->precondsp()) {
|
nodep->v3warn(UNUSEDLOOP,
|
||||||
nodep->replaceWith(nodep->precondsp());
|
"Loop condition is always false; body will never execute");
|
||||||
} else {
|
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSEDLOOP, true);
|
||||||
nodep->v3warn(UNUSEDLOOP,
|
nodep->unlinkFrBack();
|
||||||
"Loop condition is always false; body will never execute");
|
|
||||||
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSEDLOOP, true);
|
|
||||||
nodep->unlinkFrBack();
|
|
||||||
}
|
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
} else if (nodep->condp()->isNeqZero()) {
|
} else if (nodep->condp()->isNeqZero()) {
|
||||||
if (!thisWhileHasJumpDelay) {
|
if (!thisWhileHasJumpDelay) {
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,6 @@ class CoverageVisitor final : public VNVisitor {
|
||||||
{
|
{
|
||||||
VL_RESTORER(m_inLoopNotBody);
|
VL_RESTORER(m_inLoopNotBody);
|
||||||
m_inLoopNotBody = true;
|
m_inLoopNotBody = true;
|
||||||
iterateAndNextNull(nodep->precondsp());
|
|
||||||
iterateNull(nodep->condp());
|
iterateNull(nodep->condp());
|
||||||
iterateAndNextNull(nodep->incsp());
|
iterateAndNextNull(nodep->incsp());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1014,13 +1014,11 @@ public:
|
||||||
}
|
}
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
VL_RESTORER(m_createdScopeHash);
|
VL_RESTORER(m_createdScopeHash);
|
||||||
iterateAndNextConstNull(nodep->precondsp());
|
|
||||||
putns(nodep, "while (");
|
putns(nodep, "while (");
|
||||||
iterateAndNextConstNull(nodep->condp());
|
iterateAndNextConstNull(nodep->condp());
|
||||||
puts(") {\n");
|
puts(") {\n");
|
||||||
iterateAndNextConstNull(nodep->stmtsp());
|
iterateAndNextConstNull(nodep->stmtsp());
|
||||||
iterateAndNextConstNull(nodep->incsp());
|
iterateAndNextConstNull(nodep->incsp());
|
||||||
iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop
|
|
||||||
puts("}\n");
|
puts("}\n");
|
||||||
}
|
}
|
||||||
void visit(AstNodeIf* nodep) override {
|
void visit(AstNodeIf* nodep) override {
|
||||||
|
|
|
||||||
|
|
@ -365,13 +365,11 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
putfs(nodep, "end\n");
|
putfs(nodep, "end\n");
|
||||||
}
|
}
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
iterateAndNextConstNull(nodep->precondsp());
|
|
||||||
putfs(nodep, "while (");
|
putfs(nodep, "while (");
|
||||||
iterateAndNextConstNull(nodep->condp());
|
iterateAndNextConstNull(nodep->condp());
|
||||||
puts(") begin\n");
|
puts(") begin\n");
|
||||||
iterateAndNextConstNull(nodep->stmtsp());
|
iterateAndNextConstNull(nodep->stmtsp());
|
||||||
iterateAndNextConstNull(nodep->incsp());
|
iterateAndNextConstNull(nodep->incsp());
|
||||||
iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop
|
|
||||||
putfs(nodep, "end\n");
|
putfs(nodep, "end\n");
|
||||||
}
|
}
|
||||||
void visit(AstNodeIf* nodep) override {
|
void visit(AstNodeIf* nodep) override {
|
||||||
|
|
|
||||||
|
|
@ -129,9 +129,6 @@ class EmitXmlFileVisitor final : public VNVisitorConst {
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
outputTag(nodep, "while");
|
outputTag(nodep, "while");
|
||||||
puts(">\n");
|
puts(">\n");
|
||||||
puts("<begin>\n");
|
|
||||||
iterateAndNextConstNull(nodep->precondsp());
|
|
||||||
puts("</begin>\n");
|
|
||||||
if (nodep->condp()) {
|
if (nodep->condp()) {
|
||||||
puts("<begin>\n");
|
puts("<begin>\n");
|
||||||
iterateAndNextConstNull(nodep->condp());
|
iterateAndNextConstNull(nodep->condp());
|
||||||
|
|
|
||||||
|
|
@ -401,7 +401,6 @@ class LifeVisitor final : public VNVisitor {
|
||||||
LifeBlock* const bodyLifep = new LifeBlock{prevLifep, m_statep};
|
LifeBlock* const bodyLifep = new LifeBlock{prevLifep, m_statep};
|
||||||
{
|
{
|
||||||
m_lifep = condLifep;
|
m_lifep = condLifep;
|
||||||
iterateAndNextNull(nodep->precondsp());
|
|
||||||
iterateAndNextNull(nodep->condp());
|
iterateAndNextNull(nodep->condp());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -54,18 +54,11 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
class LinkIncVisitor final : public VNVisitor {
|
class LinkIncVisitor final : public VNVisitor {
|
||||||
// TYPES
|
|
||||||
enum InsertMode : uint8_t {
|
|
||||||
IM_BEFORE, // Pointing at statement ref is in, insert before this
|
|
||||||
IM_AFTER, // Pointing at last inserted stmt, insert after
|
|
||||||
IM_WHILE_PRECOND // Pointing to for loop, add to body end
|
|
||||||
};
|
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside
|
AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside
|
||||||
AstNodeModule* m_modp = nullptr; // Module we're inside
|
AstNodeModule* m_modp = nullptr; // Module we're inside
|
||||||
int m_modIncrementsNum = 0; // Var name counter
|
int m_modIncrementsNum = 0; // Var name counter
|
||||||
InsertMode m_insMode = IM_BEFORE; // How to insert
|
AstWhile* m_inWhileCondp = nullptr; // Inside condition of this while loop
|
||||||
AstNode* m_insStmtp = nullptr; // Where to insert statement
|
AstNode* m_insStmtp = nullptr; // Where to insert statement
|
||||||
bool m_unsupportedHere = false; // Used to detect where it's not supported yet
|
bool m_unsupportedHere = false; // Used to detect where it's not supported yet
|
||||||
|
|
||||||
|
|
@ -86,23 +79,14 @@ class LinkIncVisitor final : public VNVisitor {
|
||||||
m_modp->addStmtsp(newp);
|
m_modp->addStmtsp(newp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void insertNextToStmt(AstNode* nodep, AstNode* newp) {
|
void insertBeforeStmt(AstNode* nodep, AstNode* newp) {
|
||||||
// Return node that must be visited, if any
|
// Return node that must be visited, if any
|
||||||
if (debug() >= 9) newp->dumpTree("- newstmt: ");
|
if (debug() >= 9) newp->dumpTree("- newstmt: ");
|
||||||
UASSERT_OBJ(m_insStmtp, nodep, "Function not underneath a statement");
|
UASSERT_OBJ(m_insStmtp, nodep, "Expression not underneath a statement");
|
||||||
if (m_insMode == IM_BEFORE) {
|
// In a while condition, the statement also needs to go on the
|
||||||
// Add the whole thing before insertAt
|
// back-edge to the loop header, 'incsp' is that place.
|
||||||
if (debug() >= 9) newp->dumpTree("- newfunc: ");
|
if (m_inWhileCondp) m_inWhileCondp->addIncsp(newp->cloneTreePure(true));
|
||||||
m_insStmtp->addHereThisAsNext(newp);
|
m_insStmtp->addHereThisAsNext(newp);
|
||||||
} else if (m_insMode == IM_AFTER) {
|
|
||||||
m_insStmtp->addNextHere(newp);
|
|
||||||
} else if (m_insMode == IM_WHILE_PRECOND) {
|
|
||||||
AstWhile* const whilep = VN_AS(m_insStmtp, While);
|
|
||||||
UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE");
|
|
||||||
whilep->addPrecondsp(newp);
|
|
||||||
} else {
|
|
||||||
nodep->v3fatalSrc("Unknown InsertMode");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
|
|
@ -120,14 +104,13 @@ class LinkIncVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
// Special, as statements need to be put in different places
|
// Special, as statements need to be put in different places
|
||||||
// Preconditions insert first just before themselves (the normal
|
|
||||||
// rule for other statement types)
|
|
||||||
m_insStmtp = nullptr; // First thing should be new statement
|
|
||||||
iterateAndNextNull(nodep->precondsp());
|
|
||||||
// Conditions insert first at end of precondsp.
|
|
||||||
m_insMode = IM_WHILE_PRECOND;
|
|
||||||
m_insStmtp = nodep;
|
m_insStmtp = nodep;
|
||||||
iterateAndNextNull(nodep->condp());
|
{
|
||||||
|
// Conditions insert before the loop and into incsp
|
||||||
|
VL_RESTORER(m_inWhileCondp);
|
||||||
|
m_inWhileCondp = nodep;
|
||||||
|
iterateAndNextNull(nodep->condp());
|
||||||
|
}
|
||||||
// Body insert just before themselves
|
// Body insert just before themselves
|
||||||
m_insStmtp = nullptr; // First thing should be new statement
|
m_insStmtp = nullptr; // First thing should be new statement
|
||||||
iterateAndNextNull(nodep->stmtsp());
|
iterateAndNextNull(nodep->stmtsp());
|
||||||
|
|
@ -160,7 +143,6 @@ class LinkIncVisitor final : public VNVisitor {
|
||||||
m_insStmtp = nullptr;
|
m_insStmtp = nullptr;
|
||||||
}
|
}
|
||||||
void visit(AstCaseItem* nodep) override {
|
void visit(AstCaseItem* nodep) override {
|
||||||
m_insMode = IM_BEFORE;
|
|
||||||
{
|
{
|
||||||
VL_RESTORER(m_unsupportedHere);
|
VL_RESTORER(m_unsupportedHere);
|
||||||
m_unsupportedHere = true;
|
m_unsupportedHere = true;
|
||||||
|
|
@ -193,7 +175,6 @@ class LinkIncVisitor final : public VNVisitor {
|
||||||
m_insStmtp = nullptr;
|
m_insStmtp = nullptr;
|
||||||
}
|
}
|
||||||
void visit(AstNodeStmt* nodep) override {
|
void visit(AstNodeStmt* nodep) override {
|
||||||
m_insMode = IM_BEFORE;
|
|
||||||
m_insStmtp = nodep;
|
m_insStmtp = nodep;
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
m_insStmtp = nullptr; // Next thing should be new statement
|
m_insStmtp = nullptr; // Next thing should be new statement
|
||||||
|
|
@ -332,18 +313,17 @@ class LinkIncVisitor final : public VNVisitor {
|
||||||
// Immediately after declaration - increment it by one
|
// Immediately after declaration - increment it by one
|
||||||
AstAssign* const assignp
|
AstAssign* const assignp
|
||||||
= new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp};
|
= new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp};
|
||||||
insertNextToStmt(nodep, assignp);
|
|
||||||
// Immediately after incrementing - assign it to the original variable
|
// Immediately after incrementing - assign it to the original variable
|
||||||
assignp->addNextHere(
|
assignp->addNext(new AstAssign{fl, writep, new AstVarRef{fl, varp, VAccess::READ}});
|
||||||
new AstAssign{fl, writep, new AstVarRef{fl, varp, VAccess::READ}});
|
insertBeforeStmt(nodep, assignp);
|
||||||
} else {
|
} else {
|
||||||
// PostAdd/PostSub operations
|
// PostAdd/PostSub operations
|
||||||
// Assign the original variable to the temporary one
|
// Assign the original variable to the temporary one
|
||||||
AstAssign* const assignp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
AstAssign* const assignp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||||
readp->cloneTreePure(true)};
|
readp->cloneTreePure(true)};
|
||||||
insertNextToStmt(nodep, assignp);
|
|
||||||
// Increment the original variable by one
|
// Increment the original variable by one
|
||||||
assignp->addNextHere(new AstAssign{fl, writep, operp});
|
assignp->addNext(new AstAssign{fl, writep, operp});
|
||||||
|
insertBeforeStmt(nodep, assignp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the node with the temporary
|
// Replace the node with the temporary
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,6 @@ class LinkJumpVisitor final : public VNVisitor {
|
||||||
VL_RESTORER(m_loopInc);
|
VL_RESTORER(m_loopInc);
|
||||||
m_loopp = nodep;
|
m_loopp = nodep;
|
||||||
m_loopInc = false;
|
m_loopInc = false;
|
||||||
iterateAndNextNull(nodep->precondsp());
|
|
||||||
iterateAndNextNull(nodep->condp());
|
iterateAndNextNull(nodep->condp());
|
||||||
iterateAndNextNull(nodep->stmtsp());
|
iterateAndNextNull(nodep->stmtsp());
|
||||||
m_loopInc = true;
|
m_loopInc = true;
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ class PremitVisitor final : public VNVisitor {
|
||||||
&& !constp->num().isString(); // Not a string
|
&& !constp->num().isString(); // Not a string
|
||||||
|
|
||||||
AstVar* varp = nullptr;
|
AstVar* varp = nullptr;
|
||||||
AstAssign* assignp = nullptr;
|
|
||||||
|
|
||||||
if (useConstPool) {
|
if (useConstPool) {
|
||||||
// Extract into constant pool.
|
// Extract into constant pool.
|
||||||
|
|
@ -96,24 +95,20 @@ class PremitVisitor final : public VNVisitor {
|
||||||
m_cfuncp->addInitsp(varp);
|
m_cfuncp->addInitsp(varp);
|
||||||
++m_temporaryVarsCreated;
|
++m_temporaryVarsCreated;
|
||||||
|
|
||||||
// Put assignment before the referencing statement
|
// Assignment to put before the referencing statement
|
||||||
assignp = new AstAssign{flp, new AstVarRef{flp, varp, VAccess::WRITE}, nodep};
|
AstAssign* const assignp
|
||||||
if (m_inWhileCondp) {
|
= new AstAssign{flp, new AstVarRef{flp, varp, VAccess::WRITE}, nodep};
|
||||||
// Statements that are needed for the 'condition' in a while
|
// Insert before the statement
|
||||||
// actually have to be put before & after the loop, since we
|
m_stmtp->addHereThisAsNext(assignp);
|
||||||
// can't do any statements in a while's (cond).
|
// Statements that are needed for the 'condition' in a while also
|
||||||
m_inWhileCondp->addPrecondsp(assignp);
|
// need to be inserted on the back-edge to the loop header.
|
||||||
} else {
|
// 'incsp' is just right palce to do this
|
||||||
m_stmtp->addHereThisAsNext(assignp);
|
if (m_inWhileCondp) m_inWhileCondp->addIncsp(assignp->cloneTree(false));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace node with VarRef to new Var
|
// Replace node with VarRef to new Var
|
||||||
relinker.relink(new AstVarRef{flp, varp, VAccess::READ});
|
relinker.relink(new AstVarRef{flp, varp, VAccess::READ});
|
||||||
|
|
||||||
// Handle wide expressions inside the expression recursively
|
|
||||||
if (assignp) iterate(assignp);
|
|
||||||
|
|
||||||
// Return the temporary variable
|
// Return the temporary variable
|
||||||
return varp;
|
return varp;
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +181,6 @@ class PremitVisitor final : public VNVisitor {
|
||||||
UINFO(4, " WHILE " << nodep);
|
UINFO(4, " WHILE " << nodep);
|
||||||
// cppcheck-suppress shadowVariable // Also restored below
|
// cppcheck-suppress shadowVariable // Also restored below
|
||||||
START_STATEMENT_OR_RETURN(nodep);
|
START_STATEMENT_OR_RETURN(nodep);
|
||||||
iterateAndNextNull(nodep->precondsp());
|
|
||||||
{
|
{
|
||||||
// cppcheck-suppress shadowVariable // Also restored above
|
// cppcheck-suppress shadowVariable // Also restored above
|
||||||
VL_RESTORER(m_inWhileCondp);
|
VL_RESTORER(m_inWhileCondp);
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,6 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
unsupportedWriteToVirtIface(nodep->precondsp(), "loop condition");
|
|
||||||
unsupportedWriteToVirtIface(nodep->condp(), "loop condition");
|
unsupportedWriteToVirtIface(nodep->condp(), "loop condition");
|
||||||
unsupportedWriteToVirtIface(nodep->incsp(), "loop increment statement");
|
unsupportedWriteToVirtIface(nodep->incsp(), "loop increment statement");
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1043,8 +1043,6 @@ private:
|
||||||
int loops = 0;
|
int loops = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
UINFO(5, " WHILE-ITER " << nodep);
|
UINFO(5, " WHILE-ITER " << nodep);
|
||||||
iterateAndNextConstNull(nodep->precondsp());
|
|
||||||
if (jumpingOver(nodep)) break;
|
|
||||||
iterateAndNextConstNull(nodep->condp());
|
iterateAndNextConstNull(nodep->condp());
|
||||||
if (jumpingOver(nodep)) break;
|
if (jumpingOver(nodep)) break;
|
||||||
if (!optimizable()) break;
|
if (!optimizable()) break;
|
||||||
|
|
|
||||||
|
|
@ -1588,11 +1588,8 @@ class TaskVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
// Special, as statements need to be put in different places
|
// Special, as statements need to be put in different places
|
||||||
// Preconditions insert first just before themselves (the normal
|
|
||||||
// rule for other statement types)
|
|
||||||
m_insStmtp = nullptr; // First thing should be new statement
|
|
||||||
iterateAndNextNull(nodep->precondsp());
|
|
||||||
// Conditions insert first at end of precondsp.
|
// Conditions insert first at end of precondsp.
|
||||||
|
// TODO: is this right? This is how it used to be.
|
||||||
m_insStmtp = nodep;
|
m_insStmtp = nodep;
|
||||||
iterateAndNextNull(nodep->condp());
|
iterateAndNextNull(nodep->condp());
|
||||||
// Body insert just before themselves
|
// Body insert just before themselves
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,12 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
AstNode* const nodep,
|
AstNode* const nodep,
|
||||||
const VOptionBool& unrollFull, // Pragma unroll_full, unroll_disable
|
const VOptionBool& unrollFull, // Pragma unroll_full, unroll_disable
|
||||||
AstNode* const initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
|
AstNode* const initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
|
||||||
AstNode* const precondsp, AstNode* condp,
|
AstNode* condp,
|
||||||
AstNode* const incp, // Maybe under nodep or in bodysp
|
AstNode* const incp, // Maybe under nodep or in bodysp
|
||||||
AstNode* bodysp) {
|
AstNode* bodysp) {
|
||||||
// To keep the IF levels low, we return as each test fails.
|
// To keep the IF levels low, we return as each test fails.
|
||||||
UINFO(4, " FOR Check " << nodep);
|
UINFO(4, " FOR Check " << nodep);
|
||||||
if (initp) UINFO(6, " Init " << initp);
|
if (initp) UINFO(6, " Init " << initp);
|
||||||
if (precondsp) UINFO(6, " Pcon " << precondsp);
|
|
||||||
if (condp) UINFO(6, " Cond " << condp);
|
if (condp) UINFO(6, " Cond " << condp);
|
||||||
if (incp) UINFO(6, " Inc " << incp);
|
if (incp) UINFO(6, " Inc " << incp);
|
||||||
|
|
||||||
|
|
@ -136,7 +135,6 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
m_varAssignHit = false;
|
m_varAssignHit = false;
|
||||||
m_forkHit = false;
|
m_forkHit = false;
|
||||||
m_ignoreIncp = incp;
|
m_ignoreIncp = incp;
|
||||||
iterateAndNextNull(precondsp);
|
|
||||||
iterateAndNextNull(bodysp);
|
iterateAndNextNull(bodysp);
|
||||||
iterateAndNextNull(incp);
|
iterateAndNextNull(incp);
|
||||||
m_varModeCheck = false;
|
m_varModeCheck = false;
|
||||||
|
|
@ -172,15 +170,14 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
int bodySize = 0;
|
int bodySize = 0;
|
||||||
int bodyLimit = v3Global.opt.unrollStmts();
|
int bodyLimit = v3Global.opt.unrollStmts();
|
||||||
if (loops > 0) bodyLimit = v3Global.opt.unrollStmts() / loops;
|
if (loops > 0) bodyLimit = v3Global.opt.unrollStmts() / loops;
|
||||||
if (bodySizeOverRecurse(precondsp, bodySize /*ref*/, bodyLimit)
|
if (bodySizeOverRecurse(bodysp, bodySize /*ref*/, bodyLimit)
|
||||||
|| bodySizeOverRecurse(bodysp, bodySize /*ref*/, bodyLimit)
|
|
||||||
|| bodySizeOverRecurse(incp, bodySize /*ref*/, bodyLimit)) {
|
|| bodySizeOverRecurse(incp, bodySize /*ref*/, bodyLimit)) {
|
||||||
return cantUnroll(nodep, "too many statements");
|
return cantUnroll(nodep, "too many statements");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finally, we can do it
|
// Finally, we can do it
|
||||||
if (!forUnroller(nodep, unrollFull, initAssp, condp, precondsp, incp, bodysp)) {
|
if (!forUnroller(nodep, unrollFull, initAssp, condp, incp, bodysp)) {
|
||||||
return cantUnroll(nodep, "Unable to unroll loop");
|
return cantUnroll(nodep, "Unable to unroll loop");
|
||||||
}
|
}
|
||||||
VL_DANGLING(nodep);
|
VL_DANGLING(nodep);
|
||||||
|
|
@ -268,7 +265,7 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forUnroller(AstNode* nodep, const VOptionBool& unrollFull, AstAssign* initp,
|
bool forUnroller(AstNode* nodep, const VOptionBool& unrollFull, AstAssign* initp,
|
||||||
AstNode* condp, AstNode* precondsp, AstNode* incp, AstNode* bodysp) {
|
AstNode* condp, AstNode* incp, AstNode* bodysp) {
|
||||||
UINFO(9, "forUnroller " << nodep);
|
UINFO(9, "forUnroller " << nodep);
|
||||||
V3Number loopValue{nodep};
|
V3Number loopValue{nodep};
|
||||||
if (!simulateTree(initp->rhsp(), nullptr, initp, loopValue)) { //
|
if (!simulateTree(initp->rhsp(), nullptr, initp, loopValue)) { //
|
||||||
|
|
@ -280,10 +277,6 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
// Don't add to list, we do it once, and setting loop index isn't
|
// Don't add to list, we do it once, and setting loop index isn't
|
||||||
// needed if we have > 1 loop, as we're constant propagating it
|
// needed if we have > 1 loop, as we're constant propagating it
|
||||||
}
|
}
|
||||||
if (precondsp) {
|
|
||||||
precondsp->unlinkFrBackWithNext();
|
|
||||||
stmtsp = AstNode::addNext(stmtsp, precondsp);
|
|
||||||
}
|
|
||||||
if (bodysp) {
|
if (bodysp) {
|
||||||
bodysp->unlinkFrBackWithNext();
|
bodysp->unlinkFrBackWithNext();
|
||||||
stmtsp = AstNode::addNext(stmtsp, bodysp); // Maybe null if no body
|
stmtsp = AstNode::addNext(stmtsp, bodysp); // Maybe null if no body
|
||||||
|
|
@ -374,7 +367,6 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
nodep->unlinkFrBack();
|
nodep->unlinkFrBack();
|
||||||
}
|
}
|
||||||
if (bodysp) VL_DO_DANGLING(pushDeletep(bodysp), bodysp);
|
if (bodysp) VL_DO_DANGLING(pushDeletep(bodysp), bodysp);
|
||||||
if (precondsp) VL_DO_DANGLING(pushDeletep(precondsp), precondsp);
|
|
||||||
if (initp) VL_DO_DANGLING(pushDeletep(initp), initp);
|
if (initp) VL_DO_DANGLING(pushDeletep(initp), initp);
|
||||||
if (incp && !incp->backp()) VL_DO_DANGLING(pushDeletep(incp), incp);
|
if (incp && !incp->backp()) VL_DO_DANGLING(pushDeletep(incp), incp);
|
||||||
if (debug() >= 9 && newbodysp) newbodysp->dumpTree("- _new: ");
|
if (debug() >= 9 && newbodysp) newbodysp->dumpTree("- _new: ");
|
||||||
|
|
@ -386,9 +378,6 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
if (m_varModeCheck || m_varModeReplace) {
|
if (m_varModeCheck || m_varModeReplace) {
|
||||||
} else {
|
} else {
|
||||||
// Constify before unroll call, as it may change what is underneath.
|
// Constify before unroll call, as it may change what is underneath.
|
||||||
if (nodep->precondsp()) {
|
|
||||||
V3Const::constifyEdit(nodep->precondsp()); // precondsp may change
|
|
||||||
}
|
|
||||||
if (nodep->condp()) V3Const::constifyEdit(nodep->condp()); // condp may change
|
if (nodep->condp()) V3Const::constifyEdit(nodep->condp()); // condp may change
|
||||||
// Grab initial value
|
// Grab initial value
|
||||||
AstNode* initp = nullptr; // Should be statement before the while.
|
AstNode* initp = nullptr; // Should be statement before the while.
|
||||||
|
|
@ -411,8 +400,7 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
if (incp == stmtsp) stmtsp = nullptr;
|
if (incp == stmtsp) stmtsp = nullptr;
|
||||||
}
|
}
|
||||||
// And check it
|
// And check it
|
||||||
if (forUnrollCheck(nodep, nodep->unrollFull(), initp, nodep->precondsp(),
|
if (forUnrollCheck(nodep, nodep->unrollFull(), initp, nodep->condp(), incp, stmtsp)) {
|
||||||
nodep->condp(), incp, stmtsp)) {
|
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
|
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -436,8 +424,8 @@ class UnrollVisitor final : public VNVisitor {
|
||||||
// condition, but they'll become while's which can be
|
// condition, but they'll become while's which can be
|
||||||
// deleted by V3Const.
|
// deleted by V3Const.
|
||||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||||
} else if (forUnrollCheck(nodep, VOptionBool{}, nodep->initsp(), nullptr,
|
} else if (forUnrollCheck(nodep, VOptionBool{}, nodep->initsp(), nodep->condp(),
|
||||||
nodep->condp(), nodep->incsp(), nodep->stmtsp())) {
|
nodep->incsp(), nodep->stmtsp())) {
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
|
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error("For loop doesn't have genvar index, or is malformed");
|
nodep->v3error("For loop doesn't have genvar index, or is malformed");
|
||||||
|
|
|
||||||
|
|
@ -5189,7 +5189,6 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
void visit(AstWhile* nodep) override {
|
void visit(AstWhile* nodep) override {
|
||||||
assertAtStatement(nodep);
|
assertAtStatement(nodep);
|
||||||
userIterateAndNext(nodep->precondsp(), nullptr);
|
|
||||||
iterateCheckBool(nodep, "For Test Condition", nodep->condp(),
|
iterateCheckBool(nodep, "For Test Condition", nodep->condp(),
|
||||||
BOTH); // it's like an if() condition.
|
BOTH); // it's like an if() condition.
|
||||||
userIterateAndNext(nodep->stmtsp(), nullptr);
|
userIterateAndNext(nodep->stmtsp(), nullptr);
|
||||||
|
|
|
||||||
|
|
@ -3061,7 +3061,6 @@ genvar_iteration<nodep>: // ==IEEE: genvar_iteration
|
||||||
| varRefBase yP_SSRIGHTEQ expr
|
| varRefBase yP_SSRIGHTEQ expr
|
||||||
{ $$ = new AstAssign{$2, $1, new AstShiftRS{$2, $1->cloneTreePure(true), $3}}; }
|
{ $$ = new AstAssign{$2, $1, new AstShiftRS{$2, $1->cloneTreePure(true), $3}}; }
|
||||||
// // inc_or_dec_operator
|
// // inc_or_dec_operator
|
||||||
// When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstNodeExprStmt?
|
|
||||||
| yP_PLUSPLUS varRefBase
|
| yP_PLUSPLUS varRefBase
|
||||||
{ $$ = new AstAssign{$1, $2, new AstAdd{$1, $2->cloneTreePure(true),
|
{ $$ = new AstAssign{$1, $2, new AstAdd{$1, $2->cloneTreePure(true),
|
||||||
new AstConst{$1, AstConst::StringToParse{}, "'b1"}}}; }
|
new AstConst{$1, AstConst::StringToParse{}, "'b1"}}}; }
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,4 @@
|
||||||
%Error-UNSUPPORTED: t/t_interface_virtual_unsup.v:24:66: Unsupported: write to virtual interface in loop increment statement
|
%Error-UNSUPPORTED: t/t_interface_virtual_unsup.v:24:66: Unsupported: write to virtual interface in loop increment statement
|
||||||
24 | for (int i = 0; write_data(vif.data); i += int'(write_data(vif.data)));
|
24 | for (int i = 0; write_data(vif.data); i += int'(write_data(vif.data)));
|
||||||
| ^~~
|
| ^~~
|
||||||
%Error-UNSUPPORTED: t/t_interface_virtual_unsup.v:25:34: Unsupported: write to virtual interface in loop condition
|
|
||||||
25 | for (int i = 0; write_data(vif.data++); i++);
|
|
||||||
| ^~~
|
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -879,7 +879,7 @@
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
{"type":"VARREF","name":"t.unnamedblk1.e","addr":"(LN)","loc":"d,52:17,52:18","dtypep":"(AC)","access":"WR","varp":"(UB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"t.unnamedblk1.e","addr":"(LN)","loc":"d,52:17,52:18","dtypep":"(AC)","access":"WR","varp":"(UB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||||
],"timingControlp": []},
|
],"timingControlp": []},
|
||||||
{"type":"WHILE","name":"","addr":"(MN)","loc":"d,52:7,52:10","precondsp": [],
|
{"type":"WHILE","name":"","addr":"(MN)","loc":"d,52:7,52:10",
|
||||||
"condp": [
|
"condp": [
|
||||||
{"type":"NEQ","name":"","addr":"(NN)","loc":"d,52:32,52:34","dtypep":"(FB)",
|
{"type":"NEQ","name":"","addr":"(NN)","loc":"d,52:32,52:34","dtypep":"(FB)",
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
|
|
@ -2635,7 +2635,7 @@
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
{"type":"VARREF","name":"__VnbaContinue","addr":"(JMB)","loc":"d,11:8,11:9","dtypep":"(FB)","access":"WR","varp":"(DMB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"__VnbaContinue","addr":"(JMB)","loc":"d,11:8,11:9","dtypep":"(FB)","access":"WR","varp":"(DMB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||||
],"timingControlp": []},
|
],"timingControlp": []},
|
||||||
{"type":"WHILE","name":"","addr":"(KMB)","loc":"a,0:0,0:0","precondsp": [],
|
{"type":"WHILE","name":"","addr":"(KMB)","loc":"a,0:0,0:0",
|
||||||
"condp": [
|
"condp": [
|
||||||
{"type":"VARREF","name":"__VnbaContinue","addr":"(LMB)","loc":"a,0:0,0:0","dtypep":"(FB)","access":"RD","varp":"(DMB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"__VnbaContinue","addr":"(LMB)","loc":"a,0:0,0:0","dtypep":"(FB)","access":"RD","varp":"(DMB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||||
],
|
],
|
||||||
|
|
@ -2700,7 +2700,7 @@
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
{"type":"VARREF","name":"__VactContinue","addr":"(LNB)","loc":"d,11:8,11:9","dtypep":"(FB)","access":"WR","varp":"(O)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"__VactContinue","addr":"(LNB)","loc":"d,11:8,11:9","dtypep":"(FB)","access":"WR","varp":"(O)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||||
],"timingControlp": []},
|
],"timingControlp": []},
|
||||||
{"type":"WHILE","name":"","addr":"(MNB)","loc":"a,0:0,0:0","precondsp": [],
|
{"type":"WHILE","name":"","addr":"(MNB)","loc":"a,0:0,0:0",
|
||||||
"condp": [
|
"condp": [
|
||||||
{"type":"VARREF","name":"__VactContinue","addr":"(NNB)","loc":"a,0:0,0:0","dtypep":"(FB)","access":"RD","varp":"(O)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"__VactContinue","addr":"(NNB)","loc":"a,0:0,0:0","dtypep":"(FB)","access":"RD","varp":"(O)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(OC)","loc":"d,18:10,18:11","dtypep":"(GB)","access":"WR","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(OC)","loc":"d,18:10,18:11","dtypep":"(GB)","access":"WR","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
|
||||||
],"timingControlp": []},
|
],"timingControlp": []},
|
||||||
{"type":"WHILE","name":"","addr":"(PC)","loc":"d,18:5,18:8","precondsp": [],
|
{"type":"WHILE","name":"","addr":"(PC)","loc":"d,18:5,18:8",
|
||||||
"condp": [
|
"condp": [
|
||||||
{"type":"GTS","name":"","addr":"(QC)","loc":"d,18:18,18:19","dtypep":"(RC)",
|
{"type":"GTS","name":"","addr":"(QC)","loc":"d,18:18,18:19","dtypep":"(RC)",
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(JE)","loc":"d,18:10,18:11","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
|
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(JE)","loc":"d,18:10,18:11","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
|
||||||
],"timingControlp": []},
|
],"timingControlp": []},
|
||||||
{"type":"WHILE","name":"","addr":"(KE)","loc":"d,18:5,18:8","precondsp": [],
|
{"type":"WHILE","name":"","addr":"(KE)","loc":"d,18:5,18:8",
|
||||||
"condp": [
|
"condp": [
|
||||||
{"type":"GTS","name":"","addr":"(LE)","loc":"d,18:18,18:19","dtypep":"(RC)",
|
{"type":"GTS","name":"","addr":"(LE)","loc":"d,18:18,18:19","dtypep":"(RC)",
|
||||||
"lhsp": [
|
"lhsp": [
|
||||||
|
|
|
||||||
|
|
@ -529,8 +529,6 @@
|
||||||
<varref loc="d,52,17,52,18" name="t.unnamedblk1.e" dtype_id="11"/>
|
<varref loc="d,52,17,52,18" name="t.unnamedblk1.e" dtype_id="11"/>
|
||||||
</assign>
|
</assign>
|
||||||
<while loc="d,52,7,52,10">
|
<while loc="d,52,7,52,10">
|
||||||
<begin>
|
|
||||||
</begin>
|
|
||||||
<begin>
|
<begin>
|
||||||
<neq loc="d,52,32,52,34" dtype_id="8">
|
<neq loc="d,52,32,52,34" dtype_id="8">
|
||||||
<const loc="d,52,37,52,41" name="4'h4" dtype_id="11"/>
|
<const loc="d,52,37,52,41" name="4'h4" dtype_id="11"/>
|
||||||
|
|
@ -1595,8 +1593,6 @@
|
||||||
<varref loc="d,11,8,11,9" name="__VnbaContinue" dtype_id="8"/>
|
<varref loc="d,11,8,11,9" name="__VnbaContinue" dtype_id="8"/>
|
||||||
</assign>
|
</assign>
|
||||||
<while loc="a,0,0,0,0">
|
<while loc="a,0,0,0,0">
|
||||||
<begin>
|
|
||||||
</begin>
|
|
||||||
<begin>
|
<begin>
|
||||||
<varref loc="a,0,0,0,0" name="__VnbaContinue" dtype_id="8"/>
|
<varref loc="a,0,0,0,0" name="__VnbaContinue" dtype_id="8"/>
|
||||||
</begin>
|
</begin>
|
||||||
|
|
@ -1640,8 +1636,6 @@
|
||||||
<varref loc="d,11,8,11,9" name="__VactContinue" dtype_id="8"/>
|
<varref loc="d,11,8,11,9" name="__VactContinue" dtype_id="8"/>
|
||||||
</assign>
|
</assign>
|
||||||
<while loc="a,0,0,0,0">
|
<while loc="a,0,0,0,0">
|
||||||
<begin>
|
|
||||||
</begin>
|
|
||||||
<begin>
|
<begin>
|
||||||
<varref loc="a,0,0,0,0" name="__VactContinue" dtype_id="8"/>
|
<varref loc="a,0,0,0,0" name="__VactContinue" dtype_id="8"/>
|
||||||
</begin>
|
</begin>
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,6 @@
|
||||||
<varref loc="d,18,10,18,11" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
<varref loc="d,18,10,18,11" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||||
</assign>
|
</assign>
|
||||||
<while loc="d,18,5,18,8">
|
<while loc="d,18,5,18,8">
|
||||||
<begin>
|
|
||||||
</begin>
|
|
||||||
<begin>
|
<begin>
|
||||||
<gts loc="d,18,18,18,19" dtype_id="5">
|
<gts loc="d,18,18,18,19" dtype_id="5">
|
||||||
<const loc="d,18,20,18,21" name="32'sh7" dtype_id="4"/>
|
<const loc="d,18,20,18,21" name="32'sh7" dtype_id="4"/>
|
||||||
|
|
@ -142,8 +140,6 @@
|
||||||
<varref loc="d,18,10,18,11" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
<varref loc="d,18,10,18,11" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||||
</assign>
|
</assign>
|
||||||
<while loc="d,18,5,18,8">
|
<while loc="d,18,5,18,8">
|
||||||
<begin>
|
|
||||||
</begin>
|
|
||||||
<begin>
|
<begin>
|
||||||
<gts loc="d,18,18,18,19" dtype_id="5">
|
<gts loc="d,18,18,18,19" dtype_id="5">
|
||||||
<const loc="d,18,20,18,21" name="32'sh7" dtype_id="4"/>
|
<const loc="d,18,20,18,21" name="32'sh7" dtype_id="4"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue