Optimize if branches with same trailing statements (#7674)

If the same statements appears in both branches of an 'if', put a single
copy after the 'if', apply recursively. This also has the effect of
getting rid of conditionals with identical branches, but is more widely
applicable.
This commit is contained in:
Geza Lore 2026-05-29 11:26:07 +01:00 committed by GitHub
parent 5d344ab8ff
commit 9455dddab4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 0 deletions

View File

@ -541,6 +541,14 @@ public:
AstNode* backp() const VL_MT_STABLE { return m_backp; }
AstNode* abovep() const; // Get parent node above, only for list head and tail
AstNode* aboveLoopp() const; // Get parent node above, may have performance issues as loops
AstNode* lastp() const { // Get last node in list, only for list head
UASSERT_OBJ(m_backp->m_nextp != this, this, "lastp() only allowed on head of list");
return m_headtailp;
}
AstNode* prevp() const { // Previous node in list, nullptr for head of list
if (m_backp->m_nextp != this) return nullptr;
return m_backp;
}
AstNode* op1p() const VL_MT_STABLE { return m_op1p; }
AstNode* op2p() const VL_MT_STABLE { return m_op2p; }
AstNode* op3p() const VL_MT_STABLE { return m_op3p; }

View File

@ -1230,6 +1230,24 @@ class ConstVisitor final : public VNVisitor {
}
}
void matchIfSameLast(AstNodeIf* nodep) {
if (!nodep->thensp()) return;
if (!nodep->elsesp()) return;
// Iterate bodies in reverse
AstNode* tp = nodep->thensp()->lastp();
AstNode* ep = nodep->elsesp()->lastp();
while (tp && ep && tp->sameTree(ep)) {
UASSERT_OBJ(!tp->nextp(), tp, "Expected no nextp");
UASSERT_OBJ(!ep->nextp(), ep, "Expected no nextp");
AstNode* const tPrevp = tp->prevp();
AstNode* const ePrevp = ep->prevp();
nodep->addNextHere(tp->unlinkFrBack());
VL_DO_DANGLING(pushDeletep(ep->unlinkFrBack()), ep);
tp = tPrevp;
ep = ePrevp;
}
}
bool matchMaskedOr(AstAnd* nodep) {
// Masking an OR with terms that have no bits set under the mask is replaced with masking
// only the remaining terms. Canonical example as generated by V3Expand is:
@ -3636,6 +3654,7 @@ class ConstVisitor final : public VNVisitor {
} else {
// Optimizations that don't reform the IF itself
if (operandBoolShift(nodep->condp())) replaceBoolShift(nodep->condp());
matchIfSameLast(nodep);
matchIfCondCond(nodep);
}
}