Fix V3Gate crash on circular logic

The recent patch to defer substitutions on V3Gate crashes on circular
logic that has cycle length >= 3 with all inlineable signals (cycle
length 2 is detected correctly and is not inlined). Fix by stopping
recursion at the loop-back edge.

Fixes #3543
This commit is contained in:
Geza Lore
2022-09-02 19:58:58 +01:00
parent 8e8f4b1e5c
commit d42a2d6494
4 changed files with 47 additions and 3 deletions
+13 -3
View File
@@ -985,11 +985,18 @@ static void eliminate(AstNode* logicp,
const std::unordered_map<AstVarScope*, AstNode*>& substitutions,
GateDedupeVarVisitor* varVisp) {
const std::function<void(AstNodeVarRef*)> visit
= [&substitutions, &visit, varVisp](AstNodeVarRef* nodep) -> void {
// Recursion filter holding already replaced variables
std::unordered_set<const AstVarScope*> replaced(substitutions.size() * 2);
const std::function<void(AstNodeVarRef*)> visit = [&, varVisp](AstNodeVarRef* nodep) -> void {
// See if this variable has a substitution
const auto& it = substitutions.find(nodep->varScopep());
AstVarScope* const vscp = nodep->varScopep();
const auto& it = substitutions.find(vscp);
if (it == substitutions.end()) return;
// Do not substitute circular logic
if (!replaced.insert(vscp).second) return;
AstNode* const substp = it->second;
// Substitute in the new tree
@@ -1016,6 +1023,9 @@ static void eliminate(AstNode* logicp,
VL_DO_DANGLING(nodep->deleteTree(), nodep);
// Recursively substitute the new tree
newp->foreach<AstNodeVarRef>(visit);
// Remove from recursion filter
replaced.erase(vscp);
};
logicp->foreach<AstNodeVarRef>(visit);