Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a warning for large unrolled loops #234

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

lwaern-intel
Copy link
Contributor

This is both a proper PR and also just a Jenkins Pretest target to figure out how bad the issue is on VP

py/dml/codegen.py Outdated Show resolved Hide resolved
@syssimics
Copy link
Contributor

Verification #12467586: pass

@lwaern-intel lwaern-intel force-pushed the lw/unrolled-loop-warning branch from 08bda7f to d6cbc1a Compare June 14, 2024 12:31
@syssimics
Copy link
Contributor

Verification #13501484: ✅ pass

@lwaern-intel lwaern-intel requested a review from mandolaerik June 14, 2024 14:42
which is emitted when a <tt>#select</tt> or <tt>#foreach</tt> statement is
compiled to a large unrolled loop.
This warning is only enabled by default with Simics API version 8 or
above. With version 7 and below it must be explicitly enabledby passing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enabled by

if else_dead:
(last_cond, last_stmt) = clauses.pop(-1)
assert last_cond.constant and last_cond.value
if_chain = last_stmt
else:
if_chain = codegen_statement(else_ast, location, scope)
if iterations > WBIGUNROLL.limit and isinstance(lst, List):
report(WBIGUNROLL(stmt.site,
'#'*(stmt.site.dml_version() != (1, 2))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space around binop

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a stylistic choice we can quibble about: when combining + and *, I actually prefer omitting spaces around *; I feel that increases readability re. operator precedence. I see it as similar to implicit multiplication in math via concatenation (2(3)).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we don't combine + and *. but we do combine * and !=.

And I agree that PEP-8 is not always optimal; in particular, I find f(foo=bar == 2) a bit weird. But I just accept and obey the style for consistency, unless there's strong reasons not to.

Copy link
Contributor Author

@lwaern-intel lwaern-intel Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we don't combine + and *

I mean... we are, though the + is on a new line. That's good enough for readability, I admit. Though that doesn't apply to the below '#'*(site.dml_version() != (1, 2)) + 'foreach',

we do combine * and !=`.

Not on the same syntactic level, the != is within an (); I'm talking about * and +, which is on the same syntactic level, and where operator precedence determines how associations are made. This is where I'm arguing that omitting spaces around * such that such parts are more obviously whole terms helps readability. To exemplify, compare

   bla_bla_blau * blib * blub_blub + glabradahadaba + blara * dabara
+ canyoutellthat * ihavegivenup + on * variable * naming

vs.

   bla_bla_blau*blib*blub_blub + glabradahadaba + blara*dabara
+ canyoutellthat*ihavegivenupon + on*variable*naming

And that does apply to '#'*(site.dml_version() != (1, 2)) + 'foreach', but not as strongly. If you write out:

'#' * (site.dml_version() != (1, 2)) + 'foreach'

It's not as obviously clear at a glance that the (site.dml_version() != (1, 2)) is used for controlling a term of the string concatenation sequence, as opposed to being a term in of itself. Of course, the counterargument to that would be parentheses...:

('#' * (site.dml_version() != (1, 2))) + 'foreach'

If you insist on spacing, I would do the above. even though i kinda hate it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't see the + because of how GH crops things. Still, I find it strange to break the spacing rule when you have a binop within an operand where you do obey the spacing rule.

If you ask me what I prefer, then it's the normal python idiom for expressing when a value depends on a condition:

('' if version == (1, 2) else '#') + 'foreach'

I quite strongly dislike the use of bools for arithmetic on iterables. But I tolerate it since it doesn't break any agreed-upon style.

@@ -3162,6 +3169,10 @@ def foreach_constant_list(site, itername, lst, statement, location, scope):
stmt)
spec.append(mkCompound(site, decls + [stmt]))

if len(spec) > WBIGUNROLL.limit and isinstance(lst, List):
report(WBIGUNROLL(site,
'#'*(site.dml_version() != (1, 2)) + 'foreach',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space around binop

Comment on lines +206 to +207
information, see the documentation of `WBIGUNROLL` in the
[Messages](messages.html) section.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better with a direct link, add <a id= on the destination if needed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, seems that messages.html#dt:wbigunroll would work out-of-the-box

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whaaat
That's a thing? Wow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though validate_md_links.py hates it. I guess we could patch it to tolerate #dt:blabla if any line in the target file starts with * blabla?

Copy link
Contributor Author

@lwaern-intel lwaern-intel Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, seems that messages.html#dt:wbigunroll would work out-of-the-box

wait. What experiment did you do, that made you say this?
If we look at what messages_to_md.py does...

        f.write(f"  <dt><b>\n\n{fmt_message(m)} [{m.__name__}]</b></dt>\n")

Looking at this, I don't understand why the hyperlink syntax would pick out and work specifically with m.__name__.

If this doesn't work, maybe the better approach is to just tweak messages_to_md.py to generate those anchors, so we don't have to hand-write them.

Copy link
Contributor

@mandolaerik mandolaerik Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What experiment did you do, that made you say this?

I looked at the generated messages.html, and also typed file:///path/to/messages.html#dt:wsystemc into my web browser

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... huh!

Comment on lines +219 to +221
explicitly suppressed via `--no-warn=WBIGUNROLL`. In contrast,
`--warn=WBIGUNROLL` doesn't allow for `WBIGUNROLL` to be suppressed at
all.'''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's somewhat weird, when you pass --X --no-X to a compiler, you expect that the one that appears last takes precedence.

In any case, I think we can drop this paragraph entirely; there is no essential difference and the main reason for a compat feature is for consistency with other things that change with API 8.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with dropping the explanation of the difference; that was inherited from the description of suppress_WLOGMIXUP, but it doesn't bear repeating. Though, I think I should keep the mention that you can either use --warn=WBIGUNROLL or --no-compat=suppress_WBIGUNROLL.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should keep the mention that you can either use --warn=WBIGUNROLL or --no-compat=suppress_WBIGUNROLL.

Agreed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants