Skip to content

Commit b894a62

Browse files
committed
implement liveness tracing, remove old liveness system
1 parent fe21d78 commit b894a62

File tree

14 files changed

+963
-338
lines changed

14 files changed

+963
-338
lines changed

src/librustc/mir/mod.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,12 @@ impl<'tcx> Mir<'tcx> {
194194
}
195195

196196
#[inline]
197-
pub fn predecessors(&self) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> {
197+
pub fn predecessors(&self) -> ReadGuard<'_, IndexVec<BasicBlock, Vec<BasicBlock>>> {
198198
self.cache.predecessors(self)
199199
}
200200

201201
#[inline]
202-
pub fn predecessors_for(&self, bb: BasicBlock) -> ReadGuard<Vec<BasicBlock>> {
202+
pub fn predecessors_for(&self, bb: BasicBlock) -> ReadGuard<'_, Vec<BasicBlock>> {
203203
ReadGuard::map(self.predecessors(), |p| &p[bb])
204204
}
205205

@@ -328,6 +328,14 @@ impl<'tcx> Mir<'tcx> {
328328
pub fn return_ty(&self) -> Ty<'tcx> {
329329
self.local_decls[RETURN_PLACE].ty
330330
}
331+
332+
/// Get the location of the terminator for the given block
333+
pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
334+
Location {
335+
block: bb,
336+
statement_index: self[bb].statements.len(),
337+
}
338+
}
331339
}
332340

333341
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]

src/librustc_data_structures/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
2121
html_root_url = "https://doc.rust-lang.org/nightly/")]
2222

23+
#![feature(in_band_lifetimes)]
2324
#![feature(unboxed_closures)]
2425
#![feature(fn_traits)]
2526
#![feature(unsize)]
@@ -77,6 +78,7 @@ pub mod tiny_list;
7778
pub mod transitive_relation;
7879
pub mod tuple_slice;
7980
pub use ena::unify;
81+
pub mod vec_linked_list;
8082
pub mod work_queue;
8183

8284
pub struct OnDrop<F: Fn()>(pub F);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use indexed_vec::{Idx, IndexVec};
12+
13+
pub fn iter<Ls>(
14+
first: Option<Ls::LinkIndex>,
15+
links: &'a Ls,
16+
) -> impl Iterator<Item = Ls::LinkIndex> + 'a
17+
where
18+
Ls: Links,
19+
{
20+
VecLinkedListIterator {
21+
links: links,
22+
current: first,
23+
}
24+
}
25+
26+
pub struct VecLinkedListIterator<Ls>
27+
where
28+
Ls: Links,
29+
{
30+
links: Ls,
31+
current: Option<Ls::LinkIndex>,
32+
}
33+
34+
impl<Ls> Iterator for VecLinkedListIterator<Ls>
35+
where
36+
Ls: Links,
37+
{
38+
type Item = Ls::LinkIndex;
39+
40+
fn next(&mut self) -> Option<Ls::LinkIndex> {
41+
if let Some(c) = self.current {
42+
self.current = <Ls as Links>::next(&self.links, c);
43+
Some(c)
44+
} else {
45+
None
46+
}
47+
}
48+
}
49+
50+
pub trait Links {
51+
type LinkIndex: Copy;
52+
53+
fn next(links: &Self, index: Self::LinkIndex) -> Option<Self::LinkIndex>;
54+
}
55+
56+
impl<Ls> Links for &Ls
57+
where
58+
Ls: Links,
59+
{
60+
type LinkIndex = Ls::LinkIndex;
61+
62+
fn next(links: &Self, index: Ls::LinkIndex) -> Option<Ls::LinkIndex> {
63+
<Ls as Links>::next(links, index)
64+
}
65+
}
66+
67+
pub trait LinkElem {
68+
type LinkIndex: Copy;
69+
70+
fn next(elem: &Self) -> Option<Self::LinkIndex>;
71+
}
72+
73+
impl<L, E> Links for IndexVec<L, E>
74+
where
75+
E: LinkElem<LinkIndex = L>,
76+
L: Idx,
77+
{
78+
type LinkIndex = L;
79+
80+
fn next(links: &Self, index: L) -> Option<L> {
81+
<E as LinkElem>::next(&links[index])
82+
}
83+
}

src/librustc_mir/borrow_check/flows.rs

+4
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ impl<'b, 'gcx, 'tcx> FlowsAtLocation for Flows<'b, 'gcx, 'tcx> {
8989
each_flow!(self, reset_to_entry_of(bb));
9090
}
9191

