From e9281e552ea4994ec0850a5f239c963fea6d2120 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 22 Sep 2023 13:11:22 +0200 Subject: [PATCH] Refactor display instruction arg --- crates/ir/src/dfg.rs | 14 ++----- crates/ir/src/graphviz/function.rs | 6 +-- crates/ir/src/insn.rs | 67 +++++++++++++++++------------- crates/ir/src/value.rs | 45 +++++++++++--------- 4 files changed, 69 insertions(+), 63 deletions(-) diff --git a/crates/ir/src/dfg.rs b/crates/ir/src/dfg.rs index 6da96eea..ce337cc5 100644 --- a/crates/ir/src/dfg.rs +++ b/crates/ir/src/dfg.rs @@ -1,7 +1,7 @@ //! This module contains Sonatine IR data flow graph. -use std::{collections::BTreeSet, fmt}; +use std::collections::BTreeSet; -use cranelift_entity::{packed_option::PackedOption, PrimaryMap, SecondaryMap}; +use cranelift_entity::{entity_impl, packed_option::PackedOption, PrimaryMap, SecondaryMap}; use fxhash::FxHashMap; use crate::{global_variable::ConstantValue, module::ModuleCtx, GlobalVariable}; @@ -304,15 +304,9 @@ pub enum ValueDef { } /// An opaque reference to [`BlockData`] -#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, PartialOrd, Ord)] +#[derive(Clone, PartialEq, Eq, Copy, Hash, PartialOrd, Ord)] pub struct Block(pub u32); -cranelift_entity::entity_impl!(Block); - -impl fmt::Display for Block { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "block{}", self.0) - } -} +entity_impl!(Block, "block"); /// A block data definition. /// A Block data doesn't hold any information for layout of a program. It is managed by diff --git a/crates/ir/src/graphviz/function.rs b/crates/ir/src/graphviz/function.rs index 2880504b..489ef372 100644 --- a/crates/ir/src/graphviz/function.rs +++ b/crates/ir/src/graphviz/function.rs @@ -2,7 +2,7 @@ use std::iter; use dot2::{label::Text, GraphWalk, Id, Labeller, Style}; -use crate::{value::DisplayArgValues, Block, ControlFlowGraph, Function, InsnData}; +use crate::{value::DisplayArgValue, Block, ControlFlowGraph, Function, InsnData}; use super::block::BlockNode; @@ -129,8 +129,8 @@ impl<'a> BlockEdge<'a> { if let InsnData::Phi { values, blocks, .. } = func.dfg.insn_data(insn) { for (i, block) in blocks.into_iter().enumerate() { if *block == from { - let flow_arg = [values[i]]; - let v = DisplayArgValues::new(&flow_arg, &func.dfg); + let flow_arg = values[i]; + let v = DisplayArgValue::new(flow_arg, &func.dfg); return Text::LabelStr(format!("{v}").into()); } } diff --git a/crates/ir/src/insn.rs b/crates/ir/src/insn.rs index b6727016..9635bb1d 100644 --- a/crates/ir/src/insn.rs +++ b/crates/ir/src/insn.rs @@ -8,7 +8,7 @@ use smallvec::SmallVec; use crate::{ function::Function, types::{CompoundTypeData, DisplayType}, - value::{DisplayArgValues, DisplayResultValue}, + value::{display_arg_values, DisplayArgValue, DisplayResultValue}, }; use super::{ @@ -17,7 +17,7 @@ use super::{ }; /// An opaque reference to [`InsnData`] -#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, PartialOrd, Ord, Default)] pub struct Insn(pub u32); cranelift_entity::entity_impl!(Insn); @@ -441,84 +441,91 @@ impl<'a> fmt::Display for DisplayInsnData<'a> { let insn_data = dfg.insn_data(insn); match insn_data { Unary { code, args } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "{} {v};", code.as_str()) + write!(f, "{} ", code.as_str())?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Binary { code, args } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "{} {v};", code.as_str(),) + write!(f, "{} ", code.as_str())?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Cast { code, args, .. } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "{} {v};", code.as_str()) + write!(f, "{} ", code.as_str())?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Load { args, loc } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "{loc} load {v};") + write!(f, "{loc} load ")?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Store { args, loc } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "store {loc} {v};") + write!(f, "store {loc} ")?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Call { args, func: callee, .. } => { - let v = DisplayArgValues::new(args, dfg); let callee = DisplayCalleeFuncRef::new(callee, func); - write!(f, "call %{callee} {v};") + write!(f, "call %{callee} ")?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Jump { code, dests } => { let block = dests[0]; write!(f, "{code} {block};") } Branch { args, dests } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "branch {v} {} {};", dests[0], dests[1]) + "branch ".fmt(f)?; + display_arg_values(f, args, dfg)?; + write!(f, " {} {};", dests[0], dests[1]) } BrTable { args, default, table, } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "br_table {v}")?; + "br_table ".fmt(f)?; + display_arg_values(f, args, dfg)?; if let Some(block) = default { write!(f, " {block}")?; } - for block in &table[..table.len() - 2] { + for block in table { write!(f, " {block}")?; } - write!(f, " {};", table[table.len() - 1]) + ";".fmt(f) } Alloca { ty } => { let ty = DisplayType::new(*ty, dfg); write!(f, "alloca {ty};") } Return { args } => { - write!(f, "ret")?; + "ret".fmt(f)?; if let Some(arg) = args { - let arg = [*arg]; - let v = DisplayArgValues::new(&arg, dfg); + let v = DisplayArgValue::new(*arg, dfg); write!(f, " {v}")?; } - write!(f, ";") + ";".fmt(f) } Gep { args } => { - let v = DisplayArgValues::new(args, dfg); - write!(f, "gep {v};") + "gep ".fmt(f)?; + display_arg_values(f, args, dfg)?; + ";".fmt(f) } Phi { values, blocks, .. } => { - write!(f, "phi")?; + "phi".fmt(f)?; for (value, block) in values.iter().zip(blocks.iter()) { - let value = [*value]; - let v = DisplayArgValues::new(&value, dfg); + let v = DisplayArgValue::new(*value, dfg); write!(f, " ({v} {block})")?; } - write!(f, ";") + ";".fmt(f) } } } } + /// Unary operations. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum UnaryOp { diff --git a/crates/ir/src/value.rs b/crates/ir/src/value.rs index 231764ab..6ab9b67e 100644 --- a/crates/ir/src/value.rs +++ b/crates/ir/src/value.rs @@ -34,37 +34,42 @@ impl<'a> fmt::Display for DisplayResultValue<'a> { } } -pub struct DisplayArgValues<'a, 'b> { - args: &'a [Value], - dfg: &'b DataFlowGraph, +pub struct DisplayArgValue<'a> { + arg: Value, + dfg: &'a DataFlowGraph, } -impl<'a, 'b> DisplayArgValues<'a, 'b> { - pub fn new(args: &'a [Value], dfg: &'b DataFlowGraph) -> Self { - Self { args, dfg } +impl<'a> DisplayArgValue<'a> { + pub fn new(arg: Value, dfg: &'a DataFlowGraph) -> Self { + Self { arg, dfg } } +} - pub fn write_arg(&self, w: &mut W, arg: &Value) -> fmt::Result { - let dfg = self.dfg; - match *dfg.value_data(*arg) { +impl<'a> fmt::Display for DisplayArgValue<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { arg, dfg } = *self; + match *dfg.value_data(arg) { ValueData::Immediate { imm, ty } => { let ty = DisplayType::new(ty, dfg); - write!(w, "{imm}.{ty}") + write!(f, "{imm}.{ty}") } - _ => write!(w, "v{}", arg.0), + _ => write!(f, "v{}", arg.0), } } } -impl<'a, 'b> fmt::Display for DisplayArgValues<'a, 'b> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.write_arg(f, &self.args[0])?; - for arg in &self.args[1..] { - write!(f, " ")?; - self.write_arg(f, arg)?; - } - Ok(()) - } +pub fn display_arg_values( + f: &mut fmt::Formatter, + args: &[Value], + dfg: &DataFlowGraph, +) -> fmt::Result { + let arg0 = DisplayArgValue::new(args[0], dfg); + write!(f, "{arg0}")?; + for arg in &args[1..] { + let arg = DisplayArgValue::new(*arg, dfg); + write!(f, " {arg}")?; + } + Ok(()) } /// An value data definition.