-
Notifications
You must be signed in to change notification settings - Fork 216
Add Brilooped #541
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 Brilooped #541
Conversation
sampsyo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very very cool; nice work here! This is a substantial chunk of implementation work, and you've done a great job of explaining what you've done. And the empirical evaluation is great as well!!
I would love to merge two things into the main Bril monorepo:
- The specification of the Briloop language extension.
- The "Beyond Relooper" implementation that does the transformation.
Could I have your help opening some PRs for those into the Bril repo so we can get those merged? 😇
|
|
||
| ## Abstract | ||
|
|
||
| In this project we introduce Briloop, an extension into the [Bril programming language](https://capra.cs.cornell.edu/bril/) that supports structured control flow, this allows bril programs to use if-then-else, while, and block statements instead of relying on jumps and branches. We also implemented Ramsey's [Beyond Relooper](https://dl.acm.org/doi/10.1145/3547621) to translate bril programs into briloop automatically, having a an average performance penalty of 9% when using the core bril benchmarks. Brilooped not only enables programmers to write bril programs with structured control flow, but also enables a translation from Bril into WebAssembly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to keep capitalization consistent throughout the post: bril -> Bril and briloop -> Briloop.
|
|
||
| ## Representing Briloop Programs | ||
|
|
||
| Brilooped programs extends the Bril instruction set with the following op codes: while, block, if, break, and continue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a good idea to mark these opcode names with Markdown code backticks: while, block, if, etc.
|
|
||
| - It takes exactly one argument: a string containing the name of a boolean variable that serves as the loop condition. | ||
| - It includes an additional `children` field that contains an array of arrays of `Instr` objects representing the loop body. | ||
| - Note: this is an array of arrays to make the language a little more uniform (children field is used in both while loops and if-then-else statements) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…and presumably block as well?
Maybe it would be a good idea to, before getting into the individual opcodes, introduce this new children field in general and say that it will be used in several operations. It's interesting to highlight this up front because it means that Brilloop programs, unlike classic Bril programs, look "nested."
| } | ||
| ] | ||
| ], | ||
| "op": "while" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider putting op first in the dictionary, for legibility.
| ] | ||
| ], | ||
| "op": "while" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSON listings might be a little easier to read if you "wrap" some lines manually. For example, it can be nice to put entire instructions on one line, like this:
{ "args": ["b", "ten"], "dest": "cond", "op": "le", "type": "bool" }Same with, like, "args": ["cond"]. It requires a little manual reformatting vs. what you get out of a raw json.dump, but it makes a big difference for the reader.
|
|
||
| ### Merge nodes | ||
|
|
||
| Identifying merge nodes is a key part of the briloop algorithm, they are defined as nodes that have at least 2 in edges from nodes with a smaller reverse post order. This means that in the original control flow, there are two basic blocks that jump into it and that thse nodes do not form a loop. Detecting them is important since we need to rely on block statements and break instructions in order to reach them (see Theorem three in Peterson, Kasami, and Tokura for more info). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to hyperlink from those author names to the paper you're referring to.
| } | ||
| ``` | ||
|
|
||
| The quirk from the translation to bril to briloop is that we rely on all while loops to execute forever and rely on break statements to terminate the loop execution. This has the unfortunate consequence of worsening performance for loops (especially nested ones) as we introduce a true variable before every while translation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-actionable comment; nothing to change here] As we discussed briefly today, I think it would make sense to (in a version 1.1 of this extension) replace while with loop for this reason! It keeps the language a little simpler, and it seems unlikely to make the downstream WebAssembly backend any more complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change whiles to loop operations for the merge into the bril repo. It would definitely make things nicer and it's one of the few things that i wished we had used since the beginning instead of a while loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I think it would be just fine to merge stuff you already have, and we can try to address the while -> loop simplification in a future PR! Whatever strategy makes sense to you.
| - Recursion can be very expensive | ||
|
|
||
| 2. There doesn't seem to be any strong correlation between benchmark size and the magnitude of impact from the Brilooped transformation. Both small and large benchmarks showed varying degrees of change. Benchmarks clustered around the 10^2 instruction count range had the greatest variance, ranging from approximately -6% to +31%. | ||
| - Note: this could be a product of the benchmark suite. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can leave this note off—it's true of basically everything all the time. :)
| ### References | ||
|
|
||
| Peterson, Kasami, Tokura. "On the capabilities of while, repeat, and exit statements". https://dl.acm.org/doi/10.1145/355609.362337 | ||
|
|
||
| Ramsey, Norman. "Beyond Relooper: recursive translation of unstructured control flow to structured control flow (functional perl)". https://dl.acm.org/doi/10.1145/3547621 | ||
|
|
||
| Leroy, Xavier. "The birth of control structures: from 'goto' to structured programming". https://xavierleroy.org/CdF/2023-2024/1.pdf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is a webpage and not a PDF, I recommend just linking to these papers from the text instead of having a separate "references" section at the end!
Co-authored-by: Adrian Sampson <[email protected]>
For the briloop language extension, we tried to keep things separate in the development repo by making a copy of I'll work on sending a PR with the beyond relooper algorithm! |
I think it makes sense to just have one such command! That's the basic idea with all the Bril language extensions: the support exists in such common Bril tools as the parser and printer, but you don't have to use them. In other words, their presence in the parser/printer doesn't interfere with code that doesn't use the constructs. |
|
Anyway, this all looks great! I'll publish this post now. |
Closes #504
@gerardogtn