Skip to content

Commit

Permalink
feat: allow filtering which SSA passes are printed
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Nov 27, 2024
1 parent 6167b73 commit ea6b568
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 39 deletions.
18 changes: 16 additions & 2 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use noirc_abi::{AbiParameter, AbiType, AbiValue};
use noirc_errors::{CustomDiagnostic, FileDiagnostic};
use noirc_evaluator::create_program;
use noirc_evaluator::errors::RuntimeError;
use noirc_evaluator::ssa::SsaProgramArtifact;
use noirc_evaluator::ssa::{SsaLogging, SsaProgramArtifact};
use noirc_frontend::debug::build_debug_crate_file;
use noirc_frontend::hir::def_map::{Contract, CrateDefMap};
use noirc_frontend::hir::Context;
Expand Down Expand Up @@ -70,6 +70,11 @@ pub struct CompileOptions {
#[arg(long, hide = true)]
pub show_ssa: bool,

/// If `show_ssa` is true, setting this will only show SSA passes whose name
/// contains the provided string.
#[arg(long, hide = true)]
pub show_ssa_pass_name: Option<String>,

/// Emit the unoptimized SSA IR to file.
/// The IR will be dumped into the workspace target directory,
/// under `[compiled-package].ssa.json`.
Expand Down Expand Up @@ -577,7 +582,16 @@ pub fn compile_no_check(
}
let return_visibility = program.return_visibility;
let ssa_evaluator_options = noirc_evaluator::ssa::SsaEvaluatorOptions {
enable_ssa_logging: options.show_ssa,
ssa_logging: match &options.show_ssa_pass_name {
Some(string) => SsaLogging::Equals(string.clone()),
None => {
if options.show_ssa {
SsaLogging::All
} else {
SsaLogging::None
}
}
},
enable_brillig_logging: options.show_brillig,
force_brillig_output: options.force_brillig,
print_codegen_timings: options.benchmark_codegen,
Expand Down
91 changes: 54 additions & 37 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,16 @@ mod opt;
pub(crate) mod parser;
pub mod ssa_gen;

#[derive(Debug, Clone)]
pub enum SsaLogging {
None,
All,
Equals(String),
}

pub struct SsaEvaluatorOptions {
/// Emit debug information for the intermediate SSA IR
pub enable_ssa_logging: bool,
pub ssa_logging: SsaLogging,

pub enable_brillig_logging: bool,

Expand Down Expand Up @@ -85,46 +92,46 @@ pub(crate) fn optimize_into_acir(

let mut ssa = SsaBuilder::new(
program,
options.enable_ssa_logging,
options.ssa_logging.clone(),
options.force_brillig_output,
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 (1st):")
.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, "After Mem2Reg (1st):")
.run_pass(Ssa::simplify_cfg, "After Simplifying (1st):")
.run_pass(Ssa::as_slice_optimization, "After `as_slice` optimization")
.run_pass(Ssa::mem2reg, "Mem2Reg (1st)")
.run_pass(Ssa::simplify_cfg, "Simplifying (1st)")
.run_pass(Ssa::as_slice_optimization, "`as_slice` optimization")
.try_run_pass(
Ssa::evaluate_static_assert_and_assert_constant,
"After `static_assert` and `assert_constant`:",
"`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:")
.run_pass(Ssa::remove_bit_shifts, "After Removing Bit Shifts:")
.run_pass(Ssa::loop_invariant_code_motion, "Loop Invariant Code Motion")
.try_run_pass(Ssa::unroll_loops_iteratively, "Unrolling:")?
.run_pass(Ssa::simplify_cfg, "Simplifying (2nd)")
.run_pass(Ssa::flatten_cfg, "Flattening:")
.run_pass(Ssa::remove_bit_shifts, "Removing Bit Shifts")
// Run mem2reg once more with the flattened CFG to catch any remaining loads/stores
.run_pass(Ssa::mem2reg, "After Mem2Reg (2nd):")
.run_pass(Ssa::mem2reg, "Mem2Reg (2nd)")
// Run the inlining pass again to handle functions with `InlineType::NoPredicates`.
// Before flattening is run, we treat functions marked with the `InlineType::NoPredicates` as an entry point.
// This pass must come immediately following `mem2reg` as the succeeding passes
// may create an SSA which inlining fails to handle.
.run_pass(
|ssa| ssa.inline_functions_with_no_predicates(options.inliner_aggressiveness),
"After Inlining (2nd):",
"Inlining (2nd)",
)
.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 EnableSideEffectsIf removal:")
.run_pass(Ssa::fold_constants_using_constraints, "After Constraint Folding:")
.run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:")
.run_pass(Ssa::simplify_cfg, "After Simplifying:")
.run_pass(Ssa::array_set_optimization, "After Array Set Optimizations:")
.run_pass(Ssa::remove_if_else, "Remove IfElse")
.run_pass(Ssa::fold_constants, "Constant Folding")
.run_pass(Ssa::remove_enable_side_effects, "EnableSideEffectsIf removal")
.run_pass(Ssa::fold_constants_using_constraints, "Constraint Folding")
.run_pass(Ssa::dead_instruction_elimination, "Dead Instruction Elimination (1st)")
.run_pass(Ssa::simplify_cfg, "Simplifying:")
.run_pass(Ssa::array_set_optimization, "Array Set Optimizations")
.finish();

let ssa_level_warnings = if options.skip_underconstrained_check {
Expand All @@ -146,14 +153,11 @@ pub(crate) fn optimize_into_acir(

let ssa = SsaBuilder {
ssa,
print_ssa_passes: options.enable_ssa_logging,
ssa_logging: options.ssa_logging.clone(),
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:")
.run_pass(|ssa| ssa.fold_constants_with_brillig(&brillig), "Inlining Brillig Calls Inlining")
.run_pass(Ssa::dead_instruction_elimination, "Dead Instruction Elimination (2nd)")
.finish();

drop(ssa_gen_span_guard);
Expand Down Expand Up @@ -411,14 +415,14 @@ fn split_public_and_private_inputs(
// This is just a convenience object to bundle the ssa with `print_ssa_passes` for debug printing.
struct SsaBuilder {
ssa: Ssa,
print_ssa_passes: bool,
ssa_logging: SsaLogging,
print_codegen_timings: bool,
}

impl SsaBuilder {
fn new(
program: Program,
print_ssa_passes: bool,
ssa_logging: SsaLogging,
force_brillig_runtime: bool,
print_codegen_timings: bool,
emit_ssa: &Option<PathBuf>,
Expand All @@ -433,7 +437,7 @@ impl SsaBuilder {
let ssa_path = emit_ssa.with_extension("ssa.json");
write_to_file(&serde_json::to_vec(&ssa).unwrap(), &ssa_path);
}
Ok(SsaBuilder { print_ssa_passes, print_codegen_timings, ssa }.print("Initial SSA:"))
Ok(SsaBuilder { ssa_logging, print_codegen_timings, ssa }.print("Initial SSA:"))
}

fn finish(self) -> Ssa {
Expand All @@ -460,9 +464,22 @@ impl SsaBuilder {
}

fn print(mut self, msg: &str) -> Self {
if self.print_ssa_passes {
self.ssa.normalize_ids();
println!("{msg}\n{}", self.ssa);
match &self.ssa_logging {
SsaLogging::None => (),
SsaLogging::All => {
self.ssa.normalize_ids();
println!("After {msg}:\n{}", self.ssa);
}
SsaLogging::Equals(string) => {
let string = string.to_lowercase();
let string = string.strip_prefix("after ").unwrap_or(&string);
let string = string.strip_suffix(':').unwrap_or(string);

if msg.to_lowercase().contains(string) {
self.ssa.normalize_ids();
println!("After {msg}:\n{}", self.ssa);
}
}
}
self
}
Expand Down

0 comments on commit ea6b568

Please sign in to comment.