Remove redundant AND with 1 (#2791)

This commit is contained in:
Yutetsu TAKATSUKASA 2021-02-18 19:28:49 +09:00 committed by GitHub
parent c1b6faff6d
commit 120322df3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -168,6 +168,34 @@ private:
return (lp && VN_IS(lp->lhsp(), Const) && VN_IS(np->rhsp(), Const)
&& lp->width() == np->width());
}
bool matchRedundantClean(AstAnd* andp) {
// Remove And with constant one inserted by V3Clean
// 1 & (a == b) -> (IData)(a == b)
// When bool is casted to int, the value is either 0 or 1
AstConst* constp = VN_CAST(andp->lhsp(), Const);
UASSERT_OBJ(constp && constp->isOne(), andp->lhsp(), "TRREEOPC must meet this condition");
AstNode* rhsp = andp->rhsp();
AstCCast* ccastp = nullptr;
auto isEqOrNeq
= [](AstNode* nodep) -> bool { return VN_IS(nodep, Eq) || VN_IS(nodep, Neq); };
if (isEqOrNeq(rhsp)) {
ccastp = new AstCCast{andp->fileline(), rhsp->unlinkFrBack(), andp};
} else if (AstCCast* tmpp = VN_CAST(rhsp, CCast)) {
if (isEqOrNeq(tmpp->lhsp())) {
if (tmpp->width() == andp->width()) {
tmpp->unlinkFrBack();
ccastp = tmpp;
} else {
ccastp = new AstCCast{andp->fileline(), tmpp->lhsp()->unlinkFrBack(), andp};
}
}
}
if (ccastp) {
andp->replaceWith(ccastp);
VL_DO_DANGLING(andp->deleteTree(), andp);
}
return ccastp;
}
static bool operandAndOrSame(const AstNode* nodep) {
// OR( AND(VAL,x), AND(VAL,y)) -> AND(VAL,OR(x,y))
@ -2291,6 +2319,7 @@ private:
TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)"); // a % 2^n -> a&(2^n-1)
TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y))
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
// Trinary ops
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");