Skip to content

feat: SSA pass impact report#8393

Merged
aakoshh merged 12 commits intomasterfrom
af/ssa-pass-impact
May 9, 2025
Merged

feat: SSA pass impact report#8393
aakoshh merged 12 commits intomasterfrom
af/ssa-pass-impact

Conversation

@aakoshh
Copy link
Contributor

@aakoshh aakoshh commented May 7, 2025

Description

Problem*

Part of #8218

Looking at any given SSA pass, they have a few unit tests, but it's not obvious which integration tests (ie. Noir projects under test_programs) are relevant to them.

Summary*

Added a tool to list the integration tests where a certain SSA pass has the most impact on the IR.

It can be executed as follows:

cargo run -q -p nargo_cli --example ssa_pass_impact -- --ssa-pass <ssa-pass-name>

Currently it only looks at execution_success.

Additional Context

Impact

The impact is based on the similarity between the SSA of the pass we're interested in, and the one before it. A pass can appear multiple times in the pipeline, and these are all considered separately.

The similarity is calculated based on the number of lines where the string representation of the two SSA equal each other, which is computed using the similar crate. Before comparing them, the numeric values from the variable, block and function IDs are stripped away, so a re-numbering resulting from removing or adding instructions is ignored, and only the general structure and instruction names count.

The formulas are:

similarity(a, b) = 2 * lines_equal(a, b) / (lines(a) + lines(b))
impact(a, b) = 1 - similarity(a, b)

Build pipeline

I ended up duplicating a bunch of boilerplate from the compile_cli and nargo crates, and bypassing the SsaBuilder to run passes one by one. This has some pros and cons:

Pros:

  • I can stop the compilation as soon as we have passed the last occurrence of the pass we're interested in
  • There is no need to compile into Brillig and ACIR

Cons:

  • The code does not do everything the main compiler does, and can get out of sync
  • I don't execute the secondary pipeline with the Brillig VM passes
  • Every execution of the tool compiles every program

These could be alleviated if instead of compiling in the tool we relied on what Tom started in #7853 and looked for the printed SSA saved into files, just doing the string comparisons.

Audited passes

The following is the impact on tests of the passes selected for audit:

Remove unreachable functions

cargo run -q -p nargo_cli --example ssa_pass_impact -- --ssa-pass "Removing Unreachable Functions"
Packages: 267
Passes total: 1068
Passes with no impact: 1063
Passes most impacted by 'Removing Unreachable Functions' (top 50):
	0.156 impact: step 35 following 'Brillig Entry Point Analysis' in regression_fuzz_testing
	0.100 impact: step 35 following 'Brillig Entry Point Analysis' in global_var_multiple_entry_points_nested
	0.088 impact: step 35 following 'Brillig Entry Point Analysis' in brillig_calls_array
	0.080 impact: step 35 following 'Brillig Entry Point Analysis' in global_var_func_with_multiple_entry_points
	0.006 impact: step 10 following '`as_slice` optimization' in hashmap

Defunctionalize

cargo run -q -p nargo_cli --example ssa_pass_impact -- --ssa-pass "Defunctionalization"
Packages: 267
Passes total: 267
Passes with no impact: 256
Passes most impacted by 'Defunctionalization' (top 50):
	0.302 impact: step 2 following 'Removing Unreachable Functions' in brillig_fns_as_values
	0.275 impact: step 2 following 'Removing Unreachable Functions' in 1327_concrete_in_generic
	0.121 impact: step 2 following 'Removing Unreachable Functions' in higher_order_functions
	0.050 impact: step 2 following 'Removing Unreachable Functions' in reference_only_used_as_alias
	0.026 impact: step 2 following 'Removing Unreachable Functions' in hashmap
	0.026 impact: step 2 following 'Removing Unreachable Functions' in slices
	0.024 impact: step 2 following 'Removing Unreachable Functions' in uhashmap
	0.024 impact: step 2 following 'Removing Unreachable Functions' in trait_impl_base_type
	0.024 impact: step 2 following 'Removing Unreachable Functions' in debug_logs
	0.019 impact: step 2 following 'Removing Unreachable Functions' in array_sort
	0.014 impact: step 2 following 'Removing Unreachable Functions' in regression_11294

Inline simple functions

cargo run -q -p nargo_cli --example ssa_pass_impact -- --ssa-pass "Inlining functions with at most one instruction"
Packages: 267
Passes total: 267
Passes with no impact: 32
Passes most impacted by 'Inlining functions with at most one instruction' (top 50):
	0.421 impact: step 3 following 'Defunctionalization' in overlapping_dep_and_mod
	0.253 impact: step 3 following 'Defunctionalization' in trait_as_return_type
	0.247 impact: step 3 following 'Defunctionalization' in struct
	0.182 impact: step 3 following 'Defunctionalization' in double_verify_proof
	0.182 impact: step 3 following 'Defunctionalization' in double_verify_nested_proof
	0.179 impact: step 3 following 'Defunctionalization' in brillig_loop_size_regression
	0.177 impact: step 3 following 'Defunctionalization' in conditional_1
	0.150 impact: step 3 following 'Defunctionalization' in diamond_deps_0
	0.148 impact: step 3 following 'Defunctionalization' in regression_4709
	0.143 impact: step 3 following 'Defunctionalization' in 1327_concrete_in_generic
	0.130 impact: step 3 following 'Defunctionalization' in regression_7323
	0.119 impact: step 3 following 'Defunctionalization' in brillig_acir_as_brillig
	0.118 impact: step 3 following 'Defunctionalization' in loop_keyword
	0.118 impact: step 3 following 'Defunctionalization' in comptime_variable_at_runtime
	0.115 impact: step 3 following 'Defunctionalization' in global_array_rc_regression_8259
	0.112 impact: step 3 following 'Defunctionalization' in derive
	0.111 impact: step 3 following 'Defunctionalization' in field_attribute
	0.102 impact: step 3 following 'Defunctionalization' in array_oob_regression_7965
	0.100 impact: step 3 following 'Defunctionalization' in single_verify_proof
	0.098 impact: step 3 following 'Defunctionalization' in regression_method_cannot_be_found
	0.098 impact: step 3 following 'Defunctionalization' in global_slice_rc_regression_8259
	0.096 impact: step 3 following 'Defunctionalization' in brillig_fns_as_values
	0.095 impact: step 3 following 'Defunctionalization' in nested_if_then_block_same_cond
	0.093 impact: step 3 following 'Defunctionalization' in binary_operator_overloading
	0.092 impact: step 3 following 'Defunctionalization' in wrapping_operations
	0.091 impact: step 3 following 'Defunctionalization' in references
	0.090 impact: step 3 following 'Defunctionalization' in regression
	0.090 impact: step 3 following 'Defunctionalization' in poseidon_bn254_hash_width_3
	0.086 impact: step 3 following 'Defunctionalization' in prelude
	0.082 impact: step 3 following 'Defunctionalization' in brillig_calls
	0.082 impact: step 3 following 'Defunctionalization' in regression_4124
	0.078 impact: step 3 following 'Defunctionalization' in slice_regex
	0.077 impact: step 3 following 'Defunctionalization' in regression_3051
	0.077 impact: step 3 following 'Defunctionalization' in bool_not
	0.077 impact: step 3 following 'Defunctionalization' in poseidonsponge_x5_254
	0.074 impact: step 3 following 'Defunctionalization' in debug_logs
	0.073 impact: step 3 following 'Defunctionalization' in array_len
	0.073 impact: step 3 following 'Defunctionalization' in brillig_calls_conditionals
	0.069 impact: step 3 following 'Defunctionalization' in regression_fuzz_testing
	0.069 impact: step 3 following 'Defunctionalization' in simple_print
	0.065 impact: step 3 following 'Defunctionalization' in strings
	0.063 impact: step 3 following 'Defunctionalization' in trait_impl_base_type
	0.063 impact: step 3 following 'Defunctionalization' in conditional_2
	0.062 impact: step 3 following 'Defunctionalization' in regression_3394
	0.062 impact: step 3 following 'Defunctionalization' in 4_sub
	0.062 impact: step 3 following 'Defunctionalization' in comptime_println
	0.059 impact: step 3 following 'Defunctionalization' in slice_loop
	0.054 impact: step 3 following 'Defunctionalization' in unary_operator_overloading
	0.054 impact: step 3 following 'Defunctionalization' in hashmap
	0.054 impact: step 3 following 'Defunctionalization' in regression_5252

Documentation*

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [For Experimental Features] Documentation to be submitted in a separate PR.

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Execution Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 6d95024 Previous: a686856 Ratio
rollup-merge 0.004 s 0.003 s 1.33

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

@aakoshh aakoshh force-pushed the af/ssa-pass-impact branch from 74e9d5e to fd27dfa Compare May 8, 2025 17:17
@aakoshh aakoshh enabled auto-merge May 9, 2025 14:30
@aakoshh aakoshh added this pull request to the merge queue May 9, 2025
Merged via the queue into master with commit b6570a5 May 9, 2025
117 checks passed
@aakoshh aakoshh deleted the af/ssa-pass-impact branch May 9, 2025 15:03
github-merge-queue bot pushed a commit to AztecProtocol/aztec-packages that referenced this pull request May 12, 2025
Automated pull of nightly from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
fix: always type-check turbofish, and error when it's not allowed
(noir-lang/noir#8437)
chore: Release Noir(1.0.0-beta.5)
(noir-lang/noir#7955)
feat(greybox_fuzzer): Parallel fuzz tests
(noir-lang/noir#8432)
fix(ssa): Mislabeled instructions with side effects in
EnableSideEffectsIf removal pass
(noir-lang/noir#8355)
feat: SSA pass impact report
(noir-lang/noir#8393)
chore: bump external pinned commits
(noir-lang/noir#8433)
chore: separate benchmarking from github actions more
(noir-lang/noir#7943)
chore(fuzz): Break up the AST fuzzer `compare` module
(noir-lang/noir#8431)
chore(fuzz): Rename `init_vs_final` to `min_vs_full`
(noir-lang/noir#8430)
fix!: error on tuple mismatch
(noir-lang/noir#8424)
chore: bump external pinned commits
(noir-lang/noir#8429)
chore(acir): Test whether the predicate has an effect on slice
intrinsics (noir-lang/noir#8421)
feat(ssa): Mark transitively dead parameters during DIE
(noir-lang/noir#8254)
fix(ssa_gen): Do not code gen fetching of empty arrays when initializing
the data bus (noir-lang/noir#8426)
chore: remove `.aztec-sync-commit`
(noir-lang/noir#8415)
chore(test): Add more unit tests for
`inline_functions_with_at_most_one_instruction`
(noir-lang/noir#8418)
chore: add minor docs for interpreter
(noir-lang/noir#8397)
fix: print slice composite types surrounded by parentheses
(noir-lang/noir#8412)
feat: Skip SSA passes that contain any of the given messages
(noir-lang/noir#8416)
fix: disable range constraints using the predicate
(noir-lang/noir#8396)
chore: bumping external libraries
(noir-lang/noir#8406)
chore: redo typo PR by shystrui1199
(noir-lang/noir#8405)
feat(test): add `nargo_fuzz_target`
(noir-lang/noir#8308)
fix: allow names to collide in the values/types namespaces
(noir-lang/noir#8286)
fix: Fix sequencing of side-effects in lvalue
(noir-lang/noir#8384)
feat(greybox_fuzzer): Maximum executions parameter added
(noir-lang/noir#8390)
fix: warn on and discard unreachable statements after break and continue
(noir-lang/noir#8382)
fix: add handling for u128 infix ops in interpreter
(noir-lang/noir#8392)
chore: move acirgen tests into separate file
(noir-lang/noir#8376)
feat(fuzz): initial version of comptime vs brillig target for AST fuzzer
(noir-lang/noir#8335)
chore: apply lints to `ast_fuzzer`
(noir-lang/noir#8386)
chore: add note on AI generated PRs in `CONTRIBUTING.md`
(noir-lang/noir#8385)
chore: document flattening pass
(noir-lang/noir#8312)
fix: comptime shift-right overflow is zero
(noir-lang/noir#8380)
feat: let static_assert accept any type for its message
(noir-lang/noir#8322)
fix(expand): output safety comment before statements
(noir-lang/noir#8378)
chore: avoid need to rebuild after running tests
(noir-lang/noir#8379)
chore: bump dependencies (noir-lang/noir#8372)
chore: Add GITHUB_TOKEN to cross build
(noir-lang/noir#8370)
chore: redo typo PR by GarmashAlex
(noir-lang/noir#8364)
chore: remove unsafe code from greybox fuzzer
(noir-lang/noir#8315)
feat: add `--fuzz-timeout` to `nargo test` options
(noir-lang/noir#8326)
chore: bump external pinned commits
(noir-lang/noir#8334)
fix(expand): try to use "Self" in function calls
(noir-lang/noir#8353)
fix: Fix evaluation order of assignments with side-effects in their rhs
(noir-lang/noir#8342)
fix: let comptime Field value carry the field's sign
(noir-lang/noir#8343)
fix: Ordering of items in callstacks
(noir-lang/noir#8338)
chore: add snapshosts for nargo expand tests
(noir-lang/noir#8318)
fix(ownership): Clone global arrays
(noir-lang/noir#8328)
chore: Replace all SSA interpreter panics with error variants
(noir-lang/noir#8311)
feat: Metamorphic AST fuzzing
(noir-lang/noir#8299)
fix: fix some Display implementations for AST nodes
(noir-lang/noir#8316)
chore: remove leftover file
(noir-lang/noir#8313)
fix: uses non-zero points with ec-add-unsafe
(noir-lang/noir#8248)
END_COMMIT_OVERRIDE

---------

Co-authored-by: AztecBot <tech@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
github-merge-queue bot pushed a commit to AztecProtocol/aztec-packages that referenced this pull request May 12, 2025
Automated pull of nightly from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
fix: always type-check turbofish, and error when it's not allowed
(noir-lang/noir#8437)
chore: Release Noir(1.0.0-beta.5)
(noir-lang/noir#7955)
feat(greybox_fuzzer): Parallel fuzz tests
(noir-lang/noir#8432)
fix(ssa): Mislabeled instructions with side effects in
EnableSideEffectsIf removal pass
(noir-lang/noir#8355)
feat: SSA pass impact report
(noir-lang/noir#8393)
chore: bump external pinned commits
(noir-lang/noir#8433)
chore: separate benchmarking from github actions more
(noir-lang/noir#7943)
chore(fuzz): Break up the AST fuzzer `compare` module
(noir-lang/noir#8431)
chore(fuzz): Rename `init_vs_final` to `min_vs_full`
(noir-lang/noir#8430)
fix!: error on tuple mismatch
(noir-lang/noir#8424)
chore: bump external pinned commits
(noir-lang/noir#8429)
chore(acir): Test whether the predicate has an effect on slice
intrinsics (noir-lang/noir#8421)
feat(ssa): Mark transitively dead parameters during DIE
(noir-lang/noir#8254)
fix(ssa_gen): Do not code gen fetching of empty arrays when initializing
the data bus (noir-lang/noir#8426)
chore: remove `.aztec-sync-commit`
(noir-lang/noir#8415)
chore(test): Add more unit tests for
`inline_functions_with_at_most_one_instruction`
(noir-lang/noir#8418)
chore: add minor docs for interpreter
(noir-lang/noir#8397)
fix: print slice composite types surrounded by parentheses
(noir-lang/noir#8412)
feat: Skip SSA passes that contain any of the given messages
(noir-lang/noir#8416)
fix: disable range constraints using the predicate
(noir-lang/noir#8396)
chore: bumping external libraries
(noir-lang/noir#8406)
chore: redo typo PR by shystrui1199
(noir-lang/noir#8405)
feat(test): add `nargo_fuzz_target`
(noir-lang/noir#8308)
fix: allow names to collide in the values/types namespaces
(noir-lang/noir#8286)
fix: Fix sequencing of side-effects in lvalue
(noir-lang/noir#8384)
feat(greybox_fuzzer): Maximum executions parameter added
(noir-lang/noir#8390)
fix: warn on and discard unreachable statements after break and continue
(noir-lang/noir#8382)
fix: add handling for u128 infix ops in interpreter
(noir-lang/noir#8392)
chore: move acirgen tests into separate file
(noir-lang/noir#8376)
feat(fuzz): initial version of comptime vs brillig target for AST fuzzer
(noir-lang/noir#8335)
chore: apply lints to `ast_fuzzer`
(noir-lang/noir#8386)
chore: add note on AI generated PRs in `CONTRIBUTING.md`
(noir-lang/noir#8385)
chore: document flattening pass
(noir-lang/noir#8312)
fix: comptime shift-right overflow is zero
(noir-lang/noir#8380)
feat: let static_assert accept any type for its message
(noir-lang/noir#8322)
fix(expand): output safety comment before statements
(noir-lang/noir#8378)
chore: avoid need to rebuild after running tests
(noir-lang/noir#8379)
chore: bump dependencies (noir-lang/noir#8372)
chore: Add GITHUB_TOKEN to cross build
(noir-lang/noir#8370)
chore: redo typo PR by GarmashAlex
(noir-lang/noir#8364)
chore: remove unsafe code from greybox fuzzer
(noir-lang/noir#8315)
feat: add `--fuzz-timeout` to `nargo test` options
(noir-lang/noir#8326)
chore: bump external pinned commits
(noir-lang/noir#8334)
fix(expand): try to use "Self" in function calls
(noir-lang/noir#8353)
fix: Fix evaluation order of assignments with side-effects in their rhs
(noir-lang/noir#8342)
fix: let comptime Field value carry the field's sign
(noir-lang/noir#8343)
fix: Ordering of items in callstacks
(noir-lang/noir#8338)
chore: add snapshosts for nargo expand tests
(noir-lang/noir#8318)
fix(ownership): Clone global arrays
(noir-lang/noir#8328)
chore: Replace all SSA interpreter panics with error variants
(noir-lang/noir#8311)
feat: Metamorphic AST fuzzing
(noir-lang/noir#8299)
fix: fix some Display implementations for AST nodes
(noir-lang/noir#8316)
chore: remove leftover file
(noir-lang/noir#8313)
fix: uses non-zero points with ec-add-unsafe
(noir-lang/noir#8248)
END_COMMIT_OVERRIDE

---------

Co-authored-by: AztecBot <tech@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
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.

2 participants