deconstruct the `ControlFlowGraph` trait into more granular traits
This commit is contained in:
parent
5fa240e96a
commit
28c483b946
|
@ -22,7 +22,7 @@ use mir::visit::MirVisitable;
|
|||
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 @@ impl<'tcx> ControlFlowGraph for Mir<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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>>;
|
||||
}
|
||||
|
|
|
@ -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("")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,18 +17,37 @@ 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 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 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> {
|
||||
|
@ -36,7 +55,23 @@ pub trait GraphPredecessors<'graph> {
|
|||
type Iter: Iterator<Item = Self::Item>;
|
||||
}
|
||||
|
||||
pub trait GraphSuccessors<'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,
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
fn predecessors<'iter>(&'iter self,
|
||||
node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'iter>>::Iter {
|
||||
(**self).predecessors(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<'iter, 'graph, G: ControlFlowGraph> GraphPredecessors<'iter> for &'graph G {
|
||||
impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G {
|
||||
fn predecessors<'iter>(&'iter self,
|
||||
node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'iter>>::Iter {
|
||||
(**self).predecessors(node)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue