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

feat: Sync from noir #10110

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8f9c85e
[1 changes] feat: try to inline brillig calls with all constant argum…
AztecBot Nov 21, 2024
55dfa6a
chore: apply sync fixes
AztecBot Nov 21, 2024
9c56e4d
.
TomAFrench Nov 21, 2024
a4cbd43
[1 changes] fix: remove `compiler_version` from new `Nargo.toml` (htt…
AztecBot Nov 21, 2024
2505ae4
chore: apply sync fixes
AztecBot Nov 22, 2024
8e90562
fix: remove `compiler_version` from new `Nargo.toml` (https://github.…
AztecBot Nov 22, 2024
811eda4
[1 changes] feat(ssa): Loop invariant code motion (https://github.com…
AztecBot Nov 22, 2024
735d9d8
chore: apply sync fixes
AztecBot Nov 22, 2024
d5e150c
feat(ssa): Loop invariant code motion (https://github.com/noir-lang/n…
AztecBot Nov 22, 2024
8719b3b
[1 changes] feat: Add `array_refcount` and `slice_refcount` builtins …
AztecBot Nov 23, 2024
4fe76c4
chore: apply sync fixes
AztecBot Nov 23, 2024
ee7a338
feat: Add `array_refcount` and `slice_refcount` builtins for debuggin…
AztecBot Nov 23, 2024
88c2f3d
[1 changes] feat: Add `array_refcount` and `slice_refcount` builtins …
AztecBot Nov 24, 2024
08c0e67
chore: apply sync fixes
AztecBot Nov 24, 2024
d20740f
feat: Add `array_refcount` and `slice_refcount` builtins for debuggin…
AztecBot Nov 24, 2024
7b367fe
[1 changes] feat: Add `array_refcount` and `slice_refcount` builtins …
AztecBot Nov 25, 2024
2d4240a
chore: apply sync fixes
AztecBot Nov 25, 2024
24e1c5b
feat: Add `array_refcount` and `slice_refcount` builtins for debuggin…
AztecBot Nov 25, 2024
bb7380e
[1 changes] feat(comptime): Implement blackbox functions in comptime …
AztecBot Nov 26, 2024
c727735
chore: apply sync fixes
AztecBot Nov 26, 2024
7a776ac
feat(comptime): Implement blackbox functions in comptime interpreter …
AztecBot Nov 26, 2024
d0ca5e1
[1 changes] fix(ssa): Track all local allocations during flattening (…
AztecBot Nov 26, 2024
22163b6
chore: apply sync fixes
AztecBot Nov 26, 2024
b2653c0
fix(ssa): Track all local allocations during flattening (https://gith…
AztecBot Nov 26, 2024
0911fb1
Merge branch 'master' into sync-noir
TomAFrench Nov 26, 2024
a5d4de0
.
TomAFrench Nov 26, 2024
795606b
[1 changes] chore!: remove `ec` module from stdlib (https://github.co…
AztecBot Nov 27, 2024
cc17c3c
chore: apply sync fixes
AztecBot Nov 27, 2024
657adc4
chore!: remove `ec` module from stdlib (https://github.com/noir-lang/…
AztecBot Nov 27, 2024
29dc5cb
Merge branch 'master' into sync-noir
sirasistant Nov 27, 2024
40404ed
use external ec lib
sirasistant Nov 27, 2024
2d9e412
fix version
sirasistant Nov 27, 2024
9a691bc
add missing types
sirasistant Nov 27, 2024
968325d
.
TomAFrench Nov 27, 2024
afd5612
.
TomAFrench Nov 27, 2024
fbe3491
.
TomAFrench Nov 27, 2024
a33ae1a
.
TomAFrench Nov 27, 2024
144907c
Merge branch 'master' into sync-noir
TomAFrench Nov 27, 2024
7d27f23
Merge branch 'master' into sync-noir
TomAFrench Nov 27, 2024
8c17851
[1 changes] feat(ssa): Deduplicate intrinsics with predicates (https:…
AztecBot Nov 28, 2024
b6c4d27
chore: apply sync fixes
AztecBot Nov 28, 2024
d229b1f
feat(ssa): Deduplicate intrinsics with predicates (https://github.com…
AztecBot Nov 28, 2024
cfab7da
Merge branch 'master' into sync-noir
TomAFrench Nov 28, 2024
35133a5
[1 changes] chore: pin foundry version in CI (https://github.com/noir…
AztecBot Nov 28, 2024
b0068d4
chore: apply sync fixes
AztecBot Nov 28, 2024
20dbf72
chore: pin foundry version in CI (https://github.com/noir-lang/noir/p…
AztecBot Nov 28, 2024
d94d1e2
.
TomAFrench Nov 28, 2024
d753635
.
TomAFrench Nov 28, 2024
ecc07c2
.
TomAFrench Nov 28, 2024
5ca6c88
.
TomAFrench Nov 28, 2024
0fef6a4
Merge branch 'master' into sync-noir
TomAFrench Nov 28, 2024
0e87bea
Apply suggestions from code review
TomAFrench Nov 28, 2024
35d114f
Merge branch 'master' into sync-noir
TomAFrench Nov 28, 2024
6039177
Merge branch 'master' into sync-noir
TomAFrench Nov 28, 2024
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
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
68c32b4ffd9b069fe4b119327dbf4018c17ab9d4
dfc9ff7266d2b6694cae3da88418013664440daa
7 changes: 7 additions & 0 deletions noir/noir-repo/compiler/noirc_evaluator/src/acir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2762,6 +2762,13 @@ impl<'a> Context<'a> {
Intrinsic::FieldLessThan => {
unreachable!("FieldLessThan can only be called in unconstrained")
}
Intrinsic::ArrayRefCount | Intrinsic::SliceRefCount => {
let zero = self.acir_context.add_constant(FieldElement::zero());
Ok(vec![AcirValue::Var(
zero,
AcirType::NumericType(NumericType::Unsigned { bit_size: 32 }),
)])
}
}
}

Expand Down

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub(crate) fn optimize_into_acir(
Ssa::evaluate_static_assert_and_assert_constant,
"After `static_assert` and `assert_constant`:",
)?
.run_pass(Ssa::loop_invariant_code_motion, "After Loop Invariant Code Motion:")
.try_run_pass(Ssa::unroll_loops_iteratively, "After Unrolling:")?
.run_pass(Ssa::simplify_cfg, "After Simplifying (2nd):")
.run_pass(Ssa::flatten_cfg, "After Flattening:")
Expand Down Expand Up @@ -140,6 +141,23 @@ pub(crate) fn optimize_into_acir(
ssa.to_brillig(options.enable_brillig_logging)
});

let ssa_gen_span = span!(Level::TRACE, "ssa_generation");
let ssa_gen_span_guard = ssa_gen_span.enter();

let ssa = SsaBuilder {
ssa,
print_ssa_passes: options.enable_ssa_logging,
print_codegen_timings: options.print_codegen_timings,
}
.run_pass(
|ssa| ssa.fold_constants_with_brillig(&brillig),
"After Constant Folding with Brillig:",
)
.run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:")
.finish();

drop(ssa_gen_span_guard);

let artifacts = time("SSA to ACIR", options.print_codegen_timings, || {
ssa.into_acir(&brillig, options.expression_width)
})?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,18 @@ impl Context {
| Intrinsic::IsUnconstrained => {}
Intrinsic::ArrayLen
| Intrinsic::ArrayAsStrUnchecked
| Intrinsic::ArrayRefCount
| Intrinsic::AsField
| Intrinsic::AsSlice
| Intrinsic::BlackBox(..)
| Intrinsic::DerivePedersenGenerators
| Intrinsic::FromField
| Intrinsic::SliceInsert
| Intrinsic::SlicePushBack
| Intrinsic::SlicePushFront
| Intrinsic::SlicePopBack
| Intrinsic::SlicePopFront
| Intrinsic::SliceInsert
| Intrinsic::SliceRefCount
| Intrinsic::SliceRemove
| Intrinsic::StaticAssert
| Intrinsic::StrAsBytes
Expand Down
81 changes: 71 additions & 10 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use fxhash::FxHasher64;
use iter_extended::vecmap;
use noirc_frontend::hir_def::types::Type as HirType;

use crate::ssa::opt::flatten_cfg::value_merger::ValueMerger;
use crate::ssa::{ir::function::RuntimeType, opt::flatten_cfg::value_merger::ValueMerger};

use super::{
basic_block::BasicBlockId,
Expand Down Expand Up @@ -45,8 +45,7 @@ pub(crate) type InstructionId = Id<Instruction>;
/// - Opcodes which the IR knows the target machine has
/// special support for. (LowLevel)
/// - Opcodes which have no function definition in the
/// source code and must be processed by the IR. An example
/// of this is println.
/// source code and must be processed by the IR.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub(crate) enum Intrinsic {
ArrayLen,
Expand All @@ -71,6 +70,8 @@ pub(crate) enum Intrinsic {
IsUnconstrained,
DerivePedersenGenerators,
FieldLessThan,
ArrayRefCount,
SliceRefCount,
}

impl std::fmt::Display for Intrinsic {
Expand Down Expand Up @@ -100,6 +101,8 @@ impl std::fmt::Display for Intrinsic {
Intrinsic::IsUnconstrained => write!(f, "is_unconstrained"),
Intrinsic::DerivePedersenGenerators => write!(f, "derive_pedersen_generators"),
Intrinsic::FieldLessThan => write!(f, "field_less_than"),
Intrinsic::ArrayRefCount => write!(f, "array_refcount"),
Intrinsic::SliceRefCount => write!(f, "slice_refcount"),
}
}
}
Expand All @@ -108,11 +111,18 @@ impl Intrinsic {
/// Returns whether the `Intrinsic` has side effects.
///
/// If there are no side effects then the `Intrinsic` can be removed if the result is unused.
///
/// An example of a side effect is increasing the reference count of an array, but functions
/// which can fail due to implicit constraints are also considered to have a side effect.
pub(crate) fn has_side_effects(&self) -> bool {
match self {
Intrinsic::AssertConstant
| Intrinsic::StaticAssert
| Intrinsic::ApplyRangeConstraint
// Array & slice ref counts are treated as having side effects since they operate
// on hidden variables on otherwise identical array values.
| Intrinsic::ArrayRefCount
| Intrinsic::SliceRefCount
| Intrinsic::AsWitness => true,

// These apply a constraint that the input must fit into a specified number of limbs.
Expand Down Expand Up @@ -144,6 +154,39 @@ impl Intrinsic {
}
}

/// Intrinsics which only have a side effect due to the chance that
/// they can fail a constraint can be deduplicated.
pub(crate) fn can_be_deduplicated(&self, deduplicate_with_predicate: bool) -> bool {
match self {
// These apply a constraint in the form of ACIR opcodes, but they can be deduplicated
// if the inputs are the same. If they depend on a side effect variable (e.g. because
// they were in an if-then-else) then `handle_instruction_side_effects` in `flatten_cfg`
// will have attached the condition variable to their inputs directly, so they don't
// directly depend on the corresponding `enable_side_effect` instruction any more.
// However, to conform with the expectations of `Instruction::can_be_deduplicated` and
// `constant_folding` we only use this information if the caller shows interest in it.
Intrinsic::ToBits(_)
| Intrinsic::ToRadix(_)
| Intrinsic::BlackBox(
BlackBoxFunc::MultiScalarMul
| BlackBoxFunc::EmbeddedCurveAdd
| BlackBoxFunc::RecursiveAggregation,
) => deduplicate_with_predicate,

// Operations that remove items from a slice don't modify the slice, they just assert it's non-empty.
Intrinsic::SlicePopBack | Intrinsic::SlicePopFront | Intrinsic::SliceRemove => {
deduplicate_with_predicate
}

Intrinsic::AssertConstant
| Intrinsic::StaticAssert
| Intrinsic::ApplyRangeConstraint
| Intrinsic::AsWitness => deduplicate_with_predicate,

_ => !self.has_side_effects(),
}
}

/// Lookup an Intrinsic by name and return it if found.
/// If there is no such intrinsic by that name, None is returned.
pub(crate) fn lookup(name: &str) -> Option<Intrinsic> {
Expand Down Expand Up @@ -171,6 +214,8 @@ impl Intrinsic {
"is_unconstrained" => Some(Intrinsic::IsUnconstrained),
"derive_pedersen_generators" => Some(Intrinsic::DerivePedersenGenerators),
"field_less_than" => Some(Intrinsic::FieldLessThan),
"array_refcount" => Some(Intrinsic::ArrayRefCount),
"slice_refcount" => Some(Intrinsic::SliceRefCount),

other => BlackBoxFunc::lookup(other).map(Intrinsic::BlackBox),
}
Expand Down Expand Up @@ -235,7 +280,7 @@ pub(crate) enum Instruction {
/// - `code1` will have side effects iff `condition1` evaluates to `true`
///
/// This instruction is only emitted after the cfg flattening pass, and is used to annotate
/// instruction regions with an condition that corresponds to their position in the CFG's
/// instruction regions with a condition that corresponds to their position in the CFG's
/// if-branching structure.
EnableSideEffectsIf { condition: ValueId },

Expand Down Expand Up @@ -270,9 +315,6 @@ pub(crate) enum Instruction {
/// else_value
/// }
/// ```
///
/// Where we save the result of !then_condition so that we have the same
/// ValueId for it each time.
IfElse { then_condition: ValueId, then_value: ValueId, else_value: ValueId },

/// Creates a new array or slice.
Expand Down Expand Up @@ -324,6 +366,11 @@ impl Instruction {
/// If `deduplicate_with_predicate` is set, we assume we're deduplicating with the instruction
/// and its predicate, rather than just the instruction. Setting this means instructions that
/// rely on predicates can be deduplicated as well.
///
/// Some instructions get the predicate attached to their inputs by `handle_instruction_side_effects` in `flatten_cfg`.
/// These can be deduplicated because they implicitly depend on the predicate, not only when the caller uses the
/// predicate variable as a key to cache results. However, to avoid tight coupling between passes, we make the deduplication
/// conditional on whether the caller wants the predicate to be taken into account or not.
pub(crate) fn can_be_deduplicated(
&self,
dfg: &DataFlowGraph,
Expand All @@ -341,7 +388,9 @@ impl Instruction {
| DecrementRc { .. } => false,

Call { func, .. } => match dfg[*func] {
Value::Intrinsic(intrinsic) => !intrinsic.has_side_effects(),
Value::Intrinsic(intrinsic) => {
intrinsic.can_be_deduplicated(deduplicate_with_predicate)
}
_ => false,
},

Expand Down Expand Up @@ -391,8 +440,19 @@ impl Instruction {
| ArraySet { .. }
| MakeArray { .. } => true,

// Store instructions must be removed by DIE in acir code, any load
// instructions should already be unused by that point.
//
// Note that this check assumes that it is being performed after the flattening
// pass and after the last mem2reg pass. This is currently the case for the DIE
// pass where this check is done, but does mean that we cannot perform mem2reg
// after the DIE pass.
Store { .. } => {
matches!(function.runtime(), RuntimeType::Acir(_))
&& function.reachable_blocks().len() == 1
}

Constrain(..)
| Store { .. }
| EnableSideEffectsIf { .. }
| IncrementRc { .. }
| DecrementRc { .. }
Expand All @@ -403,6 +463,7 @@ impl Instruction {
// Explicitly allows removal of unused ec operations, even if they can fail
Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::MultiScalarMul))
| Value::Intrinsic(Intrinsic::BlackBox(BlackBoxFunc::EmbeddedCurveAdd)) => true,

Value::Intrinsic(intrinsic) => !intrinsic.has_side_effects(),

// All foreign functions are treated as having side effects.
Expand All @@ -418,7 +479,7 @@ impl Instruction {
}
}

/// If true the instruction will depends on enable_side_effects context during acir-gen
/// If true the instruction will depend on `enable_side_effects` context during acir-gen.
pub(crate) fn requires_acir_gen_predicate(&self, dfg: &DataFlowGraph) -> bool {
match self {
Instruction::Binary(binary)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ pub(super) fn simplify_call(
SimplifyResult::None
}
}
Intrinsic::ArrayRefCount => SimplifyResult::None,
Intrinsic::SliceRefCount => SimplifyResult::None,
}
}

Expand Down
Loading
Loading