Skip to content

Commit

Permalink
chore: Daily merge of master, 07 Jan 2025
Browse files Browse the repository at this point in the history
With PR noir-lang#6894 upstream have moved the SSA optimization
"separate_runtime" to be happening during the monomorphization phase.
  • Loading branch information
Aristotelis2002 committed Jan 7, 2025
2 parents 08bfd77 + 7cc8dbf commit 8138bb0
Show file tree
Hide file tree
Showing 48 changed files with 6,882 additions and 696 deletions.
6,248 changes: 6,248 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,12 @@ jsonrpsee = { version = "0.24.7", features = ["client-core"] }
flate2 = "1.0.24"
color-eyre = "0.6.2"
rand = "0.8.5"
proptest = "1.2.0"
proptest-derive = "0.4.0"
# The `fork` and `timeout` feature doesn't compile with Wasm (wait-timeout doesn't find the `imp` module).
proptest = { version = "1.6.0", default-features = false, features = [
"std",
"bit-set",
] }
proptest-derive = "0.5.0"
rayon = "1.8.0"
sha2 = { version = "0.10.6", features = ["compress"] }
sha3 = "0.10.6"
Expand Down
24 changes: 14 additions & 10 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,9 @@ pub fn check_crate(
crate_id: CrateId,
options: &CompileOptions,
) -> CompilationResult<()> {
let error_on_unused_imports = true;
let diagnostics = CrateDefMap::collect_defs(
crate_id,
context,
options.debug_comptime_in_file.as_deref(),
error_on_unused_imports,
);
let diagnostics =
CrateDefMap::collect_defs(crate_id, context, options.debug_comptime_in_file.as_deref());
let crate_files = context.crate_files(&crate_id);
let warnings_and_errors: Vec<FileDiagnostic> = diagnostics
.into_iter()
.map(|(error, file_id)| {
Expand All @@ -338,6 +334,14 @@ pub fn check_crate(
// We filter out any warnings if they're going to be ignored later on to free up memory.
!options.silence_warnings || diagnostic.diagnostic.kind != DiagnosticKind::Warning
})
.filter(|error| {
// Only keep warnings from the crate we are checking
if error.diagnostic.is_warning() {
crate_files.contains(&error.file_id)
} else {
true
}
})
.collect();

if has_errors(&warnings_and_errors, options.deny_warnings) {
Expand Down Expand Up @@ -612,10 +616,11 @@ pub fn compile_no_check(
compile_plonky2_circuit: bool,
create_debug_trace_list: bool,
) -> Result<CompiledProgram, CompileError> {
let force_unconstrained = options.force_brillig;
let monomorph = if options.instrument_debug {
monomorphize_debug(main_function, &mut context.def_interner, &context.debug_instrumenter)?
monomorphize_debug(main_function, &mut context.def_interner, &context.debug_instrumenter, force_unconstrained)?
} else {
monomorphize(main_function, &mut context.def_interner)?
monomorphize(main_function, &mut context.def_interner, force_unconstrained)?
};

if options.show_monomorphized {
Expand Down Expand Up @@ -654,7 +659,6 @@ pub fn compile_no_check(
}
},
enable_brillig_logging: options.show_brillig,
force_brillig_output: options.force_brillig,
print_codegen_timings: options.benchmark_codegen,
expression_width: if options.bounded_codegen {
options.expression_width.unwrap_or(DEFAULT_EXPRESSION_WIDTH)
Expand Down
3 changes: 2 additions & 1 deletion compiler/noirc_evaluator/src/acir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,8 @@ impl<'a> Context<'a> {
unreachable!("Expected all load instructions to be removed before acir_gen")
}
Instruction::IncrementRc { .. } | Instruction::DecrementRc { .. } => {
// Do nothing. Only Brillig needs to worry about reference counted arrays
// Only Brillig needs to worry about reference counted arrays
unreachable!("Expected all Rc instructions to be removed before acir_gen")
}
Instruction::RangeCheck { value, max_bit_size, assert_message } => {
let acir_var = self.convert_numeric_value(*value, dfg)?;
Expand Down
40 changes: 13 additions & 27 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,16 @@ use noirc_frontend::{hir_def::function::FunctionSignature, monomorphization::ast
use ssa_gen::Ssa;
use tracing::{span, Level};

use self::{
plonky2_gen::{Builder, Plonky2Circuit},
};
use self::plonky2_gen::{Builder, Plonky2Circuit};
use crate::acir::{Artifacts, GeneratedAcir};

mod checks;
pub(super) mod function_builder;
pub mod ir;
mod opt;
pub mod plonky2_gen;
#[cfg(test)]
pub(crate) mod parser;
pub mod plonky2_gen;
pub mod ssa_gen;

#[derive(Debug, Clone)]
Expand All @@ -61,9 +59,6 @@ pub struct SsaEvaluatorOptions {

pub enable_brillig_logging: bool,

/// Force Brillig output (for step debugging)
pub force_brillig_output: bool,

/// Pretty print benchmark times of each code generation pass
pub print_codegen_timings: bool,

Expand Down Expand Up @@ -112,7 +107,6 @@ pub(crate) fn optimize_into_acir(
let builder = SsaBuilder::new(
program,
options.ssa_logging.clone(),
options.force_brillig_output,
options.print_codegen_timings,
&options.emit_ssa,
)?;
Expand Down Expand Up @@ -180,13 +174,11 @@ pub(crate) fn optimize_into_plonky2(
let ssa = SsaBuilder::new(
program,
options.ssa_logging.clone(),
false,
options.print_codegen_timings,
&options.emit_ssa,
)?
.run_pass(Ssa::defunctionalize, "After Defunctionalization:")
.run_pass(Ssa::remove_paired_rc, "After Removing Paired rc_inc & rc_decs:")
.run_pass(Ssa::separate_runtime, "After Runtime Separation:")
.run_pass(Ssa::resolve_is_unconstrained, "After Resolving IsUnconstrained:")
.run_pass(|ssa| ssa.inline_functions(options.inliner_aggressiveness), "After Inlining:")
// Run mem2reg with the CFG separated into blocks
Expand All @@ -212,7 +204,8 @@ pub(crate) fn optimize_into_plonky2(
.run_pass(
|ssa| ssa.inline_functions_with_no_predicates(options.inliner_aggressiveness),
"After Inlining:",
) .run_pass(Ssa::remove_if_else, "After Remove IfElse:")
)
.run_pass(Ssa::remove_if_else, "After Remove IfElse:")
.run_pass(Ssa::fold_constants, "After Constant Folding:")
.run_pass(Ssa::remove_enable_side_effects, "After EnableSideEffects removal:")
.run_pass(Ssa::fold_constants_using_constraints, "After Constraint Folding:")
Expand All @@ -233,15 +226,16 @@ pub(crate) fn optimize_into_plonky2(
/// Run all SSA passes.
fn optimize_all(builder: SsaBuilder, options: &SsaEvaluatorOptions) -> Result<Ssa, RuntimeError> {
Ok(builder
.run_pass(Ssa::remove_unreachable_functions, "Removing Unreachable Functions")
.run_pass(Ssa::defunctionalize, "Defunctionalization")
.run_pass(Ssa::remove_paired_rc, "Removing Paired rc_inc & rc_decs")
.run_pass(Ssa::separate_runtime, "Runtime Separation")
.run_pass(Ssa::resolve_is_unconstrained, "Resolving IsUnconstrained")
.run_pass(|ssa| ssa.inline_functions(options.inliner_aggressiveness), "Inlining (1st)")
// Run mem2reg with the CFG separated into blocks
.run_pass(Ssa::mem2reg, "Mem2Reg (1st)")
.run_pass(Ssa::simplify_cfg, "Simplifying (1st)")
.run_pass(Ssa::as_slice_optimization, "`as_slice` optimization")
.run_pass(Ssa::remove_unreachable_functions, "Removing Unreachable Functions")
.try_run_pass(
Ssa::evaluate_static_assert_and_assert_constant,
"`static_assert` and `assert_constant`",
Expand Down Expand Up @@ -354,19 +348,12 @@ pub fn create_program(
(generated_acirs, generated_brillig, brillig_function_names, error_types),
ssa_level_warnings,
) = optimize_into_acir(program, options)?;
if options.force_brillig_output {
assert_eq!(
generated_acirs.len(),
1,
"Only the main ACIR is expected when forcing Brillig output"
);
} else {
assert_eq!(
generated_acirs.len(),
func_sigs.len(),
"The generated ACIRs should match the supplied function signatures"
);
}

assert_eq!(
generated_acirs.len(),
func_sigs.len(),
"The generated ACIRs should match the supplied function signatures"
);

let error_types = error_types
.into_iter()
Expand Down Expand Up @@ -539,11 +526,10 @@ impl SsaBuilder {
fn new(
program: Program,
ssa_logging: SsaLogging,
force_brillig_runtime: bool,
print_codegen_timings: bool,
emit_ssa: &Option<PathBuf>,
) -> Result<SsaBuilder, RuntimeError> {
let ssa = ssa_gen::generate_ssa(program, force_brillig_runtime)?;
let ssa = ssa_gen::generate_ssa(program)?;
if let Some(emit_ssa) = emit_ssa {
let mut emit_ssa_dir = emit_ssa.clone();
// We expect the full package artifact path to be passed in here,
Expand Down
70 changes: 44 additions & 26 deletions compiler/noirc_evaluator/src/ssa/function_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub(crate) struct FunctionBuilder {
finished_functions: Vec<Function>,
call_stack: CallStackId,
error_types: BTreeMap<ErrorSelector, HirType>,

/// Whether instructions are simplified as soon as they are inserted into this builder.
/// This is true by default unless changed to false after constructing a builder.
pub(crate) simplify: bool,
}

impl FunctionBuilder {
Expand All @@ -56,6 +60,7 @@ impl FunctionBuilder {
finished_functions: Vec::new(),
call_stack: CallStackId::root(),
error_types: BTreeMap::default(),
simplify: true,
}
}

Expand Down Expand Up @@ -172,12 +177,21 @@ impl FunctionBuilder {
ctrl_typevars: Option<Vec<Type>>,
) -> InsertInstructionResult {
let block = self.current_block();
self.current_function.dfg.insert_instruction_and_results(
instruction,
block,
ctrl_typevars,
self.call_stack,
)
if self.simplify {
self.current_function.dfg.insert_instruction_and_results(
instruction,
block,
ctrl_typevars,
self.call_stack,
)
} else {
self.current_function.dfg.insert_instruction_and_results_without_simplification(
instruction,
block,
ctrl_typevars,
self.call_stack,
)
}
}

/// Switch to inserting instructions in the given block.
Expand Down Expand Up @@ -469,29 +483,33 @@ impl FunctionBuilder {
///
/// Returns whether a reference count instruction was issued.
fn update_array_reference_count(&mut self, value: ValueId, increment: bool) -> bool {
match self.type_of_value(value) {
Type::Numeric(_) => false,
Type::Function => false,
Type::Reference(element) => {
if element.contains_an_array() {
let reference = value;
let value = self.insert_load(reference, element.as_ref().clone());
self.update_array_reference_count(value, increment);
true
} else {
false
if self.current_function.runtime().is_brillig() {
match self.type_of_value(value) {
Type::Numeric(_) => false,
Type::Function => false,
Type::Reference(element) => {
if element.contains_an_array() {
let reference = value;
let value = self.insert_load(reference, element.as_ref().clone());
self.update_array_reference_count(value, increment);
true
} else {
false
}
}
}
Type::Array(..) | Type::Slice(..) => {
// If there are nested arrays or slices, we wait until ArrayGet
// is issued to increment the count of that array.
if increment {
self.insert_inc_rc(value);
} else {
self.insert_dec_rc(value);
Type::Array(..) | Type::Slice(..) => {
// If there are nested arrays or slices, we wait until ArrayGet
// is issued to increment the count of that array.
if increment {
self.insert_inc_rc(value);
} else {
self.insert_dec_rc(value);
}
true
}
true
}
} else {
false
}
}

Expand Down
34 changes: 31 additions & 3 deletions compiler/noirc_evaluator/src/ssa/ir/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::ssa::{function_builder::data_bus::DataBus, ir::instruction::SimplifyR
use super::{
basic_block::{BasicBlock, BasicBlockId},
call_stack::{CallStack, CallStackHelper, CallStackId},
function::FunctionId,
function::{FunctionId, RuntimeType},
instruction::{
Instruction, InstructionId, InstructionResultType, Intrinsic, TerminatorInstruction,
},
Expand All @@ -26,8 +26,13 @@ use serde_with::DisplayFromStr;
/// owning most data in a function and handing out Ids to this data that can be
/// shared without worrying about ownership.
#[serde_as]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub(crate) struct DataFlowGraph {
/// Runtime of the [Function] that owns this [DataFlowGraph].
/// This might change during the `runtime_separation` pass where
/// ACIR functions are cloned as Brillig functions.
runtime: RuntimeType,

/// All of the instructions in a function
instructions: DenseMap<Instruction>,

Expand Down Expand Up @@ -100,6 +105,16 @@ pub(crate) struct DataFlowGraph {
}

impl DataFlowGraph {
/// Runtime type of the function.
pub(crate) fn runtime(&self) -> RuntimeType {
self.runtime
}

/// Set runtime type of the function.
pub(crate) fn set_runtime(&mut self, runtime: RuntimeType) {
self.runtime = runtime;
}

/// Creates a new basic block with no parameters.
/// After being created, the block is unreachable in the current function
/// until another block is made to jump to it.
Expand Down Expand Up @@ -164,6 +179,11 @@ impl DataFlowGraph {
id
}

/// Check if the function runtime would simply ignore this instruction.
pub(crate) fn is_handled_by_runtime(&self, instruction: &Instruction) -> bool {
!(self.runtime().is_acir() && instruction.is_brillig_only())
}

fn insert_instruction_without_simplification(
&mut self,
instruction_data: Instruction,
Expand All @@ -184,6 +204,10 @@ impl DataFlowGraph {
ctrl_typevars: Option<Vec<Type>>,
call_stack: CallStackId,
) -> InsertInstructionResult {
if !self.is_handled_by_runtime(&instruction_data) {
return InsertInstructionResult::InstructionRemoved;
}

let id = self.insert_instruction_without_simplification(
instruction_data,
block,
Expand All @@ -194,14 +218,18 @@ impl DataFlowGraph {
InsertInstructionResult::Results(id, self.instruction_results(id))
}

/// Inserts a new instruction at the end of the given block and returns its results
/// Simplifies a new instruction and inserts it at the end of the given block and returns its results.
/// If the instruction is not handled by the current runtime, `InstructionRemoved` is returned.
pub(crate) fn insert_instruction_and_results(
&mut self,
instruction: Instruction,
block: BasicBlockId,
ctrl_typevars: Option<Vec<Type>>,
call_stack: CallStackId,
) -> InsertInstructionResult {
if !self.is_handled_by_runtime(&instruction) {
return InsertInstructionResult::InstructionRemoved;
}
match instruction.simplify(self, block, ctrl_typevars.clone(), call_stack) {
SimplifyResult::SimplifiedTo(simplification) => {
InsertInstructionResult::SimplifiedTo(simplification)
Expand Down
Loading

0 comments on commit 8138bb0

Please sign in to comment.