Skip to content

Commit

Permalink
fix: perform arithmetic simplification through CheckedCast (noir-la…
Browse files Browse the repository at this point in the history
…ng/noir#6502)

feat: SSA parser (noir-lang/noir#6489)
chore(test): Run test matrix on test_programs (noir-lang/noir#6429)
chore(ci): fix cargo deny (noir-lang/noir#6501)
feat: Deduplicate instructions across blocks (noir-lang/noir#6499)
chore: move tests for arithmetic generics closer to the code (noir-lang/noir#6497)
fix(docs): Fix broken links in oracles doc (noir-lang/noir#6488)
fix: Treat all parameters as possible aliases of each other (noir-lang/noir#6477)
chore: bump rust dependencies (noir-lang/noir#6482)
feat: use a full `BlackBoxFunctionSolver` implementation when execution brillig during acirgen (noir-lang/noir#6481)
chore(docs): Update How to Oracles (noir-lang/noir#5675)
chore: Release Noir(0.38.0) (noir-lang/noir#6422)
fix(ssa): Change array_set to not mutate slices coming from function inputs (noir-lang/noir#6463)
chore: update example to show how to split public inputs in bash (noir-lang/noir#6472)
fix: Discard optimisation that would change execution ordering or that is related to call outputs (noir-lang/noir#6461)
chore: proptest for `canonicalize` on infix type expressions (noir-lang/noir#6269)
fix: let formatter respect newlines between comments (noir-lang/noir#6458)
fix: check infix expression is valid in program input (noir-lang/noir#6450)
fix: don't crash on AsTraitPath with empty path (noir-lang/noir#6454)
fix(tests): Prevent EOF error while running test programs (noir-lang/noir#6455)
fix(sea): mem2reg to treat block input references as alias (noir-lang/noir#6452)
chore: revamp attributes (noir-lang/noir#6424)
feat!: Always Check Arithmetic Generics at Monomorphization (noir-lang/noir#6329)
chore: split path and import lookups (noir-lang/noir#6430)
fix(ssa): Resolve value IDs in terminator before comparing to array (noir-lang/noir#6448)
fix: right shift is not a regular division (noir-lang/noir#6400)
  • Loading branch information
AztecBot committed Nov 12, 2024
2 parents cd9b001 + eabf1fd commit 90adecd
Show file tree
Hide file tree
Showing 36 changed files with 3,155 additions and 1,157 deletions.
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b65a63d8d898e46cc686baa500f0b8070e45df14
72e8de0656c4789f57ff1d3ddecc8901df627aab
2 changes: 2 additions & 0 deletions noir/noir-repo/Cargo.lock

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

4 changes: 3 additions & 1 deletion noir/noir-repo/compiler/noirc_evaluator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fxhash.workspace = true
iter-extended.workspace = true
thiserror.workspace = true
num-bigint = "0.4"
num-traits.workspace = true
im.workspace = true
serde.workspace = true
serde_json.workspace = true
Expand All @@ -31,7 +32,8 @@ cfg-if.workspace = true

[dev-dependencies]
proptest.workspace = true
similar-asserts.workspace = true

[features]
bn254 = ["noirc_frontend/bn254"]
bls12_381= []
bls12_381 = []
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use super::procedures::ProcedureId;

use super::procedures::ProcedureId;

use super::procedures::ProcedureId;

/// Represents a parameter or a return value of an entry point function.
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub(crate) enum BrilligParameter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,59 @@ impl std::fmt::Display for ProcedureId {
}
}

impl ProcedureId {
pub(crate) fn to_debug_id(self) -> ProcedureDebugId {
ProcedureDebugId(match self {
ProcedureId::ArrayCopy => 0,
ProcedureId::ArrayReverse => 1,
ProcedureId::VectorCopy => 2,
ProcedureId::MemCopy => 3,
ProcedureId::PrepareVectorPush(true) => 4,
ProcedureId::PrepareVectorPush(false) => 5,
ProcedureId::VectorPopFront => 6,
ProcedureId::VectorPopBack => 7,
ProcedureId::PrepareVectorInsert => 8,
ProcedureId::VectorRemove => 9,
ProcedureId::CheckMaxStackDepth => 10,
})
}

pub fn from_debug_id(debug_id: ProcedureDebugId) -> Self {
let inner = debug_id.0;
match inner {
0 => ProcedureId::ArrayCopy,
1 => ProcedureId::ArrayReverse,
2 => ProcedureId::VectorCopy,
3 => ProcedureId::MemCopy,
4 => ProcedureId::PrepareVectorPush(true),
5 => ProcedureId::PrepareVectorPush(false),
6 => ProcedureId::VectorPopFront,
7 => ProcedureId::VectorPopBack,
8 => ProcedureId::PrepareVectorInsert,
9 => ProcedureId::VectorRemove,
10 => ProcedureId::CheckMaxStackDepth,
_ => panic!("Unsupported procedure debug ID of {inner} was supplied"),
}
}
}

impl std::fmt::Display for ProcedureId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ProcedureId::ArrayCopy => write!(f, "ArrayCopy"),
ProcedureId::ArrayReverse => write!(f, "ArrayReverse"),
ProcedureId::VectorCopy => write!(f, "VectorCopy"),
ProcedureId::MemCopy => write!(f, "MemCopy"),
ProcedureId::PrepareVectorPush(flag) => write!(f, "PrepareVectorPush({flag})"),
ProcedureId::VectorPopFront => write!(f, "VectorPopFront"),
ProcedureId::VectorPopBack => write!(f, "VectorPopBack"),
ProcedureId::PrepareVectorInsert => write!(f, "PrepareVectorInsert"),
ProcedureId::VectorRemove => write!(f, "VectorRemove"),
ProcedureId::CheckMaxStackDepth => write!(f, "CheckMaxStackDepth"),
}
}
}

pub(crate) fn compile_procedure<F: AcirField + DebugToString>(
procedure_id: ProcedureId,
) -> BrilligArtifact<F> {
Expand Down
18 changes: 17 additions & 1 deletion noir/noir-repo/compiler/noirc_evaluator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,20 @@ pub mod brillig;

pub use ssa::create_program;

pub use ssa::ir::instruction::ErrorType;
/// Trims leading whitespace from each line of the input string, according to
/// how much leading whitespace there is on the first non-empty line.
#[cfg(test)]
pub(crate) fn trim_leading_whitespace_from_lines(src: &str) -> String {
let mut lines = src.trim_end().lines();
let mut first_line = lines.next().unwrap();
while first_line.is_empty() {
first_line = lines.next().unwrap();
}
let indent = first_line.len() - first_line.trim_start().len();
let mut result = first_line.trim_start().to_string();
for line in lines {
result.push('\n');
result.push_str(&line[indent..]);
}
result
}
5 changes: 3 additions & 2 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod checks;
pub(super) mod function_builder;
pub mod ir;
mod opt;
mod parser;
pub mod ssa_gen;

pub struct SsaEvaluatorOptions {
Expand Down Expand Up @@ -95,7 +96,7 @@ pub(crate) fn optimize_into_acir(
.run_pass(Ssa::remove_paired_rc, "After Removing Paired rc_inc & rc_decs:")
.run_pass(Ssa::separate_runtime, "After Runtime Separation:")
.run_pass(Ssa::resolve_is_unconstrained, "After Resolving IsUnconstrained:")
.run_pass(|ssa| ssa.inline_functions(options.inliner_aggressiveness), "After Inlining:")
.run_pass(|ssa| ssa.inline_functions(options.inliner_aggressiveness), "After Inlining (1st):")
// Run mem2reg with the CFG separated into blocks
.run_pass(Ssa::mem2reg, "After Mem2Reg (1st):")
.run_pass(Ssa::simplify_cfg, "After Simplifying (1st):")
Expand All @@ -116,7 +117,7 @@ pub(crate) fn optimize_into_acir(
// may create an SSA which inlining fails to handle.
.run_pass(
|ssa| ssa.inline_functions_with_no_predicates(options.inliner_aggressiveness),
"After Inlining:",
"After Inlining (2nd):",
)
.run_pass(Ssa::remove_if_else, "After Remove IfElse:")
.run_pass(Ssa::fold_constants, "After Constant Folding:")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,16 @@ impl FunctionBuilder {
.first()
}

pub(crate) fn insert_mutable_array_set(
&mut self,
array: ValueId,
index: ValueId,
value: ValueId,
) -> ValueId {
self.insert_instruction(Instruction::ArraySet { array, index, value, mutable: true }, None)
.first()
}

/// Insert an instruction to increment an array's reference count. This only has an effect
/// in unconstrained code where arrays are reference counted and copy on write.
pub(crate) fn insert_inc_rc(&mut self, value: ValueId) {
Expand Down
50 changes: 42 additions & 8 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,16 @@ fn value(function: &Function, id: ValueId) -> String {
}
Value::Function(id) => id.to_string(),
Value::Intrinsic(intrinsic) => intrinsic.to_string(),
Value::Array { array, .. } => {
Value::Array { array, typ } => {
let elements = vecmap(array, |element| value(function, *element));
format!("[{}]", elements.join(", "))
let element_types = &typ.clone().element_types();
let element_types_str =
element_types.iter().map(|typ| typ.to_string()).collect::<Vec<String>>().join(", ");
if element_types.len() == 1 {
format!("[{}] of {}", elements.join(", "), element_types_str)
} else {
format!("[{}] of ({})", elements.join(", "), element_types_str)
}
}
Value::Param { .. } | Value::Instruction { .. } | Value::ForeignFunction(_) => {
id.to_string()
Expand Down Expand Up @@ -119,7 +126,11 @@ pub(crate) fn display_terminator(
)
}
Some(TerminatorInstruction::Return { return_values, .. }) => {
writeln!(f, " return {}", value_list(function, return_values))
if return_values.is_empty() {
writeln!(f, " return")
} else {
writeln!(f, " return {}", value_list(function, return_values))
}
}
None => writeln!(f, " (no terminator instruction)"),
}
Expand All @@ -139,12 +150,13 @@ pub(crate) fn display_instruction(
write!(f, "{} = ", value_list(function, results))?;
}

display_instruction_inner(function, &function.dfg[instruction], f)
display_instruction_inner(function, &function.dfg[instruction], results, f)
}

fn display_instruction_inner(
function: &Function,
instruction: &Instruction,
results: &[ValueId],
f: &mut Formatter,
) -> Result {
let show = |id| value(function, id);
Expand All @@ -168,18 +180,29 @@ fn display_instruction_inner(
}
}
Instruction::Call { func, arguments } => {
writeln!(f, "call {}({})", show(*func), value_list(function, arguments))
let arguments = value_list(function, arguments);
writeln!(f, "call {}({}){}", show(*func), arguments, result_types(function, results))
}
Instruction::Allocate => {
writeln!(f, "allocate{}", result_types(function, results))
}
Instruction::Load { address } => {
writeln!(f, "load {}{}", show(*address), result_types(function, results))
}
Instruction::Allocate => writeln!(f, "allocate"),
Instruction::Load { address } => writeln!(f, "load {}", show(*address)),
Instruction::Store { address, value } => {
writeln!(f, "store {} at {}", show(*value), show(*address))
}
Instruction::EnableSideEffectsIf { condition } => {
writeln!(f, "enable_side_effects {}", show(*condition))
}
Instruction::ArrayGet { array, index } => {
writeln!(f, "array_get {}, index {}", show(*array), show(*index))
writeln!(
f,
"array_get {}, index {}{}",
show(*array),
show(*index),
result_types(function, results)
)
}
Instruction::ArraySet { array, index, value, mutable } => {
let array = show(*array);
Expand Down Expand Up @@ -210,6 +233,17 @@ fn display_instruction_inner(
}
}

fn result_types(function: &Function, results: &[ValueId]) -> String {
let types = vecmap(results, |result| function.dfg.type_of_value(*result).to_string());
if types.is_empty() {
String::new()
} else if types.len() == 1 {
format!(" -> {}", types[0])
} else {
format!(" -> ({})", types.join(", "))
}
}

/// Tries to extract a constant string from an error payload.
pub(crate) fn try_to_extract_string_from_error_payload(
is_string_type: bool,
Expand Down
6 changes: 5 additions & 1 deletion noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,11 @@ impl std::fmt::Display for Type {
Type::Reference(element) => write!(f, "&mut {element}"),
Type::Array(element, length) => {
let elements = vecmap(element.iter(), |element| element.to_string());
write!(f, "[{}; {length}]", elements.join(", "))
if elements.len() == 1 {
write!(f, "[{}; {length}]", elements.join(", "))
} else {
write!(f, "[({}); {length}]", elements.join(", "))
}
}
Type::Slice(element) => {
let elements = vecmap(element.iter(), |element| element.to_string());
Expand Down
Loading

0 comments on commit 90adecd

Please sign in to comment.