Skip to content

Commit

Permalink
Move PointIndex to mir_dataflow.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Oct 21, 2023
1 parent 249624b commit 5f389e7
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 203 deletions.
6 changes: 2 additions & 4 deletions compiler/rustc_borrowck/src/constraint_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ use rustc_middle::mir::{
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
use rustc_mir_dataflow::points::LivenessValues;

use crate::{
borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict,
region_infer::values::LivenessValues,
};
use crate::{borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict};

pub(super) fn generate_constraints<'tcx>(
infcx: &InferCtxt<'tcx>,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::symbol::sym;
use std::env;
use std::io;
Expand All @@ -33,7 +34,7 @@ use crate::{
facts::{AllFacts, AllFactsExt, RustcFacts},
invalidation,
location::LocationTable,
region_infer::{values::RegionValueElements, RegionInferenceContext},
region_infer::RegionInferenceContext,
renumber,
type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
universal_regions::UniversalRegions,
Expand Down Expand Up @@ -179,7 +180,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(

let universal_regions = Rc::new(universal_regions);

let elements = &Rc::new(RegionValueElements::new(&body));
let elements = &Rc::new(DenseLocationMap::new(&body));

// Run the MIR type-checker.
let MirTypeckResults {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/dump_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
) -> io::Result<()> {
for region in self.definitions.indices() {
let value = self.liveness_constraints.region_value_str(region);
let value = self.region_value_str(region);
if value != "{}" {
with_msg(&format!("{region:?} live at {value}"))?;
}
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc_middle::mir::{
use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_mir_dataflow::points::{DenseLocationMap, LivenessValues, PointIndex};
use rustc_span::Span;

use crate::dataflow::BorrowIndex;
Expand All @@ -31,10 +32,7 @@ use crate::{
member_constraints::{MemberConstraintSet, NllMemberConstraintIndex},
nll::PoloniusOutput,
region_infer::reverse_sccs::ReverseSccGraph,
region_infer::values::{
LivenessValues, PlaceholderIndices, PointIndex, RegionElement, RegionValueElements,
RegionValues, ToElementIndex,
},
region_infer::values::{PlaceholderIndices, RegionElement, RegionValues, ToElementIndex},
type_check::{free_region_relations::UniversalRegionRelations, Locations},
universal_regions::UniversalRegions,
BorrowckInferCtxt,
Expand Down Expand Up @@ -334,7 +332,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
type_tests: Vec<TypeTest<'tcx>>,
liveness_constraints: LivenessValues<RegionVid>,
elements: &Rc<RegionValueElements>,
elements: &Rc<DenseLocationMap>,
live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
) -> Self {
debug!("universal_regions: {:#?}", universal_regions);
Expand Down Expand Up @@ -1970,7 +1968,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
trace!(universe = ?self.scc_universes[self.constraint_sccs.scc(fr1)]);
self.find_constraint_paths_between_regions(fr1, |r| {
// First look for some `r` such that `fr1: r` and `r` is live at `elem`
trace!(?r, liveness_constraints=?self.liveness_constraints.region_value_str(r));
trace!(?r, liveness_constraints=?self.region_value_str(r));
self.liveness_constraints.contains(r, elem)
})
.or_else(|| {
Expand Down
165 changes: 7 additions & 158 deletions compiler/rustc_borrowck/src/region_infer/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,98 +2,14 @@
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxIndexSet;
use rustc_index::bit_set::SparseBitMatrix;
use rustc_index::interval::IntervalSet;
use rustc_index::interval::SparseIntervalMatrix;
use rustc_index::Idx;
use rustc_index::IndexVec;
use rustc_middle::mir::{BasicBlock, Body, Location};
use rustc_middle::mir::{BasicBlock, Location};
use rustc_middle::ty::{self, RegionVid};
use rustc_mir_dataflow::points::{DenseLocationMap, LivenessValues, PointIndex};
use std::fmt::Debug;
use std::rc::Rc;

/// Maps between a `Location` and a `PointIndex` (and vice versa).
pub(crate) struct RegionValueElements {
/// For each basic block, how many points are contained within?
statements_before_block: IndexVec<BasicBlock, usize>,

/// Map backward from each point to the basic block that it
/// belongs to.
basic_blocks: IndexVec<PointIndex, BasicBlock>,

num_points: usize,
}

impl RegionValueElements {
pub(crate) fn new(body: &Body<'_>) -> Self {
let mut num_points = 0;
let statements_before_block: IndexVec<BasicBlock, usize> = body
.basic_blocks
.iter()
.map(|block_data| {
let v = num_points;
num_points += block_data.statements.len() + 1;
v
})
.collect();
debug!("RegionValueElements: statements_before_block={:#?}", statements_before_block);
debug!("RegionValueElements: num_points={:#?}", num_points);

let mut basic_blocks = IndexVec::with_capacity(num_points);
for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
}

Self { statements_before_block, basic_blocks, num_points }
}

/// Total number of point indices
pub(crate) fn num_points(&self) -> usize {
self.num_points
}

/// Converts a `Location` into a `PointIndex`. O(1).
pub(crate) fn point_from_location(&self, location: Location) -> PointIndex {
let Location { block, statement_index } = location;
let start_index = self.statements_before_block[block];
PointIndex::new(start_index + statement_index)
}

/// Converts a `Location` into a `PointIndex`. O(1).
pub(crate) fn entry_point(&self, block: BasicBlock) -> PointIndex {
let start_index = self.statements_before_block[block];
PointIndex::new(start_index)
}

/// Return the PointIndex for the block start of this index.
pub(crate) fn to_block_start(&self, index: PointIndex) -> PointIndex {
PointIndex::new(self.statements_before_block[self.basic_blocks[index]])
}

/// Converts a `PointIndex` back to a location. O(1).
pub(crate) fn to_location(&self, index: PointIndex) -> Location {
assert!(index.index() < self.num_points);
let block = self.basic_blocks[index];
let start_index = self.statements_before_block[block];
let statement_index = index.index() - start_index;
Location { block, statement_index }
}

/// Sometimes we get point-indices back from bitsets that may be
/// out of range (because they round up to the nearest 2^N number
/// of bits). Use this function to filter such points out if you
/// like.
pub(crate) fn point_in_range(&self, index: PointIndex) -> bool {
index.index() < self.num_points
}
}

rustc_index::newtype_index! {
/// A single integer representing a `Location` in the MIR control-flow
/// graph. Constructed efficiently from `RegionValueElements`.
#[debug_format = "PointIndex({})"]
pub struct PointIndex {}
}

rustc_index::newtype_index! {
/// A single integer representing a `ty::Placeholder`.
#[debug_format = "PlaceholderIndex({})"]
Expand All @@ -116,73 +32,6 @@ pub(crate) enum RegionElement {
PlaceholderRegion(ty::PlaceholderRegion),
}

/// When we initially compute liveness, we use an interval matrix storing
/// liveness ranges for each region-vid.
pub(crate) struct LivenessValues<N: Idx> {
elements: Rc<RegionValueElements>,
points: SparseIntervalMatrix<N, PointIndex>,
}

impl<N: Idx> LivenessValues<N> {
/// Creates a new set of "region values" that tracks causal information.
/// Each of the regions in num_region_variables will be initialized with an
/// empty set of points and no causal information.
pub(crate) fn new(elements: Rc<RegionValueElements>) -> Self {
Self { points: SparseIntervalMatrix::new(elements.num_points), elements }
}

/// Iterate through each region that has a value in this set.
pub(crate) fn rows(&self) -> impl Iterator<Item = N> {
self.points.rows()
}

/// Adds the given element to the value for the given region. Returns whether
/// the element is newly added (i.e., was not already present).
pub(crate) fn add_element(&mut self, row: N, location: Location) -> bool {
debug!("LivenessValues::add(r={:?}, location={:?})", row, location);
let index = self.elements.point_from_location(location);
self.points.insert(row, index)
}

/// Adds all the elements in the given bit array into the given
/// region. Returns whether any of them are newly added.
pub(crate) fn add_elements(&mut self, row: N, locations: &IntervalSet<PointIndex>) -> bool {
debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations);
self.points.union_row(row, locations)
}

/// Adds all the control-flow points to the values for `r`.
pub(crate) fn add_all_points(&mut self, row: N) {
self.points.insert_all_into_row(row);
}

/// Returns `true` if the region `r` contains the given element.
pub(crate) fn contains(&self, row: N, location: Location) -> bool {
let index = self.elements.point_from_location(location);
self.points.row(row).is_some_and(|r| r.contains(index))
}

/// Returns an iterator of all the elements contained by the region `r`
pub(crate) fn get_elements(&self, row: N) -> impl Iterator<Item = Location> + '_ {
self.points
.row(row)
.into_iter()
.flat_map(|set| set.iter())
.take_while(move |&p| self.elements.point_in_range(p))
.map(move |p| self.elements.to_location(p))
}

/// Returns a "pretty" string value of the region. Meant for debugging.
pub(crate) fn region_value_str(&self, r: N) -> String {
region_value_str(self.get_elements(r).map(RegionElement::Location))
}

#[inline]
pub(crate) fn point_from_location(&self, location: Location) -> PointIndex {
self.elements.point_from_location(location)
}
}

/// Maps from `ty::PlaceholderRegion` values that are used in the rest of
/// rustc to the internal `PlaceholderIndex` values that are used in
/// NLL.
Expand Down Expand Up @@ -234,7 +83,7 @@ impl PlaceholderIndices {
/// it would also contain various points from within the function.
#[derive(Clone)]
pub(crate) struct RegionValues<N: Idx> {
elements: Rc<RegionValueElements>,
elements: Rc<DenseLocationMap>,
placeholder_indices: Rc<PlaceholderIndices>,
points: SparseIntervalMatrix<N, PointIndex>,
free_regions: SparseBitMatrix<N, RegionVid>,
Expand All @@ -249,14 +98,14 @@ impl<N: Idx> RegionValues<N> {
/// Each of the regions in num_region_variables will be initialized with an
/// empty set of points and no causal information.
pub(crate) fn new(
elements: &Rc<RegionValueElements>,
elements: &Rc<DenseLocationMap>,
num_universal_regions: usize,
placeholder_indices: &Rc<PlaceholderIndices>,
) -> Self {
let num_placeholders = placeholder_indices.len();
Self {
elements: elements.clone(),
points: SparseIntervalMatrix::new(elements.num_points),
points: SparseIntervalMatrix::new(elements.num_points()),
placeholder_indices: placeholder_indices.clone(),
free_regions: SparseBitMatrix::new(num_universal_regions),
placeholders: SparseBitMatrix::new(num_placeholders),
Expand Down Expand Up @@ -308,7 +157,7 @@ impl<N: Idx> RegionValues<N> {
/// elements for the region `from` from `values` and add them to
/// the region `to` in `self`.
pub(crate) fn merge_liveness<M: Idx>(&mut self, to: N, from: M, values: &LivenessValues<M>) {
if let Some(set) = values.points.row(from) {
if let Some(set) = values.get_intervals(from) {
self.points.union_row(to, set);
}
}
Expand Down Expand Up @@ -421,7 +270,7 @@ impl ToElementIndex for ty::PlaceholderRegion {
}

pub(crate) fn location_set_str(
elements: &RegionValueElements,
elements: &DenseLocationMap,
points: impl IntoIterator<Item = PointIndex>,
) -> String {
region_value_str(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use rustc_data_structures::vec_linked_list as vll;
use rustc_index::IndexVec;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{Body, Local, Location};
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};

use crate::def_use::{self, DefUse};
use crate::region_infer::values::{PointIndex, RegionValueElements};

/// A map that cross references each local with the locations where it
/// is defined (assigned), used, or dropped. Used during liveness
Expand Down Expand Up @@ -60,7 +60,7 @@ impl vll::LinkElem for Appearance {
impl LocalUseMap {
pub(crate) fn build(
live_locals: &[Local],
elements: &RegionValueElements,
elements: &DenseLocationMap,
body: &Body<'_>,
) -> Self {
let nones = IndexVec::from_elem(None, &body.local_decls);
Expand Down Expand Up @@ -103,7 +103,7 @@ impl LocalUseMap {

struct LocalUseMapBuild<'me> {
local_use_map: &'me mut LocalUseMap,
elements: &'me RegionValueElements,
elements: &'me DenseLocationMap,

// Vector used in `visit_local` to signal which `Local`s do we need
// def/use/drop information on, constructed from `live_locals` (that
Expand Down Expand Up @@ -144,7 +144,7 @@ impl LocalUseMapBuild<'_> {
}

fn insert(
elements: &RegionValueElements,
elements: &DenseLocationMap,
first_appearance: &mut Option<AppearanceIndex>,
appearances: &mut IndexVec<AppearanceIndex, Appearance>,
location: Location,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use rustc_middle::mir::{Body, Local};
use rustc_middle::ty::{RegionVid, TyCtxt};
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::MoveData;
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_mir_dataflow::ResultsCursor;
use std::rc::Rc;

use crate::{
constraints::OutlivesConstraintSet,
facts::{AllFacts, AllFactsExt},
location::LocationTable,
region_infer::values::RegionValueElements,
universal_regions::UniversalRegions,
};

Expand All @@ -32,7 +32,7 @@ mod trace;
pub(super) fn generate<'mir, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
elements: &Rc<RegionValueElements>,
elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
move_data: &MoveData<'tcx>,
location_table: &LocationTable,
Expand Down
Loading

0 comments on commit 5f389e7

Please sign in to comment.