Skip to content

Commit bce32b5

Browse files
committed
Auto merge of #51987 - nikomatsakis:nll-region-infer-scc, r=pnkfelix
nll experiment: compute SCCs instead of iterative region solving This is an attempt to speed up region solving by replacing the current iterative dataflow with a SCC computation. The idea is to detect cycles (SCCs) amongst region constraints and then compute just one value per cycle. The graph with all cycles removed is of course a DAG, so we can then solve constraints "bottom up" once the liveness values are known. I kinda ran out of time this morning so the last commit is a bit sloppy but I wanted to get this posted, let travis run on it, and maybe do a perf run, before I clean it up.
2 parents c0955a3 + 6918c17 commit bce32b5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1728
-919
lines changed

src/librustc/cfg/construct.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use rustc_data_structures::graph;
1211
use cfg::*;
1312
use middle::region;
14-
use ty::{self, TyCtxt};
13+
use rustc_data_structures::graph::implementation as graph;
1514
use syntax::ptr::P;
15+
use ty::{self, TyCtxt};
1616

1717
use hir::{self, PatKind};
1818
use hir::def_id::DefId;

src/librustc/cfg/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Module that constructs a control-flow graph representing an item.
1212
//! Uses `Graph` as the underlying representation.
1313
14-
use rustc_data_structures::graph;
14+
use rustc_data_structures::graph::implementation as graph;
1515
use ty::TyCtxt;
1616
use hir;
1717
use hir::def_id::DefId;

src/librustc/dep_graph/query.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
// except according to those terms.
1010

1111
use rustc_data_structures::fx::FxHashMap;
12-
use rustc_data_structures::graph::{Direction, INCOMING, Graph, NodeIndex, OUTGOING};
12+
use rustc_data_structures::graph::implementation::{
13+
Direction, INCOMING, Graph, NodeIndex, OUTGOING
14+
};
1315

1416
use super::DepNode;
1517

src/librustc/infer/lexical_region_resolve/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use infer::region_constraints::VerifyBound;
2020
use middle::free_region::RegionRelations;
2121
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
2222
use rustc_data_structures::fx::FxHashSet;
23-
use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
23+
use rustc_data_structures::graph::implementation::{Graph, Direction, NodeIndex, INCOMING, OUTGOING};
2424
use std::fmt;
2525
use std::u32;
2626
use ty::{self, TyCtxt};
@@ -99,7 +99,7 @@ struct RegionAndOrigin<'tcx> {
9999
origin: SubregionOrigin<'tcx>,
100100
}
101101

102-
type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>;
102+
type RegionGraph<'tcx> = Graph<(), Constraint<'tcx>>;
103103

104104
struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
105105
region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>,
@@ -501,7 +501,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
501501
fn construct_graph(&self) -> RegionGraph<'tcx> {
502502
let num_vars = self.num_vars();
503503

504-
let mut graph = graph::Graph::new();
504+
let mut graph = Graph::new();
505505

