-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Unroll loops iteratively (#4779)
# Description ## Problem\* Resolves #4736 ## Summary\* Instead of trying to unroll loops once, adds a meta pass that tries to unroll as many times as necessary, simplifying and doing mem2reg between unrolls. - For the cases where the program unrolls succesfully at the first try, no compile time overhead is created - For the cases where the program does contain an unknown at compile time loop bound, it'll try one more time before failing, since the stop condition is that "this unroll retry generated the same amount of errors as the previous one" - For the cases where the program doesn't contain an unknown at compile time loop bound, instead of failing it'll do as many unrolls as necessary to unroll the loop. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher <[email protected]>
- Loading branch information
1 parent
606ff44
commit f831b0b
Showing
5 changed files
with
95 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "slice_loop" | ||
type = "bin" | ||
authors = [""] | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[[points]] | ||
x = "1" | ||
y = "2" | ||
|
||
[[points]] | ||
x = "3" | ||
y = "4" | ||
|
||
[[points]] | ||
x = "5" | ||
y = "6" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
struct Point { | ||
x: Field, | ||
y: Field, | ||
} | ||
|
||
impl Point { | ||
fn serialize(self) -> [Field; 2] { | ||
[self.x, self.y] | ||
} | ||
} | ||
|
||
fn sum(values: [Field]) -> Field { | ||
let mut sum = 0; | ||
for value in values { | ||
sum = sum + value; | ||
} | ||
sum | ||
} | ||
|
||
fn main(points: [Point; 3]) { | ||
let mut serialized_points = &[]; | ||
for point in points { | ||
serialized_points = serialized_points.append(point.serialize().as_slice()); | ||
} | ||
// Do a compile-time check that needs the previous loop to be unrolled | ||
if serialized_points.len() > 5 { | ||
let empty_point = Point { x: 0, y: 0 }; | ||
serialized_points = serialized_points.append(empty_point.serialize().as_slice()); | ||
} | ||
// Do a sum that needs both the previous loop and the previous if to have been simplified | ||
assert_eq(sum(serialized_points), 21); | ||
} |