diff --git a/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/compiler/noirc_evaluator/src/ssa/ir/printer.rs index aa2952d5abc..29e79728303 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -1,8 +1,5 @@ //! This file is for pretty-printing the SSA IR in a human-readable form for debugging. -use std::{ - collections::HashSet, - fmt::{Formatter, Result}, -}; +use std::fmt::{Formatter, Result}; use acvm::acir::AcirField; use im::Vector; @@ -21,28 +18,10 @@ use super::{ /// Helper function for Function's Display impl to pretty-print the function with the given formatter. pub(crate) fn display_function(function: &Function, f: &mut Formatter) -> Result { writeln!(f, "{} fn {} {} {{", function.runtime(), function.name(), function.id())?; - display_block_with_successors(function, function.entry_block(), &mut HashSet::new(), f)?; - write!(f, "}}") -} - -/// Displays a block followed by all of its successors recursively. -/// This uses a HashSet to keep track of the visited blocks. Otherwise -/// there would be infinite recursion for any loops in the IR. -pub(crate) fn display_block_with_successors( - function: &Function, - block_id: BasicBlockId, - visited: &mut HashSet, - f: &mut Formatter, -) -> Result { - display_block(function, block_id, f)?; - visited.insert(block_id); - - for successor in function.dfg[block_id].successors() { - if !visited.contains(&successor) { - display_block_with_successors(function, successor, visited, f)?; - } + for block_id in function.reachable_blocks() { + display_block(function, block_id, f)?; } - Ok(()) + write!(f, "}}") } /// Display a single block. This will not display the block's successors. diff --git a/compiler/noirc_evaluator/src/ssa/opt/array_set.rs b/compiler/noirc_evaluator/src/ssa/opt/array_set.rs index 96de22600a4..09339cf0797 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/array_set.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/array_set.rs @@ -209,6 +209,8 @@ mod tests { b1(v0: u32): v8 = lt v0, u32 5 jmpif v8 then: b3, else: b2 + b2(): + return b3(): v9 = eq v0, u32 5 jmpif v9 then: b4, else: b5 @@ -224,8 +226,6 @@ mod tests { store v15 at v4 v17 = add v0, u32 1 jmp b1(v17) - b2(): - return } "; let ssa = Ssa::from_str(src).unwrap(); diff --git a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs index 93ca428c6d0..e039b8f0f9e 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs @@ -1521,18 +1521,18 @@ mod test { b0(v0: u32): v2 = eq v0, u32 0 jmpif v2 then: b4, else: b1 - b4(): - v5 = sub v0, u32 1 - jmp b5() - b5(): - return b1(): jmpif v0 then: b3, else: b2 + b2(): + jmp b5() b3(): v4 = sub v0, u32 1 // We can't hoist this because v0 is zero here and it will lead to an underflow jmp b5() - b2(): + b4(): + v5 = sub v0, u32 1 jmp b5() + b5(): + return } "; let ssa = Ssa::from_str(src).unwrap(); diff --git a/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs b/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs index 290d2a33846..87e7f8bcff3 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs @@ -251,13 +251,13 @@ mod test { b1(v2: u32): v5 = lt v2, u32 4 jmpif v5 then: b3, else: b2 + b2(): + return b3(): v6 = mul v0, v1 constrain v6 == u32 6 v8 = add v2, u32 1 jmp b1(v8) - b2(): - return } "; @@ -276,12 +276,12 @@ mod test { b1(v2: u32): v6 = lt v2, u32 4 jmpif v6 then: b3, else: b2 + b2(): + return b3(): constrain v3 == u32 6 v9 = add v2, u32 1 jmp b1(v9) - b2(): - return } "; @@ -300,21 +300,21 @@ mod test { b1(v2: u32): v6 = lt v2, u32 4 jmpif v6 then: b3, else: b2 + b2(): + return b3(): jmp b4(u32 0) b4(v3: u32): v7 = lt v3, u32 4 jmpif v7 then: b6, else: b5 + b5(): + v9 = add v2, u32 1 + jmp b1(v9) b6(): v10 = mul v0, v1 constrain v10 == u32 6 v12 = add v3, u32 1 jmp b4(v12) - b5(): - v9 = add v2, u32 1 - jmp b1(v9) - b2(): - return } "; @@ -333,20 +333,20 @@ mod test { b1(v2: u32): v7 = lt v2, u32 4 jmpif v7 then: b3, else: b2 + b2(): + return b3(): jmp b4(u32 0) b4(v3: u32): v8 = lt v3, u32 4 jmpif v8 then: b6, else: b5 + b5(): + v10 = add v2, u32 1 + jmp b1(v10) b6(): constrain v4 == u32 6 v12 = add v3, u32 1 jmp b4(v12) - b5(): - v10 = add v2, u32 1 - jmp b1(v10) - b2(): - return } "; @@ -374,6 +374,8 @@ mod test { b1(v2: u32): v5 = lt v2, u32 4 jmpif v5 then: b3, else: b2 + b2(): + return b3(): v6 = mul v0, v1 v7 = mul v6, v0 @@ -381,8 +383,6 @@ mod test { constrain v7 == u32 12 v9 = add v2, u32 1 jmp b1(v9) - b2(): - return } "; @@ -402,12 +402,12 @@ mod test { b1(v2: u32): v9 = lt v2, u32 4 jmpif v9 then: b3, else: b2 + b2(): + return b3(): constrain v4 == u32 12 v11 = add v2, u32 1 jmp b1(v11) - b2(): - return } "; @@ -431,17 +431,17 @@ mod test { b1(v2: u32): v7 = lt v2, u32 4 jmpif v7 then: b3, else: b2 + b2(): + v8 = load v5 -> [u32; 5] + v10 = array_get v8, index u32 2 -> u32 + constrain v10 == u32 3 + return b3(): v12 = load v5 -> [u32; 5] v13 = array_set v12, index v0, value v1 store v13 at v5 v15 = add v2, u32 1 jmp b1(v15) - b2(): - v8 = load v5 -> [u32; 5] - v10 = array_get v8, index u32 2 -> u32 - constrain v10 == u32 3 - return } "; @@ -485,16 +485,24 @@ mod test { b1(v2: u32): v9 = lt v2, u32 4 jmpif v9 then: b3, else: b2 + b2(): + return b3(): jmp b4(u32 0) b4(v3: u32): v10 = lt v3, u32 4 jmpif v10 then: b6, else: b5 + b5(): + v12 = add v2, u32 1 + jmp b1(v12) b6(): jmp b7(u32 0) b7(v4: u32): v13 = lt v4, u32 4 jmpif v13 then: b9, else: b8 + b8(): + v14 = add v3, u32 1 + jmp b4(v14) b9(): v15 = array_get v6, index v2 -> u32 v16 = eq v15, v0 @@ -504,14 +512,6 @@ mod test { constrain v17 == v0 v19 = add v4, u32 1 jmp b7(v19) - b8(): - v14 = add v3, u32 1 - jmp b4(v14) - b5(): - v12 = add v2, u32 1 - jmp b1(v12) - b2(): - return } "; @@ -526,6 +526,8 @@ mod test { b1(v2: u32): v9 = lt v2, u32 4 jmpif v9 then: b3, else: b2 + b2(): + return b3(): v10 = array_get v6, index v2 -> u32 v11 = eq v10, v0 @@ -533,6 +535,9 @@ mod test { b4(v3: u32): v12 = lt v3, u32 4 jmpif v12 then: b6, else: b5 + b5(): + v14 = add v2, u32 1 + jmp b1(v14) b6(): v15 = array_get v6, index v3 -> u32 v16 = eq v15, v0 @@ -540,19 +545,14 @@ mod test { b7(v4: u32): v17 = lt v4, u32 4 jmpif v17 then: b9, else: b8 + b8(): + v18 = add v3, u32 1 + jmp b4(v18) b9(): constrain v10 == v0 constrain v15 == v0 v19 = add v4, u32 1 jmp b7(v19) - b8(): - v18 = add v3, u32 1 - jmp b4(v18) - b5(): - v14 = add v2, u32 1 - jmp b1(v14) - b2(): - return } "; diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 53a31ae57c1..77ad53df9cf 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -1121,11 +1121,6 @@ mod tests { b1(v0: Field): v4 = eq v0, Field 0 jmpif v4 then: b3, else: b2 - b3(): - v11 = load v3 -> &mut Field - store Field 2 at v11 - v13 = add v0, Field 1 - jmp b1(v13) b2(): v5 = load v1 -> Field v7 = eq v5, Field 2 @@ -1135,6 +1130,11 @@ mod tests { v10 = eq v9, Field 2 constrain v9 == Field 2 return + b3(): + v11 = load v3 -> &mut Field + store Field 2 at v11 + v13 = add v0, Field 1 + jmp b1(v13) } "; @@ -1157,11 +1157,6 @@ mod tests { b1(v0: Field): v4 = eq v0, Field 0 jmpif v4 then: b3, else: b2 - b3(): - v13 = load v3 -> &mut Field - store Field 2 at v13 - v15 = add v0, Field 1 - jmp b1(v15) b2(): v5 = load v1 -> Field v7 = eq v5, Field 2 @@ -1173,6 +1168,11 @@ mod tests { v12 = eq v11, Field 2 constrain v11 == Field 2 return + b3(): + v13 = load v3 -> &mut Field + store Field 2 at v13 + v15 = add v0, Field 1 + jmp b1(v15) } acir(inline) fn foo f1 { b0(v0: &mut Field): @@ -1195,6 +1195,10 @@ mod tests { acir(inline) fn main f0 { b0(v0: u1): jmpif v0 then: b2, else: b1 + b1(): + v4 = allocate -> &mut Field + store Field 1 at v4 + jmp b3(v4, v4, v4) b2(): v6 = allocate -> &mut Field store Field 0 at v6 @@ -1212,10 +1216,6 @@ mod tests { constrain v11 == Field 1 constrain v13 == Field 3 return - b1(): - v4 = allocate -> &mut Field - store Field 1 at v4 - jmp b3(v4, v4, v4) } "; diff --git a/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs index c282e2df451..e7f8d227d28 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/simplify_cfg.rs @@ -442,14 +442,14 @@ mod test { store Field 0 at v1 v3 = not v0 jmpif v0 then: b2, else: b1 + b1(): + store Field 2 at v1 + jmp b2() b2(): v5 = load v1 -> Field v6 = eq v5, Field 2 constrain v5 == Field 2 return - b1(): - store Field 2 at v1 - jmp b2() }"; assert_normalized_ssa_equals(ssa.simplify_cfg(), expected); } diff --git a/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs b/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs index 1a13acc5435..22daba1de45 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs @@ -1337,12 +1337,15 @@ mod tests { b2(): v7 = eq v0, u32 2 jmpif v7 then: b7, else: b3 - b7(): - v18 = add v0, u32 1 - jmp b1(v18) b3(): v9 = eq v0, u32 5 jmpif v9 then: b5, else: b4 + b4(): + v10 = load v1 -> Field + v12 = add v10, Field 1 + store v12 at v1 + v14 = add v0, u32 1 + jmp b1(v14) b5(): jmp b6() b6(): @@ -1350,12 +1353,9 @@ mod tests { v17 = eq v15, Field 4 constrain v15 == Field 4 return - b4(): - v10 = load v1 -> Field - v12 = add v10, Field 1 - store v12 at v1 - v14 = add v0, u32 1 - jmp b1(v14) + b7(): + v18 = add v0, u32 1 + jmp b1(v18) } "; let ssa = Ssa::from_str(src).unwrap(); diff --git a/compiler/noirc_evaluator/src/ssa/parser/tests.rs b/compiler/noirc_evaluator/src/ssa/parser/tests.rs index 6318f9dc56e..dab96dfa04f 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/tests.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/tests.rs @@ -143,10 +143,10 @@ fn test_jmpif() { acir(inline) fn main f0 { b0(v0: Field): jmpif v0 then: b2, else: b1 - b2(): - return b1(): return + b2(): + return } "; assert_ssa_roundtrip(src);