Internals: Optimize empty 'if' into StmtExpr

This commit is contained in:
Wilson Snyder 2025-08-08 05:10:40 -04:00
parent 6a225d5d00
commit d1f851e1e1
5 changed files with 18 additions and 6 deletions

View File

@ -4524,6 +4524,7 @@ public:
void isImplicit(bool flag) { m_isImplicit = flag; }
bool isScoped() const { return m_isScoped; }
void isScoped(bool flag) { m_isScoped = flag; }
bool isPure() override { return false; }
};
class AstTaskRef final : public AstNodeFTaskRef {
// A reference to a task

View File

@ -3241,10 +3241,16 @@ class ConstVisitor final : public VNVisitor {
} else if (!AstNode::afterCommentp(nodep->thensp())
&& !AstNode::afterCommentp(nodep->elsesp())) {
if (!nodep->condp()->isPure()) {
// Condition has side effect - leave - perhaps in
// future simplify to remove all but side effect terms
// Condition has side effect - leave, but don't need return value
UINFO(4, "IF({x}) ; => STMTEXPR({x}): " << nodep);
nodep->fileline()->warnOff(V3ErrorCode::IGNOREDRETURN, true);
AstNodeStmt* const newp
= new AstStmtExpr{nodep->fileline(), nodep->condp()->unlinkFrBack()};
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
} else {
// Empty block, remove it
UINFO(4, "IF({x}) ; => ; : " << nodep);
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
}
} else if (!AstNode::afterCommentp(nodep->thensp())) {
@ -3498,6 +3504,8 @@ class ConstVisitor final : public VNVisitor {
}
// TODO if there's an ExprStmt underneath just keep lower statements
// (No current test case needs this)
// TODO if non-pure, can remove keep removing upper pure-itself
// NodeUniOp/NodeBiOp until get to the non-pure child-node expression
}
// Simplify

View File

@ -241,7 +241,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
methodHardp->v3fatalSrc("Unknown rand_mode() receiver");
}
}
if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr)) {
if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr)
&& !nodep->backp()->fileline()->warnIsOff(V3ErrorCode::IGNOREDRETURN)) {
nodep->v3warn(
IGNOREDRETURN,
"Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)");
@ -302,7 +303,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
nodep->v3error(
"'constraint_mode()' with arguments cannot be called as a function");
valid = false;
} else if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr)) {
} else if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr)
&& !nodep->backp()->fileline()->warnIsOff(V3ErrorCode::IGNOREDRETURN)) {
nodep->v3warn(
IGNOREDRETURN,
"Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)");

View File

@ -1510,7 +1510,8 @@ class TaskVisitor final : public VNVisitor {
VIsCached::clearCacheTree();
} else { // VN_IS(nodep->backp(), StmtExpr)
insertBeforeStmt(nodep, beginp);
if (nodep->taskp()->isFunction()) {
if (nodep->taskp()->isFunction()
&& !nodep->backp()->fileline()->warnIsOff(V3ErrorCode::IGNOREDRETURN)) {
nodep->v3warn(
IGNOREDRETURN,
"Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)");

View File

@ -7,7 +7,7 @@
typedef class Derived;
class Base;
function Derived cast();
if ($cast(cast,this)) begin end
if (!$cast(cast, this)) begin end
endfunction
endclass