Skip to content

Commit

Permalink
chore(ssa refactor): Add support for the distinct keyword (#1810)
Browse files Browse the repository at this point in the history
* make `create_witness_for_expression` crate visible so we can create distinct witnesses in acir_gen

* add method to check whether we need a distinct abi and create the constraints needed

* add example with distinct keyword

* fix clippy
  • Loading branch information
kevaundray authored Jun 23, 2023
1 parent 2e330e0 commit a365464
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 5 deletions.
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 = "3"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Example that uses the distinct keyword
fn main(x: pub Field) -> distinct pub [Field;2] {
[x+1, x]
}
3 changes: 2 additions & 1 deletion crates/noirc_evaluator/src/ssa_refactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub(crate) fn optimize_into_acir(
allow_log_ops: bool,
print_ssa_passes: bool,
) -> GeneratedAcir {
let abi_distinctness = program.return_distinctness;
let ssa = ssa_gen::generate_ssa(program).print(print_ssa_passes, "Initial SSA:");
let brillig = ssa.to_brillig();
ssa.inline_functions()
Expand All @@ -49,7 +50,7 @@ pub(crate) fn optimize_into_acir(
.print(print_ssa_passes, "After Constant Folding:")
.dead_instruction_elimination()
.print(print_ssa_passes, "After Dead Instruction Elimination:")
.into_acir(brillig, allow_log_ops)
.into_acir(brillig, abi_distinctness, allow_log_ops)
}

/// Compiles the Program into ACIR and applies optimizations to the arithmetic gates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl GeneratedAcir {
/// This means you cannot multiply an infinite amount of `Expression`s together.
/// Once the `Expression` goes over degree-2, then it needs to be reduced to a `Witness`
/// which has degree-1 in order to be able to continue the multiplication chain.
fn create_witness_for_expression(&mut self, expression: &Expression) -> Witness {
pub(crate) fn create_witness_for_expression(&mut self, expression: &Expression) -> Witness {
let fresh_witness = self.next_witness_index();

// Create a constraint that sets them to be equal to each other
Expand Down
32 changes: 29 additions & 3 deletions crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ use super::{
},
ssa_gen::Ssa,
};
use acvm::FieldElement;
use acvm::{acir::native_types::Expression, FieldElement};
use iter_extended::vecmap;

pub(crate) use acir_ir::generated_acir::GeneratedAcir;
use noirc_abi::AbiDistinctness;

mod acir_ir;

Expand Down Expand Up @@ -71,9 +72,34 @@ impl AcirValue {
}

impl Ssa {
pub(crate) fn into_acir(self, brillig: Brillig, allow_log_ops: bool) -> GeneratedAcir {
pub(crate) fn into_acir(
self,
brillig: Brillig,
abi_distinctness: AbiDistinctness,
allow_log_ops: bool,
) -> GeneratedAcir {
let context = Context::default();
context.convert_ssa(self, brillig, allow_log_ops)
let mut generated_acir = context.convert_ssa(self, brillig, allow_log_ops);

match abi_distinctness {
AbiDistinctness::Distinct => {
// Create a witness for each return witness we have
// to guarantee that the return witnesses are distinct
let distinct_return_witness: Vec<_> = generated_acir
.return_witnesses
.clone()
.into_iter()
.map(|return_witness| {
generated_acir
.create_witness_for_expression(&Expression::from(return_witness))
})
.collect();

generated_acir.return_witnesses = distinct_return_witness;
generated_acir
}
AbiDistinctness::DuplicationAllowed => generated_acir,
}
}
}

Expand Down

0 comments on commit a365464

Please sign in to comment.