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(); }
|
bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); }
|
||||||
};
|
};
|
||||||
class AstJumpBlock final : public AstNodeStmt {
|
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}
|
// Parents: {statement list}
|
||||||
// Children: {statement list, with JumpGo and JumpLabel below}
|
// Children: {statement list, with JumpGo and JumpLabel below}
|
||||||
// @astgen op1 := stmtsp : List[AstNode]
|
// @astgen op1 := stmtsp : List[AstNode]
|
||||||
|
@ -3207,7 +3207,7 @@ private:
|
|||||||
|
|
||||||
void visit(AstJumpGo* nodep) override {
|
void visit(AstJumpGo* nodep) override {
|
||||||
iterateChildren(nodep);
|
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)) {
|
if (nodep->labelp() == VN_CAST(nodep->nextp(), JumpLabel)) {
|
||||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||||
// Keep the label, might be other jumps pointing to it, gets cleaned later
|
// Keep the label, might be other jumps pointing to it, gets cleaned later
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "V3LinkJump.h"
|
#include "V3LinkJump.h"
|
||||||
|
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
#include "V3AstUserAllocator.h"
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -46,6 +47,12 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
|||||||
|
|
||||||
class LinkJumpVisitor final : public VNVisitor {
|
class LinkJumpVisitor final : public VNVisitor {
|
||||||
private:
|
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
|
// STATE
|
||||||
AstNodeModule* m_modp = nullptr; // Current module
|
AstNodeModule* m_modp = nullptr; // Current module
|
||||||
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||||
@ -61,6 +68,13 @@ private:
|
|||||||
UINFO(4, "Create label for " << nodep << endl);
|
UINFO(4, "Create label for " << nodep << endl);
|
||||||
if (VN_IS(nodep, JumpLabel)) return VN_AS(nodep, JumpLabel); // Done
|
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;
|
AstNode* underp = nullptr;
|
||||||
bool under_and_next = true;
|
bool under_and_next = true;
|
||||||
if (VN_IS(nodep, NodeBlock)) {
|
if (VN_IS(nodep, NodeBlock)) {
|
||||||
@ -125,6 +139,11 @@ private:
|
|||||||
}
|
}
|
||||||
// Label goes last
|
// Label goes last
|
||||||
blockp->addEndStmtsp(labelp);
|
blockp->addEndStmtsp(labelp);
|
||||||
|
if (endOfIter) {
|
||||||
|
nodep->user1p(labelp);
|
||||||
|
} else {
|
||||||
|
nodep->user2p(labelp);
|
||||||
|
}
|
||||||
return labelp;
|
return labelp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ private:
|
|||||||
bool m_isOutputter; // Creates output
|
bool m_isOutputter; // Creates output
|
||||||
int m_instrCount; ///< Number of nodes
|
int m_instrCount; ///< Number of nodes
|
||||||
int m_dataCount; ///< Bytes of data
|
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:
|
// Simulating:
|
||||||
std::unordered_map<const AstNodeDType*, std::deque<AstConst*>>
|
std::unordered_map<const AstNodeDType*, std::deque<AstConst*>>
|
||||||
m_constps; ///< Lists of all AstConst* allocated per dtype
|
m_constps; ///< Lists of all AstConst* allocated per dtype
|
||||||
|
@ -337,14 +337,12 @@ module Vt_debug_emitv_sub;
|
|||||||
function f;
|
function f;
|
||||||
input signed int [31:0] v;
|
input signed int [31:0] v;
|
||||||
begin : label0
|
begin : label0
|
||||||
begin : label0
|
if ((v == 'sh0)) begin
|
||||||
if ((v == 'sh0)) begin
|
f = 'sh21;
|
||||||
f = 'sh21;
|
|
||||||
disable label0;
|
|
||||||
end
|
|
||||||
f = ({32'h1{{31'h0, v[2]}}} + 32'h1);
|
|
||||||
disable label0;
|
disable label0;
|
||||||
end
|
end
|
||||||
|
f = ({32'h1{{31'h0, v[2]}}} + 32'h1);
|
||||||
|
disable label0;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
signed real r;
|
signed real r;
|
||||||
|
Loading…
Reference in New Issue
Block a user