-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* make ranges be polymorphic integers * feat: brillig loop support * fix: fixed brillig returns and stop * fix: do not apply constants folding to brillig fns * chore: update acvm pointer, cleanup * style: newline on cargo toml * make behavior consistent * remove closure * change index_type * Update crates/noirc_frontend/src/hir/type_check/expr.rs * better debug information for unsupported instruction * remove edge case for optimizations * clippy fix * patch infinite loop --------- Co-authored-by: kevaundray <kevtheappdev@gmail.com> Co-authored-by: jfecher <jake@aztecprotocol.com>
- Loading branch information
1 parent
5247a48
commit 5995b30
Showing
14 changed files
with
225 additions
and
113 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
crates/nargo_cli/tests/test_data_ssa_refactor/brillig_loop/Nargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[package] | ||
authors = [""] | ||
compiler_version = "0.1" | ||
|
||
[dependencies] |
1 change: 1 addition & 0 deletions
1
crates/nargo_cli/tests/test_data_ssa_refactor/brillig_loop/Prover.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sum = "6" |
14 changes: 14 additions & 0 deletions
14
crates/nargo_cli/tests/test_data_ssa_refactor/brillig_loop/src/main.nr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Tests a very simple program. | ||
// | ||
// The features being tested is basic looping on brillig | ||
fn main(sum: u32){ | ||
assert(loop(4) == sum); | ||
} | ||
|
||
unconstrained fn loop(x: u32) -> u32 { | ||
let mut sum = 0; | ||
for i in 0..x { | ||
sum = sum + i; | ||
} | ||
sum | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use crate::ssa_refactor::ir::{ | ||
instruction::BinaryOp, | ||
types::{NumericType, Type}, | ||
}; | ||
use acvm::acir::brillig_vm::{BinaryFieldOp, BinaryIntOp}; | ||
|
||
/// Type to encapsulate the binary operation types in Brillig | ||
pub(crate) enum BrilligBinaryOp { | ||
Field { op: BinaryFieldOp }, | ||
Integer { op: BinaryIntOp, bit_size: u32 }, | ||
} | ||
|
||
impl BrilligBinaryOp { | ||
/// Convert an SSA binary operation into: | ||
/// - Brillig Binary Integer Op, if it is a integer type | ||
/// - Brillig Binary Field Op, if it is a field type | ||
pub(crate) fn convert_ssa_binary_op_to_brillig_binary_op( | ||
ssa_op: BinaryOp, | ||
typ: Type, | ||
) -> BrilligBinaryOp { | ||
// First get the bit size and whether its a signed integer, if it is a numeric type | ||
// if it is not,then we return None, indicating that | ||
// it is a Field. | ||
let bit_size_signedness = match typ { | ||
Type::Numeric(numeric_type) => match numeric_type { | ||
NumericType::Signed { bit_size } => Some((bit_size, true)), | ||
NumericType::Unsigned { bit_size } => Some((bit_size, false)), | ||
NumericType::NativeField => None, | ||
}, | ||
_ => unreachable!("only numeric types are allowed in binary operations. References are handled separately"), | ||
}; | ||
|
||
fn binary_op_to_field_op(op: BinaryOp) -> BinaryFieldOp { | ||
match op { | ||
BinaryOp::Add => BinaryFieldOp::Add, | ||
BinaryOp::Sub => BinaryFieldOp::Sub, | ||
BinaryOp::Mul => BinaryFieldOp::Mul, | ||
BinaryOp::Div => BinaryFieldOp::Div, | ||
BinaryOp::Eq => BinaryFieldOp::Equals, | ||
_ => unreachable!( | ||
"Field type cannot be used with {op}. This should have been caught by the frontend" | ||
), | ||
} | ||
} | ||
fn binary_op_to_int_op(op: BinaryOp, is_signed: bool) -> BinaryIntOp { | ||
match op { | ||
BinaryOp::Add => BinaryIntOp::Add, | ||
BinaryOp::Sub => BinaryIntOp::Sub, | ||
BinaryOp::Mul => BinaryIntOp::Mul, | ||
BinaryOp::Div => { | ||
if is_signed { | ||
BinaryIntOp::SignedDiv | ||
} else { | ||
BinaryIntOp::UnsignedDiv | ||
} | ||
}, | ||
BinaryOp::Mod => todo!("This is not supported by Brillig. It should either be added into Brillig or legalized by the SSA IR"), | ||
BinaryOp::Eq => BinaryIntOp::Equals, | ||
BinaryOp::Lt => BinaryIntOp::LessThan, | ||
BinaryOp::And => BinaryIntOp::And, | ||
BinaryOp::Or => BinaryIntOp::Or, | ||
BinaryOp::Xor => BinaryIntOp::Xor, | ||
BinaryOp::Shl => BinaryIntOp::Shl, | ||
BinaryOp::Shr => BinaryIntOp::Shr, | ||
} | ||
} | ||
// If bit size is available then it is a binary integer operation | ||
match bit_size_signedness { | ||
Some((bit_size, is_signed)) => { | ||
let binary_int_op = binary_op_to_int_op(ssa_op, is_signed); | ||
BrilligBinaryOp::Integer { op: binary_int_op, bit_size } | ||
} | ||
None => { | ||
let binary_field_op = binary_op_to_field_op(ssa_op); | ||
BrilligBinaryOp::Field { op: binary_field_op } | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Returns the type of the operation considering the types of the operands | ||
/// TODO: SSA issues binary operations between fields and integers. | ||
/// This probably should be explicitely casted in SSA to avoid having to coerce at this level. | ||
pub(crate) fn type_of_binary_operation(lhs_type: Type, rhs_type: Type) -> Type { | ||
match (lhs_type, rhs_type) { | ||
// If either side is a Field constant then, we coerce into the type | ||
// of the other operand | ||
(Type::Numeric(NumericType::NativeField), typ) | ||
| (typ, Type::Numeric(NumericType::NativeField)) => typ, | ||
// If both sides are numeric type, then we expect their types to be | ||
// the same. | ||
(Type::Numeric(lhs_type), Type::Numeric(rhs_type)) => { | ||
assert_eq!( | ||
lhs_type, rhs_type, | ||
"lhs and rhs types in a binary operation are always the same" | ||
); | ||
Type::Numeric(lhs_type) | ||
} | ||
_ => { | ||
unreachable!( | ||
"ICE: Binary operation between types {:?} and {:?} is not allowed", | ||
lhs_type, rhs_type | ||
) | ||
} | ||
} | ||
} |
Oops, something went wrong.