mirror of
https://github.com/verilator/verilator.git
synced 2026-09-02 10:48:27 +02:00
Internals: Use runtime type info instead of dynamic_cast for faster graph type checks (#4397)
This commit is contained in:
+11
-9
@@ -65,6 +65,7 @@ public:
|
||||
// Support classes
|
||||
|
||||
class GateEitherVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
VL_RTTI_IMPL(GateEitherVertex, V3GraphVertex)
|
||||
AstScope* const m_scopep; // Scope vertex refers to
|
||||
bool m_reducible = true; // True if this node should be able to be eliminated
|
||||
bool m_dedupable = true; // True if this node should be able to be deduped
|
||||
@@ -122,6 +123,7 @@ public:
|
||||
};
|
||||
|
||||
class GateVarVertex final : public GateEitherVertex {
|
||||
VL_RTTI_IMPL(GateVarVertex, GateEitherVertex)
|
||||
AstVarScope* const m_varScp;
|
||||
bool m_isTop = false;
|
||||
bool m_isClock = false;
|
||||
@@ -164,6 +166,7 @@ public:
|
||||
};
|
||||
|
||||
class GateLogicVertex final : public GateEitherVertex {
|
||||
VL_RTTI_IMPL(GateLogicVertex, GateEitherVertex)
|
||||
AstNode* const m_nodep;
|
||||
AstActive* const m_activep; // Under what active; nullptr is ok (under cfunc or such)
|
||||
const bool m_slow; // In slow block
|
||||
@@ -568,7 +571,7 @@ public:
|
||||
|
||||
void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp);
|
||||
GateVarVertex* const vvertexp = itp->cast<GateVarVertex>();
|
||||
|
||||
// Consider "inlining" variables
|
||||
if (!vvertexp) continue;
|
||||
@@ -710,7 +713,7 @@ void GateVisitor::consumedMove() {
|
||||
// We need the "usually" block logic to do a better job at this
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (const GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(vertexp)) {
|
||||
if (const GateVarVertex* const vvertexp = vertexp->cast<GateVarVertex>()) {
|
||||
if (!vvertexp->consumed() && !vvertexp->user()) {
|
||||
UINFO(8, "Unconsumed " << vvertexp->varScp() << endl);
|
||||
}
|
||||
@@ -734,7 +737,7 @@ void GateVisitor::consumedMove() {
|
||||
void GateVisitor::warnSignals() {
|
||||
AstNode::user2ClearTree();
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (const GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (const GateVarVertex* const vvertexp = itp->cast<GateVarVertex>()) {
|
||||
const AstVarScope* const vscp = vvertexp->varScp();
|
||||
const AstNode* const sp = vvertexp->rstSyncNodep();
|
||||
const AstNode* const ap = vvertexp->rstAsyncNodep();
|
||||
@@ -1136,14 +1139,14 @@ void GateVisitor::dedupe() {
|
||||
// Traverse starting from each of the clocks
|
||||
UINFO(9, "Gate dedupe() clocks:\n");
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = itp->cast<GateVarVertex>()) {
|
||||
if (vvertexp->isClock()) deduper.dedupeTree(vvertexp);
|
||||
}
|
||||
}
|
||||
// Traverse starting from each of the outputs
|
||||
UINFO(9, "Gate dedupe() outputs:\n");
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = itp->cast<GateVarVertex>()) {
|
||||
if (vvertexp->isTop() && vvertexp->varScp()->varp()->isWritable()) {
|
||||
deduper.dedupeTree(vvertexp);
|
||||
}
|
||||
@@ -1187,8 +1190,7 @@ private:
|
||||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep;) {
|
||||
V3GraphEdge* oldedgep = edgep;
|
||||
edgep = edgep->inNextp(); // for recursive since the edge could be deleted
|
||||
if (GateLogicVertex* const lvertexp
|
||||
= dynamic_cast<GateLogicVertex*>(oldedgep->fromp())) {
|
||||
if (GateLogicVertex* const lvertexp = oldedgep->fromp()->cast<GateLogicVertex>()) {
|
||||
if (AstNodeAssign* const assignp = VN_CAST(lvertexp->nodep(), NodeAssign)) {
|
||||
// if (lvertexp->outSize1() && VN_IS(assignp->lhsp(), Sel)) {
|
||||
if (VN_IS(assignp->lhsp(), Sel) && lvertexp->outSize1()) {
|
||||
@@ -1274,7 +1276,7 @@ void GateVisitor::mergeAssigns() {
|
||||
UINFO(6, "mergeAssigns\n");
|
||||
GateMergeAssignsGraphVisitor merger{&m_graph};
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = itp->cast<GateVarVertex>()) {
|
||||
merger.mergeAssignsTree(vvertexp);
|
||||
}
|
||||
}
|
||||
@@ -1460,7 +1462,7 @@ void GateVisitor::decomposeClkVectors() {
|
||||
AstNode::user2ClearTree();
|
||||
GateClkDecompGraphVisitor decomposer{&m_graph};
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* const vertp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vertp = itp->cast<GateVarVertex>()) {
|
||||
const AstVarScope* const vsp = vertp->varScp();
|
||||
if (vsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_YES) {
|
||||
if (vsp->varp()->width() > 1) {
|
||||
|
||||
Reference in New Issue
Block a user