about summary refs log tree commit diff
path: root/src/librustc_data_structures
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-07-01 16:54:01 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-07-12 00:38:40 -0400
commit28c483b9462327bcda109e327251b5800ceb3fe5 (patch)
tree3a90d6d94e51ac9e9c6ac2521a6b545048fee7d1 /src/librustc_data_structures
parent5fa240e96a5f5a0f4f819feda34fd6927cf7d60d (diff)
downloadrust-28c483b9462327bcda109e327251b5800ceb3fe5.tar.gz
rust-28c483b9462327bcda109e327251b5800ceb3fe5.zip
deconstruct the `ControlFlowGraph` trait into more granular traits
Diffstat (limited to 'src/librustc_data_structures')
-rw-r--r--src/librustc_data_structures/control_flow_graph/dominators/mod.rs67
-rw-r--r--src/librustc_data_structures/control_flow_graph/iterate/mod.rs31
-rw-r--r--src/librustc_data_structures/control_flow_graph/mod.rs57
-rw-r--r--src/librustc_data_structures/control_flow_graph/reference.rs22
4 files changed, 117 insertions, 60 deletions
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
 //! <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 @@ impl<Node: Idx> DominatorTree<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 @@ impl<'tree, Node: Idx> fmt::Debug for DominatorTreeNode<'tree, Node> {
         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<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
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 @@ mod reference;
 #[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,
+{
+}
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) -> <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;
 }