-
Notifications
You must be signed in to change notification settings - Fork 212
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(ssa): Hoist MakeArray instructions during loop invariant code motion #6782
Conversation
Changes to Brillig bytecode sizes
🧾 Summary (10% most significant diffs)
Full diff report 👇
|
Changes to number of Brillig opcodes executed
🧾 Summary (10% most significant diffs)
Full diff report 👇
|
Peak Memory Sample
|
Compilation Sample
|
I'll note that if we're creating an array in the loop and mutating it each iteration then this approach would be slower since we'd have an extra inc_rc instruction each iteration and need to do a dynamic check to copy the array. Overall though it's probably a fine tradeoff since the good case of this opt is much better than the worst case applying it can have. |
Yeah good note. The trade-off noted in the description is more for creating immutable arrays outside the loop. However, an array declared mutable inside the loop should already be issuing an inc_rc instruction after being created and will be copied already every iteration. |
…nto mv/hoist-make-array-fromloops
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 hoisting without the mutable checks should be fine. Unlike deduplication, there should be no chance the array in question is used between the hoist point and original point since the instruction just wasn't present there before.
…iant code motion (noir-lang/noir#6782) feat: add `(x | 1)` optimization for booleans (noir-lang/noir#6795) feat: `nargo test -q` (or `nargo test --format terse`) (noir-lang/noir#6776) fix: disable failure persistance in nargo test fuzzing (noir-lang/noir#6777) feat(cli): Verify `return` against ABI and `Prover.toml` (noir-lang/noir#6765) chore(ssa): Activate loop invariant code motion on ACIR functions (noir-lang/noir#6785) fix: use extension in docs link so it also works on GitHub (noir-lang/noir#6787) fix: optimizer to keep track of changing opcode locations (noir-lang/noir#6781) fix: Minimal change to avoid reverting entire PR #6685 (noir-lang/noir#6778)
…tion (noir-lang/noir#6782) feat: add `(x | 1)` optimization for booleans (noir-lang/noir#6795) feat: `nargo test -q` (or `nargo test --format terse`) (noir-lang/noir#6776) fix: disable failure persistance in nargo test fuzzing (noir-lang/noir#6777) feat(cli): Verify `return` against ABI and `Prover.toml` (noir-lang/noir#6765) chore(ssa): Activate loop invariant code motion on ACIR functions (noir-lang/noir#6785) fix: use extension in docs link so it also works on GitHub (noir-lang/noir#6787) fix: optimizer to keep track of changing opcode locations (noir-lang/noir#6781) fix: Minimal change to avoid reverting entire PR #6685 (noir-lang/noir#6778)
Description
Problem*
Resolves #6775
Summary*
In #6685 we restricted that
MakeArray
can only be deduplicated in an ACIR runtime. This is due to that arrays can actually be mutated in unconstrained code.Now when hoisting loop invariants, we check whether we are hoisting a
MakeArray
. If we have hoisted aMakeArray
instruction, we also insert anIncrementRc
instruction in the old location ofMakeArray
in the loop block.This PR is trading off the cost of creating an array inside of a loop vs. the cost of creating an array once + incrementing its reference counter inside the loop. Other than for the smallest of arrays, this tradeoff should almost always be worth it.
Before merging we may want to determine some kind of heuristic for when this optimization should run. It could also be left for a follow-up PR.
Additional Context
A potential optimization to follow-up this PR would be to bring back the rc tracker that was fully removed in DIE #6700. This would more generally help with the cost from deduplicating
MakeArray
instructions more generally as right now we always insert anIncrementRc
upon deduplicating or hoisting aMakeArray
. If that array is never mutably borrowed in the block, DIE should be able to remove those instructions that were included to maintain correctness.regression_4709
performance:Master:
The test was previously excluded from our CI's Brillig tests due to that execution would hang. I even ran out of memory and crashed the mainframe when trying to profile it.
After this PR:
~52 million opcodes executed
After this PR w/ #6783:
~1.2 millions opcodes executed
blob
performance:Master:
~990 million opcodes executed
After this PR:
~775 million opcodes executed (23.7% improvement from master)
After this PR w/ #6783:
~449 million opcodes executed (54.6% improvement from master)
Documentation*
Check one:
PR Checklist*
cargo fmt
on default settings.