Move PointIndex to mir_dataflow.
This commit is contained in:
parent
75c68cfd2b
commit
c4b1054525
9 changed files with 127 additions and 114 deletions
|
@ -12,6 +12,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
|
use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
|
||||||
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
||||||
use rustc_mir_dataflow::move_paths::MoveData;
|
use rustc_mir_dataflow::move_paths::MoveData;
|
||||||
|
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||||
use rustc_mir_dataflow::ResultsCursor;
|
use rustc_mir_dataflow::ResultsCursor;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -27,7 +28,7 @@ use crate::{
|
||||||
facts::{AllFacts, AllFactsExt, RustcFacts},
|
facts::{AllFacts, AllFactsExt, RustcFacts},
|
||||||
location::LocationTable,
|
location::LocationTable,
|
||||||
polonius,
|
polonius,
|
||||||
region_infer::{values::RegionValueElements, RegionInferenceContext},
|
region_infer::RegionInferenceContext,
|
||||||
renumber,
|
renumber,
|
||||||
type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
|
type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
|
||||||
universal_regions::UniversalRegions,
|
universal_regions::UniversalRegions,
|
||||||
|
@ -98,7 +99,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
|
|
||||||
let universal_regions = Rc::new(universal_regions);
|
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.
|
// Run the MIR type-checker.
|
||||||
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
|
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
|
||||||
|
|
|
@ -19,6 +19,7 @@ use rustc_middle::mir::{
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::traits::ObligationCauseCode;
|
use rustc_middle::traits::ObligationCauseCode;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||||
|
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
|
use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
|
||||||
|
@ -30,8 +31,7 @@ use crate::{
|
||||||
nll::PoloniusOutput,
|
nll::PoloniusOutput,
|
||||||
region_infer::reverse_sccs::ReverseSccGraph,
|
region_infer::reverse_sccs::ReverseSccGraph,
|
||||||
region_infer::values::{
|
region_infer::values::{
|
||||||
LivenessValues, PlaceholderIndices, RegionElement, RegionValueElements, RegionValues,
|
LivenessValues, PlaceholderIndices, RegionElement, RegionValues, ToElementIndex,
|
||||||
ToElementIndex,
|
|
||||||
},
|
},
|
||||||
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
||||||
universal_regions::UniversalRegions,
|
universal_regions::UniversalRegions,
|
||||||
|
@ -330,7 +330,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
||||||
type_tests: Vec<TypeTest<'tcx>>,
|
type_tests: Vec<TypeTest<'tcx>>,
|
||||||
liveness_constraints: LivenessValues,
|
liveness_constraints: LivenessValues,
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<DenseLocationMap>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
debug!("universal_regions: {:#?}", universal_regions);
|
debug!("universal_regions: {:#?}", universal_regions);
|
||||||
debug!("outlives constraints: {:#?}", outlives_constraints);
|
debug!("outlives constraints: {:#?}", outlives_constraints);
|
||||||
|
|
|
@ -5,97 +5,13 @@ use rustc_index::bit_set::SparseBitMatrix;
|
||||||
use rustc_index::interval::IntervalSet;
|
use rustc_index::interval::IntervalSet;
|
||||||
use rustc_index::interval::SparseIntervalMatrix;
|
use rustc_index::interval::SparseIntervalMatrix;
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
use rustc_index::IndexVec;
|
use rustc_middle::mir::{BasicBlock, Location};
|
||||||
use rustc_middle::mir::{BasicBlock, Body, Location};
|
|
||||||
use rustc_middle::ty::{self, RegionVid};
|
use rustc_middle::ty::{self, RegionVid};
|
||||||
|
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::dataflow::BorrowIndex;
|
use crate::BorrowIndex;
|
||||||
|
|
||||||
/// 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`.
|
|
||||||
#[orderable]
|
|
||||||
#[debug_format = "PointIndex({})"]
|
|
||||||
pub struct PointIndex {}
|
|
||||||
}
|
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// A single integer representing a `ty::Placeholder`.
|
/// A single integer representing a `ty::Placeholder`.
|
||||||
|
@ -123,7 +39,7 @@ pub(crate) enum RegionElement {
|
||||||
/// an interval matrix storing liveness ranges for each region-vid.
|
/// an interval matrix storing liveness ranges for each region-vid.
|
||||||
pub(crate) struct LivenessValues {
|
pub(crate) struct LivenessValues {
|
||||||
/// The map from locations to points.
|
/// The map from locations to points.
|
||||||
elements: Rc<RegionValueElements>,
|
elements: Rc<DenseLocationMap>,
|
||||||
|
|
||||||
/// For each region: the points where it is live.
|
/// For each region: the points where it is live.
|
||||||
points: SparseIntervalMatrix<RegionVid, PointIndex>,
|
points: SparseIntervalMatrix<RegionVid, PointIndex>,
|
||||||
|
@ -155,9 +71,9 @@ impl LiveLoans {
|
||||||
|
|
||||||
impl LivenessValues {
|
impl LivenessValues {
|
||||||
/// Create an empty map of regions to locations where they're live.
|
/// Create an empty map of regions to locations where they're live.
|
||||||
pub(crate) fn new(elements: Rc<RegionValueElements>) -> Self {
|
pub(crate) fn new(elements: Rc<DenseLocationMap>) -> Self {
|
||||||
LivenessValues {
|
LivenessValues {
|
||||||
points: SparseIntervalMatrix::new(elements.num_points),
|
points: SparseIntervalMatrix::new(elements.num_points()),
|
||||||
elements,
|
elements,
|
||||||
loans: None,
|
loans: None,
|
||||||
}
|
}
|
||||||
|
@ -298,7 +214,7 @@ impl PlaceholderIndices {
|
||||||
/// it would also contain various points from within the function.
|
/// it would also contain various points from within the function.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct RegionValues<N: Idx> {
|
pub(crate) struct RegionValues<N: Idx> {
|
||||||
elements: Rc<RegionValueElements>,
|
elements: Rc<DenseLocationMap>,
|
||||||
placeholder_indices: Rc<PlaceholderIndices>,
|
placeholder_indices: Rc<PlaceholderIndices>,
|
||||||
points: SparseIntervalMatrix<N, PointIndex>,
|
points: SparseIntervalMatrix<N, PointIndex>,
|
||||||
free_regions: SparseBitMatrix<N, RegionVid>,
|
free_regions: SparseBitMatrix<N, RegionVid>,
|
||||||
|
@ -313,14 +229,14 @@ impl<N: Idx> RegionValues<N> {
|
||||||
/// Each of the regions in num_region_variables will be initialized with an
|
/// Each of the regions in num_region_variables will be initialized with an
|
||||||
/// empty set of points and no causal information.
|
/// empty set of points and no causal information.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<DenseLocationMap>,
|
||||||
num_universal_regions: usize,
|
num_universal_regions: usize,
|
||||||
placeholder_indices: &Rc<PlaceholderIndices>,
|
placeholder_indices: &Rc<PlaceholderIndices>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let num_placeholders = placeholder_indices.len();
|
let num_placeholders = placeholder_indices.len();
|
||||||
Self {
|
Self {
|
||||||
elements: elements.clone(),
|
elements: elements.clone(),
|
||||||
points: SparseIntervalMatrix::new(elements.num_points),
|
points: SparseIntervalMatrix::new(elements.num_points()),
|
||||||
placeholder_indices: placeholder_indices.clone(),
|
placeholder_indices: placeholder_indices.clone(),
|
||||||
free_regions: SparseBitMatrix::new(num_universal_regions),
|
free_regions: SparseBitMatrix::new(num_universal_regions),
|
||||||
placeholders: SparseBitMatrix::new(num_placeholders),
|
placeholders: SparseBitMatrix::new(num_placeholders),
|
||||||
|
@ -486,7 +402,7 @@ impl ToElementIndex for ty::PlaceholderRegion {
|
||||||
|
|
||||||
/// For debugging purposes, returns a pretty-printed string of the given points.
|
/// For debugging purposes, returns a pretty-printed string of the given points.
|
||||||
pub(crate) fn pretty_print_points(
|
pub(crate) fn pretty_print_points(
|
||||||
elements: &RegionValueElements,
|
elements: &DenseLocationMap,
|
||||||
points: impl IntoIterator<Item = PointIndex>,
|
points: impl IntoIterator<Item = PointIndex>,
|
||||||
) -> String {
|
) -> String {
|
||||||
pretty_print_region_elements(
|
pretty_print_region_elements(
|
||||||
|
|
|
@ -2,9 +2,9 @@ use rustc_data_structures::vec_linked_list as vll;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::{Body, Local, Location};
|
use rustc_middle::mir::{Body, Local, Location};
|
||||||
|
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
|
||||||
|
|
||||||
use crate::def_use::{self, DefUse};
|
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
|
/// A map that cross references each local with the locations where it
|
||||||
/// is defined (assigned), used, or dropped. Used during liveness
|
/// is defined (assigned), used, or dropped. Used during liveness
|
||||||
|
@ -60,7 +60,7 @@ impl vll::LinkElem for Appearance {
|
||||||
impl LocalUseMap {
|
impl LocalUseMap {
|
||||||
pub(crate) fn build(
|
pub(crate) fn build(
|
||||||
live_locals: &[Local],
|
live_locals: &[Local],
|
||||||
elements: &RegionValueElements,
|
elements: &DenseLocationMap,
|
||||||
body: &Body<'_>,
|
body: &Body<'_>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let nones = IndexVec::from_elem(None, &body.local_decls);
|
let nones = IndexVec::from_elem(None, &body.local_decls);
|
||||||
|
@ -103,7 +103,7 @@ impl LocalUseMap {
|
||||||
|
|
||||||
struct LocalUseMapBuild<'me> {
|
struct LocalUseMapBuild<'me> {
|
||||||
local_use_map: &'me mut LocalUseMap,
|
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
|
// Vector used in `visit_local` to signal which `Local`s do we need
|
||||||
// def/use/drop information on, constructed from `live_locals` (that
|
// def/use/drop information on, constructed from `live_locals` (that
|
||||||
|
@ -144,7 +144,7 @@ impl LocalUseMapBuild<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(
|
fn insert(
|
||||||
elements: &RegionValueElements,
|
elements: &DenseLocationMap,
|
||||||
first_appearance: &mut Option<AppearanceIndex>,
|
first_appearance: &mut Option<AppearanceIndex>,
|
||||||
appearances: &mut IndexVec<AppearanceIndex, Appearance>,
|
appearances: &mut IndexVec<AppearanceIndex, Appearance>,
|
||||||
location: Location,
|
location: Location,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rustc_middle::ty::visit::TypeVisitable;
|
||||||
use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt};
|
use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt};
|
||||||
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
|
||||||
use rustc_mir_dataflow::move_paths::MoveData;
|
use rustc_mir_dataflow::move_paths::MoveData;
|
||||||
|
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||||
use rustc_mir_dataflow::ResultsCursor;
|
use rustc_mir_dataflow::ResultsCursor;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ use crate::{
|
||||||
constraints::OutlivesConstraintSet,
|
constraints::OutlivesConstraintSet,
|
||||||
facts::{AllFacts, AllFactsExt},
|
facts::{AllFacts, AllFactsExt},
|
||||||
location::LocationTable,
|
location::LocationTable,
|
||||||
region_infer::values::{LivenessValues, RegionValueElements},
|
region_infer::values::LivenessValues,
|
||||||
universal_regions::UniversalRegions,
|
universal_regions::UniversalRegions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ mod trace;
|
||||||
pub(super) fn generate<'mir, 'tcx>(
|
pub(super) fn generate<'mir, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<DenseLocationMap>,
|
||||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
location_table: &LocationTable,
|
location_table: &LocationTable,
|
||||||
|
|
|
@ -7,6 +7,7 @@ use rustc_infer::infer::outlives::for_liveness;
|
||||||
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
|
use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
|
||||||
use rustc_middle::traits::query::DropckOutlivesResult;
|
use rustc_middle::traits::query::DropckOutlivesResult;
|
||||||
use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
|
use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
|
||||||
|
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
|
use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
|
||||||
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||||
|
@ -17,7 +18,7 @@ use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex};
|
||||||
use rustc_mir_dataflow::ResultsCursor;
|
use rustc_mir_dataflow::ResultsCursor;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
region_infer::values::{self, LiveLoans, PointIndex, RegionValueElements},
|
region_infer::values::{self, LiveLoans},
|
||||||
type_check::liveness::local_use_map::LocalUseMap,
|
type_check::liveness::local_use_map::LocalUseMap,
|
||||||
type_check::liveness::polonius,
|
type_check::liveness::polonius,
|
||||||
type_check::NormalizeLocation,
|
type_check::NormalizeLocation,
|
||||||
|
@ -41,7 +42,7 @@ use crate::{
|
||||||
pub(super) fn trace<'mir, 'tcx>(
|
pub(super) fn trace<'mir, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<DenseLocationMap>,
|
||||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
relevant_live_locals: Vec<Local>,
|
relevant_live_locals: Vec<Local>,
|
||||||
|
@ -105,7 +106,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
|
||||||
typeck: &'me mut TypeChecker<'typeck, 'tcx>,
|
typeck: &'me mut TypeChecker<'typeck, 'tcx>,
|
||||||
|
|
||||||
/// Defines the `PointIndex` mapping
|
/// Defines the `PointIndex` mapping
|
||||||
elements: &'me RegionValueElements,
|
elements: &'me DenseLocationMap,
|
||||||
|
|
||||||
/// MIR we are analyzing.
|
/// MIR we are analyzing.
|
||||||
body: &'me Body<'tcx>,
|
body: &'me Body<'tcx>,
|
||||||
|
@ -570,7 +571,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_all_regions_live(
|
fn make_all_regions_live(
|
||||||
elements: &RegionValueElements,
|
elements: &DenseLocationMap,
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
value: impl TypeVisitable<TyCtxt<'tcx>>,
|
value: impl TypeVisitable<TyCtxt<'tcx>>,
|
||||||
live_at: &IntervalSet<PointIndex>,
|
live_at: &IntervalSet<PointIndex>,
|
||||||
|
|
|
@ -35,6 +35,7 @@ use rustc_middle::ty::{
|
||||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{GenericArgsRef, UserArgs};
|
use rustc_middle::ty::{GenericArgsRef, UserArgs};
|
||||||
|
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||||
use rustc_span::def_id::CRATE_DEF_ID;
|
use rustc_span::def_id::CRATE_DEF_ID;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -58,9 +59,7 @@ use crate::{
|
||||||
location::LocationTable,
|
location::LocationTable,
|
||||||
member_constraints::MemberConstraintSet,
|
member_constraints::MemberConstraintSet,
|
||||||
path_utils,
|
path_utils,
|
||||||
region_infer::values::{
|
region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices},
|
||||||
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
|
|
||||||
},
|
|
||||||
region_infer::TypeTest,
|
region_infer::TypeTest,
|
||||||
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
|
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
|
||||||
universal_regions::{DefiningTy, UniversalRegions},
|
universal_regions::{DefiningTy, UniversalRegions},
|
||||||
|
@ -133,7 +132,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
all_facts: &mut Option<AllFacts>,
|
all_facts: &mut Option<AllFacts>,
|
||||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||||
move_data: &MoveData<'tcx>,
|
move_data: &MoveData<'tcx>,
|
||||||
elements: &Rc<RegionValueElements>,
|
elements: &Rc<DenseLocationMap>,
|
||||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||||
use_polonius: bool,
|
use_polonius: bool,
|
||||||
) -> MirTypeckResults<'tcx> {
|
) -> MirTypeckResults<'tcx> {
|
||||||
|
@ -545,7 +544,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
let all_facts = &mut None;
|
let all_facts = &mut None;
|
||||||
let mut constraints = Default::default();
|
let mut constraints = Default::default();
|
||||||
let mut liveness_constraints =
|
let mut liveness_constraints =
|
||||||
LivenessValues::new(Rc::new(RegionValueElements::new(promoted_body)));
|
LivenessValues::new(Rc::new(DenseLocationMap::new(promoted_body)));
|
||||||
// Don't try to add borrow_region facts for the promoted MIR
|
// Don't try to add borrow_region facts for the promoted MIR
|
||||||
|
|
||||||
let mut swap_constraints = |this: &mut Self| {
|
let mut swap_constraints = |this: &mut Self| {
|
||||||
|
|
|
@ -34,6 +34,7 @@ mod errors;
|
||||||
mod framework;
|
mod framework;
|
||||||
pub mod impls;
|
pub mod impls;
|
||||||
pub mod move_paths;
|
pub mod move_paths;
|
||||||
|
pub mod points;
|
||||||
pub mod rustc_peek;
|
pub mod rustc_peek;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod un_derefer;
|
pub mod un_derefer;
|
||||||
|
|
94
compiler/rustc_mir_dataflow/src/points.rs
Normal file
94
compiler/rustc_mir_dataflow/src/points.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
use rustc_index::Idx;
|
||||||
|
use rustc_index::IndexVec;
|
||||||
|
use rustc_middle::mir::{BasicBlock, Body, Location};
|
||||||
|
|
||||||
|
/// Maps between a `Location` and a `PointIndex` (and vice versa).
|
||||||
|
pub struct DenseLocationMap {
|
||||||
|
/// 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 DenseLocationMap {
|
||||||
|
#[inline]
|
||||||
|
pub 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!("DenseLocationMap: statements_before_block={:#?}", statements_before_block);
|
||||||
|
debug!("DenseLocationMap: 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
|
||||||
|
#[inline]
|
||||||
|
pub fn num_points(&self) -> usize {
|
||||||
|
self.num_points
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a `Location` into a `PointIndex`. O(1).
|
||||||
|
#[inline]
|
||||||
|
pub 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).
|
||||||
|
#[inline]
|
||||||
|
pub 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.
|
||||||
|
#[inline]
|
||||||
|
pub 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).
|
||||||
|
#[inline]
|
||||||
|
pub 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.
|
||||||
|
#[inline]
|
||||||
|
pub 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 `DenseLocationMap`.
|
||||||
|
#[orderable]
|
||||||
|
#[debug_format = "PointIndex({})"]
|
||||||
|
pub struct PointIndex {}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue