Skip to content

Commit

Permalink
chore: Use DFG in SSA printer (#6986)
Browse files Browse the repository at this point in the history
  • Loading branch information
vezenovm authored Jan 8, 2025
1 parent e08f4fa commit bb8dd5c
Showing 1 changed file with 38 additions and 38 deletions.
76 changes: 38 additions & 38 deletions compiler/noirc_evaluator/src/ssa/ir/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,33 @@ use super::{
pub(crate) fn display_function(function: &Function, f: &mut Formatter) -> Result {
writeln!(f, "{} fn {} {} {{", function.runtime(), function.name(), function.id())?;
for block_id in function.reachable_blocks() {
display_block(function, block_id, f)?;
display_block(&function.dfg, block_id, f)?;
}
write!(f, "}}")
}

/// Display a single block. This will not display the block's successors.
pub(crate) fn display_block(
function: &Function,
dfg: &DataFlowGraph,
block_id: BasicBlockId,
f: &mut Formatter,
) -> Result {
let block = &function.dfg[block_id];
let block = &dfg[block_id];

writeln!(f, " {}({}):", block_id, value_list_with_types(function, block.parameters()))?;
writeln!(f, " {}({}):", block_id, value_list_with_types(dfg, block.parameters()))?;

for instruction in block.instructions() {
display_instruction(function, *instruction, f)?;
display_instruction(dfg, *instruction, f)?;
}

display_terminator(function, block.terminator(), f)
display_terminator(dfg, block.terminator(), f)
}

/// Specialize displaying value ids so that if they refer to a numeric
/// constant or a function we print those directly.
fn value(function: &Function, id: ValueId) -> String {
let id = function.dfg.resolve(id);
match &function.dfg[id] {
fn value(dfg: &DataFlowGraph, id: ValueId) -> String {
let id = dfg.resolve(id);
match &dfg[id] {
Value::NumericConstant { constant, typ } => {
format!("{typ} {constant}")
}
Expand All @@ -57,29 +57,29 @@ fn value(function: &Function, id: ValueId) -> String {
}

/// Display each value along with its type. E.g. `v0: Field, v1: u64, v2: u1`
fn value_list_with_types(function: &Function, values: &[ValueId]) -> String {
fn value_list_with_types(dfg: &DataFlowGraph, values: &[ValueId]) -> String {
vecmap(values, |id| {
let value = value(function, *id);
let typ = function.dfg.type_of_value(*id);
let value = value(dfg, *id);
let typ = dfg.type_of_value(*id);
format!("{value}: {typ}")
})
.join(", ")
}

/// Display each value separated by a comma
fn value_list(function: &Function, values: &[ValueId]) -> String {
vecmap(values, |id| value(function, *id)).join(", ")
fn value_list(dfg: &DataFlowGraph, values: &[ValueId]) -> String {
vecmap(values, |id| value(dfg, *id)).join(", ")
}

/// Display a terminator instruction
pub(crate) fn display_terminator(
function: &Function,
dfg: &DataFlowGraph,
terminator: Option<&TerminatorInstruction>,
f: &mut Formatter,
) -> Result {
match terminator {
Some(TerminatorInstruction::Jmp { destination, arguments, call_stack: _ }) => {
writeln!(f, " jmp {}({})", destination, value_list(function, arguments))
writeln!(f, " jmp {}({})", destination, value_list(dfg, arguments))
}
Some(TerminatorInstruction::JmpIf {
condition,
Expand All @@ -90,7 +90,7 @@ pub(crate) fn display_terminator(
writeln!(
f,
" jmpif {} then: {}, else: {}",
value(function, *condition),
value(dfg, *condition),
then_destination,
else_destination
)
Expand All @@ -99,7 +99,7 @@ pub(crate) fn display_terminator(
if return_values.is_empty() {
writeln!(f, " return")
} else {
writeln!(f, " return {}", value_list(function, return_values))
writeln!(f, " return {}", value_list(dfg, return_values))
}
}
None => writeln!(f, " (no terminator instruction)"),
Expand All @@ -108,28 +108,28 @@ pub(crate) fn display_terminator(

/// Display an arbitrary instruction
pub(crate) fn display_instruction(
function: &Function,
dfg: &DataFlowGraph,
instruction: InstructionId,
f: &mut Formatter,
) -> Result {
// instructions are always indented within a function
write!(f, " ")?;

let results = function.dfg.instruction_results(instruction);
let results = dfg.instruction_results(instruction);
if !results.is_empty() {
write!(f, "{} = ", value_list(function, results))?;
write!(f, "{} = ", value_list(dfg, results))?;
}

display_instruction_inner(function, &function.dfg[instruction], results, f)
display_instruction_inner(dfg, &dfg[instruction], results, f)
}

fn display_instruction_inner(
function: &Function,
dfg: &DataFlowGraph,
instruction: &Instruction,
results: &[ValueId],
f: &mut Formatter,
) -> Result {
let show = |id| value(function, id);
let show = |id| value(dfg, id);

match instruction {
Instruction::Binary(binary) => {
Expand All @@ -144,20 +144,20 @@ fn display_instruction_inner(
Instruction::Constrain(lhs, rhs, error) => {
write!(f, "constrain {} == {}", show(*lhs), show(*rhs))?;
if let Some(error) = error {
display_constrain_error(function, error, f)
display_constrain_error(dfg, error, f)
} else {
writeln!(f)
}
}
Instruction::Call { func, arguments } => {
let arguments = value_list(function, arguments);
writeln!(f, "call {}({}){}", show(*func), arguments, result_types(function, results))
let arguments = value_list(dfg, arguments);
writeln!(f, "call {}({}){}", show(*func), arguments, result_types(dfg, results))
}
Instruction::Allocate => {
writeln!(f, "allocate{}", result_types(function, results))
writeln!(f, "allocate{}", result_types(dfg, results))
}
Instruction::Load { address } => {
writeln!(f, "load {}{}", show(*address), result_types(function, results))
writeln!(f, "load {}{}", show(*address), result_types(dfg, results))
}
Instruction::Store { address, value } => {
writeln!(f, "store {} at {}", show(*value), show(*address))
Expand All @@ -171,7 +171,7 @@ fn display_instruction_inner(
"array_get {}, index {}{}",
show(*array),
show(*index),
result_types(function, results)
result_types(dfg, results)
)
}
Instruction::ArraySet { array, index, value, mutable } => {
Expand Down Expand Up @@ -214,7 +214,7 @@ fn display_instruction_inner(
if element_types.len() == 1
&& element_types[0] == Type::Numeric(NumericType::Unsigned { bit_size: 8 })
{
if let Some(string) = try_byte_array_to_string(elements, function) {
if let Some(string) = try_byte_array_to_string(elements, dfg) {
if is_slice {
return writeln!(f, "make_array &b{:?}", string);
} else {
Expand All @@ -238,10 +238,10 @@ fn display_instruction_inner(
}
}

fn try_byte_array_to_string(elements: &Vector<ValueId>, function: &Function) -> Option<String> {
fn try_byte_array_to_string(elements: &Vector<ValueId>, dfg: &DataFlowGraph) -> Option<String> {
let mut string = String::new();
for element in elements {
let element = function.dfg.get_numeric_constant(*element)?;
let element = dfg.get_numeric_constant(*element)?;
let element = element.try_to_u32()?;
if element > 0xFF {
return None;
Expand All @@ -257,8 +257,8 @@ fn try_byte_array_to_string(elements: &Vector<ValueId>, function: &Function) ->
Some(string)
}

fn result_types(function: &Function, results: &[ValueId]) -> String {
let types = vecmap(results, |result| function.dfg.type_of_value(*result).to_string());
fn result_types(dfg: &DataFlowGraph, results: &[ValueId]) -> String {
let types = vecmap(results, |result| dfg.type_of_value(*result).to_string());
if types.is_empty() {
String::new()
} else if types.len() == 1 {
Expand Down Expand Up @@ -293,7 +293,7 @@ pub(crate) fn try_to_extract_string_from_error_payload(
}

fn display_constrain_error(
function: &Function,
dfg: &DataFlowGraph,
error: &ConstrainError,
f: &mut Formatter,
) -> Result {
Expand All @@ -303,11 +303,11 @@ fn display_constrain_error(
}
ConstrainError::Dynamic(_, is_string, values) => {
if let Some(constant_string) =
try_to_extract_string_from_error_payload(*is_string, values, &function.dfg)
try_to_extract_string_from_error_payload(*is_string, values, dfg)
{
writeln!(f, ", {constant_string:?}")
} else {
writeln!(f, ", data {}", value_list(function, values))
writeln!(f, ", data {}", value_list(dfg, values))
}
}
}
Expand Down

0 comments on commit bb8dd5c

Please sign in to comment.