Skip to content
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
1 change: 1 addition & 0 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ impl CompileOptions {
enable_debug_trace: self.show_brillig,
enable_debug_assertions: self.enable_brillig_debug_assertions,
enable_array_copy_counter: self.count_array_copies,
..Default::default()
},
print_codegen_timings: self.benchmark_codegen,
expression_width: if self.bounded_codegen {
Expand Down
81 changes: 41 additions & 40 deletions compiler/noirc_evaluator/src/acir/tests/brillig_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ fn multiple_brillig_calls_one_bytecode() {
unconstrained func 0: foo
0: @2 = const u32 1
1: @1 = const u32 32839
2: @0 = const u32 3
2: @0 = const u32 71
3: sp[3] = const u32 2
4: sp[4] = const u32 0
5: @32836 = calldata copy [sp[4]; sp[3]]
6: sp[1] = @32836
7: sp[2] = @32837
5: @68 = calldata copy [sp[4]; sp[3]]
Comment thread
vezenovm marked this conversation as resolved.
6: sp[1] = @68
7: sp[2] = @69
8: call 14
9: call 15
10: @32838 = sp[1]
11: sp[2] = const u32 32838
10: @70 = sp[1]
11: sp[2] = const u32 70
12: sp[3] = const u32 1
13: stop &[sp[2]; sp[3]]
14: return
Expand All @@ -75,25 +75,25 @@ fn multiple_brillig_calls_one_bytecode() {
20: sp[5] = const u32 0
21: trap &[@1; sp[5]]
22: return
23: @32772 = const u32 30720
24: @32771 = u32 lt @0, @32772
25: jump if @32771 to 28
23: @4 = const u32 30791
24: @3 = u32 lt @0, @4
25: jump if @3 to 28
26: @1 = indirect const u64 15764276373176857197
27: trap &[@1; @2]
28: return
unconstrained func 1: foo
0: @2 = const u32 1
1: @1 = const u32 32839
2: @0 = const u32 3
2: @0 = const u32 71
3: sp[3] = const u32 2
4: sp[4] = const u32 0
5: @32836 = calldata copy [sp[4]; sp[3]]
6: sp[1] = @32836
7: sp[2] = @32837
5: @68 = calldata copy [sp[4]; sp[3]]
6: sp[1] = @68
7: sp[2] = @69
8: call 14
9: call 15
10: @32838 = sp[1]
11: sp[2] = const u32 32838
10: @70 = sp[1]
11: sp[2] = const u32 70
12: sp[3] = const u32 1
13: stop &[sp[2]; sp[3]]
14: return
Expand All @@ -105,9 +105,9 @@ fn multiple_brillig_calls_one_bytecode() {
20: sp[5] = const u32 0
21: trap &[@1; sp[5]]
22: return
23: @32772 = const u32 30720
24: @32771 = u32 lt @0, @32772
25: jump if @32771 to 28
23: @4 = const u32 30791
24: @3 = u32 lt @0, @4
25: jump if @3 to 28
26: @1 = indirect const u64 15764276373176857197
27: trap &[@1; @2]
28: return
Expand All @@ -128,6 +128,7 @@ fn multiple_brillig_stdlib_calls() {
return
}";
let (program, debug) = ssa_to_acir_program_with_debug_info(src);

// We expect two brillig functions:
// - Quotient (shared between both divisions)
// - Inversion, caused by division-by-zero check (shared between both divisions)
Expand Down Expand Up @@ -262,18 +263,18 @@ fn brillig_stdlib_calls_with_regular_brillig_call() {
unconstrained func 0: foo
0: @2 = const u32 1
1: @1 = const u32 32839
2: @0 = const u32 3
2: @0 = const u32 71
3: sp[3] = const u32 2
4: sp[4] = const u32 0
5: @32836 = calldata copy [sp[4]; sp[3]]
6: @32836 = cast @32836 to u32
7: @32837 = cast @32837 to u32
8: sp[1] = @32836
9: sp[2] = @32837
5: @68 = calldata copy [sp[4]; sp[3]]
6: @68 = cast @68 to u32
7: @69 = cast @69 to u32
8: sp[1] = @68
9: sp[2] = @69
10: call 16
11: call 17
12: @32838 = sp[1]
13: sp[2] = const u32 32838
12: @70 = sp[1]
13: sp[2] = const u32 70
14: sp[3] = const u32 1
15: stop &[sp[2]; sp[3]]
16: return
Expand All @@ -285,9 +286,9 @@ fn brillig_stdlib_calls_with_regular_brillig_call() {
22: sp[5] = const u32 0
23: trap &[@1; sp[5]]
24: return
25: @32772 = const u32 30720
26: @32771 = u32 lt @0, @32772
27: jump if @32771 to 30
25: @4 = const u32 30791
26: @3 = u32 lt @0, @4
27: jump if @3 to 30
28: @1 = indirect const u64 15764276373176857197
29: trap &[@1; @2]
30: return
Expand Down Expand Up @@ -409,18 +410,18 @@ fn brillig_stdlib_calls_with_multiple_acir_calls() {
unconstrained func 0: foo
0: @2 = const u32 1
1: @1 = const u32 32839
2: @0 = const u32 3
2: @0 = const u32 71
3: sp[3] = const u32 2
4: sp[4] = const u32 0
5: @32836 = calldata copy [sp[4]; sp[3]]
6: @32836 = cast @32836 to u32
7: @32837 = cast @32837 to u32
8: sp[1] = @32836
9: sp[2] = @32837
5: @68 = calldata copy [sp[4]; sp[3]]
6: @68 = cast @68 to u32
7: @69 = cast @69 to u32
8: sp[1] = @68
9: sp[2] = @69
10: call 16
11: call 17
12: @32838 = sp[1]
13: sp[2] = const u32 32838
12: @70 = sp[1]
13: sp[2] = const u32 70
14: sp[3] = const u32 1
15: stop &[sp[2]; sp[3]]
16: return
Expand All @@ -432,9 +433,9 @@ fn brillig_stdlib_calls_with_multiple_acir_calls() {
22: sp[5] = const u32 0
23: trap &[@1; sp[5]]
24: return
25: @32772 = const u32 30720
26: @32771 = u32 lt @0, @32772
27: jump if @32771 to 30
25: @4 = const u32 30791
26: @3 = u32 lt @0, @4
27: jump if @3 to 30
28: @1 = indirect const u64 15764276373176857197
29: trap &[@1; @2]
30: return
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_evaluator/src/brillig/brillig_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub(crate) fn gen_brillig_for(

let options = BrilligOptions { enable_debug_trace: false, ..*options };

let mut entry_point = BrilligContext::new_entry_point_artifact(
let (mut entry_point, stack_start) = BrilligContext::new_entry_point_artifact(
arguments,
FunctionContext::return_values(func),
func.id(),
Expand All @@ -66,7 +66,7 @@ pub(crate) fn gen_brillig_for(

// Link the entry point with all dependencies
while let Some(unresolved_fn_label) = entry_point.first_unresolved_function_call() {
let artifact = &brillig.find_by_label(unresolved_fn_label.clone(), &options);
let artifact = &brillig.find_by_label(unresolved_fn_label.clone(), &options, stack_start);
let artifact = match artifact {
Some(artifact) => artifact,
None => {
Expand Down
33 changes: 23 additions & 10 deletions compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,7 @@ mod tests {
acir::brillig::{BitSize, IntegerBitSize, Opcode},
};

use crate::brillig::{
BrilligOptions, GlobalSpace, LabelType, Ssa, brillig_ir::registers::RegisterAllocator,
};
use crate::brillig::{BrilligOptions, GlobalSpace, LabelType, Ssa};

use super::ConstantAllocation;

Expand Down Expand Up @@ -332,7 +330,8 @@ mod tests {
";

let ssa = Ssa::from_str(src).unwrap();
let brillig = ssa.to_brillig(&BrilligOptions::default());
let options = BrilligOptions::default();
let brillig = ssa.to_brillig(&options);

assert_eq!(
brillig.globals.len(),
Expand Down Expand Up @@ -364,7 +363,10 @@ mod tests {
let Opcode::Const { destination, bit_size, value } = &artifact.byte_code[0] else {
panic!("First opcode is expected to be `Const`");
};
assert_eq!(destination.unwrap_direct(), GlobalSpace::start());
assert_eq!(
destination.unwrap_direct(),
GlobalSpace::start_with_layout(&options.layout)
);
assert!(matches!(bit_size, BitSize::Field));
assert_eq!(*value, FieldElement::from(2u128));

Expand Down Expand Up @@ -448,7 +450,8 @@ mod tests {
// Need to run SSA pass that sets up Brillig array gets
let ssa = ssa.brillig_array_get_and_set();

let brillig = ssa.to_brillig(&BrilligOptions::default());
let options = BrilligOptions::default();
let brillig = ssa.to_brillig(&options);

assert_eq!(
brillig.globals.len(),
Expand All @@ -473,7 +476,10 @@ mod tests {
let Opcode::Const { destination, bit_size, value } = &artifact.byte_code[0] else {
panic!("First opcode is expected to be `Const`");
};
assert_eq!(destination.unwrap_direct(), GlobalSpace::start());
assert_eq!(
destination.unwrap_direct(),
GlobalSpace::start_with_layout(&options.layout)
);
assert!(matches!(bit_size, BitSize::Field));
assert_eq!(*value, FieldElement::from(1u128));
assert!(matches!(&artifact.byte_code[1], Opcode::Return));
Expand Down Expand Up @@ -556,7 +562,8 @@ mod tests {
}
}

let brillig = ssa.to_brillig(&BrilligOptions::default());
let options = BrilligOptions::default();
let brillig = ssa.to_brillig(&options);

assert_eq!(brillig.globals.len(), 1, "Should have a single entry point");
for (func_id, artifact) in brillig.globals {
Expand All @@ -569,14 +576,20 @@ mod tests {
let Opcode::Const { destination, bit_size, value } = &artifact.byte_code[0] else {
panic!("First opcode is expected to be `Const`");
};
assert_eq!(destination.unwrap_direct(), GlobalSpace::start());
assert_eq!(
destination.unwrap_direct(),
GlobalSpace::start_with_layout(&options.layout)
);
assert!(matches!(bit_size, BitSize::Integer(IntegerBitSize::U1)));
assert_eq!(*value, FieldElement::from(0u128));

let Opcode::Const { destination, bit_size, value } = &artifact.byte_code[1] else {
panic!("First opcode is expected to be `Const`");
};
assert_eq!(destination.unwrap_direct(), GlobalSpace::start() + 1);
assert_eq!(
destination.unwrap_direct(),
GlobalSpace::start_with_layout(&options.layout) + 1
);
assert!(matches!(bit_size, BitSize::Field));
assert_eq!(*value, FieldElement::from(1u128));

Expand Down
28 changes: 19 additions & 9 deletions compiler/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub(crate) use instructions::BrilligBinaryOp;
use noirc_errors::call_stack::CallStackId;
use registers::{RegisterAllocator, ScratchSpace};

pub(crate) use self::registers::LayoutConfig;
use self::{artifact::BrilligArtifact, debug_show::DebugToString, registers::Stack};
use acvm::{
AcirField,
Expand Down Expand Up @@ -101,9 +102,12 @@ pub(crate) struct BrilligContext<F, Registers> {
count_arrays_copied: bool,

globals_memory_size: Option<usize>,

/// Memory layout information. See [self::registers] for more information about the memory layout.
layout: LayoutConfig,
}

impl<F, R> BrilligContext<F, R> {
impl<F, R: RegisterAllocator> BrilligContext<F, R> {
/// Enable the insertion of bytecode with extra assertions during testing.
pub(crate) fn enable_debug_assertions(&self) -> bool {
self.enable_debug_assertions
Expand All @@ -118,7 +122,7 @@ impl<F, R> BrilligContext<F, R> {
);

// The copy counter is always put in the first global slot
MemoryAddress::Direct(GlobalSpace::start())
MemoryAddress::Direct(GlobalSpace::start_with_layout(&self.registers.layout()))
}

pub(crate) fn count_array_copies(&self) -> bool {
Expand All @@ -145,7 +149,7 @@ impl<F: AcirField + DebugToString> BrilligContext<F, Stack> {
obj.name = function_name.to_owned();
BrilligContext {
obj,
registers: Stack::new(),
registers: Stack::new(options.layout),
context_label: Label::entrypoint(),
current_section: 0,
next_section: 1,
Expand All @@ -154,6 +158,7 @@ impl<F: AcirField + DebugToString> BrilligContext<F, Stack> {
count_arrays_copied: options.enable_array_copy_counter,
can_call_procedures: true,
globals_memory_size: None,
layout: options.layout,
}
}
}
Expand Down Expand Up @@ -267,7 +272,7 @@ impl<F: AcirField + DebugToString> BrilligContext<F, ScratchSpace> {
obj.procedure = Some(procedure_id);
BrilligContext {
obj,
registers: ScratchSpace::new(),
registers: ScratchSpace::new(options.layout),
context_label: Label::entrypoint(),
current_section: 0,
next_section: 1,
Expand All @@ -276,6 +281,7 @@ impl<F: AcirField + DebugToString> BrilligContext<F, ScratchSpace> {
count_arrays_copied: options.enable_array_copy_counter,
can_call_procedures: false,
globals_memory_size: None,
layout: options.layout,
}
}
}
Expand All @@ -288,7 +294,7 @@ impl<F: AcirField + DebugToString> BrilligContext<F, GlobalSpace> {
) -> BrilligContext<F, GlobalSpace> {
BrilligContext {
obj: BrilligArtifact::default(),
registers: GlobalSpace::new(),
registers: GlobalSpace::new(options.layout),
context_label: Label::globals_init(entry_point),
current_section: 0,
next_section: 1,
Expand All @@ -297,12 +303,13 @@ impl<F: AcirField + DebugToString> BrilligContext<F, GlobalSpace> {
count_arrays_copied: options.enable_array_copy_counter,
can_call_procedures: false,
globals_memory_size: None,
layout: options.layout,
}
}

pub(crate) fn global_space_size(&self) -> usize {
// `GlobalSpace::start()` is inclusive so we must add one to get the accurate total global memory size
(self.registers.max_memory_address() + 1) - GlobalSpace::start()
// `GlobalSpace::start` is inclusive so we must add one to get the accurate total global memory size
(self.registers.max_memory_address() + 1) - self.registers.start()
}
}

Expand Down Expand Up @@ -389,6 +396,7 @@ pub(crate) mod tests {
enable_debug_trace: true,
enable_debug_assertions: true,
enable_array_copy_counter: false,
..Default::default()
};
let mut context = BrilligContext::new("test", &options);
context.enter_context(Label::function(id));
Expand All @@ -404,9 +412,10 @@ pub(crate) mod tests {
enable_debug_trace: false,
enable_debug_assertions: context.enable_debug_assertions,
enable_array_copy_counter: context.count_arrays_copied,
..Default::default()
};
let artifact = context.artifact();
let mut entry_point_artifact = BrilligContext::new_entry_point_artifact(
let (mut entry_point_artifact, stack_start) = BrilligContext::new_entry_point_artifact(
arguments,
returns,
FunctionId::test_new(0),
Expand All @@ -421,7 +430,7 @@ pub(crate) mod tests {
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, &options);
let procedure_artifact = compile_procedure(procedure_id, &options, stack_start);
entry_point_artifact.link_with(&procedure_artifact);
}
entry_point_artifact.finish()
Expand Down Expand Up @@ -459,6 +468,7 @@ pub(crate) mod tests {
enable_debug_trace: true,
enable_debug_assertions: true,
enable_array_copy_counter: false,
..Default::default()
};
let mut context = BrilligContext::new("test", &options);
let r_stack = ReservedRegisters::free_memory_pointer();
Expand Down
Loading
Loading