Skip to content
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

chore(ssa refactor): Fix loading from mutable parameters #1248

Merged
merged 18 commits into from
Apr 28, 2023

Conversation

jfecher
Copy link
Contributor

@jfecher jfecher commented Apr 28, 2023

Related issue(s)

Resolves #

Description

Summary of changes

Fixes a couple bugs with mutable parameters:

  1. Mutable parameters were not being Instruction::Load'ed from automatically because they were not wrapped in Value::Mutable. This lead to a later panic in mutate_load_into_store.
  2. Because we evaluate lhs before rhs in lhs = rhs; we generate a load from lhs before we evaluate rhs and store to it. To create the store however, we replaced the load with a store previously, which would then create a store instruction storing rhs before rhs was even evaluated. So the IR would resemble store v3 at v1; v3 = .... Since the store should be after everything else, I've replaced mutate_load_into_store with a new function to instead remove the old load and insert a new store at the end of the current block.
  3. Fixed a small issue where store instructions were being printed backwards.

This PR depends on the previous fixes PR which is in the process of being merged. Until then this PR will show those changes as well.

Dependency additions / changes

Test additions / changes

Checklist

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt with default settings.
  • I have linked this PR to the issue(s) that it resolves.
  • I have reviewed the changes on GitHub, line by line.
  • I have ensured all changes are covered in the description.

Documentation needs

  • This PR requires documentation updates when merged.

Additional context

@jfecher jfecher requested a review from kevaundray April 28, 2023 16:08
@jfecher
Copy link
Contributor Author

jfecher commented Apr 28, 2023

Update: Fixed storing to mutable arrays as well. Previously the code

fn main() {
    let mut my_array = [1, 2];
    my_array[1] = 3;
}

Would result in the IR:

fn main f0 {
  b0():
    v3 = alloc 2 fields
    store Field 1 at v3
    v5 = add v3, Field 1
    store Field 2 at v5
    v6 = alloc 1 fields
    store v3 at v6
    v9 = load v6
    v12 = mul Field 1, Field 1
    store Field 3 at v9
    return unit 0
}

Note the final v12 that is never used and that we're storing to v9 (the start of the array) rather than (start + 1).
After the newest commit we'll produce the following fixed code. With the correct v13 instruction to get the offset of the array before storing to it.

fn main f0 {
  b0():
    v3 = alloc 2 fields
    store Field 1 at v3
    v5 = add v3, Field 1
    store Field 2 at v5
    v6 = alloc 1 fields
    store v3 at v6
    v9 = load v6
    v12 = mul Field 1, Field 1
    v13 = add v9, v12
    store Field 3 at v13
    return unit 0
}

For the curious the v12 1 * 1 instruction that looks useless is used to calculate type offsets if the element type of the array is larger than 1 field.

Edit: The root cause seems to have actually been a bug in insert_load not inserting the address addition if the offset was not a constant. I've fixed this but kept the previous fix as well since it seems more correct to not insert the loads in the first place rather than removing them later.

@jfecher
Copy link
Contributor Author

jfecher commented Apr 28, 2023

After some more testing I've determined this is the final bugfix PR needed for the new ssa gen pass 🎉. It likely still has bugs but none that I can find by running any of our examples and looking at the output manually.

Note that this is except for one known failure: The first-class-functions test fails completely when we attempt to use a value from another function without importing it as a parameter first. This is by design, but fixing it means we need to do proper closure conversion. Proper closure conversion was needed previously due to a known bug when using closures but for the most part the old SSA ir was fine with using these values without importing them so it worked for the most part. I've opened an appropriate issue for this.

@kevaundray
Copy link
Contributor

kevaundray commented Apr 28, 2023

After some more testing I've determined this is the final bugfix PR needed for the new ssa gen pass 🎉. It likely still has bugs but none that I can find by running any of our examples and looking at the output manually.

Note that this is except for one known failure: The first-class-functions test fails completely when we attempt to use a value from another function without importing it as a parameter first. This is by design, but fixing it means we need to do proper closure conversion. Proper closure conversion was needed previously due to a known bug when using closures but for the most part the old SSA ir was fine with using these values without importing them so it worked for the most part. I've opened an appropriate issue for this.

Yay :D Great work on getting the ssa gen pass complete!

Can you link the issue for poper closure conversion?

Spoke too soon, its #1254

kevaundray
kevaundray previously approved these changes Apr 28, 2023
Copy link
Contributor

@kevaundray kevaundray left a comment

