Optimize additional display statements (#2702).

This commit is contained in:
Wilson Snyder 2020-12-19 11:12:46 -05:00
parent 788de3ad24
commit b93e409f0e
5 changed files with 55 additions and 16 deletions

View File

@ -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

View File

@ -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(")");

View File

@ -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 *-*

View File

@ -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;

View File

@ -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