]> git.lizzy.rs Git - rust.git/commitdiff
deconstruct the `ControlFlowGraph` trait into more granular traits
authorNiko Matsakis <niko@alum.mit.edu>
Sun, 1 Jul 2018 20:54:01 +0000 (16:54 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 12 Jul 2018 04:38:40 +0000 (00:38 -0400)
src/librustc/mir/mod.rs
src/librustc_data_structures/control_flow_graph/dominators/mod.rs
src/librustc_data_structures/control_flow_graph/iterate/mod.rs
src/librustc_data_structures/control_flow_graph/mod.rs
src/librustc_data_structures/control_flow_graph/reference.rs

index cd4b32735e57a220f0f395da909f91f9e364803c..1ce5742b4646fcdfcabd6d8b789e7fb82c7265ca 100644 (file)
@@ -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,
     ) -> <Self as GraphPredecessors<'graph>>::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<BasicBlock>;
 }
 
-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<Successors<'b>>;
 }
index 54407658e6ccc85f77e27682800529d98db3fba0..d134fad2855bbdd999907698e10e7e17cfd8e07b 100644 (file)
@@ -14,9 +14,9 @@
 //! Rice Computer Science TS-06-33870
 //! <https://www.cs.rice.edu/~keith/EMBED/dom.pdf>
 
-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<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
     dominators_given_rpo(graph, &rpo)
 }
 
-pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
-                                                 rpo: &[G::Node])
-                                                 -> Dominators<G::Node> {
+pub fn dominators_given_rpo<G: ControlFlowGraph>(
+    graph: &G,
+    rpo: &[G::Node],
+) -> Dominators<G::Node> {
     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<G::Node, usize> = IndexVec::from_elem_n(usize::default(),
-                                                                              graph.num_nodes());
+    let mut post_order_rank: IndexVec<G::Node, usize> =
+        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<G: ControlFlowGraph>(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<G: ControlFlowGraph>(graph: &G,
     }
 }
 
-fn intersect_opt<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
-                            immediate_dominators: &IndexVec<Node, Option<Node>>,
-                            node1: Option<Node>,
-                            node2: Option<Node>)
-                            -> Option<Node> {
+fn intersect_opt<Node: Idx>(
+    post_order_rank: &IndexVec<Node, usize>,
+    immediate_dominators: &IndexVec<Node, Option<Node>>,
+    node1: Option<Node>,
+    node2: Option<Node>,
+) -> Option<Node> {
     match (node1, node2) {
         (None, None) => None,
         (Some(n), None) | (None, Some(n)) => Some(n),
@@ -88,11 +92,12 @@ fn intersect_opt<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
     }
 }
 
-fn intersect<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
-                        immediate_dominators: &IndexVec<Node, Option<Node>>,
-                        mut node1: Node,
-                        mut node2: Node)
-                        -> Node {
+fn intersect<Node: Idx>(
+    post_order_rank: &IndexVec<Node, usize>,
+    immediate_dominators: &IndexVec<Node, Option<Node>>,
+    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<Node: Idx> fmt::Debug for DominatorTree<Node> {
     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("")
index 2d70b4063426d6f983707cc6e2a4cc092b5f7888..3afdc88d60279a001724064acbca44e3a1c7a091 100644 (file)
@@ -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<G: ControlFlowGraph>(graph: &G, start_node: G::Node) -> Vec<G::Node> {
+pub fn post_order_from<G: DirectedGraph + WithSuccessors + WithNumNodes>(
+    graph: &G,
+    start_node: G::Node,
+) -> Vec<G::Node> {
     post_order_from_to(graph, start_node, None)
 }
 
-pub fn post_order_from_to<G: ControlFlowGraph>(graph: &G,
-                                               start_node: G::Node,
-                                               end_node: Option<G::Node>)
-                                               -> Vec<G::Node> {
+pub fn post_order_from_to<G: DirectedGraph + WithSuccessors + WithNumNodes>(
+    graph: &G,
+    start_node: G::Node,
+    end_node: Option<G::Node>,
+) -> Vec<G::Node> {
     let mut visited: IndexVec<G::Node, bool> = IndexVec::from_elem_n(false, graph.num_nodes());
     let mut result: Vec<G::Node> = Vec::with_capacity(graph.num_nodes());
     if let Some(end_node) = end_node {
@@ -31,10 +35,12 @@ pub fn post_order_from_to<G: ControlFlowGraph>(graph: &G,
     result
 }
 
-fn post_order_walk<G: ControlFlowGraph>(graph: &G,
-                                        node: G::Node,
-                                        result: &mut Vec<G::Node>,
-                                        visited: &mut IndexVec<G::Node, bool>) {
+fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>(
+    graph: &G,
+    node: G::Node,
+    result: &mut Vec<G::Node>,
+    visited: &mut IndexVec<G::Node, bool>,
+) {
     if visited[node] {
         return;
     }
@@ -47,7 +53,10 @@ fn post_order_walk<G: ControlFlowGraph>(graph: &G,
     result.push(node);
 }
 
-pub fn reverse_post_order<G: ControlFlowGraph>(graph: &G, start_node: G::Node) -> Vec<G::Node> {
+pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(
+    graph: &G,
+    start_node: G::Node,
+) -> Vec<G::Node> {
     let mut vec = post_order_from(graph, start_node);
     vec.reverse();
     vec
index 7bf776675c6a0ad4f3482538b8457798e03a22d6..cfb4b07b50582d11fa835633656cdd7d0b7a4056 100644 (file)
 #[cfg(test)]
 mod test;
 
-pub trait ControlFlowGraph
-    where Self: for<'graph> GraphPredecessors<'graph, Item=<Self as ControlFlowGraph>::Node>,
-          Self: for<'graph> GraphSuccessors<'graph, Item=<Self as ControlFlowGraph>::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)
-                            -> <Self as GraphPredecessors<'graph>>::Iter;
-    fn successors<'graph>(&'graph self, node: Self::Node)
-                            -> <Self as GraphSuccessors<'graph>>::Iter;
 }
 
-pub trait GraphPredecessors<'graph> {
+pub trait WithSuccessors: DirectedGraph
+where
+    Self: for<'graph> GraphSuccessors<'graph, Item = <Self as DirectedGraph>::Node>,
+{
+    fn successors<'graph>(
+        &'graph self,
+        node: Self::Node,
+    ) -> <Self as GraphSuccessors<'graph>>::Iter;
+}
+
+pub trait GraphSuccessors<'graph> {
     type Item;
     type Iter: Iterator<Item = Self::Item>;
 }
 
-pub trait GraphSuccessors<'graph> {
+pub trait WithPredecessors: DirectedGraph
+where
+    Self: for<'graph> GraphPredecessors<'graph, Item = <Self as DirectedGraph>::Node>,
+{
+    fn predecessors<'graph>(
+        &'graph self,
+        node: Self::Node,
+    ) -> <Self as GraphPredecessors<'graph>>::Iter;
+}
+
+pub trait GraphPredecessors<'graph> {
     type Item;
     type Iter: Iterator<Item = Self::Item>;
 }
+
+pub trait WithStartNode: DirectedGraph {
+    fn start_node(&self) -> Self::Node;
+}
+
+pub trait ControlFlowGraph:
+    DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes
+{
+    // convenient trait
+}
+
+impl<T> ControlFlowGraph for T
+where
+    T: DirectedGraph
+        + WithStartNode
+        + WithPredecessors
+        + WithStartNode
+        + WithSuccessors
+        + WithNumNodes,
+{
+}
index 3b8b01f2ff43b5820daee85e5230dedf9d51085a..a7b763db8da293eed8ae251d6d4c3ebb5fc2ef51 100644 (file)
 
 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) -> <Self as GraphSuccessors<'iter>>::Iter {
+        (**self).successors(node)
+    }
+}
 
+impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G {
     fn predecessors<'iter>(&'iter self,
                            node: Self::Node)
                            -> <Self as GraphPredecessors<'iter>>::Iter {
         (**self).predecessors(node)
     }
-
-    fn successors<'iter>(&'iter self, node: Self::Node) -> <Self as GraphSuccessors<'iter>>::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 = <G as GraphPredecessors<'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 = <G as GraphSuccessors<'iter>>::Iter;
 }