diff --git a/src/V3Const.cpp b/src/V3Const.cpp index e66b760a7..09e752aac 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -94,6 +94,7 @@ private: bool m_wremove = true; // Inside scope, no assignw removal bool m_warn = false; // Output warnings bool m_doExpensive = false; // Enable computationally expensive optimizations + bool m_doCpp = false; // Enable late-stage C++ optimizations bool m_doNConst = false; // Enable non-constant-child simplifications bool m_doShort = true; // Remove expressions that short circuit bool m_doV = false; // Verilog, not C++ conversion @@ -1967,7 +1968,6 @@ private: bool stmtDisplayDisplay(AstDisplay* nodep) { // DISPLAY(SFORMAT(text1)),DISPLAY(SFORMAT(text2)) -> DISPLAY(SFORMAT(text1+text2)) if (!m_modp) return false; // Don't optimize under single statement - if (!nodep->backp()) return false; AstDisplay* prevp = VN_CAST(nodep->backp(), Display); if (!prevp) return false; if (!((prevp->displayType() == nodep->displayType()) @@ -1981,12 +1981,21 @@ private: return false; if (!prevp->fmtp() || prevp->fmtp()->nextp() || !nodep->fmtp() || nodep->fmtp()->nextp()) return false; - // We don't merge scopeNames as might be different scopes (late in process) - // We don't merge arguments as might need to later print warnings with right line numbers AstSFormatF* pformatp = prevp->fmtp(); - if (!pformatp || pformatp->exprsp() || pformatp->scopeNamep()) return false; + if (!pformatp) return false; AstSFormatF* nformatp = nodep->fmtp(); - if (!nformatp || nformatp->exprsp() || nformatp->scopeNamep()) return false; + if (!nformatp) return false; + // We don't merge scopeNames as can have only one and might be different scopes (late in + // process) Also rare for real code to print %m multiple times in same message + if (nformatp->scopeNamep() && pformatp->scopeNamep()) return false; + // We don't early merge arguments as might need to later print warnings with + // right line numbers, nor scopeNames as might be different scopes (late in process) + if (!m_doCpp && pformatp->exprsp()) return false; + if (!m_doCpp && nformatp->exprsp()) return false; + // Avoid huge merges + static constexpr int DISPLAY_MAX_MERGE_LENGTH = 500; + if (pformatp->text().length() + nformatp->text().length() > DISPLAY_MAX_MERGE_LENGTH) + return false; // UINFO(9, "DISPLAY(SF({a})) DISPLAY(SF({b})) -> DISPLAY(SF({a}+{b}))" << endl); // Convert DT_DISPLAY to DT_WRITE as may allow later optimizations @@ -1998,9 +2007,10 @@ private: // So instead we edit the prev note itself. if (prevp->addNewline()) pformatp->text(pformatp->text() + "\n"); pformatp->text(pformatp->text() + nformatp->text()); - if (!prevp->addNewline() && nodep->addNewline()) { - pformatp->text(pformatp->text() + "\n"); - } + if (!prevp->addNewline() && nodep->addNewline()) pformatp->text(pformatp->text() + "\n"); + if (nformatp->exprsp()) pformatp->addExprsp(nformatp->exprsp()->unlinkFrBackWithNext()); + if (nformatp->scopeNamep()) + pformatp->scopeNamep(nformatp->scopeNamep()->unlinkFrBackWithNext()); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return true; } @@ -2549,7 +2559,7 @@ public: case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; break; case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break; case PROC_V_EXPENSIVE: m_doV = true; m_doNConst = true; m_doExpensive = true; break; - case PROC_CPP: m_doV = false; m_doNConst = true; break; + case PROC_CPP: m_doV = false; m_doNConst = true; m_doCpp = true; break; default: v3fatalSrc("Bad case"); break; } // clang-format on diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index ea15ef3a6..8aedcb160 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -576,9 +576,9 @@ public: emitIQW(nodep->outp()); puts("("); puts(cvtToStr(nodep->outp()->widthMin())); - puts(","); + puts(", "); emitCvtPackStr(nodep->searchp()); - puts(","); + puts(", "); putbs(""); iterateAndNextNull(nodep->outp()); puts(")"); diff --git a/test_regress/t/t_display_merge.out b/test_regress/t/t_display_merge.out index 7ab198f50..358455d76 100644 --- a/test_regress/t/t_display_merge.out +++ b/test_regress/t/t_display_merge.out @@ -1,8 +1,7 @@ Merge: This should merge f - a=top.t - b=top.t + 1=1 a=top.t 1=1 1=1 b=top.t 1=1 pre t=0 t2=0 @@ -15,5 +14,14 @@ m mm f a=top.t b=top.t pre t=0 t2=0 post t3=0 t4=0 t5=0 0m t=0 t2=0 t3=0 t4=0 t5=0 t=0 t2=0 t3=0 t4=0 t5=0mm +very very very very very very very very very very very very very very very very very very very very very very +very very very very very very very very very very very very very very very very very very very very very very +very very very very very very very very very very very very very very very very very very very very very very +very very very very very very very very very very very very very very very very very very very very very very +very very very very very very very very very very very very very very very very very very very very very very +very very very very very very very very very very very very very very very very very very very very very very +very very very very very very very very very very very very very very very very very very very very very very +11111 11111 +11111 11111 *-* All Finished *-* diff --git a/test_regress/t/t_display_merge.pl b/test_regress/t/t_display_merge.pl index 67b3d10f3..66642748d 100755 --- a/test_regress/t/t_display_merge.pl +++ b/test_regress/t/t_display_merge.pl @@ -20,7 +20,7 @@ execute( ); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}__stats.txt", - qr/Node count, DISPLAY \s+ 32 \s+ 25 \s+ 25 \s+ 25/); + qr/Node count, DISPLAY \s+ 41 \s+ 27 \s+ 27 \s+ 6/); ok(1); 1; diff --git a/test_regress/t/t_display_merge.v b/test_regress/t/t_display_merge.v index cdf8ea8cc..9d5b1e3ec 100644 --- a/test_regress/t/t_display_merge.v +++ b/test_regress/t/t_display_merge.v @@ -5,6 +5,14 @@ // SPDX-License-Identifier: CC0-1.0 module t (/*AUTOARG*/); + int one = +`ifdef verilator + $c32(1) +`else + 1 +`endif + ; + initial begin $display("Merge:"); $write("This "); @@ -12,8 +20,8 @@ module t (/*AUTOARG*/); $display("merge"); $display("f"); - $display(" a=%m"); - $display(" b=%m"); + $write(" 1=%0d a=%m 1=%0d", one, one); + $display(" 1=%0d b=%m 1=%0d", one, one); $display(" pre"); $display(" t=%0d",$time); $display(" t2=%0d",$time); @@ -40,6 +48,19 @@ module t (/*AUTOARG*/); $write(" t=%0d t2=%0d t3=%0d t4=%0d t5=%0d",$time,$time,$time,$time,$time); $display("mm"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("very very very very very very very very very very very very very very very very very very very very very very"); + $display("%0d%0d%0d%0d%0d %0d%0d%0d%0d%0d", + one, one, one, one, one, + one, one, one, one, one); + $display("%0d%0d%0d%0d%0d %0d%0d%0d%0d%0d", + one, one, one, one, one, + one, one, one, one, one); $write("\n*-* All Finished *-*\n"); $finish; end