Fix severe runtime performance bug in certain foreach loops.
This commit is contained in:
parent
2d580e6939
commit
f55040a38b
2
Changes
2
Changes
|
|
@ -16,6 +16,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
*** Add --no-debug-leak to reduce memory use under debug. [John Coiner]
|
*** Add --no-debug-leak to reduce memory use under debug. [John Coiner]
|
||||||
|
|
||||||
|
**** Fix severe runtime performance bug in certain foreach loops. [John Coiner]
|
||||||
|
|
||||||
**** On convergence errors, show activity. [John Coiner]
|
**** On convergence errors, show activity. [John Coiner]
|
||||||
|
|
||||||
**** Fix GCC 8.0 issues, bug1273.
|
**** Fix GCC 8.0 issues, bug1273.
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,7 @@ private:
|
||||||
FileLine* fl = varsp->fileline();
|
FileLine* fl = varsp->fileline();
|
||||||
AstNode* varp = new AstVar(fl, AstVarType::BLOCKTEMP,
|
AstNode* varp = new AstVar(fl, AstVarType::BLOCKTEMP,
|
||||||
varsp->name(), nodep->findSigned32DType());
|
varsp->name(), nodep->findSigned32DType());
|
||||||
|
// These will be the left and right dimensions of the array:
|
||||||
AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT,
|
AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT,
|
||||||
new AstVarRef(fl, arrayp->name(), false),
|
new AstVarRef(fl, arrayp->name(), false),
|
||||||
new AstConst(fl, dimension));
|
new AstConst(fl, dimension));
|
||||||
|
|
@ -347,19 +348,26 @@ private:
|
||||||
new AstVarRef(fl, arrayp->name(), false),
|
new AstVarRef(fl, arrayp->name(), false),
|
||||||
new AstConst(fl, dimension));
|
new AstConst(fl, dimension));
|
||||||
AstNode* stmtsp = varp;
|
AstNode* stmtsp = varp;
|
||||||
stmtsp->addNext(new AstAssign(fl, new AstVarRef(fl, varp->name(), true), leftp));
|
// Assign left-dimension into the loop var:
|
||||||
AstNode* comparep =
|
stmtsp->addNext(new AstAssign
|
||||||
new AstCond(fl, new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true)),
|
(fl, new AstVarRef(fl, varp->name(), true), leftp));
|
||||||
// left increments up to right
|
// This will turn into a bool constant, indicating whether
|
||||||
new AstLte(fl, new AstVarRef(fl, varp->name(), false), rightp->cloneTree(true)),
|
// we count the loop variable up or down:
|
||||||
// left decrements down to right
|
AstNode* countupp = new AstLte(fl, leftp->cloneTree(true),
|
||||||
new AstGte(fl, new AstVarRef(fl, varp->name(), false), rightp));
|
rightp->cloneTree(true));
|
||||||
AstNode* incp =
|
AstNode* comparep = new AstCond(
|
||||||
new AstAssign(fl, new AstVarRef(fl, varp->name(), true),
|
fl, countupp->cloneTree(true),
|
||||||
new AstAdd(fl, new AstVarRef(fl, varp->name(), false),
|
// Left increments up to right
|
||||||
new AstNegate(fl, new AstAttrOf(fl, AstAttrType::DIM_INCREMENT,
|
new AstLte(fl, new AstVarRef(fl, varp->name(), false),
|
||||||
new AstVarRef(fl, arrayp->name(), false),
|
rightp->cloneTree(true)),
|
||||||
new AstConst(fl, dimension)))));
|
// Left decrements down to right
|
||||||
|
new AstGte(fl, new AstVarRef(fl, varp->name(), false), rightp));
|
||||||
|
AstNode* incp = new AstAssign(
|
||||||
|
fl, new AstVarRef(fl, varp->name(), true),
|
||||||
|
new AstAdd(fl, new AstVarRef(fl, varp->name(), false),
|
||||||
|
new AstCond(fl, countupp,
|
||||||
|
new AstConst(fl, 1),
|
||||||
|
new AstConst(fl, -1))));
|
||||||
stmtsp->addNext(new AstWhile(fl, comparep, newp, incp));
|
stmtsp->addNext(new AstWhile(fl, comparep, newp, incp));
|
||||||
newp = new AstBegin(nodep->fileline(),"",stmtsp);
|
newp = new AstBegin(nodep->fileline(),"",stmtsp);
|
||||||
dimension--;
|
dimension--;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|
||||||
compile (
|
compile (
|
||||||
|
verilator_flags2 => ['--assert']
|
||||||
);
|
);
|
||||||
|
|
||||||
execute (
|
execute (
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,24 @@ module t (/*AUTOARG*/);
|
||||||
reg [63:0] sum;
|
reg [63:0] sum;
|
||||||
reg [2:1] [4:3] array [5:6] [7:8];
|
reg [2:1] [4:3] array [5:6] [7:8];
|
||||||
reg [1:2] [3:4] larray [6:5] [8:7];
|
reg [1:2] [3:4] larray [6:5] [8:7];
|
||||||
|
bit [31:0] depth1_array [0:0];
|
||||||
|
|
||||||
function [63:0] crc (input [63:0] sum, input [31:0] a, input [31:0] b, input [31:0] c, input [31:0] d);
|
function [63:0] crc (input [63:0] sum, input [31:0] a, input [31:0] b, input [31:0] c, input [31:0] d);
|
||||||
crc = {sum[62:0],sum[63]} ^ {4'b0,a[7:0], 4'h0,b[7:0], 4'h0,c[7:0], 4'h0,d[7:0]};
|
crc = {sum[62:0],sum[63]} ^ {4'b0,a[7:0], 4'h0,b[7:0], 4'h0,c[7:0], 4'h0,d[7:0]};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
|
sum = 0;
|
||||||
|
foreach (depth1_array[index]) begin
|
||||||
|
sum = crc(sum, index, 0, 0, 0);
|
||||||
|
|
||||||
|
// Ensure the index never goes out of bounds.
|
||||||
|
// We used to get this wrong for an array of depth 1.
|
||||||
|
assert (index != -1);
|
||||||
|
assert (index != 1);
|
||||||
|
end
|
||||||
|
`checkh(sum, 64'h0);
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
foreach (array[a]) begin
|
foreach (array[a]) begin
|
||||||
sum = crc(sum, a, 0, 0, 0);
|
sum = crc(sum, a, 0, 0, 0);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue