Skip to content

feat: only print SSA optimization result if it produced changes#11587

Merged
asterite merged 5 commits intomasterfrom
ab/do-not-show-ssa-pass-result-if-no-changes
Feb 18, 2026
Merged

feat: only print SSA optimization result if it produced changes#11587
asterite merged 5 commits intomasterfrom
ab/do-not-show-ssa-pass-result-if-no-changes

Conversation

@asterite
Copy link
Copy Markdown
Collaborator

@asterite asterite commented Feb 14, 2026

Description

Problem

No issue.

Summary

While working on #11586 and trying to find which SSA pass produced a change that I had to look into, I realized that we could avoid showing the result of an SSA pass if it didn't modify the previous SSA.

Initially I thought of showing this as "After some optimization: (no changes)" but then I found all that output to not be that useful. So now only the steps that produced changes are shown.

For example, for this Noir code we now get this output instead of that plus 30+ steps that show an SSA unchanged:

fn main(cond: bool, mut array: [Field; 2]) -> pub Field {
    if cond {
        array[0] = 1;
    }
    array[0]
}

we now get this output:

Output of `nargo compile --show-ssa`
After Initial SSA:
acir(inline) fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    store v1 at v2
    jmpif v0 then: b1, else: b2
  b1():
    v3 = load v2 -> [Field; 2]
    v6 = array_set v3, index u32 0, value Field 1
    store v6 at v2
    jmp b2()
  b2():
    v7 = load v2 -> [Field; 2]
    v8 = array_get v7, index u32 0 -> Field
    return v8
}

After Mem2Reg (1) (step 6):
acir(inline) fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    store v1 at v2
    jmpif v0 then: b1, else: b2
  b1():
    v5 = array_set v1, index u32 0, value Field 1
    store v5 at v2
    jmp b2()
  b2():
    v6 = load v2 -> [Field; 2]
    v7 = array_get v6, index u32 0 -> Field
    return v7
}

After Purity Analysis (1) (step 7):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    store v1 at v2
    jmpif v0 then: b1, else: b2
  b1():
    v5 = array_set v1, index u32 0, value Field 1
    store v5 at v2
    jmp b2()
  b2():
    v6 = load v2 -> [Field; 2]
    v7 = array_get v6, index u32 0 -> Field
    return v7
}

After Flattening (1) (step 23):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    store v1 at v2
    enable_side_effects v0
    v5 = array_set v1, index u32 0, value Field 1
    v6 = load v2 -> [Field; 2]
    v7 = not v0
    v8 = if v0 then v5 else (if v7) v6
    store v8 at v2
    enable_side_effects u1 1
    v10 = load v2 -> [Field; 2]
    v11 = array_get v10, index u32 0 -> Field
    return v11
}

After Mem2Reg (4) (step 24):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    enable_side_effects v0
    v5 = array_set v1, index u32 0, value Field 1
    v6 = not v0
    v7 = if v0 then v5 else (if v6) v1
    enable_side_effects u1 1
    v9 = array_get v7, index u32 0 -> Field
    return v9
}

After Remove IfElse (1) (step 26):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    enable_side_effects v0
    v5 = array_set v1, index u32 0, value Field 1
    v6 = not v0
    enable_side_effects u1 1
    v8 = array_get v1, index u32 0 -> Field
    v9 = cast v0 as Field
    v10 = cast v6 as Field
    v11 = mul v10, v8
    v12 = add v9, v11
    v14 = array_get v1, index u32 1 -> Field
    v15 = array_get v1, index u32 1 -> Field
    v16 = cast v0 as Field
    v17 = cast v6 as Field
    v18 = mul v16, v14
    v19 = mul v17, v15
    v20 = add v18, v19
    v21 = make_array [v12, v20] : [Field; 2]
    enable_side_effects v0
    enable_side_effects u1 1
    return v12
}

After Constant Folding (1) (step 28):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    enable_side_effects v0
    v5 = array_set v1, index u32 0, value Field 1
    v6 = not v0
    enable_side_effects u1 1
    v8 = array_get v1, index u32 0 -> Field
    v9 = cast v0 as Field
    v10 = cast v6 as Field
    v11 = mul v10, v8
    v12 = add v9, v11
    v14 = array_get v1, index u32 1 -> Field
    v15 = mul v9, v14
    v16 = mul v10, v14
    v17 = add v15, v16
    v18 = make_array [v12, v17] : [Field; 2]
    enable_side_effects u1 1
    return v12
}

After EnableSideEffectsIf removal (1) (step 30):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    v2 = allocate -> &mut [Field; 2]
    enable_side_effects v0
    v5 = array_set v1, index u32 0, value Field 1
    v6 = not v0
    enable_side_effects u1 1
    v8 = array_get v1, index u32 0 -> Field
    v9 = cast v0 as Field
    v10 = cast v6 as Field
    v11 = mul v10, v8
    v12 = add v9, v11
    v14 = array_get v1, index u32 1 -> Field
    v15 = mul v9, v14
    v16 = mul v10, v14
    v17 = add v15, v16
    v18 = make_array [v12, v17] : [Field; 2]
    return v12
}

After Dead Instruction Elimination (2) (step 39):
acir(inline) predicate_pure fn main f0 {
  b0(v0: u1, v1: [Field; 2]):
    enable_side_effects v0
    v2 = not v0
    enable_side_effects u1 1
    v5 = array_get v1, index u32 0 -> Field
    v6 = cast v0 as Field
    v7 = cast v2 as Field
    v8 = mul v7, v5
    v9 = add v6, v8
    return v9
}

Additional Context

Let me know if you'd prefer to show the "skipped" steps instead, or feel free to push to this PR. (or we could make it configurable, I'm case you really want to see a proof that a pass ran but it did nothing)

User Documentation

Check one:

  • No user documentation needed.
  • Changes in docs/ included in this PR.
  • [For Experimental Features] Changes in docs/ 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.

@asterite asterite changed the title feat: only print SSA optimization result if it produces changes feat: only print SSA optimization result if it produced changes Feb 14, 2026
Copy link
Copy Markdown
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 'Brillig Execution Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 5c5ef6a Previous: 11c71e4 Ratio
rollup-block-root-first-empty-tx 0.004 s 0.003 s 1.33

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

CC: @TomAFrench

@TomAFrench
Copy link
Copy Markdown
Member

One note of caution here is that I can imagine that it will confuse Claude greatly if we don't document this in the necessary places.

@asterite
Copy link
Copy Markdown
Collaborator Author

I guess we can add a new flag to hide passes that don't produce changes.

@aakoshh
Copy link
Copy Markdown
Contributor

aakoshh commented Feb 16, 2026

I agree that it would be nice to have a CLI flag to turn this behaviour on, and show every step by default.

@asterite
Copy link
Copy Markdown
Collaborator Author

Done! Added a new --skip-unchanged-ssa CLI option.

@asterite asterite requested a review from a team February 18, 2026 12:45
Copy link
Copy Markdown
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: 5c5ef6a Previous: 11c71e4 Ratio
sha512-100-bytes 0.08 s 0.06 s 1.33

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

CC: @TomAFrench

Copy link
Copy Markdown
Contributor

@aakoshh aakoshh left a comment

Choose a reason for hiding this comment

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

Great!

@asterite asterite added this pull request to the merge queue Feb 18, 2026
Merged via the queue into master with commit 4e26919 Feb 18, 2026
137 checks passed
@asterite asterite deleted the ab/do-not-show-ssa-pass-result-if-no-changes branch February 18, 2026 15:07
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.

3 participants