Skip to content

Commit

Permalink
feat: recursion working in brillig (#1854)
Browse files Browse the repository at this point in the history
* feat: recursion working in brillig

* Update crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs

* fix: removed redundant clone

* Update crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs

* fix: merge change
  • Loading branch information
sirasistant authored Jul 4, 2023
1 parent b2e71bb commit e55b5a8
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "10"
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Tests a very simple program.
//
// The feature being tested is brillig recursion
fn main(x: u32) {
assert(fibonacci(x) == 55);
}

unconstrained fn fibonacci(x : u32) -> u32 {
if x <= 1 {
x
} else {
fibonacci(x - 1) + fibonacci(x - 2)
}
}
25 changes: 9 additions & 16 deletions crates/noirc_evaluator/src/brillig/brillig_ir/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,17 @@ impl BrilligArtifact {
}
}

/// Creates an entry point artifact wrapping the bytecode of the function provided.
pub(crate) fn to_entry_point_artifact(artifact: &BrilligArtifact) -> BrilligArtifact {
let mut entry_point_artifact =
BrilligArtifact::new(artifact.arguments.clone(), artifact.return_parameters.clone());
/// Creates an entry point artifact that will jump to the function label provided.
pub(crate) fn new_entry_point_artifact(
arguments: Vec<BrilligParameter>,
return_parameters: Vec<BrilligParameter>,
target_function: Label,
) -> BrilligArtifact {
let mut entry_point_artifact = BrilligArtifact::new(arguments, return_parameters);
entry_point_artifact.entry_point_instruction();

entry_point_artifact.add_unresolved_jumps_and_calls(artifact);
entry_point_artifact.byte_code.extend_from_slice(&artifact.byte_code);
entry_point_artifact
.add_unresolved_external_call(BrilligOpcode::Call { location: 0 }, target_function);

entry_point_artifact.exit_point_instruction();
entry_point_artifact
Expand Down Expand Up @@ -126,16 +129,6 @@ impl BrilligArtifact {
// We want all functions to follow the calling convention of returning
// their results in the first `n` registers. So we modify the bytecode of the
// function to move the return values to the first `n` registers once completed.
//
// Swap the stop opcode with a jump to the exit point section

let stop_position =
self.byte_code.iter().position(|opcode| matches!(opcode, BrilligOpcode::Stop));

let stop_position = stop_position.expect("expected a stop opcode");

let exit_section = self.index_of_next_opcode();
self.byte_code[stop_position] = BrilligOpcode::Jump { location: exit_section };

// TODO: this _seems_ like an abstraction leak, we need to know about the reserved
// TODO: registers in order to do this.
Expand Down
11 changes: 9 additions & 2 deletions crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
use std::collections::HashMap;

use crate::brillig::{brillig_ir::artifact::BrilligArtifact, Brillig};
use crate::brillig::{
brillig_gen::brillig_fn::FunctionContext as BrilligFunctionContext,
brillig_ir::artifact::BrilligArtifact, Brillig,
};

use self::acir_ir::{
acir_variable::{AcirContext, AcirType, AcirVar},
Expand Down Expand Up @@ -338,7 +341,11 @@ impl Context {

fn gen_brillig_for(&self, func: &Function, brillig: &Brillig) -> Vec<Opcode> {
// Create the entry point artifact
let mut entry_point = BrilligArtifact::to_entry_point_artifact(&brillig[func.id()]);
let mut entry_point = BrilligArtifact::new_entry_point_artifact(
BrilligFunctionContext::parameters(func),
BrilligFunctionContext::return_values(func),
BrilligFunctionContext::function_id_to_function_label(func.id()),
);
// Link the entry point with all dependencies
while let Some(unresolved_fn_label) = entry_point.first_unresolved_function_call() {
let artifact = &brillig
Expand Down

0 comments on commit e55b5a8

Please sign in to comment.