Skip to content

Conversation

@devv64
Copy link
Contributor

@devv64 devv64 commented May 14, 2025

Closes #504
@gerardogtn

Copy link
Owner

@sampsyo sampsyo left a 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.
Copy link
Owner

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.
Copy link
Owner

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)
Copy link
Owner

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"
Copy link
Owner

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"
},
Copy link
Owner

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).
Copy link
Owner

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.
Copy link
Owner

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.

Copy link
Contributor

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

Copy link
Owner

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.
Copy link
Owner

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. :)

Comment on lines 437 to 443
### 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
Copy link
Owner

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!

@gerardogtn
Copy link
Contributor

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? 😇

For the briloop language extension, we tried to keep things separate in the development repo by making a copy of briltxt.py and naming it brilooptxt.py for example. Would you prefer we merge this into the briltxt.py and keep it as the default behaviour of bril2json/bril2txt, or would you prefer to keep them as separate commands?

I'll work on sending a PR with the beyond relooper algorithm!

@sampsyo
Copy link
Owner

sampsyo commented May 15, 2025

For the briloop language extension, we tried to keep things separate in the development repo by making a copy of briltxt.py and naming it brilooptxt.py for example. Would you prefer we merge this into the briltxt.py and keep it as the default behaviour of bril2json/bril2txt, or would you prefer to keep them as separate commands?

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.

@sampsyo
Copy link
Owner

sampsyo commented May 15, 2025

Anyway, this all looks great! I'll publish this post now.

@sampsyo sampsyo merged commit 52e3145 into sampsyo:2025sp May 15, 2025
2 checks passed
@sampsyo sampsyo added the 2025sp label May 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Project Proposal: Brilooped

3 participants