Skip to content

Commit cd3649b

Browse files
committed
Only exclude locals if the place is not indirect.
1 parent 0d59b8c commit cd3649b

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ where
121121
// for now. See discussion on [#61069].
122122
//
123123
// [#61069]: https://github.com/rust-lang/rust/pull/61069
124-
self.trans.gen(dropped_place.local);
124+
if !dropped_place.is_indirect() {
125+
self.trans.gen(dropped_place.local);
126+
}
125127
}
126128

127129
TerminatorKind::Abort

compiler/rustc_mir_dataflow/src/value_analysis.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use std::fmt::{Debug, Formatter};
3636

3737
use rustc_data_structures::fx::FxHashMap;
38+
use rustc_index::bit_set::BitSet;
3839
use rustc_index::vec::IndexVec;
3940
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
4041
use rustc_middle::mir::*;
@@ -589,7 +590,7 @@ impl Map {
589590
) -> Self {
590591
let mut map = Self::new();
591592
let exclude = excluded_locals(body);
592-
map.register_with_filter(tcx, body, filter, &exclude);
593+
map.register_with_filter(tcx, body, filter, exclude);
593594
debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len());
594595
map
595596
}
@@ -600,12 +601,12 @@ impl Map {
600601
tcx: TyCtxt<'tcx>,
601602
body: &Body<'tcx>,
602603
mut filter: impl FnMut(Ty<'tcx>) -> bool,
603-
exclude: &IndexVec<Local, bool>,
604+
exclude: BitSet<Local>,
604605
) {
605606
// We use this vector as stack, pushing and popping projections.
606607
let mut projection = Vec::new();
607608
for (local, decl) in body.local_decls.iter_enumerated() {
608-
if !exclude[local] {
609+
if !exclude.contains(local) {
609610
self.register_with_filter_rec(tcx, local, &mut projection, decl.ty, &mut filter);
610611
}
611612
}
@@ -823,26 +824,27 @@ pub fn iter_fields<'tcx>(
823824
}
824825

825826
/// Returns all locals with projections that have their reference or address taken.
826-
pub fn excluded_locals(body: &Body<'_>) -> IndexVec<Local, bool> {
827+
pub fn excluded_locals(body: &Body<'_>) -> BitSet<Local> {
827828
struct Collector {
828-
result: IndexVec<Local, bool>,
829+
result: BitSet<Local>,
829830
}
830831

831832
impl<'tcx> Visitor<'tcx> for Collector {
832833
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
833-
if context.is_borrow()
834+
if (context.is_borrow()
834835
|| context.is_address_of()
835836
|| context.is_drop()
836-
|| context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)
837+
|| context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput))
838+
&& !place.is_indirect()
837839
{
838840
// A pointer to a place could be used to access other places with the same local,
839841
// hence we have to exclude the local completely.
840-
self.result[place.local] = true;
842+
self.result.insert(place.local);
841843
}
842844
}
843845
}
844846

845-
let mut collector = Collector { result: IndexVec::from_elem(false, &body.local_decls) };
847+
let mut collector = Collector { result: BitSet::new_empty(body.local_decls.len()) };
846848
collector.visit_body(body);
847849
collector.result
848850
}

compiler/rustc_mir_transform/src/sroa.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::MirPass;
2-
use rustc_index::bit_set::BitSet;
2+
use rustc_index::bit_set::{BitSet, GrowableBitSet};
33
use rustc_index::vec::IndexVec;
44
use rustc_middle::mir::patch::MirPatch;
55
use rustc_middle::mir::visit::*;
@@ -26,10 +26,12 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
2626
debug!(?replacements);
2727
let all_dead_locals = replace_flattened_locals(tcx, body, replacements);
2828
if !all_dead_locals.is_empty() {
29-
for local in excluded.indices() {
30-
excluded[local] |= all_dead_locals.contains(local);
31-
}
32-
excluded.raw.resize(body.local_decls.len(), false);
29+
excluded.union(&all_dead_locals);
30+
excluded = {
31+
let mut growable = GrowableBitSet::from(excluded);
32+
growable.ensure(body.local_decls.len());
33+
growable.into()
34+
};
3335
} else {
3436
break;
3537
}
@@ -44,11 +46,11 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
4446
/// - the locals is a union or an enum;
4547
/// - the local's address is taken, and thus the relative addresses of the fields are observable to
4648
/// client code.
47-
fn escaping_locals(excluded: &IndexVec<Local, bool>, body: &Body<'_>) -> BitSet<Local> {
49+
fn escaping_locals(excluded: &BitSet<Local>, body: &Body<'_>) -> BitSet<Local> {
4850
let mut set = BitSet::new_empty(body.local_decls.len());
4951
set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count));
5052
for (local, decl) in body.local_decls().iter_enumerated() {
51-
if decl.ty.is_union() || decl.ty.is_enum() || excluded[local] {
53+
if decl.ty.is_union() || decl.ty.is_enum() || excluded.contains(local) {
5254
set.insert(local);
5355
}
5456
}
@@ -172,7 +174,7 @@ fn replace_flattened_locals<'tcx>(
172174
body: &mut Body<'tcx>,
173175
replacements: ReplacementMap<'tcx>,
174176
) -> BitSet<Local> {
175-
let mut all_dead_locals = BitSet::new_empty(body.local_decls.len());
177+
let mut all_dead_locals = BitSet::new_empty(replacements.fragments.len());
176178
for (local, replacements) in replacements.fragments.iter_enumerated() {
177179
if replacements.is_some() {
178180
all_dead_locals.insert(local);

0 commit comments

Comments
 (0)