forked from github/verilator
Optimize duplicate JumpBlocks away (#4028)
This commit is contained in:
parent
ed1e377bb1
commit
85fd88ace2
@ -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]
|
||||
|
@ -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
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "V3LinkJump.h"
|
||||
|
||||
#include "V3Ast.h"
|
||||
#include "V3AstUserAllocator.h"
|
||||
#include "V3Global.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<const AstNodeDType*, std::deque<AstConst*>>
|
||||
m_constps; ///< Lists of all AstConst* allocated per dtype
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user