mirror of
https://github.com/verilator/verilator.git
synced 2026-09-01 02:16:47 +02:00
Internals: Use runtime type info instead of dynamic_cast for faster graph type checks (#4397)
This commit is contained in:
+25
-17
@@ -99,6 +99,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
||||
// Support classes
|
||||
|
||||
class SplitNodeVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
VL_RTTI_IMPL(SplitNodeVertex, V3GraphVertex)
|
||||
AstNode* const m_nodep;
|
||||
|
||||
protected:
|
||||
@@ -117,6 +118,7 @@ public:
|
||||
};
|
||||
|
||||
class SplitPliVertex final : public SplitNodeVertex {
|
||||
VL_RTTI_IMPL(SplitPliVertex, SplitNodeVertex)
|
||||
public:
|
||||
explicit SplitPliVertex(V3Graph* graphp, AstNode* nodep)
|
||||
: SplitNodeVertex{graphp, nodep} {}
|
||||
@@ -126,6 +128,7 @@ public:
|
||||
};
|
||||
|
||||
class SplitLogicVertex final : public SplitNodeVertex {
|
||||
VL_RTTI_IMPL(SplitLogicVertex, SplitNodeVertex)
|
||||
public:
|
||||
SplitLogicVertex(V3Graph* graphp, AstNode* nodep)
|
||||
: SplitNodeVertex{graphp, nodep} {}
|
||||
@@ -134,6 +137,7 @@ public:
|
||||
};
|
||||
|
||||
class SplitVarStdVertex final : public SplitNodeVertex {
|
||||
VL_RTTI_IMPL(SplitVarStdVertex, SplitNodeVertex)
|
||||
public:
|
||||
SplitVarStdVertex(V3Graph* graphp, AstNode* nodep)
|
||||
: SplitNodeVertex{graphp, nodep} {}
|
||||
@@ -142,6 +146,7 @@ public:
|
||||
};
|
||||
|
||||
class SplitVarPostVertex final : public SplitNodeVertex {
|
||||
VL_RTTI_IMPL(SplitVarPostVertex, SplitNodeVertex)
|
||||
public:
|
||||
SplitVarPostVertex(V3Graph* graphp, AstNode* nodep)
|
||||
: SplitNodeVertex{graphp, nodep} {}
|
||||
@@ -154,6 +159,7 @@ public:
|
||||
// Edge types
|
||||
|
||||
class SplitEdge VL_NOT_FINAL : public V3GraphEdge {
|
||||
VL_RTTI_IMPL(SplitEdge, V3GraphEdge)
|
||||
uint32_t m_ignoreInStep = 0; // Step number that if set to, causes this edge to be ignored
|
||||
static uint32_t s_stepNum; // Global step number
|
||||
protected:
|
||||
@@ -170,14 +176,12 @@ public:
|
||||
void setIgnoreThisStep() { m_ignoreInStep = s_stepNum; }
|
||||
virtual bool followScoreboard() const = 0;
|
||||
static bool followScoreboard(const V3GraphEdge* edgep) {
|
||||
const SplitEdge* const oedgep = dynamic_cast<const SplitEdge*>(edgep);
|
||||
if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type");
|
||||
const SplitEdge* const oedgep = edgep->as<SplitEdge>();
|
||||
if (oedgep->ignoreThisStep()) return false;
|
||||
return oedgep->followScoreboard();
|
||||
}
|
||||
static bool followCyclic(const V3GraphEdge* edgep) {
|
||||
const SplitEdge* const oedgep = dynamic_cast<const SplitEdge*>(edgep);
|
||||
if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type");
|
||||
const SplitEdge* const oedgep = edgep->as<SplitEdge>();
|
||||
return (!oedgep->ignoreThisStep());
|
||||
}
|
||||
string dotStyle() const override {
|
||||
@@ -187,6 +191,7 @@ public:
|
||||
uint32_t SplitEdge::s_stepNum = 0;
|
||||
|
||||
class SplitPostEdge final : public SplitEdge {
|
||||
VL_RTTI_IMPL(SplitPostEdge, SplitEdge)
|
||||
public:
|
||||
SplitPostEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: SplitEdge{graphp, fromp, top, WEIGHT_NORMAL} {}
|
||||
@@ -196,6 +201,7 @@ public:
|
||||
};
|
||||
|
||||
class SplitLVEdge final : public SplitEdge {
|
||||
VL_RTTI_IMPL(SplitLVEdge, SplitEdge)
|
||||
public:
|
||||
SplitLVEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: SplitEdge{graphp, fromp, top, WEIGHT_NORMAL} {}
|
||||
@@ -205,6 +211,7 @@ public:
|
||||
};
|
||||
|
||||
class SplitRVEdge final : public SplitEdge {
|
||||
VL_RTTI_IMPL(SplitRVEdge, SplitEdge)
|
||||
public:
|
||||
SplitRVEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: SplitEdge{graphp, fromp, top, WEIGHT_NORMAL} {}
|
||||
@@ -213,7 +220,8 @@ public:
|
||||
string dotColor() const override { return "green"; }
|
||||
};
|
||||
|
||||
struct SplitScorebdEdge : public SplitEdge {
|
||||
class SplitScorebdEdge final : public SplitEdge {
|
||||
VL_RTTI_IMPL(SplitScorebdEdge, SplitEdge)
|
||||
public:
|
||||
SplitScorebdEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
|
||||
: SplitEdge{graphp, fromp, top, WEIGHT_NORMAL} {}
|
||||
@@ -222,7 +230,8 @@ public:
|
||||
string dotColor() const override { return "blue"; }
|
||||
};
|
||||
|
||||
struct SplitStrictEdge : public SplitEdge {
|
||||
class SplitStrictEdge final : public SplitEdge {
|
||||
VL_RTTI_IMPL(SplitStrictEdge, SplitEdge)
|
||||
// A strict order, based on the original statement order in the graph
|
||||
// The only non-cutable edge type
|
||||
public:
|
||||
@@ -316,14 +325,14 @@ protected:
|
||||
void pruneDepsOnInputs() {
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (!vertexp->outBeginp() && dynamic_cast<SplitVarStdVertex*>(vertexp)) {
|
||||
if (!vertexp->outBeginp() && vertexp->is<SplitVarStdVertex>()) {
|
||||
if (debug() >= 9) {
|
||||
const SplitVarStdVertex* const stdp = static_cast<SplitVarStdVertex*>(vertexp);
|
||||
UINFO(0, "Will prune deps on var " << stdp->nodep() << endl);
|
||||
stdp->nodep()->dumpTree("- ");
|
||||
}
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = edgep->as<SplitEdge>();
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
}
|
||||
@@ -474,17 +483,16 @@ protected:
|
||||
// vertexes not involved with this step as unimportant
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (const SplitLogicVertex* const vvertexp
|
||||
= dynamic_cast<SplitLogicVertex*>(vertexp)) {
|
||||
if (!vvertexp->user()) {
|
||||
if (!vertexp->user()) {
|
||||
if (const SplitLogicVertex* const vvertexp = vertexp->cast<SplitLogicVertex>()) {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep;
|
||||
edgep = edgep->inNextp()) {
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = edgep->as<SplitEdge>();
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = edgep->as<SplitEdge>();
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
}
|
||||
@@ -903,7 +911,7 @@ protected:
|
||||
// inputs) prune all edges that depend on the 'if'.
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
const SplitLogicVertex* const logicp = dynamic_cast<SplitLogicVertex*>(vertexp);
|
||||
const SplitLogicVertex* const logicp = vertexp->cast<const SplitLogicVertex>();
|
||||
if (!logicp) continue;
|
||||
|
||||
const AstNodeIf* const ifNodep = VN_CAST(logicp->nodep(), NodeIf);
|
||||
@@ -911,7 +919,7 @@ protected:
|
||||
|
||||
bool pruneMe = true;
|
||||
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
const SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
const SplitEdge* const oedgep = edgep->as<const SplitEdge>();
|
||||
if (!oedgep->ignoreThisStep()) {
|
||||
// This if conditional depends on something we can't
|
||||
// prune -- a variable generated in the current block.
|
||||
@@ -921,7 +929,7 @@ protected:
|
||||
// give a hint about why...
|
||||
if (debug() >= 9) {
|
||||
V3GraphVertex* vxp = oedgep->top();
|
||||
const SplitNodeVertex* const nvxp = dynamic_cast<SplitNodeVertex*>(vxp);
|
||||
const SplitNodeVertex* const nvxp = vxp->as<const SplitNodeVertex>();
|
||||
UINFO(0, "Cannot prune if-node due to edge "
|
||||
<< oedgep << " pointing to node " << nvxp->nodep() << endl);
|
||||
nvxp->nodep()->dumpTree("- ");
|
||||
@@ -935,7 +943,7 @@ protected:
|
||||
|
||||
// This if can be split; prune dependencies on it.
|
||||
for (V3GraphEdge* edgep = logicp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = edgep->as<SplitEdge>();
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user