Cleanup V3Gate, no functional change

This commit is contained in:
Geza Lore 2022-07-31 20:04:39 +01:00
parent 2ab6272cc7
commit 682a60e325

View File

@ -558,94 +558,56 @@ public:
void GateVisitor::optimizeSignals(bool allowMultiIn) { void GateVisitor::optimizeSignals(bool allowMultiIn) {
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) { GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp);
if (vvertexp->inEmpty()) {
vvertexp->clearReducibleAndDedupable("inEmpty"); // Can't deal with no sources // Consider "inlining" variables
if (!vvertexp->isTop() // Ok if top inputs are driverless if (!vvertexp) continue;
&& !vvertexp->varScp()->varp()->valuep()
&& !vvertexp->varScp()->varp()->isSigPublic()) { if (vvertexp->inEmpty()) { // Can't deal with no sources
UINFO(4, "No drivers " << vvertexp->varScp() << endl); vvertexp->clearReducibleAndDedupable("inEmpty");
if (false) { } else if (!vvertexp->inSize1()) { // Can't deal with more than one src
// If we warned here after constant propagation, what the user considered
// reasonable logic may have disappeared. Issuing a warning would
// thus be confusing. V3Undriven now handles this.
vvertexp->varScp()->varp()->v3warn(
UNDRIVEN, "Signal has no drivers: '"
<< vvertexp->scopep()->prettyName() << "."
<< vvertexp->varScp()->varp()->prettyName() << "'");
}
}
} else if (!vvertexp->inSize1()) {
// Can't deal with more than one src
vvertexp->clearReducibleAndDedupable("size!1"); vvertexp->clearReducibleAndDedupable("size!1");
} }
// Reduce it? // Reduce it?
if (!vvertexp->reducible()) { if (!vvertexp->reducible()) continue;
UINFO(8, "SigNotRed " << vvertexp->name() << endl);
} else { // Grab the driving logic
UINFO(8, "Sig " << vvertexp->name() << endl);
GateLogicVertex* const logicVertexp GateLogicVertex* const logicVertexp
= dynamic_cast<GateLogicVertex*>(vvertexp->inBeginp()->fromp()); = static_cast<GateLogicVertex*>(vvertexp->inBeginp()->fromp());
UINFO(8, " From " << logicVertexp->name() << endl); if (!logicVertexp->reducible()) continue;
AstNode* logicp = logicVertexp->nodep();
if (logicVertexp->reducible()) {
// Can we eliminate? // Can we eliminate?
AstNode* const logicp = logicVertexp->nodep();
const GateOkVisitor okVisitor{logicp, vvertexp->isClock(), false}; const GateOkVisitor okVisitor{logicp, vvertexp->isClock(), false};
const bool multiInputs = okVisitor.rhsVarRefs().size() > 1;
// Was it ok? // Was it ok?
bool doit = okVisitor.isSimple(); if (!okVisitor.isSimple()) continue;
if (doit && multiInputs) {
if (!allowMultiIn) doit = false; // Does it read multiple source variables?
// Doit if one input, or not used, or used only once, ignoring traces if (okVisitor.rhsVarRefs().size() > 1) {
if (!allowMultiIn) continue;
// Do it if not used, or used only once, ignoring traces
int n = 0; int n = 0;
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
edgep = edgep->outNextp()) {
const GateLogicVertex* const consumeVertexp const GateLogicVertex* const consumeVertexp
= dynamic_cast<GateLogicVertex*>(edgep->top()); = static_cast<GateLogicVertex*>(edgep->top());
if (!consumeVertexp->slow()) { // Not tracing or other slow path junk // Ignore tracing or other slow path junk, or if the destination is not used
if (edgep->top()->outBeginp()) { // Destination is itself used if (!consumeVertexp->slow() && consumeVertexp->outBeginp()) n += edgep->weight();
n += edgep->weight(); if (n > 1) break;
}
}
if (n > 1) {
doit = false;
break;
}
} }
if (n > 1) continue;
} }
// Process it // Process it
if (!doit) {
if (allowMultiIn && (debug() >= 9)) {
UINFO(9, "Not ok simp" << okVisitor.isSimple() << " mi" << multiInputs
<< " ob" << vvertexp->outBeginp() << " on"
<< (vvertexp->outBeginp()
? vvertexp->outBeginp()->outNextp()
: nullptr)
<< " " << vvertexp->name() << endl);
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;
edgep = edgep->outNextp()) {
const GateLogicVertex* const consumeVertexp
= dynamic_cast<GateLogicVertex*>(edgep->top());
UINFO(9, " edge " << edgep << " to: " << consumeVertexp->nodep()
<< endl);
}
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep;
edgep = edgep->inNextp()) {
const GateLogicVertex* const consumeVertexp
= dynamic_cast<GateLogicVertex*>(edgep->fromp());
UINFO(9, " edge " << edgep << " from: "
<< consumeVertexp->nodep() << endl);
}
}
} else {
AstNode* const substp = okVisitor.substTree(); AstNode* const substp = okVisitor.substTree();
if (debug() >= 5) logicp->dumpTree(cout, " elimVar: "); if (debug() >= 5) logicp->dumpTree(cout, " elimVar: ");
if (debug() >= 5) substp->dumpTree(cout, " subst: "); if (debug() >= 5) substp->dumpTree(cout, " subst: ");
++m_statSigs; ++m_statSigs;
bool removedAllUsages = true; bool removedAllUsages = true;
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;) { for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;) {
GateLogicVertex* const consumeVertexp GateLogicVertex* const consumeVertexp = static_cast<GateLogicVertex*>(edgep->top());
= dynamic_cast<GateLogicVertex*>(edgep->top());
AstNode* const consumerp = consumeVertexp->nodep(); AstNode* const consumerp = consumeVertexp->nodep();
if (!elimLogicOkOutputs(consumeVertexp, okVisitor /*ref*/)) { if (!elimLogicOkOutputs(consumeVertexp, okVisitor /*ref*/)) {
// Cannot optimize this replacement // Cannot optimize this replacement
@ -656,10 +618,8 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
// If the new replacement referred to a signal, // If the new replacement referred to a signal,
// Correct the graph to point to this new generating variable // Correct the graph to point to this new generating variable
const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs(); const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs();
for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); for (AstNodeVarRef* const refp : rhsVarRefs) {
it != rhsVarRefs.end(); ++it) { AstVarScope* const newvarscp = refp->varScopep();
AstVarScope* const newvarscp = (*it)->varScopep();
UINFO(9, " Point-to-new vertex " << newvarscp << endl);
GateVarVertex* const varvertexp = makeVarVertex(newvarscp); GateVarVertex* const varvertexp = makeVarVertex(newvarscp);
new V3GraphEdge(&m_graph, varvertexp, consumeVertexp, 1); new V3GraphEdge(&m_graph, varvertexp, consumeVertexp, 1);
// Propagate clock attribute onto generating node // Propagate clock attribute onto generating node
@ -671,6 +631,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
edgep = vvertexp->outBeginp(); edgep = vvertexp->outBeginp();
} }
} }
if (removedAllUsages) { if (removedAllUsages) {
// Remove input links // Remove input links
while (V3GraphEdge* const edgep = vvertexp->inBeginp()) { while (V3GraphEdge* const edgep = vvertexp->inBeginp()) {
@ -681,9 +642,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
// That way if a later signal optimization that // That way if a later signal optimization that
// retained a pointer to the always can // retained a pointer to the always can
// optimize it further // optimize it further
logicp->unlinkFrBack(); VL_DO_DANGLING(vvertexp->varScp()->valuep(logicp->unlinkFrBack()), logicp);
vvertexp->varScp()->valuep(logicp);
logicp = nullptr;
// Mark the vertex so we don't mark it as being // Mark the vertex so we don't mark it as being
// unconsumed in the next step // unconsumed in the next step
vvertexp->user(true); vvertexp->user(true);
@ -691,10 +650,6 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
} }
} }
} }
}
}
}
}
bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp, bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp,
const GateOkVisitor& okVisitor) { const GateOkVisitor& okVisitor) {