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

feat: add pass which inlines constant arguments into brillig functions #7559

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
12 changes: 11 additions & 1 deletion compiler/noirc_evaluator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ pub(crate) fn trim_leading_whitespace_from_lines(src: &str) -> String {
while first_line.is_empty() {
first_line = lines.next().unwrap();
}
let first_line_original_length = first_line.len();
let mut result = first_line.trim_start().to_string();
let first_line_trimmed_length = result.len();

// Try to see how many spaces we chopped off the first line
let difference = first_line_original_length - first_line_trimmed_length;
for line in lines {
result.push('\n');
result.push_str(line.trim_start());
// Try to remove just `difference` spaces to preserve indents
if line.len() - line.trim_start().len() >= difference {
result.push_str(&line.chars().skip(difference).collect::<String>());
} else {
result.push_str(line.trim_start());
}
}
result
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ fn optimize_all(builder: SsaBuilder, options: &SsaEvaluatorOptions) -> Result<Ss
.run_pass(Ssa::remove_if_else, "Remove IfElse")
.run_pass(Ssa::purity_analysis, "Purity Analysis (2nd)")
.run_pass(Ssa::fold_constants, "Constant Folding")
.run_pass(
Ssa::inline_constants_into_brillig_functions,
"Inline constants into brillig functions",
)
.run_pass(Ssa::remove_unreachable_functions, "Removing Unreachable Functions (3rd)")
.run_pass(Ssa::flatten_basic_conditionals, "Simplify conditionals for unconstrained")
.run_pass(Ssa::remove_enable_side_effects, "EnableSideEffectsIf removal")
.run_pass(Ssa::fold_constants_using_constraints, "Constraint Folding")
Expand All @@ -223,7 +228,7 @@ fn optimize_all(builder: SsaBuilder, options: &SsaEvaluatorOptions) -> Result<Ss
// The used globals map is determined during DIE, so we should duplicate entry points before a DIE pass run.
.run_pass(Ssa::brillig_entry_point_analysis, "Brillig Entry Point Analysis")
// Remove any potentially unnecessary duplication from the Brillig entry point analysis.
.run_pass(Ssa::remove_unreachable_functions, "Removing Unreachable Functions (3rd)")
.run_pass(Ssa::remove_unreachable_functions, "Removing Unreachable Functions (4th)")
// This pass makes transformations specific to Brillig generation.
// It must be the last pass to either alter or add new instructions before Brillig generation,
// as other semantics in the compiler can potentially break (e.g. inserting instructions).
Expand Down
12 changes: 6 additions & 6 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/call/blackbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ mod test {
fn full_constant_folding() {
let src = r#"
acir(inline) fn main f0 {
b0():
b0():
v0 = make_array [Field 2, Field 3, Field 5, Field 5] : [Field; 4]
v1 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 6]
v2 = call multi_scalar_mul (v1, v0) -> [Field; 3]
Expand All @@ -327,7 +327,7 @@ mod test {

let expected_src = r#"
acir(inline) fn main f0 {
b0():
b0():
v3 = make_array [Field 2, Field 3, Field 5, Field 5] : [Field; 4]
v7 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 6]
v10 = make_array [Field 1478523918288173385110236399861791147958001875200066088686689589556927843200, Field 700144278551281040379388961242974992655630750193306467120985766322057145630, Field 0] : [Field; 3]
Expand All @@ -342,7 +342,7 @@ mod test {
fn simplify_zero() {
let src = r#"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
b0(v0: Field, v1: Field):
v2 = make_array [v0, Field 0, Field 0, Field 0, v0, Field 0] : [Field; 6]
v3 = make_array [
Field 0, Field 0, Field 1, v0, v1, Field 0, Field 1, v0, Field 0] : [Field; 9]
Expand All @@ -355,7 +355,7 @@ mod test {
//First point is zero, second scalar is zero, so we should be left with the scalar mul of the last point.
let expected_src = r#"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
b0(v0: Field, v1: Field):
v3 = make_array [v0, Field 0, Field 0, Field 0, v0, Field 0] : [Field; 6]
v5 = make_array [Field 0, Field 0, Field 1, v0, v1, Field 0, Field 1, v0, Field 0] : [Field; 9]
v6 = make_array [v0, Field 0] : [Field; 2]
Expand All @@ -372,7 +372,7 @@ mod test {
fn partial_constant_folding() {
let src = r#"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
b0(v0: Field, v1: Field):
v2 = make_array [Field 1, Field 0, v0, Field 0, Field 2, Field 0] : [Field; 6]
v3 = make_array [
Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, v0, v1, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 9]
Expand All @@ -383,7 +383,7 @@ mod test {
//First and last scalar/point are constant, so we should be left with the msm of the middle point and the folded constant point
let expected_src = r#"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
b0(v0: Field, v1: Field):
v5 = make_array [Field 1, Field 0, v0, Field 0, Field 2, Field 0] : [Field; 6]
v7 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, v0, v1, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 9]
v8 = make_array [v0, Field 0, Field 1, Field 0] : [Field; 4]
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ mod tests {
// Regression test for https://github.com/noir-lang/noir/issues/7451
let src = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u8):
b0(v0: u8):
v1 = and u8 255, v0
return v1
}
Expand All @@ -220,7 +220,7 @@ mod tests {

let expected = "
acir(inline) fn main f0 {
b0(v0: u8):
b0(v0: u8):
return v0
}
";
Expand Down
70 changes: 35 additions & 35 deletions compiler/noirc_evaluator/src/ssa/opt/basic_conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,30 +394,30 @@ mod test {
let src = "
brillig(inline) fn foo f0 {
b0(v0: u32):
v3 = eq v0, u32 0
jmpif v3 then: b2, else: b1
v3 = eq v0, u32 0
jmpif v3 then: b2, else: b1
b1():
jmp b3(u32 5)
jmp b3(u32 5)
b2():
jmp b3(u32 3)
jmp b3(u32 3)
b3(v1: u32):
return v1
return v1
}
";
let ssa = Ssa::from_str(src).unwrap();
assert_eq!(ssa.main().reachable_blocks().len(), 4);

let expected = "
brillig(inline) fn foo f0 {
b0(v0: u32):
v2 = eq v0, u32 0
v3 = not v2
v4 = cast v2 as u32
v5 = cast v3 as u32
v7 = unchecked_mul v4, u32 3
v9 = unchecked_mul v5, u32 5
v10 = unchecked_add v7, v9
return v10
b0(v0: u32):
v2 = eq v0, u32 0
v3 = not v2
v4 = cast v2 as u32
v5 = cast v3 as u32
v7 = unchecked_mul v4, u32 3
v9 = unchecked_mul v5, u32 5
v10 = unchecked_add v7, v9
return v10
}
";

Expand All @@ -430,16 +430,16 @@ mod test {
let src = r#"
brillig(inline) fn foo f0 {
b0(v0: u32):
v3 = eq v0, u32 5
jmpif v3 then: b2, else: b1
v3 = eq v0, u32 5
jmpif v3 then: b2, else: b1
b1():
v6 = make_array b"foo"
jmp b3(v6)
v6 = make_array b"foo"
jmp b3(v6)
b2():
v10 = make_array b"bar"
jmp b3(v10)
v10 = make_array b"bar"
jmp b3(v10)
b3(v1: [u8; 3]):
return v1
return v1
}
"#;
let ssa = Ssa::from_str(src).unwrap();
Expand All @@ -453,33 +453,33 @@ mod test {
fn nested_jmpifs() {
let src = "
brillig(inline) fn foo f0 {
b0(v0: u32):
b0(v0: u32):
v5 = eq v0, u32 5
v6 = not v5
jmpif v5 then: b5, else: b1
b1():
b1():
v8 = lt v0, u32 3
jmpif v8 then: b3, else: b2
b2():
b2():
v9 = truncate v0 to 2 bits, max_bit_size: 32
jmp b4(v9)
b3():
b3():
v10 = truncate v0 to 1 bits, max_bit_size: 32
jmp b4(v10)
b4(v1: u32):
b4(v1: u32):
jmp b9(v1)
b5():
b5():
v12 = lt u32 2, v0
jmpif v12 then: b7, else: b6
b6():
b6():
v13 = truncate v0 to 3 bits, max_bit_size: 32
jmp b8(v13)
b7():
b7():
v14 = and v0, u32 2
jmp b8(v14)
b8(v2: u32):
b8(v2: u32):
jmp b9(v2)
b9(v3: u32):
b9(v3: u32):
return v3
}
";
Expand All @@ -488,11 +488,11 @@ mod test {

let expected = "
brillig(inline) fn foo f0 {
b0(v0: u32):
b0(v0: u32):
v3 = eq v0, u32 5
v4 = not v3
jmpif v3 then: b2, else: b1
b1():
b1():
v6 = lt v0, u32 3
v7 = truncate v0 to 1 bits, max_bit_size: 32
v8 = not v6
Expand All @@ -503,7 +503,7 @@ mod test {
v13 = unchecked_mul v11, v9
v14 = unchecked_add v12, v13
jmp b3(v14)
b2():
b2():
v16 = lt u32 2, v0
v17 = and v0, u32 2
v18 = not v16
Expand All @@ -514,7 +514,7 @@ mod test {
v23 = unchecked_mul v21, v19
v24 = unchecked_add v22, v23
jmp b3(v24)
b3(v1: u32):
b3(v1: u32):
return v1
}
";
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_evaluator/src/ssa/opt/brillig_entry_points.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//! generated for different entry points can conflict.
//!
//! To provide a more concrete example, let's take this program:
//! ```
//! ```noir
//! global ONE: Field = 1;
//! global TWO: Field = 2;
//! global THREE: Field = 3;
Expand All @@ -40,7 +40,7 @@
//! }
//! ```
//! The two entry points will have different global allocation maps:
//! ```
//! ```noir
//! GlobalInit(Id(1)):
//! CONST M32835 = 1
//! CONST M32836 = 2
Expand Down
Loading
Loading