Skip to content
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

[feedback] per-edge dataflow #47664

Closed
50 changes: 50 additions & 0 deletions src/librustc_data_structures/access_tracker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2015 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 std::ops::{Deref, DerefMut};

/// Takes ownership of `T` and tracks whether it was accessed mutably
/// (via `DerefMut`). You can access this via the `maybe_mutated` fn.
#[derive(Clone, Debug)]
pub struct AccessTracker<T> {
value: T,
mutated: bool,
}

impl<T> AccessTracker<T> {
pub fn new(value: T) -> Self {
AccessTracker { value, mutated: false }
}

/// True if the owned value was accessed mutably (so far).
pub fn maybe_mutated(this: &Self) -> bool {
this.mutated
}

pub fn into_inner(this: Self) -> (T, bool) {
(this.value, this.mutated)
}
}

impl<T> Deref for AccessTracker<T> {
type Target = T;

fn deref(&self) -> &T {
&self.value
}
}

impl<T> DerefMut for AccessTracker<T> {
fn deref_mut(&mut self) -> &mut T {
self.mutated = true;
&mut self.value
}
}

5 changes: 5 additions & 0 deletions src/librustc_data_structures/indexed_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ impl<T: Idx> IdxSet<T> {
}
}

/// True if there are no elements
pub fn is_empty(&self) -> bool {
self.bits.iter().all(|&b| b == 0)
}

/// Removes all elements
pub fn clear(&mut self) {
for b in &mut self.bits {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ extern crate stable_deref_trait;
pub use rustc_serialize::hex::ToHex;

pub mod array_vec;
pub mod access_tracker;
pub mod accumulate_vec;
pub mod small_vec;
pub mod base_n;
Expand Down
31 changes: 18 additions & 13 deletions src/librustc_mir/dataflow/impls/borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ use rustc::ty::RegionKind;
use rustc::ty::RegionKind::ReScope;
use rustc::util::nodemap::{FxHashMap, FxHashSet};

use rustc_data_structures::access_tracker::AccessTracker;
use rustc_data_structures::bitslice::{BitwiseOperator};
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};

use dataflow::{BitDenotation, BlockSets, InitialFlow};
use dataflow::{BitDenotation, BlockSets, EdgeKind, InitialFlow};
pub use dataflow::indexes::{BorrowIndex, ReserveOrActivateIndex};
use borrow_check::nll::region_infer::RegionInferenceContext;
use borrow_check::nll::ToRegionVid;
Expand Down Expand Up @@ -677,12 +678,14 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Reservations<'a, 'gcx, 'tcx> {
self.0.terminator_effect_on_borrows(sets, location, false);
}

fn propagate_call_return(&self,
_in_out: &mut IdxSet<ReserveOrActivateIndex>,
_call_bb: mir::BasicBlock,
_dest_bb: mir::BasicBlock,
_dest_place: &mir::Place) {
// there are no effects on borrows from method call return...
fn edge_effect(
&self,
_sets: &mut AccessTracker<&mut BlockSets<Self::Idx>>,
_source_block: mir::BasicBlock,
_edge_kind: EdgeKind<'_>,
_target_terminator: mir::BasicBlock,
) {
// there are no effects on borrows from edges...
//
// ... but if overwriting a place can affect flow state, then
// latter is not true; see NOTE on Assign case in
Expand Down Expand Up @@ -738,12 +741,14 @@ impl<'a, 'gcx, 'tcx> BitDenotation for ActiveBorrows<'a, 'gcx, 'tcx> {
self.0.terminator_effect_on_borrows(sets, location, true);
}

fn propagate_call_return(&self,
_in_out: &mut IdxSet<ReserveOrActivateIndex>,
_call_bb: mir::BasicBlock,
_dest_bb: mir::BasicBlock,
_dest_place: &mir::Place) {
// there are no effects on borrows from method call return...
fn edge_effect(
&self,
_sets: &mut AccessTracker<&mut BlockSets<Self::Idx>>,
_source_block: mir::BasicBlock,
_edge_kind: EdgeKind<'_>,
_target_terminator: mir::BasicBlock,
) {
// there are no effects on borrows from edges...
//
// ... but If overwriting a place can affect flow state, then
// latter is not true; see NOTE on Assign case in
Expand Down
Loading