mirror of
https://github.com/verilator/verilator.git
synced 2026-10-07 18:42:58 +02:00
Make all expressions derive from AstNodeExpr (#3721).
Apart from the representational changes below, this patch renames AstNodeMath to AstNodeExpr, and AstCMath to AstCExpr. Now every expression (i.e.: those AstNodes that represent a [possibly void] value, with value being interpreted in a very general sense) has AstNodeExpr as a super class. This necessitates the introduction of an AstStmtExpr, which represents an expression in statement position, e.g : 'foo();' would be represented as AstStmtExpr(AstCCall(foo)). In exchange we can get rid of isStatement() in AstNodeStmt, which now really always represent a statement Peak memory consumption and verilation speed are not measurably changed. Partial step towards #3420
This commit is contained in:
+23
-21
@@ -552,10 +552,12 @@ private:
|
||||
cnewpr = cnewp;
|
||||
} else if (const AstMethodCall* const mrefp = VN_CAST(refp, MethodCall)) {
|
||||
ccallp = new AstCMethodCall(refp->fileline(), mrefp->fromp()->unlinkFrBack(), cfuncp);
|
||||
beginp->addNext(ccallp);
|
||||
ccallp->dtypeSetVoid();
|
||||
beginp->addNext(ccallp->makeStmt());
|
||||
} else {
|
||||
ccallp = new AstCCall(refp->fileline(), cfuncp);
|
||||
beginp->addNext(ccallp);
|
||||
ccallp->dtypeSetVoid();
|
||||
beginp->addNext(ccallp->makeStmt());
|
||||
}
|
||||
|
||||
// Convert complicated outputs to temp signals
|
||||
@@ -617,7 +619,7 @@ private:
|
||||
UASSERT_OBJ(snp, refp, "Missing scoping context");
|
||||
ccallp->addArgsp(snp);
|
||||
// __Vfilenamep
|
||||
ccallp->addArgsp(new AstCMath(refp->fileline(),
|
||||
ccallp->addArgsp(new AstCExpr(refp->fileline(),
|
||||
"\"" + refp->fileline()->filename() + "\"", 64, true));
|
||||
// __Vlineno
|
||||
ccallp->addArgsp(new AstConst(refp->fileline(), refp->fileline()->lineno()));
|
||||
@@ -701,7 +703,7 @@ private:
|
||||
string frstmt;
|
||||
string ket;
|
||||
const bool useSetWSvlv = TaskDpiUtils::dpiToInternalFrStmt(portp, frName, frstmt, ket);
|
||||
// Use a AstCMath, as we want V3Clean to mask off bits that don't make sense.
|
||||
// Use a AstCExpr, as we want V3Clean to mask off bits that don't make sense.
|
||||
int cwidth = VL_IDATASIZE;
|
||||
if (!useSetWSvlv && portp->basicp()) {
|
||||
if (portp->basicp()->keyword().isBitLogic()) {
|
||||
@@ -743,7 +745,7 @@ private:
|
||||
}
|
||||
from += ket;
|
||||
AstNode* const rhsp = new AstSel(
|
||||
portp->fileline(), new AstCMath(portp->fileline(), from, cwidth, false), 0,
|
||||
portp->fileline(), new AstCExpr(portp->fileline(), from, cwidth, false), 0,
|
||||
portp->width());
|
||||
stmtp = new AstAssign(portp->fileline(), srcp, rhsp);
|
||||
}
|
||||
@@ -1039,8 +1041,9 @@ private:
|
||||
cfuncp->addStmtsp(new AstText(nodep->fileline(), stmt, /* tracking: */ true));
|
||||
}
|
||||
AstCCall* const callp = new AstCCall(nodep->fileline(), dpiFuncp);
|
||||
callp->dtypeSetVoid();
|
||||
callp->argTypes(args);
|
||||
cfuncp->addStmtsp(callp);
|
||||
cfuncp->addStmtsp(callp->makeStmt());
|
||||
}
|
||||
|
||||
// Convert output/inout arguments back to internal type
|
||||
@@ -1401,30 +1404,26 @@ private:
|
||||
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
|
||||
}
|
||||
// Replace the ref
|
||||
AstNode* visitp = nullptr;
|
||||
AstNode* const visitp = insertBeforeStmt(nodep, beginp);
|
||||
|
||||
if (VN_IS(nodep, New)) {
|
||||
UASSERT_OBJ(!nodep->isStatement(), nodep, "new is non-stmt");
|
||||
UASSERT_OBJ(cnewp, nodep, "didn't create cnew for new");
|
||||
nodep->replaceWith(cnewp);
|
||||
visitp = insertBeforeStmt(nodep, beginp);
|
||||
} else if (!nodep->isStatement()) {
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else if (!VN_IS(nodep->backp(), StmtExpr)) {
|
||||
UASSERT_OBJ(nodep->taskp()->isFunction(), nodep, "func reference to non-function");
|
||||
AstVarRef* const outrefp = new AstVarRef(nodep->fileline(), outvscp, VAccess::READ);
|
||||
nodep->replaceWith(outrefp);
|
||||
// Insert new statements
|
||||
visitp = insertBeforeStmt(nodep, beginp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else {
|
||||
if (nodep->taskp()->isFunction()) {
|
||||
nodep->v3warn(
|
||||
IGNOREDRETURN,
|
||||
"Ignoring return value of non-void function (IEEE 1800-2017 13.4.1)");
|
||||
}
|
||||
// outvscp maybe non-nullptr if calling a function in a taskref,
|
||||
// but if so we want to ignore the function result
|
||||
nodep->replaceWith(beginp);
|
||||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
// Cleanup
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
UINFO(4, " FTask REF Done.\n");
|
||||
// Visit nodes that normal iteration won't find
|
||||
if (visitp) iterateAndNextNull(visitp);
|
||||
@@ -1519,15 +1518,18 @@ private:
|
||||
"For statements should have been converted to while statements in V3Begin.cpp");
|
||||
}
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
m_insMode = IM_BEFORE;
|
||||
m_insStmtp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
}
|
||||
void visit(AstStmtExpr* nodep) override {
|
||||
m_insMode = IM_BEFORE;
|
||||
m_insStmtp = nodep;
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->exprp()) VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
}
|
||||
void visit(AstSenItem* nodep) override {
|
||||
UASSERT_OBJ(!m_inSensesp, nodep, "Senitem under senitem?");
|
||||
VL_RESTORER(m_inSensesp);
|
||||
|
||||
Reference in New Issue
Block a user