-
Notifications
You must be signed in to change notification settings - Fork 199
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
feat: try to inline brillig calls with all constant arguments #6466
base: master
Are you sure you want to change the base?
Conversation
Changes to circuit sizes
🧾 Summary (10% most significant diffs)
Full diff report 👇
|
We are often going to eliminate all usage of certain brillig functions at this step but they end up being retained (and show up in |
Sure! Though... I just checked with this program: fn main(x: Field) -> pub Field {
let (a, _) = unsafe { identity(5) };
assert_eq(a, 5);
x + a
}
unconstrained fn identity(x: Field) -> (Field, Field) {
let y = x;
let z = y - 1;
let w = z + 1;
identity2(w)
}
unconstrained fn identity2(x: Field) -> (Field, Field) {
(x, x)
} and
It seems after the |
…noir into ab/inline-const-brillig-calls
I get the below SSA
We do remove this after the final inlining step but there's 9 passes in between these two steps so we get a good amount of unnecessary output in the SSA display |
Oooh... you mean removing them in this same pass, right? Sure, I'll do it :-) |
Yep, that's it |
One extra thing to note is that this branch panics on the testcase added in #6464 (as opposed to just compiling to incorrect code). Obviously there's a different issue in the compiler affecting that code already but fyi. |
Ah, it's also with loop unrolling. I had to change something in this PR to workaround an issue... I guess I'll have to learn how loop unrolling works, and why it doesn't work in these brillig functions turned into ACIR. |
71e2b29
to
59aed41
Compare
I managed to reduce the code that triggers the panic in bignum_regression: fn main() {
unsafe { foo() };
}
unconstrained fn foo() {
for i in 0..1 {
if i == 0 {
break;
}
}
} It seems it's failing because of that I can try to fix loop unrolling to account for this case, though it will likely take me a lot of time. Alternatively, we can avoid trying to inline these functions if we know they have Which one should I do? |
For now I pushed a commit that makes it not panic. I wonder if loop unrolling should be able to work in two modes, ACIR or "ACIR from Brillig". That way we can still panic and use |
For now let's just skip inlining that function and we can make improvements later. |
Sounds good, done! |
(just asked a review to signal that this is ready for review) |
compiler/noirc_evaluator/src/ssa/opt/inline_const_brillig_calls.rs
Outdated
Show resolved
Hide resolved
compiler/noirc_evaluator/src/ssa/opt/inline_const_brillig_calls.rs
Outdated
Show resolved
Hide resolved
compiler/noirc_evaluator/src/ssa/opt/inline_const_brillig_calls.rs
Outdated
Show resolved
Hide resolved
compiler/noirc_evaluator/src/ssa/opt/inline_const_brillig_calls.rs
Outdated
Show resolved
Hide resolved
compiler/noirc_evaluator/src/ssa/opt/inline_const_brillig_calls.rs
Outdated
Show resolved
Hide resolved
compiler/noirc_evaluator/src/ssa/opt/inline_const_brillig_calls.rs
Outdated
Show resolved
Hide resolved
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.
LGTM!
I marked this PR as draft because I want to try the other approach first (trying to invoke brillig functions, then inlining the results into the SSA and optimizing again) |
Description
Problem
Resolves #6453
Summary
Adds a pass that tries to inline brillig calls where all arguments are constant.
This is done by first creating a copy of the function, setting its runtime to ACIR, replacing its parameters by the call arguments, optimizing the function like we optimize everything else (except inlining no-predicates, because that requires all the functions to be in context: maybe this can be done as a follow-up PR but I'm not sure if it's worth it), then checking if the function was reduced to a single return terminator instruction.
Additional Context
The changes to the loop unrolling code are mainly there because now loop unrolling can happen inside brillig calls that we are trying to optimize out, so they can contain
break
and generally have a struct that can't happen in ACIR functions. I'm happy to try to find another way to do this, let me know!Documentation
Check one:
PR Checklist
cargo fmt
on default settings.