mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Optimize Ast read references in Dfg directly (#7354)
Introduce a new DfgAstRd vertex, which holds an AstNodeExpr that is a reference to a variable. This enables tracking all read references in Dfg, which both enables more optimization, and allows inlining of expressions in place of the reference more intelligently (e.g, when the expression is only used once, and is not in a loop). This can get rid of 20-30% of temporary variables introduced in Dfg in some designs. Note V3Gate later got rid of a lot of those, this is a step towards making V3Gate redundant. The more intelligent expression inlining is worth ~10% runtime speed on some designs.
This commit is contained in:
+22
-9
@@ -492,9 +492,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
// For now, only direct array assignment is supported (e.g. a = b, but not a = _ ? b : c)
|
||||
if (rDtypep->isArray() && !VN_IS(rhsp, VarRef)) {
|
||||
++m_ctx.m_conv.nonRepDType;
|
||||
return false;
|
||||
if (rDtypep->isArray()) {
|
||||
if (!VN_IS(rhsp, VarRef)
|
||||
|| !lhsp->dtypep()->skipRefp()->sameTree(rhsp->dtypep()->skipRefp())) {
|
||||
++m_ctx.m_conv.nonRepDType;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Widths should match at this point
|
||||
UASSERT_OBJ(lhsp->width() == rhsp->width(), nodep, "Mismatched width reached DFG");
|
||||
@@ -1746,11 +1749,16 @@ class AstToDfgSynthesize final {
|
||||
if (logicp->selectedForSynthesis()) continue;
|
||||
// There should be no sinks left for unselected DfgLogic, delete them here
|
||||
UASSERT_OBJ(!logicp->hasSinks(), vtxp, "Unselected 'DfgLogic' with sinks remaining");
|
||||
// Input variables will be read in Ast code, mark as such
|
||||
// Input variables will be read in Ast code, add Ast reference vertices
|
||||
// AstVar/AstVarScope::user4p() -> corresponding DfgVertexVar* in the graph
|
||||
const VNUser4InUse m_user4InUse;
|
||||
logicp->foreachSource([](DfgVertex& src) {
|
||||
src.as<DfgVertexVar>()->setHasModRdRefs();
|
||||
src.as<DfgVertexVar>()->nodep()->user4p(&src);
|
||||
return false;
|
||||
});
|
||||
V3DfgPasses::addAstRefs(m_dfg, logicp->nodep(), [](AstNode* varp) { //
|
||||
return varp->user4u().to<DfgVertexVar*>();
|
||||
});
|
||||
VL_DO_DANGLING(logicp->unlinkDelete(m_dfg), logicp);
|
||||
}
|
||||
debugDump("synth-selected");
|
||||
@@ -1856,12 +1864,17 @@ class AstToDfgSynthesize final {
|
||||
// If synthesized, delete the corresponding AstNode. It is now in Dfg.
|
||||
logicp->nodep()->unlinkFrBack()->deleteTree();
|
||||
} else {
|
||||
// Not synthesized. Logic stays in Ast. Mark source variables
|
||||
//as read in module. Outputs already marked by revertTransivelyAndRemove.
|
||||
logicp->foreachSource([](DfgVertex& src) { //
|
||||
src.as<DfgVertexVar>()->setHasModRdRefs();
|
||||
// Not synthesized. Logic stays in Ast. Add Ast reference vertices.
|
||||
// Outputs already marked by revertTransivelyAndRemove.
|
||||
// AstVar/AstVarScope::user4p() -> corresponding DfgVertexVar* in the graph
|
||||
const VNUser4InUse m_user4InUse;
|
||||
logicp->foreachSource([](DfgVertex& src) {
|
||||
src.as<DfgVertexVar>()->nodep()->user4p(&src);
|
||||
return false;
|
||||
});
|
||||
V3DfgPasses::addAstRefs(m_dfg, logicp->nodep(), [](AstNode* varp) { //
|
||||
return varp->user4u().to<DfgVertexVar*>();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete this DfgLogic
|
||||
|
||||
Reference in New Issue
Block a user