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:
parent
5d344ab8ff
commit
9455dddab4
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue