diff --git a/src/V3Ast.h b/src/V3Ast.h index 538998755..c22cb256c 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -968,6 +968,7 @@ public: // METHODS - queries virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays + virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 47dadf379..679ceefec 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2040,7 +2040,7 @@ struct AstBreak : public AstNodeStmt { ASTNODE_NODE_FUNCS(Break, BREAK) virtual string verilogKwd() const { return "break"; }; virtual V3Hash sameHash() const { return V3Hash(); } - virtual bool isPure() const { return false; } // SPECIAL: We don't process code after breaks + virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; struct AstContinue : public AstNodeStmt { @@ -2049,7 +2049,7 @@ struct AstContinue : public AstNodeStmt { ASTNODE_NODE_FUNCS(Continue, CONTINUE) virtual string verilogKwd() const { return "continue"; }; virtual V3Hash sameHash() const { return V3Hash(); } - virtual bool isPure() const { return false; } // SPECIAL: We don't process code after breaks + virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; struct AstDisable : public AstNodeStmt { @@ -2061,7 +2061,7 @@ public: ASTNODE_NODE_FUNCS(Disable, DISABLE) virtual string name() const { return m_name; } // * = Block name void name(const string& flag) { m_name=flag; } - virtual bool isPure() const { return false; } // SPECIAL: We don't process code after breaks + virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; struct AstReturn : public AstNodeStmt { @@ -2073,7 +2073,7 @@ struct AstReturn : public AstNodeStmt { virtual string verilogKwd() const { return "return"; }; virtual V3Hash sameHash() const { return V3Hash(); } AstNode* lhsp() const { return op1p(); } - virtual bool isPure() const { return false; } // SPECIAL: We don't process code after breaks + virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; struct AstGenIf : public AstNodeIf { @@ -2145,7 +2145,7 @@ public: virtual bool same(AstNode* samep) const { // Also same if identical tree structure all the way down, but hard to detect return labelp()==samep->castJumpGo()->labelp(); } virtual bool isGateOptimizable() const { return false; } - virtual bool isPure() const { return false; } // SPECIAL: We don't process code after breaks + virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks AstJumpLabel* labelp() const { return m_labelp; } }; diff --git a/src/V3ClkGater.cpp b/src/V3ClkGater.cpp index b352524fb..192c0f2d0 100644 --- a/src/V3ClkGater.cpp +++ b/src/V3ClkGater.cpp @@ -862,7 +862,7 @@ class GaterVisitor : public GaterBaseVisitor { m_stmtVscp = NULL; m_stmtInPli = false; } - if (!nodep->isPure()) { + if (!nodep->isPure() || nodep->isBrancher()) { // May also be a new statement (above if); if so we mark it immediately UINFO(9," NotPure "<isGateOptimizable() - || !nodep->isPure()) { + || !nodep->isPure() + || nodep->isBrancher()) { UINFO(5, "Non optimizable type: "<