Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
55 changes: 29 additions & 26 deletions compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,39 +403,20 @@ impl<F: AcirField + DebugToString, Registers: RegisterAllocator> BrilligContext<
/// Initializes an array, allocating memory to store its representation and initializing the reference counter.
pub(crate) fn codegen_initialize_array(&mut self, array: BrilligArray) {
self.codegen_allocate_immediate_mem(array.pointer, array.size + 1);
self.indirect_const_instruction(
array.pointer,
BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
1_usize.into(),
);
self.initialize_rc(array.pointer, 1);
}

pub(crate) fn codegen_initialize_vector_metadata(
&mut self,
vector: BrilligVector,
size: SingleAddrVariable,
capacity: Option<SingleAddrVariable>,
) {
// Write RC
/// Initialize the reference counter for an array or vector.
/// This should only be used internally in the array and vector initialization methods
fn initialize_rc(&mut self, pointer: MemoryAddress, rc_value: usize) {
self.indirect_const_instruction(
vector.pointer,
pointer,
BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
1_usize.into(),
rc_value.into(),
);

// Write size
let write_pointer = self.allocate_register();
self.codegen_usize_op(vector.pointer, write_pointer, BrilligBinaryOp::Add, 1);
self.store_instruction(write_pointer, size.address);

// Write capacity
self.codegen_usize_op_in_place(write_pointer, BrilligBinaryOp::Add, 1);
self.store_instruction(write_pointer, capacity.unwrap_or(size).address);

self.deallocate_register(write_pointer);
}

/// Initializes a vector, allocating memory to store its representation and initializing the reference counter, size and capacity
/// Initializes a vector, allocating memory to store its representation and initializing the reference counter
pub(crate) fn codegen_initialize_vector(
&mut self,
vector: BrilligVector,
Expand All @@ -456,6 +437,28 @@ impl<F: AcirField + DebugToString, Registers: RegisterAllocator> BrilligContext<
self.codegen_initialize_vector_metadata(vector, size, capacity);
}

/// Writes vector metadata (reference count, size, and capacity) into the allocated memory
pub(super) fn codegen_initialize_vector_metadata(
&mut self,
vector: BrilligVector,
size: SingleAddrVariable,
capacity: Option<SingleAddrVariable>,
) {
// Write RC
self.initialize_rc(vector.pointer, 1);

// Write size
let write_pointer = self.allocate_register();
self.codegen_usize_op(vector.pointer, write_pointer, BrilligBinaryOp::Add, 1);
self.store_instruction(write_pointer, size.address);

// Write capacity
self.codegen_usize_op_in_place(write_pointer, BrilligBinaryOp::Add, 1);
self.store_instruction(write_pointer, capacity.unwrap_or(size).address);

self.deallocate_register(write_pointer);
}

/// We don't know the length of a vector returned externally before the call
/// so we pass the free memory pointer and then use this function to allocate
/// after the fact when we know the length.
Expand Down
10 changes: 6 additions & 4 deletions compiler/noirc_frontend/src/ownership/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,14 @@

/// Whenever an ident is used it is always cloned unless it is the last use of the ident (not in a loop).
fn should_clone_ident(&self, ident: &Ident) -> bool {
if let Definition::Local(local_id) = &ident.definition {
if contains_array_or_str_type(&ident.typ) && !self.should_move(*local_id, ident.id) {
return true;
match &ident.definition {
Definition::Local(local_id) => {
contains_array_or_str_type(&ident.typ) && !self.should_move(*local_id, ident.id)
}
// Globals are always cloned if they contain arrays
Definition::Global(_) => contains_array_or_str_type(&ident.typ),
_ => false,
}
false
}

fn handle_ident(&self, expr: &mut Expression) {
Expand Down Expand Up @@ -384,7 +386,7 @@

Type::Array(_, _) | Type::String(_) | Type::FmtString(_, _) | Type::Slice(_) => true,

Type::Tuple(elems) => elems.iter().any(contains_array_or_str_type),

Check warning on line 389 in compiler/noirc_frontend/src/ownership/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)

Check warning on line 389 in compiler/noirc_frontend/src/ownership/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "global_array_rc_regression_8259"
type = "bin"
authors = [""]

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
global G_C: [bool; 3] = [true, false, true];
fn main(a: bool) -> pub [bool; 3] {
let b = func_1(a, G_C);
if a {
G_C
} else {
b
}
}
fn func_1(a: bool, mut b: [bool; 3]) -> [bool; 3] {
b[1] = a;
b
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[global_array_rc_regression_8259] Circuit output: Vec([Field(1), Field(0), Field(1)])
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "global_slice_rc_regression_8259"
type = "bin"
authors = [""]

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global G_C: [bool] = &[true, false, true];
fn main(a: bool) {
println(func_1(a, G_C));
println(G_C);
}
fn func_1(a: bool, mut b: [bool]) -> [bool] {
b[1] = a;
b
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
&[true, true, true]
&[true, false, true]

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading