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

chore: pull out noir-lang/noir#5120 #7205

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use dep::std;

fn main(x: u64, y: pub u64) -> pub u64 {
// We include a println statement to show that noirJS will ignore this and continue execution
std::println("foo");


assert(x < y);
x + y
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use dep::std;

fn main(
verification_key: [Field; 114],
proof: [Field; 93],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ pub(crate) mod brillig_fn;
pub(crate) mod brillig_slice_ops;
mod variable_liveness;

use acvm::FieldElement;

use self::{brillig_block::BrilligBlock, brillig_fn::FunctionContext};
use super::brillig_ir::{artifact::BrilligArtifact, BrilligContext};
use crate::ssa::ir::function::Function;

/// Converting an SSA function into Brillig bytecode.
pub(crate) fn convert_ssa_function(func: &Function, enable_debug_trace: bool) -> BrilligArtifact {
pub(crate) fn convert_ssa_function(
func: &Function,
enable_debug_trace: bool,
) -> BrilligArtifact<FieldElement> {
let mut brillig_context = BrilligContext::new(enable_debug_trace);

let mut function_context = FunctionContext::new(func);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use acvm::{
acir::{brillig::BlackBoxOp, BlackBoxFunc},
FieldElement,
AcirField,
};

use crate::brillig::brillig_ir::{
brillig_variable::{BrilligVariable, BrilligVector, SingleAddrVariable},
debug_show::DebugToString,
BrilligBinaryOp, BrilligContext,
};

/// Transforms SSA's black box function calls into the corresponding brillig instructions
/// Extracting arguments and results from the SSA function call
/// And making any necessary type conversions to adapt noir's blackbox calls to brillig's
pub(crate) fn convert_black_box_call(
brillig_context: &mut BrilligContext,
pub(crate) fn convert_black_box_call<F: AcirField + DebugToString>(
brillig_context: &mut BrilligContext<F>,
bb_func: &BlackBoxFunc,
function_arguments: &[BrilligVariable],
function_results: &[BrilligVariable],
Expand Down Expand Up @@ -341,7 +342,7 @@ pub(crate) fn convert_black_box_call(
let inputs_vector = convert_array_or_vector(brillig_context, inputs, bb_func);
let modulus_vector = convert_array_or_vector(brillig_context, modulus, bb_func);
let output_id = brillig_context.get_new_bigint_id();
brillig_context.const_instruction(*output, FieldElement::from(output_id as u128));
brillig_context.const_instruction(*output, F::from(output_id as u128));
brillig_context.black_box_op_instruction(BlackBoxOp::BigIntFromLeBytes {
inputs: inputs_vector.to_heap_vector(),
modulus: modulus_vector.to_heap_vector(),
Expand Down Expand Up @@ -426,8 +427,8 @@ pub(crate) fn convert_black_box_call(
}
}

fn convert_array_or_vector(
brillig_context: &mut BrilligContext,
fn convert_array_or_vector<F: AcirField + DebugToString>(
brillig_context: &mut BrilligContext<F>,
array_or_vector: &BrilligVariable,
bb_func: &BlackBoxFunc,
) -> BrilligVector {
Expand All @@ -442,8 +443,8 @@ fn convert_array_or_vector(
}
}

fn prepare_bigint_output(
brillig_context: &mut BrilligContext,
fn prepare_bigint_output<F: AcirField + DebugToString>(
brillig_context: &mut BrilligContext<F>,
lhs_modulus: &SingleAddrVariable,
rhs_modulus: &SingleAddrVariable,
output: &SingleAddrVariable,
Expand All @@ -465,6 +466,6 @@ fn prepare_bigint_output(
brillig_context.deallocate_register(condition);
// Set output id
let output_id = brillig_context.get_new_bigint_id();
brillig_context.const_instruction(*output, FieldElement::from(output_id as u128));
brillig_context.const_instruction(*output, F::from(output_id as u128));
brillig_context.mov_instruction(modulus_id.address, lhs_modulus.address);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub(crate) struct BrilligBlock<'block> {
/// The basic block that is being converted
pub(crate) block_id: BasicBlockId,
/// Context for creating brillig opcodes
pub(crate) brillig_context: &'block mut BrilligContext,
pub(crate) brillig_context: &'block mut BrilligContext<FieldElement>,
/// Tracks the available variable during the codegen of the block
pub(crate) variables: BlockVariables,
/// For each instruction, the set of values that are not used anymore after it.
Expand All @@ -44,7 +44,7 @@ impl<'block> BrilligBlock<'block> {
/// Converts an SSA Basic block into a sequence of Brillig opcodes
pub(crate) fn compile(
function_context: &'block mut FunctionContext,
brillig_context: &'block mut BrilligContext,
brillig_context: &'block mut BrilligContext<FieldElement>,
block_id: BasicBlockId,
dfg: &DataFlowGraph,
) {
Expand Down Expand Up @@ -944,7 +944,7 @@ impl<'block> BrilligBlock<'block> {
}

pub(crate) fn store_variable_in_array_with_ctx(
ctx: &mut BrilligContext,
ctx: &mut BrilligContext<FieldElement>,
destination_pointer: MemoryAddress,
index_register: SingleAddrVariable,
value_variable: BrilligVariable,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use acvm::FieldElement;
use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet};

use crate::{
Expand Down Expand Up @@ -50,7 +51,7 @@ impl BlockVariables {
pub(crate) fn define_variable(
&mut self,
function_context: &mut FunctionContext,
brillig_context: &mut BrilligContext,
brillig_context: &mut BrilligContext<FieldElement>,
value_id: ValueId,
dfg: &DataFlowGraph,
) -> BrilligVariable {
Expand All @@ -70,7 +71,7 @@ impl BlockVariables {
pub(crate) fn define_single_addr_variable(
&mut self,
function_context: &mut FunctionContext,
brillig_context: &mut BrilligContext,
brillig_context: &mut BrilligContext<FieldElement>,
value: ValueId,
dfg: &DataFlowGraph,
) -> SingleAddrVariable {
Expand All @@ -83,7 +84,7 @@ impl BlockVariables {
&mut self,
value_id: &ValueId,
function_context: &mut FunctionContext,
brillig_context: &mut BrilligContext,
brillig_context: &mut BrilligContext<FieldElement>,
) {
assert!(self.available_variables.remove(value_id), "ICE: Variable is not available");
let variable = function_context
Expand Down Expand Up @@ -122,7 +123,7 @@ impl BlockVariables {
/// We keep constants block-local.
pub(crate) fn allocate_constant(
&mut self,
brillig_context: &mut BrilligContext,
brillig_context: &mut BrilligContext<FieldElement>,
value_id: ValueId,
dfg: &DataFlowGraph,
) -> BrilligVariable {
Expand Down Expand Up @@ -154,9 +155,9 @@ pub(crate) fn compute_array_length(item_typ: &CompositeType, elem_count: usize)
}

/// For a given value_id, allocates the necessary registers to hold it.
pub(crate) fn allocate_value(
pub(crate) fn allocate_value<F>(
value_id: ValueId,
brillig_context: &mut BrilligContext,
brillig_context: &mut BrilligContext<F>,
dfg: &DataFlowGraph,
) -> BrilligVariable {
let typ = dfg.type_of_value(value_id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use acvm::{
acir::brillig::{BinaryFieldOp, BinaryIntOp, MemoryAddress, Opcode as BrilligOpcode},
acir::AcirField,
FieldElement,
};

use crate::brillig::brillig_ir::artifact::GeneratedBrillig;

/// Generates brillig bytecode which computes the inverse of its input if not null, and zero else.
pub(crate) fn directive_invert() -> GeneratedBrillig {
pub(crate) fn directive_invert<F: AcirField>() -> GeneratedBrillig<F> {
// We generate the following code:
// fn invert(x : Field) -> Field {
// 1/ x
Expand All @@ -28,8 +27,8 @@ pub(crate) fn directive_invert() -> GeneratedBrillig {
// Put value zero in register (2)
BrilligOpcode::Const {
destination: zero_const,
value: FieldElement::from(0_usize),
bit_size: FieldElement::max_num_bits(),
value: F::from(0_usize),
bit_size: F::max_num_bits(),
},
BrilligOpcode::BinaryFieldOp {
op: BinaryFieldOp::Equals,
Expand All @@ -42,8 +41,8 @@ pub(crate) fn directive_invert() -> GeneratedBrillig {
// Put value one in register (1)
BrilligOpcode::Const {
destination: one_const,
value: FieldElement::from(1_usize),
bit_size: FieldElement::max_num_bits(),
value: F::one(),
bit_size: F::max_num_bits(),
},
// Divide 1 by the input, and set the result of the division into register (0)
BrilligOpcode::BinaryFieldOp {
Expand All @@ -68,13 +67,13 @@ pub(crate) fn directive_invert() -> GeneratedBrillig {
/// (a/b, a-a/b*b)
/// }
/// ```
pub(crate) fn directive_quotient(bit_size: u32) -> GeneratedBrillig {
pub(crate) fn directive_quotient<F: AcirField>(bit_size: u32) -> GeneratedBrillig<F> {
// `a` is (0) (i.e register index 0)
// `b` is (1)

// TODO: The only difference between these implementations is the integer version will truncate the input to the `bit_size` via cast.
// Once we deduplicate brillig functions then we can modify this so that fields and integers share the same quotient function.
if bit_size >= FieldElement::max_num_bits() {
if bit_size >= F::max_num_bits() {
// Field version
GeneratedBrillig {
byte_code: vec![
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub(crate) struct FunctionContext {
}

impl FunctionContext {
/// Creates a new function context. It will compute the liveness of every variable.
/// Creates a new function context. It will allocate parameters for all blocks and compute the liveness of every variable.
pub(crate) fn new(function: &Function) -> Self {
let id = function.id();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ mod tests {
use crate::ssa::ir::map::Id;
use crate::ssa::ssa_gen::Ssa;

fn create_test_environment() -> (Ssa, FunctionContext, BrilligContext) {
fn create_test_environment() -> (Ssa, FunctionContext, BrilligContext<FieldElement>) {
let mut builder = FunctionBuilder::new("main".to_string(), Id::test_new(0));
builder.set_runtime(RuntimeType::Brillig);

Expand All @@ -385,7 +385,7 @@ mod tests {

fn create_brillig_block<'a>(
function_context: &'a mut FunctionContext,
brillig_context: &'a mut BrilligContext,
brillig_context: &'a mut BrilligContext<FieldElement>,
) -> BrilligBlock<'a> {
let variables = BlockVariables::default();
BrilligBlock {
Expand Down
24 changes: 13 additions & 11 deletions noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ mod instructions;

pub(crate) use instructions::BrilligBinaryOp;

use self::{artifact::BrilligArtifact, registers::BrilligRegistersContext};
use self::{
artifact::BrilligArtifact, debug_show::DebugToString, registers::BrilligRegistersContext,
};
use crate::ssa::ir::dfg::CallStack;
use acvm::{
acir::brillig::{MemoryAddress, Opcode as BrilligOpcode},
FieldElement,
AcirField,
};
use debug_show::DebugShow;

Expand Down Expand Up @@ -76,8 +78,8 @@ impl ReservedRegisters {

/// Brillig context object that is used while constructing the
/// Brillig bytecode.
pub(crate) struct BrilligContext {
obj: BrilligArtifact,
pub(crate) struct BrilligContext<F> {
obj: BrilligArtifact<F>,
/// Tracks register allocations
registers: BrilligRegistersContext,
/// Context label, must be unique with respect to the function
Expand All @@ -93,9 +95,9 @@ pub(crate) struct BrilligContext {
bigint_new_id: u32,
}

impl BrilligContext {
impl<F: AcirField + DebugToString> BrilligContext<F> {
/// Initial context state
pub(crate) fn new(enable_debug_trace: bool) -> BrilligContext {
pub(crate) fn new(enable_debug_trace: bool) -> BrilligContext<F> {
BrilligContext {
obj: BrilligArtifact::default(),
registers: BrilligRegistersContext::new(),
Expand All @@ -113,12 +115,12 @@ impl BrilligContext {
result
}
/// Adds a brillig instruction to the brillig byte code
fn push_opcode(&mut self, opcode: BrilligOpcode<FieldElement>) {
fn push_opcode(&mut self, opcode: BrilligOpcode<F>) {
self.obj.push_opcode(opcode);
}

/// Returns the artifact
pub(crate) fn artifact(self) -> BrilligArtifact {
pub(crate) fn artifact(self) -> BrilligArtifact<F> {
self.obj
}

Expand Down Expand Up @@ -200,17 +202,17 @@ pub(crate) mod tests {
}
}

pub(crate) fn create_context() -> BrilligContext {
pub(crate) fn create_context() -> BrilligContext<FieldElement> {
let mut context = BrilligContext::new(true);
context.enter_context("test");
context
}

pub(crate) fn create_entry_point_bytecode(
context: BrilligContext,
context: BrilligContext<FieldElement>,
arguments: Vec<BrilligParameter>,
returns: Vec<BrilligParameter>,
) -> GeneratedBrillig {
) -> GeneratedBrillig<FieldElement> {
let artifact = context.artifact();
let mut entry_point_artifact =
BrilligContext::new_entry_point_artifact(arguments, returns, "test".to_string());
Expand Down
Loading
Loading