diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index 2cafbf3f0..c48bdbbe7 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -327,6 +327,13 @@ class V3DfgPeephole final : public DfgVisitor { return new DfgConst{m_dfg, flp, width, 0}; } + // Create a DfgConst vertex with the given width and value all ones + DfgConst* makeOnes(FileLine* flp, uint32_t width) { + DfgConst* const resp = makeZero(flp, width); + resp->num().setAllBits1(); + return resp; + } + // Create a new vertex of the given type template Vertex* make(FileLine* flp, const DfgDataType& dtype, Operands... operands) { @@ -1850,6 +1857,14 @@ class V3DfgPeephole final : public DfgVisitor { DfgVertex* const lhsp = vtxp->lhsp(); DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_EQ) { + replace(makeOnes(flp, 1)); + return; + } + } if (DfgConst* const lhsConstp = lhsp->cast()) { if (DfgConcat* const rhsConcatp = rhsp->cast()) { @@ -1860,18 +1875,62 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgGt* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_GT) { + replace(makeZero(flp, 1)); + return; + } + } } void visit(DfgGtS* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_GTS) { + replace(makeZero(flp, 1)); + return; + } + } } void visit(DfgGte* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_GTE) { + replace(makeOnes(flp, 1)); + return; + } + } } void visit(DfgGteS* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_GTES) { + replace(makeOnes(flp, 1)); + return; + } + } } void visit(DfgLogAnd* const vtxp) override { @@ -1912,18 +1971,62 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgLt* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_LT) { + replace(makeZero(flp, 1)); + return; + } + } } void visit(DfgLtS* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_LTS) { + replace(makeZero(flp, 1)); + return; + } + } } void visit(DfgLte* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_LTE) { + replace(makeOnes(flp, 1)); + return; + } + } } void visit(DfgLteS* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_LTES) { + replace(makeOnes(flp, 1)); + return; + } + } } void visit(DfgModDiv* const vtxp) override { @@ -1948,6 +2051,17 @@ class V3DfgPeephole final : public DfgVisitor { void visit(DfgNeq* const vtxp) override { if (foldBinary(vtxp)) return; + + DfgVertex* const lhsp = vtxp->lhsp(); + DfgVertex* const rhsp = vtxp->rhsp(); + FileLine* const flp = vtxp->fileline(); + + if (isSame(lhsp, rhsp)) { + APPLYING(FOLD_SELF_NEQ) { + replace(makeZero(flp, 1)); + return; + } + } } void visit(DfgPow* const vtxp) override { diff --git a/src/V3DfgPeepholePatterns.h b/src/V3DfgPeepholePatterns.h index 522d5da9a..5910167bd 100644 --- a/src/V3DfgPeepholePatterns.h +++ b/src/V3DfgPeepholePatterns.h @@ -32,6 +32,16 @@ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_ASSOC_BINARY_RHS_OF_LHS) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_BINARY) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SEL) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_EQ) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_GT) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_GTE) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_GTES) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_GTS) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_LT) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_LTE) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_LTES) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_LTS) \ + _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_NEQ) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_UNARY) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, INLINE_ARRAYSEL_SPLICE) \ _FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, INLINE_ARRAYSEL_UNIT) \ diff --git a/test_regress/t/t_dfg_peephole.v b/test_regress/t/t_dfg_peephole.v index af36586c1..c580708d7 100644 --- a/test_regress/t/t_dfg_peephole.v +++ b/test_regress/t/t_dfg_peephole.v @@ -295,6 +295,16 @@ module t ( `signal(REPLACE_ADD_WITH_COUNT_ONES_B, 32'(rand_a[63]) + 32'(rand_a[62]) + 32'(rand_a[61])); `signal(REPLACE_ADD_WITH_COUNT_ONES_C, 200'(rand_a[63]) + 200'(rand_a[62]) + 200'(rand_a[61])); `signal(REPLACE_ADD_WITH_COUNT_ONES_D, 1'(rand_a[63]) + 1'(rand_a[62]) + 1'(rand_a[61])); + `signal(FOLD_SELF_EQ, rand_a == rand_a); + `signal(FOLD_SELF_NEQ, rand_a != rand_a); + `signal(FOLD_SELF_GT, rand_a > rand_a); + `signal(FOLD_SELF_GTS, srand_a > srand_a); + `signal(FOLD_SELF_GE, rand_a >= rand_a); + `signal(FOLD_SELF_GES, srand_a >= srand_a); + `signal(FOLD_SELF_LT, rand_a < rand_a); + `signal(FOLD_SELF_LTS, srand_a < srand_a); + `signal(FOLD_SELF_LE, rand_a <= rand_a); + `signal(FOLD_SELF_LES, srand_a <= srand_a); // Operators that should work wiht mismatched widths `signal(MISMATCHED_ShiftL,const_a << 4'd2);