Skip to content

Commit

Permalink
chore(ssa refactor): Implement for loops (#1233)
Browse files Browse the repository at this point in the history
Impl for loops
  • Loading branch information
jfecher authored Apr 26, 2023
1 parent 27c98c2 commit a9f3f20
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
5 changes: 5 additions & 0 deletions crates/noirc_evaluator/src/ssa_refactor/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ impl<'a> FunctionContext<'a> {
}
address
}

pub(super) fn define(&mut self, id: LocalId, value: Values) {
let existing = self.definitions.insert(id, value);
assert!(existing.is_none(), "Variable {id:?} was defined twice in ssa-gen pass");
}
}

/// True if the given operator cannot be encoded directly and needs
Expand Down
30 changes: 28 additions & 2 deletions crates/noirc_evaluator/src/ssa_refactor/ssa_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,34 @@ impl<'a> FunctionContext<'a> {
self.builder.insert_cast(lhs, typ).into()
}

fn codegen_for(&mut self, _for_expr: &ast::For) -> Values {
todo!()
fn codegen_for(&mut self, for_expr: &ast::For) -> Values {
let loop_entry = self.builder.insert_block();
let loop_body = self.builder.insert_block();
let loop_end = self.builder.insert_block();

// this is the 'i' in `for i in start .. end { block }`
let loop_index = self.builder.add_block_parameter(loop_entry, Type::field());

let start_index = self.codegen_non_tuple_expression(&for_expr.start_range);
let end_index = self.codegen_non_tuple_expression(&for_expr.end_range);

self.builder.terminate_with_jmp(loop_entry, vec![start_index]);

// Compile the loop entry block
self.builder.switch_to_block(loop_entry);
let jump_condition = self.builder.insert_binary(loop_index, BinaryOp::Lt, end_index);
self.builder.terminate_with_jmpif(jump_condition, loop_body, loop_end);

// Compile the loop body
self.builder.switch_to_block(loop_body);
self.define(for_expr.index_variable, loop_index.into());
self.codegen_expression(&for_expr.block);
let new_loop_index = self.make_offset(loop_index, 1);
self.builder.terminate_with_jmp(loop_entry, vec![new_loop_index]);

// Finish by switching back to the end of the loop
self.builder.switch_to_block(loop_end);
self.unit_value()
}

fn codegen_if(&mut self, if_expr: &ast::If) -> Values {
Expand Down

0 comments on commit a9f3f20

Please sign in to comment.