Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(ssa refactor): Brillig main #1561

Merged
merged 27 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6184f52
remove mac runner
kevaundray Jun 6, 2023
823bd84
chore: generate brillig opcode for simple identity unconstrained func…
guipublic Jun 6, 2023
545d333
feat(brillig): added arithmetic operations on brillig (#1565)
sirasistant Jun 6, 2023
f6810af
make ranges be polymorphic integers
kevaundray Jun 6, 2023
c5e34c5
chore(brillig): Clean up handling of Binary operations (#1571)
kevaundray Jun 6, 2023
06543b5
chore(ssa refactor): Rename Brillig example (#1563)
kevaundray Jun 6, 2023
3c9f106
chore(brillig): added tests for all field binary operations (#1586)
sirasistant Jun 7, 2023
9a9c461
chore(brillig): added tests for brillig integer operations (#1590)
sirasistant Jun 7, 2023
043c3c4
feat: process blocks and jumps when compiling brillig (#1591)
guipublic Jun 7, 2023
e51d3c6
feat: process blocks and jumps when compiling brillig (#1591)
guipublic Jun 7, 2023
cd39144
feat(brillig): parsing oracles/foreign calls (#1596)
ludamad Jun 7, 2023
cf393ff
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 8, 2023
4644da9
self.data -> self.vars
kevaundray Jun 8, 2023
d50c69f
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 8, 2023
398ddf9
chore(brillig): Add handling of the not instruction (#1609)
kevaundray Jun 8, 2023
1d52f5e
make behavior consistent
kevaundray Jun 8, 2023
2d3ab61
remove closure
kevaundray Jun 8, 2023
801a739
change index_type
kevaundray Jun 8, 2023
2bcfc24
Update crates/noirc_frontend/src/hir/type_check/expr.rs
jfecher Jun 8, 2023
49a151d
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 8, 2023
5247a48
Merge remote-tracking branch 'origin/kw/polymorphic-integers-on-for-l…
kevaundray Jun 8, 2023
5995b30
feat(brillig): loops (#1610)
sirasistant Jun 8, 2023
1a9d33c
chore: resolve immutable array merge differences (#1617)
joss-aztec Jun 9, 2023
2787cc9
chore(ssa refactor): Add more documentation for truncation (#1607)
kevaundray Jun 9, 2023
8713a89
Merge remote-tracking branch 'origin/master' into kw/brillig-main
kevaundray Jun 9, 2023
70f8fe2
Update .github/workflows/test.yml
kevaundray Jun 9, 2023
91defbc
Update .github/workflows/test.yml
kevaundray Jun 9, 2023
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
20 changes: 10 additions & 10 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ edition = "2021"
rust-version = "1.66"

[workspace.dependencies]
acvm = "=0.14.1"
acvm = "=0.14.2"
arena = { path = "crates/arena" }
fm = { path = "crates/fm" }
iter-extended = { path = "crates/iter-extended" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "1"
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 conditonal on brillig
fn main(x: Field) {
assert(4 == conditional(x as bool));
}

unconstrained fn conditional(x : bool) -> Field {
if x {
4
}else {
5
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Tests arithmetic operations on fields
fn main() {
let x = 4;
let y = 2;
assert((x + y) == add(x, y));
assert((x - y) == sub(x, y));
assert((x * y) == mul(x, y));
assert((x / y) == div(x, y));
}

unconstrained fn add(x : Field, y : Field) -> Field {
x + y
}

unconstrained fn sub(x : Field, y : Field) -> Field {
x - y
}

unconstrained fn mul(x : Field, y : Field) -> Field {
x * y
}

unconstrained fn div(x : Field, y : Field) -> Field {
x / y
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "3"

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Tests a very simple program.
//
// The features being tested is the identity function in Brillig
fn main(x : Field) {
assert(x == identity(x));
}

unconstrained fn identity(x : Field) -> Field {
x
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Tests arithmetic operations on integers
fn main() {
let x: u32 = 6;
let y: u32 = 2;

assert((x + y) == add(x, y));

assert((x - y) == sub(x, y));

assert((x * y) == mul(x, y));

assert((x / y) == div(x, y));

// TODO SSA => ACIR has some issues with i32 ops
assert(check_signed_div(6, 2, 3));

assert(eq(1, 2) == false);
assert(eq(1, 1));

assert(lt(x, y) == false);
assert(lt(y, x));

assert((x & y) == and(x, y));
assert((x | y) == or(x, y));

// TODO SSA => ACIR has some issues with xor ops

assert(check_xor(x, y, 4));
assert((x >> y) == shr(x, y));
assert((x << y) == shl(x, y));
}

unconstrained fn add(x : u32, y : u32) -> u32 {
x + y
}

unconstrained fn sub(x : u32, y : u32) -> u32 {
x - y
}

unconstrained fn mul(x : u32, y : u32) -> u32 {
x * y
}

unconstrained fn div(x : u32, y : u32) -> u32 {
x / y
}

unconstrained fn check_signed_div(x: i32, y: i32, result: i32) -> bool {
(x / y) == result
}

unconstrained fn eq(x : u32, y : u32) -> bool {
x == y
}

unconstrained fn lt(x : u32, y : u32) -> bool {
x < y
}

unconstrained fn and(x : u32, y : u32) -> u32 {
x & y
}

unconstrained fn or(x : u32, y : u32) -> u32 {
x | y
}

unconstrained fn check_xor(x : u32, y : u32, result: u32) -> bool {
(x ^ y) == result
}

unconstrained fn shr(x : u32, y : u32) -> u32 {
x >> y
}

unconstrained fn shl(x : u32, y : u32) -> u32 {
x << y
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sum = "6"
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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "1"
y = "0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Tests a very simple Brillig function.
//
// The features being tested is not instruction on brillig
fn main(x: Field, y : Field) {
assert(false == not_operator(x as bool));
assert(true == not_operator(y as bool));
}

unconstrained fn not_operator(x : bool) -> bool {
!x
}
85 changes: 79 additions & 6 deletions crates/noirc_evaluator/src/brillig/artifact.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,98 @@
use crate::ssa_refactor::ir::basic_block::BasicBlockId;
use acvm::acir::brillig_vm::Opcode as BrilligOpcode;
use std::collections::HashMap;

/// Pointer to a unresolved Jump instruction in
/// the bytecode.
pub(crate) type JumpLabel = usize;

/// Pointer to a position in the bytecode where a
/// particular basic block starts.
pub(crate) type BlockLabel = usize;

#[derive(Default, Debug, Clone)]
/// Artifacts resulting from the compilation of a function into brillig byte code
/// Currently it is just the brillig bytecode of the function
/// Artifacts resulting from the compilation of a function into brillig byte code.
/// Currently it is just the brillig bytecode of the function.
pub(crate) struct BrilligArtifact {
pub(crate) byte_code: Vec<BrilligOpcode>,
/// The set of jumps that need to have their locations
/// resolved.
unresolved_jumps: Vec<(JumpLabel, BasicBlockId)>,
/// A map of the basic blocks to their positions
/// in the bytecode.
blocks: HashMap<BasicBlockId, BlockLabel>,
}

impl BrilligArtifact {
// Link some compiled brillig bytecode with its referenced artifacts
/// Link some compiled brillig bytecode with its referenced artifacts.
pub(crate) fn link(&mut self, obj: &BrilligArtifact) -> Vec<BrilligOpcode> {
self.link_with(obj);
self.resolve_jumps();
self.byte_code.clone()
}

// Link with a brillig artifact
/// Link with a brillig artifact
fn link_with(&mut self, obj: &BrilligArtifact) {
if obj.byte_code.is_empty() {
panic!("ICE: unresolved symbol");
let offset = self.code_len();
for (jump_label, block_id) in &obj.unresolved_jumps {
self.unresolved_jumps.push((jump_label + offset, *block_id));
}

for (block_id, block_label) in &obj.blocks {
self.blocks.insert(*block_id, block_label + offset);
}

self.byte_code.extend_from_slice(&obj.byte_code);
}

/// Adds a unresolved jump to be fixed at the end of bytecode processing.
pub(crate) fn add_unresolved_jump(&mut self, destination: BasicBlockId) {
self.unresolved_jumps.push((self.code_len(), destination));
}

/// Adds a label in the bytecode to specify where this block's
/// opcodes will start.
pub(crate) fn add_block_label(&mut self, block: BasicBlockId) {
self.blocks.insert(block, self.code_len());
}

/// Number of the opcodes currently in the bytecode
pub(crate) fn code_len(&self) -> usize {
self.byte_code.len()
}

/// Resolves all of the unresolved jumps in the program.
///
/// Note: This should only be called once all blocks are processed.
fn resolve_jumps(&mut self) {
for (jump_label, block) in &self.unresolved_jumps {
let jump_instruction = self.byte_code[*jump_label].clone();

let actual_block_location = self.blocks[block];

match jump_instruction {
BrilligOpcode::Jump { location } => {
assert_eq!(location, 0, "location is not zero, which means that the jump label does not need resolving");

self.byte_code[*jump_label] =
BrilligOpcode::Jump { location: actual_block_location };
}
BrilligOpcode::JumpIfNot { condition, location } => {
assert_eq!(location, 0, "location is not zero, which means that the jump label does not need resolving");

self.byte_code[*jump_label] =
BrilligOpcode::JumpIfNot { condition, location: actual_block_location };
}
BrilligOpcode::JumpIf { condition, location } => {
assert_eq!(location, 0,"location is not zero, which means that the jump label does not need resolving");

self.byte_code[*jump_label] =
BrilligOpcode::JumpIf { condition, location: actual_block_location };
}
_ => unreachable!(
"all jump labels should point to a jump instruction in the bytecode"
),
}
}
}
}
Loading