Skip to content

Commit

Permalink
Merge c54dfb8 into d4832ec
Browse files Browse the repository at this point in the history
  • Loading branch information
sirasistant authored Sep 11, 2024
2 parents d4832ec + c54dfb8 commit 418ce5a
Show file tree
Hide file tree
Showing 9 changed files with 600 additions and 361 deletions.
418 changes: 73 additions & 345 deletions compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs

Large diffs are not rendered by default.

23 changes: 12 additions & 11 deletions compiler/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,6 @@ impl<F: AcirField + DebugToString> BrilligContext<F, Stack> {
can_call_procedures: true,
}
}
/// Allows disabling procedures so tests don't need a linking pass
pub(crate) fn disable_procedures(&mut self) {
self.can_call_procedures = false;
}
}

/// Special brillig context to codegen compiler intrinsic shared procedures
Expand Down Expand Up @@ -165,7 +161,8 @@ pub(crate) mod tests {
use crate::brillig::brillig_ir::{BrilligBinaryOp, BrilligContext};
use crate::ssa::ir::function::FunctionId;

use super::artifact::{BrilligParameter, GeneratedBrillig, Label};
use super::artifact::{BrilligParameter, GeneratedBrillig, Label, LabelType};
use super::procedures::compile_procedure;
use super::registers::Stack;
use super::{BrilligOpcode, ReservedRegisters};

Expand Down Expand Up @@ -237,13 +234,17 @@ pub(crate) mod tests {
returns: Vec<BrilligParameter>,
) -> GeneratedBrillig<FieldElement> {
let artifact = context.artifact();
let mut entry_point_artifact = BrilligContext::new_entry_point_artifact(
arguments,
returns,
FunctionId::test_new(0),
true,
);
let mut entry_point_artifact =
BrilligContext::new_entry_point_artifact(arguments, returns, FunctionId::test_new(0));
entry_point_artifact.link_with(&artifact);
while let Some(unresolved_fn_label) = entry_point_artifact.first_unresolved_function_call()
{
let LabelType::Procedure(procedure_id) = unresolved_fn_label.label_type else {
panic!("Test functions cannot be linked with other functions");
};
let procedure_artifact = compile_procedure(procedure_id);
entry_point_artifact.link_with(&procedure_artifact);
}
entry_point_artifact.finish()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ impl<F: AcirField + DebugToString> BrilligContext<F, Stack> {
arguments: Vec<BrilligParameter>,
return_parameters: Vec<BrilligParameter>,
target_function: FunctionId,
disable_procedures: bool,
) -> BrilligArtifact<F> {
let mut context = BrilligContext::new(false);
if disable_procedures {
context.disable_procedures();
}

context.codegen_entry_point(&arguments, &return_parameters);

context.add_external_call_instruction(target_function);
Expand Down
22 changes: 22 additions & 0 deletions compiler/noirc_evaluator/src/brillig/brillig_ir/procedures/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
mod array_copy;
mod array_reverse;
mod mem_copy;
mod prepare_vector_insert;
mod prepare_vector_push;
mod vector_copy;
mod vector_pop;
mod vector_remove;

use array_copy::compile_array_copy_procedure;
use array_reverse::compile_array_reverse_procedure;
use mem_copy::compile_mem_copy_procedure;
use prepare_vector_insert::compile_prepare_vector_insert_procedure;
use prepare_vector_push::compile_prepare_vector_push_procedure;
use vector_copy::compile_vector_copy_procedure;
use vector_pop::compile_vector_pop_procedure;
use vector_remove::compile_vector_remove_procedure;

use crate::brillig::brillig_ir::AcirField;

Expand All @@ -25,6 +33,10 @@ pub(crate) enum ProcedureId {
ArrayReverse,
VectorCopy,
MemCopy,
PrepareVectorPush(bool),
VectorPop(bool),
PrepareVectorInsert,
VectorRemove,
}

pub(crate) fn compile_procedure<F: AcirField + DebugToString>(
Expand All @@ -38,6 +50,16 @@ pub(crate) fn compile_procedure<F: AcirField + DebugToString>(
ProcedureId::ArrayCopy => compile_array_copy_procedure(&mut brillig_context),
ProcedureId::ArrayReverse => compile_array_reverse_procedure(&mut brillig_context),
ProcedureId::VectorCopy => compile_vector_copy_procedure(&mut brillig_context),
ProcedureId::PrepareVectorPush(push_back) => {
compile_prepare_vector_push_procedure(&mut brillig_context, push_back);
}
ProcedureId::VectorPop(pop_back) => {
compile_vector_pop_procedure(&mut brillig_context, pop_back);
}
ProcedureId::PrepareVectorInsert => {
compile_prepare_vector_insert_procedure(&mut brillig_context);
}
ProcedureId::VectorRemove => compile_vector_remove_procedure(&mut brillig_context),
};

brillig_context.stop_instruction();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use std::vec;

use acvm::{acir::brillig::MemoryAddress, AcirField};

use super::ProcedureId;
use crate::brillig::brillig_ir::{
brillig_variable::{BrilligVector, SingleAddrVariable},
debug_show::DebugToString,
registers::{RegisterAllocator, ScratchSpace},
BrilligBinaryOp, BrilligContext,
};

impl<F: AcirField + DebugToString, Registers: RegisterAllocator> BrilligContext<F, Registers> {
/// It prepares a vector for a insert operation, leaving a hole at the index position which is returned as the write_pointer.
pub(crate) fn call_prepare_vector_insert_procedure(
&mut self,
source_vector: BrilligVector,
destination_vector: BrilligVector,
index: SingleAddrVariable,
write_pointer: MemoryAddress,
item_count: usize,
) {
let source_vector_pointer_arg = MemoryAddress::from(ScratchSpace::start());
let index_arg = MemoryAddress::from(ScratchSpace::start() + 1);
let item_count_arg = MemoryAddress::from(ScratchSpace::start() + 2);
let new_vector_pointer_return = MemoryAddress::from(ScratchSpace::start() + 3);
let write_pointer_return = MemoryAddress::from(ScratchSpace::start() + 4);

self.mov_instruction(source_vector_pointer_arg, source_vector.pointer);
self.mov_instruction(index_arg, index.address);
self.usize_const_instruction(item_count_arg, item_count.into());

self.add_procedure_call_instruction(ProcedureId::PrepareVectorInsert);

self.mov_instruction(destination_vector.pointer, new_vector_pointer_return);
self.mov_instruction(write_pointer, write_pointer_return);
}
}

pub(super) fn compile_prepare_vector_insert_procedure<F: AcirField + DebugToString>(
brillig_context: &mut BrilligContext<F, ScratchSpace>,
) {
let source_vector_pointer_arg = MemoryAddress::from(ScratchSpace::start());
let index_arg = MemoryAddress::from(ScratchSpace::start() + 1);
let item_count_arg = MemoryAddress::from(ScratchSpace::start() + 2);
let new_vector_pointer_return = MemoryAddress::from(ScratchSpace::start() + 3);
let write_pointer_return = MemoryAddress::from(ScratchSpace::start() + 4);

brillig_context.set_allocated_registers(vec![
source_vector_pointer_arg,
index_arg,
item_count_arg,
new_vector_pointer_return,
write_pointer_return,
]);

let source_vector = BrilligVector { pointer: source_vector_pointer_arg };
let target_vector = BrilligVector { pointer: new_vector_pointer_return };
let index = SingleAddrVariable::new_usize(index_arg);

// First we need to allocate the target vector incrementing the size by items.len()
let source_size = brillig_context.codegen_make_vector_length(source_vector);

let target_size = SingleAddrVariable::new_usize(brillig_context.allocate_register());
brillig_context.memory_op_instruction(
source_size.address,
item_count_arg,
target_size.address,
BrilligBinaryOp::Add,
);

brillig_context.codegen_initialize_vector(target_vector, target_size);

// Copy the elements to the left of the index
let source_vector_items_pointer =
brillig_context.codegen_make_vector_items_pointer(source_vector);
let target_vector_items_pointer =
brillig_context.codegen_make_vector_items_pointer(target_vector);

brillig_context.codegen_mem_copy(
source_vector_items_pointer,
target_vector_items_pointer,
index,
);

// Compute the source pointer just at the index
let source_pointer_at_index = brillig_context.allocate_register();
brillig_context.memory_op_instruction(
source_vector_items_pointer,
index_arg,
source_pointer_at_index,
BrilligBinaryOp::Add,
);

// Compute the target pointer after the inserted elements
brillig_context.memory_op_instruction(
target_vector_items_pointer,
index.address,
write_pointer_return,
BrilligBinaryOp::Add,
);
let target_pointer_after_index = brillig_context.allocate_register();

brillig_context.memory_op_instruction(
write_pointer_return,
item_count_arg,
target_pointer_after_index,
BrilligBinaryOp::Add,
);

// Compute the number of elements to the right of the index
let item_count = brillig_context.allocate_register();
brillig_context.memory_op_instruction(
source_size.address,
index.address,
item_count,
BrilligBinaryOp::Sub,
);

// Copy the elements to the right of the index
brillig_context.codegen_mem_copy(
source_pointer_at_index,
target_pointer_after_index,
SingleAddrVariable::new_usize(item_count),
);

brillig_context.deallocate_register(source_pointer_at_index);
brillig_context.deallocate_register(target_pointer_after_index);
brillig_context.deallocate_register(item_count);
brillig_context.deallocate_single_addr(source_size);
brillig_context.deallocate_single_addr(target_size);
brillig_context.deallocate_register(source_vector_items_pointer);
brillig_context.deallocate_register(target_vector_items_pointer);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use std::vec;

use acvm::{acir::brillig::MemoryAddress, AcirField};

use super::ProcedureId;
use crate::brillig::brillig_ir::{
brillig_variable::{BrilligVector, SingleAddrVariable},
debug_show::DebugToString,
registers::{RegisterAllocator, ScratchSpace},
BrilligBinaryOp, BrilligContext,
};

impl<F: AcirField + DebugToString, Registers: RegisterAllocator> BrilligContext<F, Registers> {
/// Prepares a vector for a push operation, allocating a larger vector and copying the source vector into the destination vector.
/// It returns the write pointer to where to put the new items.
pub(crate) fn call_prepare_vector_push_procedure(
&mut self,
source_vector: BrilligVector,
destination_vector: BrilligVector,
write_pointer: MemoryAddress,
item_push_count: usize,
back: bool,
) {
let source_vector_pointer_arg = MemoryAddress::from(ScratchSpace::start());
let item_push_count_arg = MemoryAddress::from(ScratchSpace::start() + 1);
let new_vector_pointer_return = MemoryAddress::from(ScratchSpace::start() + 2);
let write_pointer_return = MemoryAddress::from(ScratchSpace::start() + 3);

self.mov_instruction(source_vector_pointer_arg, source_vector.pointer);
self.usize_const_instruction(item_push_count_arg, item_push_count.into());

self.add_procedure_call_instruction(ProcedureId::PrepareVectorPush(back));

self.mov_instruction(destination_vector.pointer, new_vector_pointer_return);
self.mov_instruction(write_pointer, write_pointer_return);
}
}

pub(super) fn compile_prepare_vector_push_procedure<F: AcirField + DebugToString>(
brillig_context: &mut BrilligContext<F, ScratchSpace>,
push_back: bool,
) {
let source_vector_pointer_arg = MemoryAddress::from(ScratchSpace::start());
let item_push_count_arg = MemoryAddress::from(ScratchSpace::start() + 1);
let new_vector_pointer_return = MemoryAddress::from(ScratchSpace::start() + 2);
let write_pointer_return = MemoryAddress::from(ScratchSpace::start() + 3);

brillig_context.set_allocated_registers(vec![
source_vector_pointer_arg,
item_push_count_arg,
new_vector_pointer_return,
write_pointer_return,
]);

let source_vector = BrilligVector { pointer: source_vector_pointer_arg };
let target_vector = BrilligVector { pointer: new_vector_pointer_return };

// First we need to allocate the target vector incrementing the size by item_push_count_arg
let source_size = brillig_context.codegen_make_vector_length(source_vector);

let target_size = SingleAddrVariable::new_usize(brillig_context.allocate_register());
brillig_context.memory_op_instruction(
source_size.address,
item_push_count_arg,
target_size.address,
BrilligBinaryOp::Add,
);

brillig_context.codegen_initialize_vector(target_vector, target_size);

// Now we copy the source vector into the target vector
let source_vector_items_pointer =
brillig_context.codegen_make_vector_items_pointer(source_vector);
let target_vector_items_pointer =
brillig_context.codegen_make_vector_items_pointer(target_vector);

if push_back {
brillig_context.codegen_mem_copy(
source_vector_items_pointer,
target_vector_items_pointer,
source_size,
);

brillig_context.memory_op_instruction(
target_vector_items_pointer,
source_size.address,
write_pointer_return,
BrilligBinaryOp::Add,
);
} else {
brillig_context.mov_instruction(write_pointer_return, target_vector_items_pointer);

brillig_context.memory_op_instruction(
target_vector_items_pointer,
item_push_count_arg,
target_vector_items_pointer,
BrilligBinaryOp::Add,
);

brillig_context.codegen_mem_copy(
source_vector_items_pointer,
target_vector_items_pointer,
source_size,
);
}

brillig_context.deallocate_single_addr(source_size);
brillig_context.deallocate_single_addr(target_size);
brillig_context.deallocate_register(source_vector_items_pointer);
brillig_context.deallocate_register(target_vector_items_pointer);
}
Loading

0 comments on commit 418ce5a

Please sign in to comment.