92+
fn reset_to_exit_of(&mut self, bb: BasicBlock) {
93+
each_flow!(self, reset_to_exit_of(bb));
94+
}
95+
9296
fn reconstruct_statement_effect(&mut self, location: Location) {
9397
each_flow!(self, reconstruct_statement_effect(location));
9498
}

src/librustc_mir/borrow_check/nll/mod.rs

+4-87
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use borrow_check::borrow_set::BorrowSet;
1212
use borrow_check::location::{LocationIndex, LocationTable};
1313
use borrow_check::nll::facts::AllFactsExt;
1414
use borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
15-
use borrow_check::nll::type_check::liveness::liveness_map::{NllLivenessMap, LocalWithRegion};
15+
use borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap;
1616
use borrow_check::nll::region_infer::values::RegionValueElements;
1717
use dataflow::indexes::BorrowIndex;
1818
use dataflow::move_paths::MoveData;
@@ -22,22 +22,19 @@ use rustc::hir::def_id::DefId;
2222
use rustc::infer::InferCtxt;
2323
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
2424
use rustc::ty::{self, RegionKind, RegionVid};
25-
use rustc::util::nodemap::FxHashMap;
2625
use rustc_errors::Diagnostic;
27-
use std::collections::BTreeSet;
2826
use std::fmt::Debug;
2927
use std::env;
3028
use std::io;
3129
use std::path::PathBuf;
3230
use std::rc::Rc;
3331
use std::str::FromStr;
3432
use transform::MirSource;
35-
use util::liveness::{LivenessResults, LiveVarSet};
3633

3734
use self::mir_util::PassWhere;
3835
use polonius_engine::{Algorithm, Output};
3936
use util as mir_util;
40-
use util::pretty::{self, ALIGN};
37+
use util::pretty;
4138

4239
mod constraint_generation;
4340
pub mod explain_borrow;
@@ -111,8 +108,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
111108
let MirTypeckResults {
112109
constraints,
113110
universal_region_relations,
114-
liveness,
115-
liveness_map,
116111
} = type_check::type_check(
117112
infcx,
118113
param_env,
@@ -205,8 +200,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
205200
// write unit-tests, as well as helping with debugging.
206201
dump_mir_results(
207202
infcx,
208-
&liveness,
209-
&liveness_map,
210203
MirSource::item(def_id),
211204
&mir,
212205
&regioncx,
@@ -222,8 +215,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
222215

223216
fn dump_mir_results<'a, 'gcx, 'tcx>(
224217
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
225-
liveness: &LivenessResults<LocalWithRegion>,
226-
liveness_map: &NllLivenessMap,
227218
source: MirSource,
228219
mir: &Mir<'tcx>,
229220
regioncx: &RegionInferenceContext,
@@ -233,34 +224,6 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
233224
return;
234225
}
235226

236-
let regular_liveness_per_location: FxHashMap<_, _> = mir
237-
.basic_blocks()
238-
.indices()
239-
.flat_map(|bb| {
240-
let mut results = vec![];
241-
liveness
242-
.regular
243-
.simulate_block(&mir, bb, liveness_map, |location, local_set| {
244-
results.push((location, local_set.clone()));
245-
});
246-
results
247-
})
248-
.collect();
249-
250-
let drop_liveness_per_location: FxHashMap<_, _> = mir
251-
.basic_blocks()
252-
.indices()
253-
.flat_map(|bb| {
254-
let mut results = vec![];
255-
liveness
256-
.drop
257-
.simulate_block(&mir, bb, liveness_map, |location, local_set| {
258-
results.push((location, local_set.clone()));
259-
});
260-
results
261-
})
262-
.collect();
263-
264227
mir_util::dump_mir(
265228
infcx.tcx,
266229
None,
@@ -283,26 +246,10 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
283246
}
284247
}
285248

