forked from github/verilator
Cleanup V3Gate, no functional change
This commit is contained in:
parent
2ab6272cc7
commit
682a60e325
117
src/V3Gate.cpp
117
src/V3Gate.cpp
@ -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,19 +642,13 @@ 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);
|
||||||
logicVertexp->user(true);
|
logicVertexp->user(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp,
|
bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp,
|
||||||
|
Loading…
Reference in New Issue
Block a user