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: delete dead code #4906

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 1 addition & 8 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@

use std::collections::BTreeSet;

use crate::{
brillig::Brillig,
errors::{RuntimeError, SsaReport},
};
use crate::errors::{RuntimeError, SsaReport};
use acvm::acir::{
circuit::{
brillig::BrilligBytecode, Circuit, ExpressionWidth, Program as AcirProgram, PublicInputs,
Expand Down Expand Up @@ -318,10 +315,6 @@ impl SsaBuilder {
Ok(self.print(msg))
}

fn to_brillig(&self, print_brillig_trace: bool) -> Brillig {
self.ssa.to_brillig(print_brillig_trace)
}

fn print(self, msg: &str) -> Self {
if self.print_ssa_passes {
println!("{msg}\n{}", self.ssa);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,55 +420,6 @@ impl GeneratedAcir {
Ok(limb_witnesses)
}

/// Returns an expression which represents `lhs * rhs`
///
/// If one has multiplicative term and the other is of degree one or more,
/// the function creates [intermediate variables][`Witness`] accordingly.
/// There are two cases where we can optimize the multiplication between two expressions:
/// 1. If the sum of the degrees of both expressions is at most 2, then we can just multiply them
/// as each term in the result will be degree-2.
/// 2. If one expression is a constant, then we can just multiply the constant with the other expression
///
/// (1) is because an [`Expression`] can hold at most a degree-2 univariate polynomial
/// which is what you get when you multiply two degree-1 univariate polynomials.
pub(crate) fn mul_with_witness(&mut self, lhs: &Expression, rhs: &Expression) -> Expression {
use std::borrow::Cow;
let lhs_is_linear = lhs.is_linear();
let rhs_is_linear = rhs.is_linear();

// Case 1: The sum of the degrees of both expressions is at most 2.
//
// If one of the expressions is constant then it does not increase the degree when multiplying by another expression.
// If both of the expressions are linear (degree <=1) then the product will be at most degree 2.
let both_are_linear = lhs_is_linear && rhs_is_linear;
let either_is_const = lhs.is_const() || rhs.is_const();
if both_are_linear || either_is_const {
return (lhs * rhs).expect("Both expressions are degree <= 1");
}

// Case 2: One or both of the sides needs to be reduced to a degree-1 univariate polynomial
let lhs_reduced = if lhs_is_linear {
Cow::Borrowed(lhs)
} else {
Cow::Owned(self.get_or_create_witness(lhs).into())
};

// If the lhs and rhs are the same, then we do not need to reduce
// rhs, we only need to square the lhs.
if lhs == rhs {
return (&*lhs_reduced * &*lhs_reduced)
.expect("Both expressions are reduced to be degree <= 1");
};

let rhs_reduced = if rhs_is_linear {
Cow::Borrowed(rhs)
} else {
Cow::Owned(self.get_or_create_witness(rhs).into())
};

(&*lhs_reduced * &*rhs_reduced).expect("Both expressions are reduced to be degree <= 1")
}

/// Adds an inversion brillig opcode.
///
/// This code will invert `expr` without applying constraints
Expand Down
19 changes: 8 additions & 11 deletions compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@
abi_distinctness: Distinctness,
) -> Result<(Vec<GeneratedAcir>, Vec<BrilligBytecode>), RuntimeError> {
let mut acirs = Vec::new();
// TODO: can we parallelise this?

Check warning on line 287 in compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (parallelise)
let mut shared_context = SharedContext::default();
for function in self.functions.values() {
let context = Context::new(&mut shared_context);
Expand Down Expand Up @@ -2782,7 +2782,7 @@
let (acir_functions, _) = ssa
.into_acir(&Brillig::default(), noirc_frontend::ast::Distinctness::Distinct)
.expect("Should compile manually written SSA into ACIR");
// The expected result should look very similar to the abvoe test expect that the input witnesses of the `Call`

Check warning on line 2785 in compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (abvoe)
// opcodes will be different. The changes can discerned from the checks below.

let main_acir = &acir_functions[0];
Expand Down Expand Up @@ -3277,18 +3277,15 @@
// This check right now expects to only call one Brillig function.
let mut num_normal_brillig_calls = 0;
for (i, opcode) in opcodes.iter().enumerate() {
match opcode {
Opcode::BrilligCall { id, .. } => {
if brillig_stdlib_function_locations.get(&OpcodeLocation::Acir(i)).is_some() {
// We should have already checked Brillig stdlib functions and only want to check normal Brillig calls here
continue;
}
// We only generate one normal Brillig call so we should expect a function ID of `0`
let expected_id = 0u32;
assert_eq!(*id, expected_id, "Expected an id of {expected_id} but got {id}");
num_normal_brillig_calls += 1;
if let Opcode::BrilligCall { id, .. } = opcode {
if brillig_stdlib_function_locations.get(&OpcodeLocation::Acir(i)).is_some() {
// We should have already checked Brillig stdlib functions and only want to check normal Brillig calls here
continue;
}
_ => {}
// We only generate one normal Brillig call so we should expect a function ID of `0`
let expected_id = 0u32;
assert_eq!(*id, expected_id, "Expected an id of {expected_id} but got {id}");
num_normal_brillig_calls += 1;
}
}

Expand Down
67 changes: 0 additions & 67 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use noirc_frontend::monomorphization::ast::{FuncId, Program};
use crate::errors::RuntimeError;
use crate::ssa::function_builder::FunctionBuilder;
use crate::ssa::ir::basic_block::BasicBlockId;
use crate::ssa::ir::dfg::DataFlowGraph;
use crate::ssa::ir::function::{Function, RuntimeType};
use crate::ssa::ir::function::{FunctionId as IrFunctionId, InlineType};
use crate::ssa::ir::instruction::BinaryOp;
Expand Down Expand Up @@ -1103,72 +1102,6 @@ fn operator_requires_swapped_operands(op: BinaryOpKind) -> bool {
matches!(op, Greater | LessEqual)
}

/// If the operation requires its result to be truncated because it is an integer, the maximum
/// number of bits that result may occupy is returned.
fn operator_result_max_bit_size_to_truncate(
op: BinaryOpKind,
lhs: ValueId,
rhs: ValueId,
dfg: &DataFlowGraph,
) -> Option<u32> {
let lhs_type = dfg.type_of_value(lhs);
let rhs_type = dfg.type_of_value(rhs);

let get_bit_size = |typ| match typ {
Type::Numeric(NumericType::Signed { bit_size } | NumericType::Unsigned { bit_size }) => {
Some(bit_size)
}
_ => None,
};

let lhs_bit_size = get_bit_size(lhs_type)?;
let rhs_bit_size = get_bit_size(rhs_type)?;
use BinaryOpKind::*;
match op {
Add => Some(std::cmp::max(lhs_bit_size, rhs_bit_size) + 1),
Subtract => Some(std::cmp::max(lhs_bit_size, rhs_bit_size) + 1),
Multiply => {
if lhs_bit_size == 1 || rhs_bit_size == 1 {
// Truncation is unnecessary as multiplication by a boolean value cannot cause an overflow.
None
} else {
Some(lhs_bit_size + rhs_bit_size)
}
}

ShiftLeft => {
if let Some(rhs_constant) = dfg.get_numeric_constant(rhs) {
// Happy case is that we know precisely by how many bits the the integer will
// increase: lhs_bit_size + rhs
return Some(lhs_bit_size + (rhs_constant.to_u128() as u32));
}
// Unhappy case is that we don't yet know the rhs value, (even though it will
// eventually have to resolve to a constant). The best we can is assume the value of
// rhs to be the maximum value of it's numeric type. If that turns out to be larger
// than the native field's bit size, we full back to using that.

// The formula for calculating the max bit size of a left shift is:
// lhs_bit_size + 2^{rhs_bit_size} - 1
// Inferring the max bit size of left shift from its operands can result in huge
// number, that might not only be larger than the native field's max bit size, but
// furthermore might not be representable as a u32. Hence we use overflow checks and
// fallback to the native field's max bits.
let field_max_bits = FieldElement::max_num_bits();
let (rhs_bit_size_pow_2, overflows) = 2_u32.overflowing_pow(rhs_bit_size);
if overflows {
return Some(field_max_bits);
}
let (max_bits_plus_1, overflows) = rhs_bit_size_pow_2.overflowing_add(lhs_bit_size);
if overflows {
return Some(field_max_bits);
}
let max_bit_size = std::cmp::min(max_bits_plus_1 - 1, field_max_bits);
Some(max_bit_size)
}
_ => None,
}
}

/// Converts the given operator to the appropriate BinaryOp.
/// Take care when using this to insert a binary instruction: this requires
/// checking operator_requires_not and operator_requires_swapped_operands
Expand Down
Loading