286-
PassWhere::BeforeLocation(location) => {
287-
let s = live_variable_set(
288-
&regular_liveness_per_location[&location],
289-
&drop_liveness_per_location[&location],
290-
);
291-
writeln!(
292-
out,
293-
"{:ALIGN$} | Live variables on entry to {:?}: {}",
294-
"",
295-
location,
296-
s,
297-
ALIGN = ALIGN
298-
)?;
249+
PassWhere::BeforeLocation(_) => {
299250
}
300251

301-
// After each basic block, dump out the values
302-
// that are live on exit from the basic block.
303-
PassWhere::AfterTerminator(bb) => {
304-
let s = live_variable_set(&liveness.regular.outs[bb], &liveness.drop.outs[bb]);
305-
writeln!(out, " | Live variables on exit from {:?}: {}", bb, s)?;
252+
PassWhere::AfterTerminator(_) => {
306253
}
307254

308255
PassWhere::BeforeBlock(_) | PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
@@ -420,33 +367,3 @@ impl ToRegionVid for RegionVid {
420367
self
421368
}
422369
}
423-
424-
fn live_variable_set(
425-
regular: &LiveVarSet<LocalWithRegion>,
426-
drops: &LiveVarSet<LocalWithRegion>
427-
) -> String {
428-
// sort and deduplicate:
429-
let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
430-
431-
// construct a string with each local, including `(drop)` if it is
432-
// only dropped, versus a regular use.
433-
let mut string = String::new();
434-
for local in all_locals {
435-
string.push_str(&format!("{:?}", local));
436-
437-
if !regular.contains(&local) {
438-
assert!(drops.contains(&local));
439-
string.push_str(" (drop)");
440-
}
441-
442-
string.push_str(", ");
443-
}
444-
445-
let len = if string.is_empty() {
446-
0
447-
} else {
448-
string.len() - 2
449-
};
450-
451-
format!("[{}]", &string[..len])
452-
}

src/librustc_mir/borrow_check/nll/region_infer/values.rs

+41-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use rustc::mir::{BasicBlock, Location, Mir};
1212
use rustc::ty::{self, RegionVid};
13-
use rustc_data_structures::bitvec::SparseBitMatrix;
13+
use rustc_data_structures::bitvec::{BitArray, SparseBitMatrix};
1414
use rustc_data_structures::indexed_vec::Idx;
1515
use rustc_data_structures::indexed_vec::IndexVec;
1616
use std::fmt::Debug;
@@ -47,8 +47,13 @@ impl RegionValueElements {
4747
}
4848
}
4949

50+
/// Total number of point indices
51+
crate fn num_points(&self) -> usize {
52+
self.num_points
53+
}
54+
5055
/// Converts a `Location` into a `PointIndex`. O(1).
51-
fn point_from_location(&self, location: Location) -> PointIndex {
56+
crate fn point_from_location(&self, location: Location) -> PointIndex {
5257
let Location {
5358
block,
5459
statement_index,
@@ -57,6 +62,12 @@ impl RegionValueElements {
5762
PointIndex::new(start_index + statement_index)
5863
}
5964

65+
/// Converts a `Location` into a `PointIndex`. O(1).
66+
crate fn entry_point(&self, block: BasicBlock) -> PointIndex {
67+
let start_index = self.statements_before_block[block];
68+
PointIndex::new(start_index)
69+
}
70+
6071
/// Converts a `PointIndex` back to a location. O(N) where N is
6172
/// the number of blocks; could be faster if we ever cared.
6273
crate fn to_location(&self, i: PointIndex) -> Location {
@@ -92,6 +103,15 @@ impl RegionValueElements {
92103
statement_index: point_index - first_index,
93104
}
94105
}
106+
107+
/// Returns an iterator of each basic block and the first point
108+
/// index within the block; the point indices for all statements
109+
/// within the block follow afterwards.
110+
crate fn head_indices(&self) -> impl Iterator<Item = (BasicBlock, PointIndex)> + '_ {
111+
self.statements_before_block
112+
.iter_enumerated()
113+
.map(move |(bb, &first_index)| (bb, PointIndex::new(first_index)))
114+
}
95115
}
96116

97117
/// A single integer representing a `Location` in the MIR control-flow
@@ -151,6 +171,13 @@ impl<N: Idx> LivenessValues<N> {
151171
self.points.add(row, index)
152172
}
153173

174+
/// Adds all the elements in the given bit array into the given
175+
/// region. Returns true if any of them are newly added.
176+
crate fn add_elements(&mut self, row: N, locations: &BitArray<PointIndex>) -> bool {
177+
debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations);
178+
self.points.merge_into(row, locations)
179+
}
180+
154181
/// Adds all the control-flow points to the values for `r`.
155182
crate fn add_all_points(&mut self, row: N) {
156183
self.points.add_all(row);
@@ -366,6 +393,18 @@ impl ToElementIndex for ty::UniverseIndex {
366393
}
367394
}
368395

396+
crate fn location_set_str(
397+
elements: &RegionValueElements,
398+
points: impl IntoIterator<Item = PointIndex>,
399+
) -> String {
400+
region_value_str(
401+
points
402+
.into_iter()
403+
.map(|p| elements.to_location(p))
404+
.map(RegionElement::Location),
405+
)
406+
}
407+
369408
fn region_value_str(elements: impl IntoIterator<Item = RegionElement>) -> String {
370409
let mut result = String::new();
371410
result.push_str("{");

0 commit comments

Comments
 (0)