506506
for _ in 0..num_vars {
507507
graph.add_node(());
@@ -550,9 +550,9 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
550550
// Errors in expanding nodes result from a lower-bound that is
551551
// not contained by an upper-bound.
552552
let (mut lower_bounds, lower_dup) =
553-
self.collect_concrete_regions(graph, node_idx, graph::INCOMING, dup_vec);
553+
self.collect_concrete_regions(graph, node_idx, INCOMING, dup_vec);
554554
let (mut upper_bounds, upper_dup) =
555-
self.collect_concrete_regions(graph, node_idx, graph::OUTGOING, dup_vec);
555+
self.collect_concrete_regions(graph, node_idx, OUTGOING, dup_vec);
556556

557557
if lower_dup || upper_dup {
558558
return;

src/librustc/middle/dataflow.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::mem;
2222
use std::usize;
2323
use syntax::print::pprust::PrintState;
2424

25-
use rustc_data_structures::graph::OUTGOING;
25+
use rustc_data_structures::graph::implementation::OUTGOING;
2626

2727
use util::nodemap::FxHashMap;
2828
use hir;

src/librustc/mir/mod.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ use mir::interpret::{EvalErrorKind, Scalar, Value};
2121
use mir::visit::MirVisitable;
2222
use rustc_apfloat::ieee::{Double, Single};
2323
use rustc_apfloat::Float;
24-
use rustc_data_structures::control_flow_graph::dominators::{dominators, Dominators};
25-
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
26-
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
24+
use rustc_data_structures::graph::dominators::{dominators, Dominators};
25+
use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
2726
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
2827
use rustc_data_structures::small_vec::SmallVec;
2928
use rustc_data_structures::sync::Lrc;
@@ -2289,23 +2288,32 @@ fn item_path_str(def_id: DefId) -> String {
22892288
ty::tls::with(|tcx| tcx.item_path_str(def_id))
22902289
}
22912290

2292-
impl<'tcx> ControlFlowGraph for Mir<'tcx> {
2291+
impl<'tcx> graph::DirectedGraph for Mir<'tcx> {
22932292
type Node = BasicBlock;
2293+
}
22942294

2295+
impl<'tcx> graph::WithNumNodes for Mir<'tcx> {
22952296
fn num_nodes(&self) -> usize {
22962297
self.basic_blocks.len()
22972298
}
2299+
}
22982300

2301+
impl<'tcx> graph::WithStartNode for Mir<'tcx> {
22992302
fn start_node(&self) -> Self::Node {
23002303
START_BLOCK
23012304
}
2305+
}
23022306

2307+
impl<'tcx> graph::WithPredecessors for Mir<'tcx> {
23032308
fn predecessors<'graph>(
23042309
&'graph self,
23052310
node: Self::Node,
23062311
) -> <Self as GraphPredecessors<'graph>>::Iter {
23072312
self.predecessors_for(node).clone().into_iter()
23082313
}
2314+
}
2315+
2316+
impl<'tcx> graph::WithSuccessors for Mir<'tcx> {
23092317
fn successors<'graph>(
23102318
&'graph self,
23112319
node: Self::Node,
@@ -2314,12 +2322,12 @@ impl<'tcx> ControlFlowGraph for Mir<'tcx> {
23142322
}
23152323
}
23162324

2317-
impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> {
2325+
impl<'a, 'b> graph::GraphPredecessors<'b> for Mir<'a> {
23182326
type Item = BasicBlock;
23192327
type Iter = IntoIter<BasicBlock>;
23202328
}
23212329

2322-
impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> {
2330+
impl<'a, 'b> graph::GraphSuccessors<'b> for Mir<'a> {
23232331
type Item = BasicBlock;
23242332
type Iter = iter::Cloned<Successors<'b>>;
23252333
}

src/librustc_codegen_llvm/mir/analyze.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//! which do not.
1313
1414
use rustc_data_structures::bitvec::BitVector;
15-
use rustc_data_structures::control_flow_graph::dominators::Dominators;
15+
use rustc_data_structures::graph::dominators::Dominators;
1616
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
1717
use rustc::mir::{self, Location, TerminatorKind};
1818
use rustc::mir::visit::{Visitor, PlaceContext};

src/librustc_data_structures/control_flow_graph/mod.rs

-42
This file was deleted.

src/librustc_data_structures/control_flow_graph/dominators/mod.rs src/librustc_data_structures/graph/dominators/mod.rs

+36-31
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
//! Rice Computer Science TS-06-33870
1515
//! <https://www.cs.rice.edu/~keith/EMBED/dom.pdf>
1616
17-
use super::ControlFlowGraph;
17+
use super::super::indexed_vec::{Idx, IndexVec};
1818
use super::iterate::reverse_post_order;
19-
use super::super::indexed_vec::{IndexVec, Idx};
19+
use super::ControlFlowGraph;
2020

2121
use std::fmt;
2222

@@ -29,15 +29,16 @@ pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
2929
dominators_given_rpo(graph, &rpo)
3030
}
3131

32-
pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
33-
rpo: &[G::Node])
34-
-> Dominators<G::Node> {
32+
pub fn dominators_given_rpo<G: ControlFlowGraph>(
33+
graph: &G,
34+
rpo: &[G::Node],
35+
) -> Dominators<G::Node> {
3536
let start_node = graph.start_node();
3637
assert_eq!(rpo[0], start_node);
3738

3839
// compute the post order index (rank) for each node
39-
let mut post_order_rank: IndexVec<G::Node, usize> = IndexVec::from_elem_n(usize::default(),
40-
graph.num_nodes());
40+
let mut post_order_rank: IndexVec<G::Node, usize> =
41+
IndexVec::from_elem_n(usize::default(), graph.num_nodes());
4142
for (index, node) in rpo.iter().rev().cloned().enumerate() {
4243
post_order_rank[node] = index;
4344
}
@@ -56,10 +57,12 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
5657
if immediate_dominators[pred].is_some() {
5758
// (*)
5859
// (*) dominators for `pred` have been calculated
59-
new_idom = intersect_opt(&post_order_rank,
60-
&immediate_dominators,
61-
new_idom,
62-
Some(pred));
60+
new_idom = intersect_opt(
61+
&post_order_rank,
62+
&immediate_dominators,
63+
new_idom,
64+
Some(pred),
65+
);
6366
}
6467
}
6568

@@ -76,23 +79,25 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
7679
}
7780
}
7881

