From 823bd84ed983e9de0dda20b07179ac78f9ec1009 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Tue, 6 Jun 2023 12:29:11 +0200 Subject: [PATCH] chore: generate brillig opcode for simple identity unconstrained function (#1536) --- .../test_data_ssa_refactor/brillig/Nargo.toml | 5 +++++ .../brillig/Prover.toml | 2 ++ .../brillig/src/main.nr | 10 +++++++++ .../acir_gen/acir_ir/acir_variable.rs | 22 ++++++++++++++++--- .../acir_gen/acir_ir/generated_acir.rs | 18 +++++++++++++++ .../src/ssa_refactor/acir_gen/mod.rs | 11 ++++------ .../src/ssa_refactor/opt/inlining.rs | 15 ++++++++----- 7 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Prover.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/brillig/src/main.nr diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Nargo.toml new file mode 100644 index 00000000000..e0b467ce5da --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Prover.toml new file mode 100644 index 00000000000..55cccb955a9 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/Prover.toml @@ -0,0 +1,2 @@ +x = "3" + diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/src/main.nr new file mode 100644 index 00000000000..4931fd24f38 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/brillig/src/main.nr @@ -0,0 +1,10 @@ +// Tests a very simple program. +// +// The features being tested is assertion +fn main(x : Field) { + assert(x == identity(x)); +} + +unconstrained fn identity(x : Field) -> Field { + x +} \ No newline at end of file diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs index 44764ba2876..3b69c8fa426 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs @@ -1,6 +1,9 @@ use crate::ssa_refactor::ir::types::Type as SsaType; use crate::ssa_refactor::ir::{instruction::Endian, types::NumericType}; -use acvm::acir::brillig_vm::Opcode as BrilligOpcode; +use acvm::acir::{ + brillig_vm::Opcode as BrilligOpcode, + circuit::brillig::{BrilligInputs, BrilligOutputs}, +}; use super::{ errors::AcirGenError, @@ -727,8 +730,21 @@ impl AcirContext { id } - pub(crate) fn brillig(&mut self, _code: Vec) { - todo!(); + pub(crate) fn brillig( + &mut self, + code: Vec, + inputs: Vec, + output_len: usize, + ) -> Vec { + let b_inputs = + vecmap(inputs, |i| BrilligInputs::Single(self.data[&i].to_expression().into_owned())); + let outputs = vecmap(0..output_len, |_| self.acir_ir.next_witness_index()); + let outputs_var = + vecmap(&outputs, |witness_index| self.add_data(AcirVarData::Witness(*witness_index))); + let b_outputs = vecmap(outputs, BrilligOutputs::Simple); + self.acir_ir.brillig(code, b_inputs, b_outputs); + + outputs_var } } diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs index 95fa1411b5e..b67eac031aa 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs @@ -2,7 +2,9 @@ //! program as it is being converted from SSA form. use super::errors::AcirGenError; use acvm::acir::{ + brillig_vm::Opcode as BrilligOpcode, circuit::{ + brillig::{Brillig as AcvmBrillig, BrilligInputs, BrilligOutputs}, directives::{LogInfo, QuotientDirective}, opcodes::{BlackBoxFuncCall, FunctionInput, Opcode as AcirOpcode}, }, @@ -464,6 +466,22 @@ impl GeneratedAcir { Ok(q_witness) } + + pub(crate) fn brillig( + &mut self, + code: Vec, + inputs: Vec, + outputs: Vec, + ) { + let opcode = AcirOpcode::Brillig(AcvmBrillig { + inputs, + outputs, + foreign_call_results: Vec::new(), + bytecode: code, + predicate: None, + }); + self.push_opcode(opcode); + } } /// This function will return the number of inputs that a blackbox function diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs index f8ccb7e0706..710fa273da4 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs @@ -22,6 +22,7 @@ use super::{ ssa_gen::Ssa, }; use crate::brillig::{artifact::BrilligArtifact, Brillig}; +use iter_extended::vecmap; use noirc_abi::{AbiType, FunctionSignature, Sign}; pub(crate) use acir_ir::generated_acir::GeneratedAcir; @@ -90,11 +91,6 @@ impl Context { brillig: Brillig, allow_log_ops: bool, ) -> GeneratedAcir { - assert_eq!( - ssa.functions.len(), - 1, - "expected only a single function to be present with all other functions being inlined." - ); let main_func = ssa.main(); let dfg = &main_func.dfg; let entry_block = &dfg[main_func.entry_block()]; @@ -214,10 +210,11 @@ impl Context { "expected an intrinsic/brillig call, but found {func:?}. All ACIR methods should be inlined" ), RuntimeType::Brillig => { + let inputs = vecmap(arguments, |&a| {self.convert_ssa_value(a, dfg)}); // Generate the brillig code of the function let code = BrilligArtifact::default().link(&brillig[*id]); - self.acir_context.brillig(code); - (result_ids.to_vec(), Vec::new()) + let outputs = self.acir_context.brillig(code, inputs, result_ids.len()); + (result_ids.to_vec(), outputs) } } } diff --git a/crates/noirc_evaluator/src/ssa_refactor/opt/inlining.rs b/crates/noirc_evaluator/src/ssa_refactor/opt/inlining.rs index 29466cba346..9d75f14b9bb 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/opt/inlining.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/opt/inlining.rs @@ -253,10 +253,7 @@ impl<'function> PerFunctionContext<'function> { match self.context.builder[id] { Value::Function(id) => Some(id), Value::Intrinsic(_) => None, - _ => { - self.context.failed_to_inline_a_call = true; - None - } + _ => None, } } @@ -326,9 +323,15 @@ impl<'function> PerFunctionContext<'function> { Instruction::Call { func, arguments } => match self.get_function(*func) { Some(function) => match ssa.functions[&function].runtime() { RuntimeType::Acir => self.inline_function(ssa, *id, function, arguments), - RuntimeType::Brillig => self.push_instruction(*id), + RuntimeType::Brillig => { + self.context.failed_to_inline_a_call = true; + self.push_instruction(*id); + } }, - None => self.push_instruction(*id), + None => { + self.context.failed_to_inline_a_call = true; + self.push_instruction(*id); + } }, _ => self.push_instruction(*id), }