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(ssa refactor) : Research on region labelling [DO NOT MERGE] #1428

Closed
wants to merge 1 commit into from
Closed
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
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 @@ -43,6 +43,7 @@ pub(crate) fn optimize_into_acir(program: Program) -> GeneratedAcir {
.mem2reg()
.print("After Mem2Reg:")
.into_acir(func_signature)
.print_acir()
}

/// Compiles the Program into ACIR and applies optimizations to the arithmetic gates
Expand All @@ -56,7 +57,7 @@ pub fn experimental_create_circuit(
_show_output: bool,
) -> Result<(Circuit, Abi), RuntimeError> {
let func_sig = program.main_function_signature.clone();
let GeneratedAcir { current_witness_index, opcodes, return_witnesses } =
let GeneratedAcir { current_witness_index, opcodes, return_witnesses, .. } =
optimize_into_acir(program);

let abi = gen_abi(func_sig, return_witnesses.clone());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub(crate) struct AcirContext {
/// For example, If one was to add two Variables together,
/// then the `acir_ir` will be populated to assert this
/// addition.
acir_ir: GeneratedAcir,
pub(crate) acir_ir: GeneratedAcir,
}

impl AcirContext {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ use acvm::{
FieldElement,
};

#[derive(Debug, Default)]
pub(crate) struct OpcodeRegionLabel {
/// Range of the opcodes included in the region
start_range: usize,
/// The end range is `None` while its on the region_stack
/// and the caller has not finalized the region.
end_range_inclusive: Option<usize>,

/// Label to apply to this region of code
label: String,
}

#[derive(Debug, Default)]
/// The output of the Acir-gen pass
pub(crate) struct GeneratedAcir {
Expand All @@ -26,9 +38,63 @@ pub(crate) struct GeneratedAcir {
/// Note: This may contain repeated indices, which is necessary for later mapping into the
/// abi's return type.
pub(crate) return_witnesses: Vec<Witness>,

/// For debugging purposes, one can label blocks of the opcode.
finalized_regions: Vec<OpcodeRegionLabel>,
region_stack: Vec<OpcodeRegionLabel>,
}

impl GeneratedAcir {
pub(crate) fn start_region_label(&mut self, region_name: String) {
self.region_stack.push(OpcodeRegionLabel {
start_range: self.opcodes.len(),
end_range_inclusive: None,
label: region_name,
})
}
pub(crate) fn end_label(&mut self) {
let mut region_label = self.region_stack.pop().expect("tried to pop a region label from the stack without first pushing a region onto the stack");
region_label.end_range_inclusive = Some(self.opcodes.len());
self.finalized_regions.push(region_label)
}

pub(crate) fn print_acir(self) -> Self {
fn check_if_region_starting(
index: usize,
regions: &[OpcodeRegionLabel],
) -> Vec<&OpcodeRegionLabel> {
regions.into_iter().filter(|region| region.start_range == index).collect()
}
fn check_if_region_ending(
index: usize,
regions: &[OpcodeRegionLabel],
) -> Vec<&OpcodeRegionLabel> {
regions
.into_iter()
.filter(|region| {
region.end_range_inclusive.expect("region has not been finalized") == index
})
.collect()
}

for (index, opcode) in self.opcodes.iter().enumerate() {
let regions_starting = check_if_region_starting(index, &self.finalized_regions);
let regions_ending = check_if_region_ending(index, &self.finalized_regions);

for region in regions_starting {
println!("region start: {}", region.label)
}

println!("OPCODE : {}", opcode);

for region in regions_ending {
println!("region end: {}", region.label)
}
}

self
}

/// Returns the current witness index.
pub(crate) fn current_witness_index(&self) -> Witness {
Witness(self.current_witness_index)
Expand Down
5 changes: 4 additions & 1 deletion crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl Context {
/// Converts an SSA instruction into its ACIR representation
fn convert_ssa_instruction(&mut self, instruction_id: InstructionId, dfg: &DataFlowGraph) {
let instruction = &dfg[instruction_id];
self.acir_context.acir_ir.start_region_label(format!("{instruction:?}"));
match instruction {
Instruction::Binary(binary) => {
let result_acir_var = self.convert_ssa_binary(binary, dfg);
Expand All @@ -101,6 +102,7 @@ impl Context {
}
_ => todo!(),
}
self.acir_context.acir_ir.end_label();
}

/// Converts an SSA terminator's return values into their ACIR representations
Expand All @@ -110,7 +112,8 @@ impl Context {
_ => unreachable!("ICE: Program must have a singular return"),
};

let is_return_unit_type = return_values.len() == 1 && dfg.type_of_value(return_values[0]) == Type::Unit;
let is_return_unit_type =
return_values.len() == 1 && dfg.type_of_value(return_values[0]) == Type::Unit;
if is_return_unit_type {
return;
}
Expand Down