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: Use DFG in SSA printer #6986

Merged
merged 1 commit into from
Jan 8, 2025
Merged
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
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
Loading