From: Niko Matsakis Date: Sun, 1 Jul 2018 20:54:01 +0000 (-0400) Subject: deconstruct the `ControlFlowGraph` trait into more granular traits X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=28c483b9462327bcda109e327251b5800ceb3fe5;p=rust.git deconstruct the `ControlFlowGraph` trait into more granular traits --- diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index cd4b32735e5..1ce5742b464 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -22,7 +22,7 @@ use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_data_structures::control_flow_graph::dominators::{dominators, Dominators}; -use rustc_data_structures::control_flow_graph::ControlFlowGraph; +use rustc_data_structures::control_flow_graph; use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::small_vec::SmallVec; @@ -2289,23 +2289,32 @@ fn item_path_str(def_id: DefId) -> String { ty::tls::with(|tcx| tcx.item_path_str(def_id)) } -impl<'tcx> ControlFlowGraph for Mir<'tcx> { +impl<'tcx> control_flow_graph::DirectedGraph for Mir<'tcx> { type Node = BasicBlock; +} +impl<'tcx> control_flow_graph::WithNumNodes for Mir<'tcx> { fn num_nodes(&self) -> usize { self.basic_blocks.len() } +} +impl<'tcx> control_flow_graph::WithStartNode for Mir<'tcx> { fn start_node(&self) -> Self::Node { START_BLOCK } +} +impl<'tcx> control_flow_graph::WithPredecessors for Mir<'tcx> { fn predecessors<'graph>( &'graph self, node: Self::Node, ) -> >::Iter { self.predecessors_for(node).clone().into_iter() } +} + +impl<'tcx> control_flow_graph::WithSuccessors for Mir<'tcx> { fn successors<'graph>( &'graph self, node: Self::Node, @@ -2314,12 +2323,12 @@ fn successors<'graph>( } } -impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> { +impl<'a, 'b> control_flow_graph::GraphPredecessors<'b> for Mir<'a> { type Item = BasicBlock; type Iter = IntoIter; } -impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> { +impl<'a, 'b> control_flow_graph::GraphSuccessors<'b> for Mir<'a> { type Item = BasicBlock; type Iter = iter::Cloned>; } diff --git a/src/librustc_data_structures/control_flow_graph/dominators/mod.rs b/src/librustc_data_structures/control_flow_graph/dominators/mod.rs index 54407658e6c..d134fad2855 100644 --- a/src/librustc_data_structures/control_flow_graph/dominators/mod.rs +++ b/src/librustc_data_structures/control_flow_graph/dominators/mod.rs @@ -14,9 +14,9 @@ //! Rice Computer Science TS-06-33870 //! -use super::ControlFlowGraph; +use super::super::indexed_vec::{Idx, IndexVec}; use super::iterate::reverse_post_order; -use super::super::indexed_vec::{IndexVec, Idx}; +use super::ControlFlowGraph; use std::fmt; @@ -29,15 +29,16 @@ pub fn dominators(graph: &G) -> Dominators { dominators_given_rpo(graph, &rpo) } -pub fn dominators_given_rpo(graph: &G, - rpo: &[G::Node]) - -> Dominators { +pub fn dominators_given_rpo( + graph: &G, + rpo: &[G::Node], +) -> Dominators { let start_node = graph.start_node(); assert_eq!(rpo[0], start_node); // compute the post order index (rank) for each node - let mut post_order_rank: IndexVec = IndexVec::from_elem_n(usize::default(), - graph.num_nodes()); + let mut post_order_rank: IndexVec = + IndexVec::from_elem_n(usize::default(), graph.num_nodes()); for (index, node) in rpo.iter().rev().cloned().enumerate() { post_order_rank[node] = index; } @@ -56,10 +57,12 @@ pub fn dominators_given_rpo(graph: &G, if immediate_dominators[pred].is_some() { // (*) // (*) dominators for `pred` have been calculated - new_idom = intersect_opt(&post_order_rank, - &immediate_dominators, - new_idom, - Some(pred)); + new_idom = intersect_opt( + &post_order_rank, + &immediate_dominators, + new_idom, + Some(pred), + ); } } @@ -76,11 +79,12 @@ pub fn dominators_given_rpo(graph: &G, } } -fn intersect_opt(post_order_rank: &IndexVec, - immediate_dominators: &IndexVec>, - node1: Option, - node2: Option) - -> Option { +fn intersect_opt( + post_order_rank: &IndexVec, + immediate_dominators: &IndexVec>, + node1: Option, + node2: Option, +) -> Option { match (node1, node2) { (None, None) => None, (Some(n), None) | (None, Some(n)) => Some(n), @@ -88,11 +92,12 @@ fn intersect_opt(post_order_rank: &IndexVec, } } -fn intersect(post_order_rank: &IndexVec, - immediate_dominators: &IndexVec>, - mut node1: Node, - mut node2: Node) - -> Node { +fn intersect( + post_order_rank: &IndexVec, + immediate_dominators: &IndexVec>, + mut node1: Node, + mut node2: Node, +) -> Node { while node1 != node2 { while post_order_rank[node1] < post_order_rank[node2] { node1 = immediate_dominators[node1].unwrap(); @@ -176,11 +181,13 @@ pub fn children(&self, node: Node) -> &[Node] { impl fmt::Debug for DominatorTree { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&DominatorTreeNode { - tree: self, - node: self.root, - }, - fmt) + fmt::Debug::fmt( + &DominatorTreeNode { + tree: self, + node: self.root, + }, + fmt, + ) } } @@ -194,11 +201,9 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let subtrees: Vec<_> = self.tree .children(self.node) .iter() - .map(|&child| { - DominatorTreeNode { - tree: self.tree, - node: child, - } + .map(|&child| DominatorTreeNode { + tree: self.tree, + node: child, }) .collect(); fmt.debug_tuple("") diff --git a/src/librustc_data_structures/control_flow_graph/iterate/mod.rs b/src/librustc_data_structures/control_flow_graph/iterate/mod.rs index 2d70b406342..3afdc88d602 100644 --- a/src/librustc_data_structures/control_flow_graph/iterate/mod.rs +++ b/src/librustc_data_structures/control_flow_graph/iterate/mod.rs @@ -8,20 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::ControlFlowGraph; use super::super::indexed_vec::IndexVec; +use super::{DirectedGraph, WithSuccessors, WithNumNodes}; #[cfg(test)] mod test; -pub fn post_order_from(graph: &G, start_node: G::Node) -> Vec { +pub fn post_order_from( + graph: &G, + start_node: G::Node, +) -> Vec { post_order_from_to(graph, start_node, None) } -pub fn post_order_from_to(graph: &G, - start_node: G::Node, - end_node: Option) - -> Vec { +pub fn post_order_from_to( + graph: &G, + start_node: G::Node, + end_node: Option, +) -> Vec { let mut visited: IndexVec = IndexVec::from_elem_n(false, graph.num_nodes()); let mut result: Vec = Vec::with_capacity(graph.num_nodes()); if let Some(end_node) = end_node { @@ -31,10 +35,12 @@ pub fn post_order_from_to(graph: &G, result } -fn post_order_walk(graph: &G, - node: G::Node, - result: &mut Vec, - visited: &mut IndexVec) { +fn post_order_walk( + graph: &G, + node: G::Node, + result: &mut Vec, + visited: &mut IndexVec, +) { if visited[node] { return; } @@ -47,7 +53,10 @@ fn post_order_walk(graph: &G, result.push(node); } -pub fn reverse_post_order(graph: &G, start_node: G::Node) -> Vec { +pub fn reverse_post_order( + graph: &G, + start_node: G::Node, +) -> Vec { let mut vec = post_order_from(graph, start_node); vec.reverse(); vec diff --git a/src/librustc_data_structures/control_flow_graph/mod.rs b/src/librustc_data_structures/control_flow_graph/mod.rs index 7bf776675c6..cfb4b07b505 100644 --- a/src/librustc_data_structures/control_flow_graph/mod.rs +++ b/src/librustc_data_structures/control_flow_graph/mod.rs @@ -17,26 +17,61 @@ #[cfg(test)] mod test; -pub trait ControlFlowGraph - where Self: for<'graph> GraphPredecessors<'graph, Item=::Node>, - Self: for<'graph> GraphSuccessors<'graph, Item=::Node> -{ +pub trait DirectedGraph { type Node: Idx; +} +pub trait WithNumNodes: DirectedGraph { fn num_nodes(&self) -> usize; - fn start_node(&self) -> Self::Node; - fn predecessors<'graph>(&'graph self, node: Self::Node) - -> >::Iter; - fn successors<'graph>(&'graph self, node: Self::Node) - -> >::Iter; } -pub trait GraphPredecessors<'graph> { +pub trait WithSuccessors: DirectedGraph +where + Self: for<'graph> GraphSuccessors<'graph, Item = ::Node>, +{ + fn successors<'graph>( + &'graph self, + node: Self::Node, + ) -> >::Iter; +} + +pub trait GraphSuccessors<'graph> { type Item; type Iter: Iterator; } -pub trait GraphSuccessors<'graph> { +pub trait WithPredecessors: DirectedGraph +where + Self: for<'graph> GraphPredecessors<'graph, Item = ::Node>, +{ + fn predecessors<'graph>( + &'graph self, + node: Self::Node, + ) -> >::Iter; +} + +pub trait GraphPredecessors<'graph> { type Item; type Iter: Iterator; } + +pub trait WithStartNode: DirectedGraph { + fn start_node(&self) -> Self::Node; +} + +pub trait ControlFlowGraph: + DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes +{ + // convenient trait +} + +impl ControlFlowGraph for T +where + T: DirectedGraph + + WithStartNode + + WithPredecessors + + WithStartNode + + WithSuccessors + + WithNumNodes, +{ +} diff --git a/src/librustc_data_structures/control_flow_graph/reference.rs b/src/librustc_data_structures/control_flow_graph/reference.rs index 3b8b01f2ff4..a7b763db8da 100644 --- a/src/librustc_data_structures/control_flow_graph/reference.rs +++ b/src/librustc_data_structures/control_flow_graph/reference.rs @@ -10,34 +10,42 @@ use super::*; -impl<'graph, G: ControlFlowGraph> ControlFlowGraph for &'graph G { +impl<'graph, G: DirectedGraph> DirectedGraph for &'graph G { type Node = G::Node; +} +impl<'graph, G: WithNumNodes> WithNumNodes for &'graph G { fn num_nodes(&self) -> usize { (**self).num_nodes() } +} +impl<'graph, G: WithStartNode> WithStartNode for &'graph G { fn start_node(&self) -> Self::Node { (**self).start_node() } +} + +impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G { + fn successors<'iter>(&'iter self, node: Self::Node) -> >::Iter { + (**self).successors(node) + } +} +impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G { fn predecessors<'iter>(&'iter self, node: Self::Node) -> >::Iter { (**self).predecessors(node) } - - fn successors<'iter>(&'iter self, node: Self::Node) -> >::Iter { - (**self).successors(node) - } } -impl<'iter, 'graph, G: ControlFlowGraph> GraphPredecessors<'iter> for &'graph G { +impl<'iter, 'graph, G: WithPredecessors> GraphPredecessors<'iter> for &'graph G { type Item = G::Node; type Iter = >::Iter; } -impl<'iter, 'graph, G: ControlFlowGraph> GraphSuccessors<'iter> for &'graph G { +impl<'iter, 'graph, G: WithSuccessors> GraphSuccessors<'iter> for &'graph G { type Item = G::Node; type Iter = >::Iter; }