From 85fd88ace2447fde2986f2861f8f2e66295235d7 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 16 Mar 2023 22:18:03 -0400 Subject: [PATCH] Optimize duplicate JumpBlocks away (#4028) --- src/V3AstNodeOther.h | 2 +- src/V3Const.cpp | 2 +- src/V3LinkJump.cpp | 19 +++++++++++++++++++ src/V3Simulate.h | 2 +- test_regress/t/t_debug_emitv.out | 10 ++++------ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 607f3f52d..72db0c8d0 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2779,7 +2779,7 @@ public: bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstJumpBlock final : public AstNodeStmt { - // Block of code including a JumpGo and JumpLabel + // Block of code including a single JumpLabel, and 0+ JumpGo's to that label // Parents: {statement list} // Children: {statement list, with JumpGo and JumpLabel below} // @astgen op1 := stmtsp : List[AstNode] diff --git a/src/V3Const.cpp b/src/V3Const.cpp index dc195e158..8824aa2e1 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -3207,7 +3207,7 @@ private: void visit(AstJumpGo* nodep) override { iterateChildren(nodep); - // Jump to label where label immediately follows label is not useful + // Jump to label where label immediately follows this go is not useful if (nodep->labelp() == VN_CAST(nodep->nextp(), JumpLabel)) { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); // Keep the label, might be other jumps pointing to it, gets cleaned later diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index ec1ce3f1a..deba207eb 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -35,6 +35,7 @@ #include "V3LinkJump.h" #include "V3Ast.h" +#include "V3AstUserAllocator.h" #include "V3Global.h" #include @@ -46,6 +47,12 @@ VL_DEFINE_DEBUG_FUNCTIONS; class LinkJumpVisitor final : public VNVisitor { private: + // NODE STATE + // AstNode::user1() -> AstJumpLabel*, for this block if endOfIter + // AstNode::user2() -> AstJumpLabel*, for this block if !endOfIter + const VNUser1InUse m_user1InUse; + const VNUser2InUse m_user2InUse; + // STATE AstNodeModule* m_modp = nullptr; // Current module AstNodeFTask* m_ftaskp = nullptr; // Current function/task @@ -61,6 +68,13 @@ private: UINFO(4, "Create label for " << nodep << endl); if (VN_IS(nodep, JumpLabel)) return VN_AS(nodep, JumpLabel); // Done + // Made it previously? We always jump to the end, so this works out + if (endOfIter) { + if (nodep->user1p()) return VN_AS(nodep->user1p(), JumpLabel); + } else { + if (nodep->user2p()) return VN_AS(nodep->user2p(), JumpLabel); + } + AstNode* underp = nullptr; bool under_and_next = true; if (VN_IS(nodep, NodeBlock)) { @@ -125,6 +139,11 @@ private: } // Label goes last blockp->addEndStmtsp(labelp); + if (endOfIter) { + nodep->user1p(labelp); + } else { + nodep->user2p(labelp); + } return labelp; } } diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 7668b453d..d8b5e599a 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -103,7 +103,7 @@ private: bool m_isOutputter; // Creates output int m_instrCount; ///< Number of nodes int m_dataCount; ///< Bytes of data - AstJumpGo* m_jumpp; ///< Jump label we're branching from + AstJumpGo* m_jumpp = nullptr; ///< Jump label we're branching from // Simulating: std::unordered_map> m_constps; ///< Lists of all AstConst* allocated per dtype diff --git a/test_regress/t/t_debug_emitv.out b/test_regress/t/t_debug_emitv.out index 2775f2c02..abfcc0c61 100644 --- a/test_regress/t/t_debug_emitv.out +++ b/test_regress/t/t_debug_emitv.out @@ -337,14 +337,12 @@ module Vt_debug_emitv_sub; function f; input signed int [31:0] v; begin : label0 - begin : label0 - if ((v == 'sh0)) begin - f = 'sh21; - disable label0; - end - f = ({32'h1{{31'h0, v[2]}}} + 32'h1); + if ((v == 'sh0)) begin + f = 'sh21; disable label0; end + f = ({32'h1{{31'h0, v[2]}}} + 32'h1); + disable label0; end endfunction signed real r;