diff --git a/py/dml/codegen.py b/py/dml/codegen.py index af092ef6e..4b87cd74e 100644 --- a/py/dml/codegen.py +++ b/py/dml/codegen.py @@ -3055,7 +3055,7 @@ def stmt_select(stmt, location, scope): if_chain = last_stmt else: if_chain = codegen_statement(else_ast, location, scope) - if iterations > 50 and isinstance(lst, List): + if iterations > WBIGUNROLL.limit and isinstance(lst, List): report(WBIGUNROLL(stmt.site, '#'*(stmt.site.dml_version() != (1, 2)) + 'select', @@ -3186,7 +3186,7 @@ def foreach_constant_list(site, itername, lst, statement, location, scope): stmt) spec.append(mkCompound(site, decls + [stmt])) - if len(spec) > 50 and isinstance(lst, List): + if len(spec) > WBIGUNROLL.limit and isinstance(lst, List): report(WBIGUNROLL(site, '#'*(site.dml_version() != (1, 2)) + 'foreach', len(spec))) diff --git a/py/dml/messages.py b/py/dml/messages.py index b8756bbe7..8f27fd5cc 100644 --- a/py/dml/messages.py +++ b/py/dml/messages.py @@ -2012,16 +2012,17 @@ class WHOOKSEND(DMLWarning): + "information about the differences between 'send' and 'send_now'") class WBIGUNROLL(DMLWarning): - """ + limit = 64 + __doc__ = f""" A `#select` or `#foreach` statement was specified which caused DMLC to study the body and generate duplicated C code for it a large number of - times (more than 50 times.) This can dramatically increase both DMLC and - GCC compile times and code size, if not crash DMLC outright. + times (more than {limit} times.) This can dramatically increase both DMLC + and GCC compile times and code size, if not crash DMLC outright. To address this, you have two options: * Ensure most iterations can be entirely eliminated at compile-time by DMLC. For `#select`, this can be done by ensuring that the `where` check - will be a constant (typically a constant equality) for most if not all + will be a constant value (e.g. a constant equality) for most if not all items of the specified list. For `#foreach`, encase the body in an `#if` check that is false for most items of the specified list. * Don't use `#select` or `#foreach`. Represent the specified compile-time diff --git a/test/1.2/errors/T_WBIGUNROLL.dml b/test/1.2/errors/T_WBIGUNROLL.dml index 8e4f4b340..81d63c574 100644 --- a/test/1.2/errors/T_WBIGUNROLL.dml +++ b/test/1.2/errors/T_WBIGUNROLL.dml @@ -11,61 +11,64 @@ device test; data int zero = 0; -parameter zeroes_50 = [$zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, +parameter zeroes_64 = [$zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, - $zero, $zero]; + $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, + $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero]; -// Fiftieth zero is constant -parameter zeroes_51 = [$zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, +// Sixtyfourth zero is constant +parameter zeroes_65 = [$zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, + $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, $zero, - $zero, 0, $zero]; + $zero, $zero, $zero, $zero, $zero, $zero, $zero, 0, + $zero]; bank b { - register regs[i in 0..50] size 4 @ undefined; + register regs[i in 0..64] size 4 @ undefined; } method init { - local int i; + local int nonconstant; // no warning - foreach x in ($zeroes_50) assert true; + foreach x in ($zeroes_64) assert true; // The else branch is not considered an iteration - select x in ($zeroes_50) where (x == i) { + select x in ($zeroes_64) where (x == nonconstant) { assert true; } else assert true; /// WARNING WBIGUNROLL - foreach x in ($zeroes_51) assert true; + foreach x in ($zeroes_65) assert true; /// WARNING WBIGUNROLL - select x in ($zeroes_51) where (x == i) { + select x in ($zeroes_65) where (x == nonconstant) { assert true; } else assert true; // no warning - foreach x in ($zeroes_51) { - // As fiftieth bit is constant 0, DML 1.2 semantics eliminates this if - // entirely, and subsequently causes that iteration to be omitted from - // codegen entirely; reducing the total count to 50 + foreach x in ($zeroes_65) { + // As sixtyfourth bit is constant 0, DML 1.2 semantics eliminates this + // if, and subsequently causes that iteration to be omitted from + // codegen entirely; reducing the total count to 64 if (x != 0) assert true; } - // As fiftieth bit is constant 0, select can cut short at it, reducing the - // total number of iterations to 50 - select x in ($zeroes_50) where (x == 0) { + // As sixtyfourth bit is constant 0, select can cut short at it, reducing + // the total number of iterations to 64 + select x in ($zeroes_65) where (x == 0) { assert true; } else assert true; - // As fiftieth bit is constant 0, select can omit the check and thus - // iteration for it, reducing the total number of iterations to 50 - select x in ($zeroes_50) where (x == 1) { + // As sixtyfourth bit is constant 0, select can omit the check and thus + // iteration for it, reducing the total number of iterations to 64 + select x in ($zeroes_65) where (x != 0) { assert true; } else assert true; @@ -74,7 +77,7 @@ method init { // syntax, not the object lists generated by DMLC // no warning foreach x in ($b.unmapped_registers) assert true; - select x in ($b.unmapped_registers) where (i == 0) { + select x in ($b.unmapped_registers) where (x == nonconstant) { assert true; } else assert true; }