use crate::error::*; use crate::ir::*; use falcon::{graph::Graph, il}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct ControlFlowGraph { graph: Graph, Edge>, entry: Option, exit: Option, } impl ControlFlowGraph { pub fn from_il( control_flow_graph: &il::ControlFlowGraph, ) -> Result> { let mut graph: Graph, Edge> = Graph::new(); control_flow_graph .blocks() .into_iter() .try_for_each(|block| graph.insert_vertex(Block::::from_il(block)))?; control_flow_graph .edges() .into_iter() .try_for_each(|edge| graph.insert_edge(Edge::::from_il(edge)))?; Ok(ControlFlowGraph { graph, entry: control_flow_graph.entry(), exit: control_flow_graph.exit(), }) } pub fn graph(&self) -> &Graph, Edge> { &self.graph } pub fn graph_mut(&mut self) -> &mut Graph, Edge> { &mut self.graph } pub fn entry(&self) -> Option { self.entry } pub fn exit(&self) -> Option { self.exit } pub fn block(&self, index: usize) -> Result<&Block> { Ok(self.graph.vertex(index)?) } pub fn block_mut(&mut self, index: usize) -> Result<&mut Block> { Ok(self.graph.vertex_mut(index)?) } pub fn blocks(&self) -> Vec<&Block> { self.graph.vertices() } pub fn blocks_mut(&mut self) -> Vec<&mut Block> { self.graph.vertices_mut() } pub fn edge(&self, head: usize, tail: usize) -> Result<&Edge> { Ok(self.graph().edge(head, tail)?) } pub fn edge_mut(&mut self, head: usize, tail: usize) -> Result<&mut Edge> { Ok(self.graph.edge_mut(head, tail)?) } pub fn edges(&self) -> Vec<&Edge> { self.graph.edges() } pub fn edges_mut(&mut self) -> Vec<&mut Edge> { self.graph.edges_mut() } pub fn edges_out(&self, block_index: usize) -> Result>> { Ok(self.graph.edges_out(block_index)?) } pub fn edges_in(&self, block_index: usize) -> Result>> { Ok(self.graph.edges_in(block_index)?) } }