79-
fn intersect_opt<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
80-
immediate_dominators: &IndexVec<Node, Option<Node>>,
81-
node1: Option<Node>,
82-
node2: Option<Node>)
83-
-> Option<Node> {
82+
fn intersect_opt<Node: Idx>(
83+
post_order_rank: &IndexVec<Node, usize>,
84+
immediate_dominators: &IndexVec<Node, Option<Node>>,
85+
node1: Option<Node>,
86+
node2: Option<Node>,
87+
) -> Option<Node> {
8488
match (node1, node2) {
8589
(None, None) => None,
8690
(Some(n), None) | (None, Some(n)) => Some(n),
8791
(Some(n1), Some(n2)) => Some(intersect(post_order_rank, immediate_dominators, n1, n2)),
8892
}
8993
}
9094

91-
fn intersect<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
92-
immediate_dominators: &IndexVec<Node, Option<Node>>,
93-
mut node1: Node,
94-
mut node2: Node)
95-
-> Node {
95+
fn intersect<Node: Idx>(
96+
post_order_rank: &IndexVec<Node, usize>,
97+
immediate_dominators: &IndexVec<Node, Option<Node>>,
98+
mut node1: Node,
99+
mut node2: Node,
100+
) -> Node {
96101
while node1 != node2 {
97102
while post_order_rank[node1] < post_order_rank[node2] {
98103
node1 = immediate_dominators[node1].unwrap();
@@ -176,11 +181,13 @@ impl<Node: Idx> DominatorTree<Node> {
176181

177182
impl<Node: Idx> fmt::Debug for DominatorTree<Node> {
178183
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
179-
fmt::Debug::fmt(&DominatorTreeNode {
180-
tree: self,
181-
node: self.root,
182-
},
183-
fmt)
184+
fmt::Debug::fmt(
185+
&DominatorTreeNode {
186+
tree: self,
187+
node: self.root,
188+
},
189+
fmt,
190+
)
184191
}
185192
}
186193

@@ -194,11 +201,9 @@ impl<'tree, Node: Idx> fmt::Debug for DominatorTreeNode<'tree, Node> {
194201
let subtrees: Vec<_> = self.tree
195202
.children(self.node)
196203
.iter()
197-
.map(|&child| {
198-
DominatorTreeNode {
199-
tree: self.tree,
200-
node: child,
201-
}
204+
.map(|&child| DominatorTreeNode {
205+
tree: self.tree,
206+
node: child,
202207
})
203208
.collect();
204209
fmt.debug_tuple("")

0 commit comments

Comments
 (0)