Skip to content

introduce -Znll-facts to dump base-facts for the NLL analysis #50370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,11 @@ impl fmt::Debug for Location {
}

impl Location {
pub const START: Location = Location {
block: START_BLOCK,
statement_index: 0,
};

/// Returns the location immediately after this one within the enclosing block.
///
/// Note that if this location represents a terminator, then the
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"choose which RELRO level to use"),
nll_subminimal_causes: bool = (false, parse_bool, [UNTRACKED],
"when tracking region error causes, accept subminimal results for faster execution."),
nll_facts: bool = (false, parse_bool, [UNTRACKED],
"dump facts from NLL analysis into side files"),
disable_nll_user_type_assert: bool = (false, parse_bool, [UNTRACKED],
"disable user provided type assertion in NLL"),
trans_time_graph: bool = (false, parse_bool, [UNTRACKED],
Expand Down
123 changes: 123 additions & 0 deletions src/librustc_mir/borrow_check/location.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::mir::{BasicBlock, Location, Mir};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};

/// Maps between a MIR Location, which identifies the a particular
/// statement within a basic block, to a "rich location", which
/// identifies at a finer granularity. In particular, we distinguish
/// the *start* of a statement and the *mid-point*. The mid-point is
/// the point *just* before the statement takes effect; in particular,
/// for an assignment `A = B`, it is the point where B is about to be
/// written into A. This mid-point is a kind of hack to work around
/// our inability to track the position information at sufficient
/// granularity through outlives relations; however, the rich location
/// table serves another purpose: it compresses locations from
/// multiple words into a single u32.
crate struct LocationTable {
num_points: usize,
statements_before_block: IndexVec<BasicBlock, usize>,
}

newtype_index!(LocationIndex { DEBUG_FORMAT = "LocationIndex({})" });

#[derive(Copy, Clone, Debug)]
crate enum RichLocation {
Start(Location),
Mid(Location),
}

impl LocationTable {
crate fn new(mir: &Mir<'_>) -> Self {
let mut num_points = 0;
let statements_before_block = mir.basic_blocks()
.iter()
.map(|block_data| {
let v = num_points;
num_points += (block_data.statements.len() + 1) * 2;
v
})
.collect();

debug!(
"LocationTable(statements_before_block={:#?})",
statements_before_block
);
debug!("LocationTable: num_points={:#?}", num_points);

Self {
num_points,
statements_before_block,
}
}

crate fn all_points(&self) -> impl Iterator<Item = LocationIndex> {
(0..self.num_points).map(LocationIndex::new)
}

crate fn start_index(&self, location: Location) -> LocationIndex {
let Location {
block,
statement_index,
} = location;
let start_index = self.statements_before_block[block];
LocationIndex::new(start_index + statement_index * 2)
}

crate fn mid_index(&self, location: Location) -> LocationIndex {
let Location {
block,
statement_index,
} = location;
let start_index = self.statements_before_block[block];
LocationIndex::new(start_index + statement_index * 2 + 1)
}

crate fn to_location(&self, index: LocationIndex) -> RichLocation {
let point_index = index.index();

// Find the basic block. We have a vector with the
// starting index of the statement in each block. Imagine
// we have statement #22, and we have a vector like:
//
// [0, 10, 20]
//
// In that case, this represents point_index 2 of
// basic block BB2. We know this because BB0 accounts for
// 0..10, BB1 accounts for 11..20, and BB2 accounts for
// 20...
//
// To compute this, we could do a binary search, but
// because I am lazy we instead iterate through to find
// the last point where the "first index" (0, 10, or 20)
// was less than the statement index (22). In our case, this will
// be (BB2, 20).
let (block, &first_index) = self.statements_before_block
.iter_enumerated()
.filter(|(_, first_index)| **first_index <= point_index)
.last()
.unwrap();

let statement_index = (point_index - first_index) / 2;
if index.is_start() {
RichLocation::Start(Location { block, statement_index })
} else {
RichLocation::Mid(Location { block, statement_index })
}
}
}

impl LocationIndex {
fn is_start(&self) -> bool {
// even indices are start points; odd indices are mid points
(self.index() % 2) == 0
}
}
4 changes: 4 additions & 0 deletions src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ use std::iter;

use self::borrow_set::{BorrowSet, BorrowData};
use self::flows::Flows;
use self::location::LocationTable;
use self::prefixes::PrefixSet;
use self::MutateMode::{JustWrite, WriteAndRead};

crate mod borrow_set;
mod error_reporting;
mod flows;
mod location;
crate mod place_ext;
mod prefixes;

Expand Down Expand Up @@ -110,6 +112,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
let mut mir: Mir<'tcx> = input_mir.clone();
let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut mir);
let mir = &mir; // no further changes
let location_table = &LocationTable::new(mir);

let move_data: MoveData<'tcx> = match MoveData::gather_moves(mir, tcx) {
Ok(move_data) => move_data,
Expand Down Expand Up @@ -199,6 +202,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
def_id,
free_regions,
mir,
location_table,
param_env,
&mut flow_inits,
&mdpe.move_data,
Expand Down
Loading