Choose a reason for hiding this comment

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

LGTM - one nit but not blocking

@kevaundray
Copy link
Contributor

kevaundray commented Apr 28, 2023

Would result in the IR:

fn main f0 {
  b0():
    v3 = alloc 2 fields
    store Field 1 at v3
    v5 = add v3, Field 1
    store Field 2 at v5
    v6 = alloc 1 fields
    store v3 at v6
    v9 = load v6
    v12 = mul Field 1, Field 1
    store Field 3 at v9
    return unit 0
}

Sidenote: I love the way blocks/functions are printed now :)

@jfecher jfecher enabled auto-merge April 28, 2023 19:09
@jfecher jfecher added this pull request to the merge queue Apr 28, 2023
Merged via the queue into master with commit a0c6bfe Apr 28, 2023
@jfecher jfecher deleted the jf/ssa-fix-mutable-parameters branch April 28, 2023 19:51
TomAFrench added a commit that referenced this pull request Apr 29, 2023
* master: (223 commits)
  chore(noir): Release 0.5.0 (#1202)
  chore(ci): Utilize new workflow to build binaries (#1250)
  chore(ssa refactor): Fix loading from mutable parameters (#1248)
  fix(wasm): add std after dependencies (#1245)
  chore(ssa refactor): Fix no returns & duplicate main (#1243)
  chore(ssa refactor): Implement intrinsics (#1241)
  chore(ssa refactor): Implement first-class functions (#1238)
  chore: address clippy warnings (#1239)
  chore(ssa refactor): Implement function calls (#1235)
  chore(ssa refactor): Implement mutable and immutable variables (#1234)
  chore(ssa refactor): Fix recursive printing of blocks (#1230)
  feat(noir): added assert keyword (#1227)
  chore(ssa refactor): Implement ssa-gen for indexing, cast, constrain, if, unary (#1225)
  feat(noir): added `distinct` keyword (#1219)
  chore(nargo): update panic message to suggest searching for similar issues (#1224)
  chore(ssa refactor): Update how instruction result types are retrieved (#1222)
  chore(ssa refactor): Implement ssa-gen for binary, block, tuple, extract-tuple-field, and semi expressions (#1217)
  chore: add RUST_BACKTRACE environment variable to nix config (#1216)
  chore(ssa): Add intial control flow graph  (#1200)
  chore(ssa refactor): Handle codegen for literals (#1209)
  ...
TomAFrench pushed a commit that referenced this pull request May 2, 2023
* Implement first-class functions

* Update crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs

Co-authored-by: kevaundray <kevtheappdev@gmail.com>

* Implement intrinsics

* Fix no return & duplicate main

* bad git. remove duplicated functions

* Remove Option<Function> in builder

* Undo debug printing in driver

* Fix loading from mutable parameters

* Grammar

* Fix storing to mutable arrays

* Fix unused variable

* Fix array loading

* Change terminology

---------

Co-authored-by: kevaundray <kevtheappdev@gmail.com>
TomAFrench added a commit that referenced this pull request May 2, 2023
* master: (63 commits)
  feat(nargo): Remove usage of `CompiledProgram` in CLI code and use separate ABI/bytecode (#1269)
  feat: add integration tests for bitshift operators (#1272)
  chore: Replace explicit if-elses with `FieldElement::from<bool>()` for boolean fields (#1266)
  chore(noir): constrain expr; -> assert(expr); (#1276)
  chore: fix clippy warning (#1270)
  chore(ssa refactor): Add all remaining doc comments to ssa generation pass (#1256)
  chore(noir): Release 0.5.1 (#1264)
  fix: Add Poseidon examples into integration tests (#1257)
  chore(nargo): replace `aztec_backend` with `acvm-backend-barretenberg` (#1226)
  chore(noir): Release 0.5.0 (#1202)
  chore(ci): Utilize new workflow to build binaries (#1250)
  chore(ssa refactor): Fix loading from mutable parameters (#1248)
  fix(wasm): add std after dependencies (#1245)
  chore(ssa refactor): Fix no returns & duplicate main (#1243)
  chore(ssa refactor): Implement intrinsics (#1241)
  chore(ssa refactor): Implement first-class functions (#1238)
  chore: address clippy warnings (#1239)
  chore(ssa refactor): Implement function calls (#1235)
  chore(ssa refactor): Implement mutable and immutable variables (#1234)
  chore(ssa refactor): Fix recursive printing of blocks (#1230)
  ...
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