Path: blob/main/cranelift/codegen/src/cfg_printer.rs
1693 views
//! The `CFGPrinter` utility.12use alloc::vec::Vec;3use core::fmt::{Display, Formatter, Result, Write};45use crate::entity::SecondaryMap;6use crate::flowgraph::{BlockPredecessor, ControlFlowGraph};7use crate::ir::Function;8use crate::write::{FuncWriter, PlainWriter};910/// A utility for pretty-printing the CFG of a `Function`.11pub struct CFGPrinter<'a> {12func: &'a Function,13cfg: ControlFlowGraph,14}1516/// A utility for pretty-printing the CFG of a `Function`.17impl<'a> CFGPrinter<'a> {18/// Create a new CFGPrinter.19pub fn new(func: &'a Function) -> Self {20Self {21func,22cfg: ControlFlowGraph::with_function(func),23}24}2526/// Write the CFG for this function to `w`.27pub fn write(&self, w: &mut dyn Write) -> Result {28self.header(w)?;29self.block_nodes(w)?;30self.cfg_connections(w)?;31writeln!(w, "}}")32}3334fn header(&self, w: &mut dyn Write) -> Result {35writeln!(w, "digraph \"{}\" {{", self.func.name)?;36if let Some(entry) = self.func.layout.entry_block() {37writeln!(w, " {{rank=min; {entry}}}")?;38}39Ok(())40}4142fn block_nodes(&self, w: &mut dyn Write) -> Result {43let mut aliases = SecondaryMap::<_, Vec<_>>::new();44for v in self.func.dfg.values() {45// VADFS returns the immediate target of an alias46if let Some(k) = self.func.dfg.value_alias_dest_for_serialization(v) {47aliases[k].push(v);48}49}5051for block in &self.func.layout {52write!(w, " {block} [shape=record, label=\"{{")?;53crate::write::write_block_header(w, self.func, block, 4)?;54// Add all outgoing branch instructions to the label.55if let Some(inst) = self.func.layout.last_inst(block) {56write!(w, " | <{inst}>")?;57PlainWriter.write_instruction(w, self.func, &aliases, inst, 0)?;58}59writeln!(w, "}}\"]")?60}61Ok(())62}6364fn cfg_connections(&self, w: &mut dyn Write) -> Result {65for block in &self.func.layout {66for BlockPredecessor {67block: parent,68inst,69} in self.cfg.pred_iter(block)70{71writeln!(w, " {parent}:{inst} -> {block}")?;72}73}74Ok(())75}76}7778impl<'a> Display for CFGPrinter<'a> {79fn fmt(&self, f: &mut Formatter) -> Result {80self.write(f)81}82}838485