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;
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,
}
}
-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>>;
}
//! 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;
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;
}
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),
+ );
}
}
}
}
-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),
}
}
-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();
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,
+ )
}
}
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("")
// 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 {
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;
}
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
#[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,
+{
+}
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;
}