Skip to content

Commit

Permalink
Refactored DFS to be much cleaner. Added continue after noting that b…
Browse files Browse the repository at this point in the history
…orrow is out of scope at location.
  • Loading branch information
davidtwco committed May 29, 2018
1 parent 24ee506 commit 4500fe0
Showing 1 changed file with 27 additions and 99 deletions.
126 changes: 27 additions & 99 deletions src/librustc_mir/dataflow/impls/borrows.rs
Expand Up @@ -15,13 +15,13 @@ use rustc;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::middle::region;
use rustc::mir::{self, Location, Place, Mir, TerminatorKind};
use rustc::mir::{self, Location, Place, Mir};
use rustc::ty::TyCtxt;
use rustc::ty::{RegionKind, RegionVid};
use rustc::ty::RegionKind::ReScope;

use rustc_data_structures::bitslice::BitwiseOperator;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_set::IdxSet;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::sync::Lrc;
Expand Down Expand Up @@ -60,104 +60,33 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
borrow_index: BorrowIndex,
borrow_region: RegionVid,
location: Location,
visited_locations: &mut Vec<Location>
) {
// Check if we have already visited this location and skip
// it if we have - avoids infinite loops.
if visited_locations.contains(&location) { return; }
visited_locations.push(location.clone());

// Next, add the borrow index to the current location's vector if the region does
// not contain the point at that location (or create a new vector if required).
if !regioncx.region_contains_point(borrow_region, location) {
borrows_out_of_scope_at_location
.entry(location.clone())
.and_modify(|m| m.push(borrow_index))
.or_insert(vec![ borrow_index ]);
}
// Keep track of places we've locations to check and locations that we have checked.
let mut stack = vec![ location ];
let mut visited = FxHashSet();
visited.insert(location);

while let Some(location) = stack.pop() {
// If region does not contain a point at the location, then add to list and skip
// successor locations.
if !regioncx.region_contains_point(borrow_region, location) {
borrows_out_of_scope_at_location
.entry(location)
.or_insert(vec![])
.push(borrow_index);
continue;
}

let bb_data = &mir[location.block];
// If we are past the last statement, then check the terminator
// to determine which location to proceed to.
if location.statement_index == bb_data.statements.len() {
// Add successors to locations to visit, if not visited before.
let bb_data = &mir[location.block];
if let Some(ref terminator) = bb_data.terminator {
match terminator.kind {
TerminatorKind::Goto { target } |
TerminatorKind::FalseEdges { real_target: target, .. } |
TerminatorKind::FalseUnwind { real_target: target, .. } => {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, target.start_location(),
visited_locations
);
},
TerminatorKind::SwitchInt { ref targets, .. } => {
for block in targets {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, block.start_location(),
visited_locations
);
}
},
TerminatorKind::Drop { target, unwind, .. } |
TerminatorKind::DropAndReplace { target, unwind, .. } => {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, target.start_location(),
visited_locations
);

if let Some(unwind_block) = unwind {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, unwind_block.start_location(),
visited_locations
);
}
},
TerminatorKind::Call { ref destination, cleanup, .. } => {
if let Some((_, block)) = destination {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, block.start_location(),
visited_locations
);
}

if let Some(block) = cleanup {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, block.start_location(),
visited_locations
);
}
},
TerminatorKind::Assert { target, cleanup, .. } |
TerminatorKind::Yield { resume: target, drop: cleanup, .. } => {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, target.start_location(),
visited_locations
);

if let Some(block) = cleanup {
precompute_borrows_out_of_scope(
mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region, block.start_location(),
visited_locations
);
}
},
_ => {},
};
};
// If we're not on the last statement, then go to the next
// statement in this block.
} else {
precompute_borrows_out_of_scope(mir, regioncx, borrows_out_of_scope_at_location,
borrow_index, borrow_region,
location.successor_within_block(), visited_locations);
for block in terminator.successors() {
let loc = block.start_location();
if visited.insert(loc) {
stack.push(loc);
}
}
}
}
}

Expand All @@ -182,8 +111,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {

precompute_borrows_out_of_scope(mir, &nonlexical_regioncx,
&mut borrows_out_of_scope_at_location,
borrow_index, borrow_region, location,
&mut Vec::new());
borrow_index, borrow_region, location);
}

Borrows {
Expand Down

0 comments on commit 4500fe0

Please sign in to comment.