Skip to content

Commit a4cbd43

Browse files
author
AztecBot
committed
[1 changes] fix: remove compiler_version from new Nargo.toml (noir-lang/noir#6590)
feat: Avoid incrementing reference counts in some cases (noir-lang/noir#6568) chore: fix typo in test name (noir-lang/noir#6589) fix: consider prereleases to be compatible with pre-1.0.0 releases (noir-lang/noir#6580) feat: try to inline brillig calls with all constant arguments (noir-lang/noir#6548) fix: correct type when simplifying `derive_pedersen_generators` (noir-lang/noir#6579) feat: Sync from aztec-packages (noir-lang/noir#6576)
1 parent b8bace9 commit a4cbd43

File tree

26 files changed

+1146
-511
lines changed

26 files changed

+1146
-511
lines changed

.noir-sync-commit

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
68c32b4ffd9b069fe4b119327dbf4018c17ab9d4
1+
df8f2eee5c27d3cd4b6128056afdd9bd4a0322fe

noir/noir-repo/acvm-repo/acvm_js/build.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function run_if_available {
2525
require_command jq
2626
require_command cargo
2727
require_command wasm-bindgen
28-
#require_command wasm-opt
28+
require_command wasm-opt
2929

3030
self_path=$(dirname "$(readlink -f "$0")")
3131
pname=$(cargo read-manifest | jq -r '.name')

noir/noir-repo/compiler/integration-tests/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0"
1414
},
1515
"dependencies": {
16-
"@aztec/bb.js": "portal:../../../../barretenberg/ts",
16+
"@aztec/bb.js": "0.63.1",
1717
"@noir-lang/noir_js": "workspace:*",
1818
"@noir-lang/noir_wasm": "workspace:*",
1919
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",

noir/noir-repo/compiler/noirc_evaluator/src/acir/mod.rs

+4-48
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,10 @@ mod big_int;
2424
mod brillig_directive;
2525
mod generated_acir;
2626

27+
use crate::brillig::brillig_gen::gen_brillig_for;
2728
use crate::brillig::{
2829
brillig_gen::brillig_fn::FunctionContext as BrilligFunctionContext,
29-
brillig_ir::{
30-
artifact::{BrilligParameter, GeneratedBrillig},
31-
BrilligContext,
32-
},
30+
brillig_ir::artifact::{BrilligParameter, GeneratedBrillig},
3331
Brillig,
3432
};
3533
use crate::errors::{InternalError, InternalWarning, RuntimeError, SsaReport};
@@ -518,7 +516,7 @@ impl<'a> Context<'a> {
518516
let outputs: Vec<AcirType> =
519517
vecmap(main_func.returns(), |result_id| dfg.type_of_value(*result_id).into());
520518

521-
let code = self.gen_brillig_for(main_func, arguments.clone(), brillig)?;
519+
let code = gen_brillig_for(main_func, arguments.clone(), brillig)?;
522520

523521
// We specifically do not attempt execution of the brillig code being generated as this can result in it being
524522
// replaced with constraints on witnesses to the program outputs.
@@ -878,8 +876,7 @@ impl<'a> Context<'a> {
878876
None,
879877
)?
880878
} else {
881-
let code =
882-
self.gen_brillig_for(func, arguments.clone(), brillig)?;
879+
let code = gen_brillig_for(func, arguments.clone(), brillig)?;
883880
let generated_pointer =
884881
self.shared_context.new_generated_pointer();
885882
let output_values = self.acir_context.brillig_call(
@@ -999,47 +996,6 @@ impl<'a> Context<'a> {
999996
.collect()
1000997
}
1001998

1002-
fn gen_brillig_for(
1003-
&self,
1004-
func: &Function,
1005-
arguments: Vec<BrilligParameter>,
1006-
brillig: &Brillig,
1007-
) -> Result<GeneratedBrillig<FieldElement>, InternalError> {
1008-
// Create the entry point artifact
1009-
let mut entry_point = BrilligContext::new_entry_point_artifact(
1010-
arguments,
1011-
BrilligFunctionContext::return_values(func),
1012-
func.id(),
1013-
);
1014-
entry_point.name = func.name().to_string();
1015-
1016-
// Link the entry point with all dependencies
1017-
while let Some(unresolved_fn_label) = entry_point.first_unresolved_function_call() {
1018-
let artifact = &brillig.find_by_label(unresolved_fn_label.clone());
1019-
let artifact = match artifact {
1020-
Some(artifact) => artifact,
1021-
None => {
1022-
return Err(InternalError::General {
1023-
message: format!("Cannot find linked fn {unresolved_fn_label}"),
1024-
call_stack: CallStack::new(),
1025-
})
1026-
}
1027-
};
1028-
entry_point.link_with(artifact);
1029-
// Insert the range of opcode locations occupied by a procedure
1030-
if let Some(procedure_id) = &artifact.procedure {
1031-
let num_opcodes = entry_point.byte_code.len();
1032-
let previous_num_opcodes = entry_point.byte_code.len() - artifact.byte_code.len();
1033-
// We subtract one as to keep the range inclusive on both ends
1034-
entry_point
1035-
.procedure_locations
1036-
.insert(procedure_id.clone(), (previous_num_opcodes, num_opcodes - 1));
1037-
}
1038-
}
1039-
// Generate the final bytecode
1040-
Ok(entry_point.finish())
1041-
}
1042-
1043999
/// Handles an ArrayGet or ArraySet instruction.
10441000
/// To set an index of the array (and create a new array in doing so), pass Some(value) for
10451001
/// store_value. To just retrieve an index of the array, pass None for store_value.

noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen.rs

+50-4
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ mod variable_liveness;
99
use acvm::FieldElement;
1010

1111
use self::{brillig_block::BrilligBlock, brillig_fn::FunctionContext};
12-
use super::brillig_ir::{
13-
artifact::{BrilligArtifact, Label},
14-
BrilligContext,
12+
use super::{
13+
brillig_ir::{
14+
artifact::{BrilligArtifact, BrilligParameter, GeneratedBrillig, Label},
15+
BrilligContext,
16+
},
17+
Brillig,
18+
};
19+
use crate::{
20+
errors::InternalError,
21+
ssa::ir::{dfg::CallStack, function::Function},
1522
};
16-
use crate::ssa::ir::function::Function;
1723

1824
/// Converting an SSA function into Brillig bytecode.
1925
pub(crate) fn convert_ssa_function(
@@ -36,3 +42,43 @@ pub(crate) fn convert_ssa_function(
3642
artifact.name = func.name().to_string();
3743
artifact
3844
}
45+
46+
pub(crate) fn gen_brillig_for(
47+
func: &Function,
48+
arguments: Vec<BrilligParameter>,
49+
brillig: &Brillig,
50+
) -> Result<GeneratedBrillig<FieldElement>, InternalError> {
51+
// Create the entry point artifact
52+
let mut entry_point = BrilligContext::new_entry_point_artifact(
53+
arguments,
54+
FunctionContext::return_values(func),
55+
func.id(),
56+
);
57+
entry_point.name = func.name().to_string();
58+
59+
// Link the entry point with all dependencies
60+
while let Some(unresolved_fn_label) = entry_point.first_unresolved_function_call() {
61+
let artifact = &brillig.find_by_label(unresolved_fn_label.clone());
62+
let artifact = match artifact {
63+
Some(artifact) => artifact,
64+
None => {
65+
return Err(InternalError::General {
66+
message: format!("Cannot find linked fn {unresolved_fn_label}"),
67+
call_stack: CallStack::new(),
68+
})
69+
}
70+
};
71+
entry_point.link_with(artifact);
72+
// Insert the range of opcode locations occupied by a procedure
73+
if let Some(procedure_id) = &artifact.procedure {
74+
let num_opcodes = entry_point.byte_code.len();
75+
let previous_num_opcodes = entry_point.byte_code.len() - artifact.byte_code.len();
76+
// We subtract one as to keep the range inclusive on both ends
77+
entry_point
78+
.procedure_locations
79+
.insert(procedure_id.clone(), (previous_num_opcodes, num_opcodes - 1));
80+
}
81+
}
82+
// Generate the final bytecode
83+
Ok(entry_point.finish())
84+
}

noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs

+17
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,23 @@ pub(crate) fn optimize_into_acir(
140140
ssa.to_brillig(options.enable_brillig_logging)
141141
});
142142

143+
let ssa_gen_span = span!(Level::TRACE, "ssa_generation");
144+
let ssa_gen_span_guard = ssa_gen_span.enter();
145+
146+
let ssa = SsaBuilder {
147+
ssa,
148+
print_ssa_passes: options.enable_ssa_logging,
149+
print_codegen_timings: options.print_codegen_timings,
150+
}
151+
.run_pass(
152+
|ssa| ssa.fold_constants_with_brillig(&brillig),
153+
"After Constant Folding with Brillig:",
154+
)
155+
.run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:")
156+
.finish();
157+
158+
drop(ssa_gen_span_guard);
159+
143160
let artifacts = time("SSA to ACIR", options.print_codegen_timings, || {
144161
ssa.into_acir(&brillig, options.expression_width)
145162
})?;

noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction.rs

+25-27
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use fxhash::FxHasher64;
1111
use iter_extended::vecmap;
1212
use noirc_frontend::hir_def::types::Type as HirType;
1313

14-
use crate::ssa::opt::flatten_cfg::value_merger::ValueMerger;
14+
use crate::ssa::{ir::function::RuntimeType, opt::flatten_cfg::value_merger::ValueMerger};
1515

1616
use super::{
1717
basic_block::BasicBlockId,
1818
dfg::{CallStack, DataFlowGraph},
19+
function::Function,
1920
map::Id,
2021
types::{NumericType, Type},
2122
value::{Value, ValueId},
@@ -269,15 +270,7 @@ pub(crate) enum Instruction {
269270
/// else_value
270271
/// }
271272
/// ```
272-
///
273-
/// Where we save the result of !then_condition so that we have the same
274-
/// ValueId for it each time.
275-
IfElse {
276-
then_condition: ValueId,
277-
then_value: ValueId,
278-
else_condition: ValueId,
279-
else_value: ValueId,
280-
},
273+
IfElse { then_condition: ValueId, then_value: ValueId, else_value: ValueId },
281274

282275
/// Creates a new array or slice.
283276
///
@@ -371,12 +364,12 @@ impl Instruction {
371364
}
372365
}
373366

374-
pub(crate) fn can_eliminate_if_unused(&self, dfg: &DataFlowGraph) -> bool {
367+
pub(crate) fn can_eliminate_if_unused(&self, function: &Function) -> bool {
375368
use Instruction::*;
376369
match self {
377370
Binary(binary) => {
378371
if matches!(binary.operator, BinaryOp::Div | BinaryOp::Mod) {
379-
if let Some(rhs) = dfg.get_numeric_constant(binary.rhs) {
372+
if let Some(rhs) = function.dfg.get_numeric_constant(binary.rhs) {
380373
rhs != FieldElement::zero()
381374
} else {
382375
false
@@ -395,15 +388,26 @@ impl Instruction {
395388
| ArraySet { .. }
396389
| MakeArray { .. } => true,
397390

391+
// Store instructions must be removed by DIE in acir code, any load
392+
// instructions should already be unused by that point.
393+
//
394+
// Note that this check assumes that it is being performed after the flattening
395+
// pass and after the last mem2reg pass. This is currently the case for the DIE
396+
// pass where this check is done, but does mean that we cannot perform mem2reg
397+
// after the DIE pass.
398+
Store { .. } => {
399+
matches!(function.runtime(), RuntimeType::Acir(_))
400+
&& function.reachable_blocks().len() == 1
401+
}
402+
398403
Constrain(..)
399-
| Store { .. }
400404
| EnableSideEffectsIf { .. }
401405
| IncrementRc { .. }
402406
| DecrementRc { .. }
403407
| RangeCheck { .. } => false,
404408

405409
// Some `Intrinsic`s have side effects so we must check what kind of `Call` this is.
406-
Call { func, .. } => match dfg[*func] {
410+
Call { func, .. } => match function.dfg[*func] {
407411
// Explicitly allows removal of unused ec operations, even if they can fail
408412
Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::MultiScalarMul))
409413
| Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::EmbeddedCurveAdd)) => true,
@@ -524,14 +528,11 @@ impl Instruction {
524528
assert_message: assert_message.clone(),
525529
}
526530
}
527-
Instruction::IfElse { then_condition, then_value, else_condition, else_value } => {
528-
Instruction::IfElse {
529-
then_condition: f(*then_condition),
530-
then_value: f(*then_value),
531-
else_condition: f(*else_condition),
532-
else_value: f(*else_value),
533-
}
534-
}
531+
Instruction::IfElse { then_condition, then_value, else_value } => Instruction::IfElse {
532+
then_condition: f(*then_condition),
533+
then_value: f(*then_value),
534+
else_value: f(*else_value),
535+
},
535536
Instruction::MakeArray { elements, typ } => Instruction::MakeArray {
536537
elements: elements.iter().copied().map(f).collect(),
537538
typ: typ.clone(),
@@ -590,10 +591,9 @@ impl Instruction {
590591
| Instruction::RangeCheck { value, .. } => {
591592
f(*value);
592593
}
593-
Instruction::IfElse { then_condition, then_value, else_condition, else_value } => {
594+
Instruction::IfElse { then_condition, then_value, else_value } => {
594595
f(*then_condition);
595596
f(*then_value);
596-
f(*else_condition);
597597
f(*else_value);
598598
}
599599
Instruction::MakeArray { elements, typ: _ } => {
@@ -756,7 +756,7 @@ impl Instruction {
756756
None
757757
}
758758
}
759-
Instruction::IfElse { then_condition, then_value, else_condition, else_value } => {
759+
Instruction::IfElse { then_condition, then_value, else_value } => {
760760
let typ = dfg.type_of_value(*then_value);
761761

762762
if let Some(constant) = dfg.get_numeric_constant(*then_condition) {
@@ -775,13 +775,11 @@ impl Instruction {
775775

776776
if matches!(&typ, Type::Numeric(_)) {
777777
let then_condition = *then_condition;
778-
let else_condition = *else_condition;
779778

780779
let result = ValueMerger::merge_numeric_values(
781780
dfg,
782781
block,
783782
then_condition,
784-
else_condition,
785783
then_value,
786784
else_value,
787785
);

noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs

+35-7
Original file line numberDiff line numberDiff line change
@@ -443,12 +443,8 @@ fn simplify_slice_push_back(
443443
let mut value_merger =
444444
ValueMerger::new(dfg, block, &mut slice_sizes, unknown, None, call_stack);
445445

446-
let new_slice = value_merger.merge_values(
447-
len_not_equals_capacity,
448-
len_equals_capacity,
449-
set_last_slice_value,
450-
new_slice,
451-
);
446+
let new_slice =
447+
value_merger.merge_values(len_not_equals_capacity, set_last_slice_value, new_slice);
452448

453449
SimplifyResult::SimplifiedToMultiple(vec![new_slice_length, new_slice])
454450
}
@@ -810,7 +806,8 @@ fn simplify_derive_generators(
810806
results.push(is_infinite);
811807
}
812808
let len = results.len();
813-
let typ = Type::Array(vec![Type::field()].into(), len);
809+
let typ =
810+
Type::Array(vec![Type::field(), Type::field(), Type::unsigned(1)].into(), len / 3);
814811
let result = make_array(dfg, results.into(), typ, block, call_stack);
815812
SimplifyResult::SimplifiedTo(result)
816813
} else {
@@ -820,3 +817,34 @@ fn simplify_derive_generators(
820817
unreachable!("Unexpected number of arguments to derive_generators");
821818
}
822819
}
820+
821+
#[cfg(test)]
822+
mod tests {
823+
use crate::ssa::{opt::assert_normalized_ssa_equals, Ssa};
824+
825+
#[test]
826+
fn simplify_derive_generators_has_correct_type() {
827+
let src = "
828+
brillig(inline) fn main f0 {
829+
b0():
830+
v0 = make_array [u8 68, u8 69, u8 70, u8 65, u8 85, u8 76, u8 84, u8 95, u8 68, u8 79, u8 77, u8 65, u8 73, u8 78, u8 95, u8 83, u8 69, u8 80, u8 65, u8 82, u8 65, u8 84, u8 79, u8 82] : [u8; 24]
831+
832+
// This call was previously incorrectly simplified to something that returned `[Field; 3]`
833+
v2 = call derive_pedersen_generators(v0, u32 0) -> [(Field, Field, u1); 1]
834+
835+
return v2
836+
}
837+
";
838+
let ssa = Ssa::from_str(src).unwrap();
839+
840+
let expected = "
841+
brillig(inline) fn main f0 {
842+
b0():
843+
v15 = make_array [u8 68, u8 69, u8 70, u8 65, u8 85, u8 76, u8 84, u8 95, u8 68, u8 79, u8 77, u8 65, u8 73, u8 78, u8 95, u8 83, u8 69, u8 80, u8 65, u8 82, u8 65, u8 84, u8 79, u8 82] : [u8; 24]
844+
v19 = make_array [Field 3728882899078719075161482178784387565366481897740339799480980287259621149274, Field -9903063709032878667290627648209915537972247634463802596148419711785767431332, u1 0] : [(Field, Field, u1); 1]
845+
return v19
846+
}
847+
";
848+
assert_normalized_ssa_equals(ssa, expected);
849+
}
850+
}

0 commit comments

Comments
 (0)