Skip to content

Commit a9194f3

Browse files
committed
Use IndexVec for coroutine local mapping
1 parent 2db4ff4 commit a9194f3

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

compiler/rustc_index/src/vec.rs

+5
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ impl<I: Idx, T> IndexVec<I, Option<T>> {
208208
pub fn remove(&mut self, index: I) -> Option<T> {
209209
self.get_mut(index)?.take()
210210
}
211+
212+
#[inline]
213+
pub fn contains(&self, index: I) -> bool {
214+
self.get(index).and_then(Option::as_ref).is_some()
215+
}
211216
}
212217

213218
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {

compiler/rustc_mir_transform/src/coroutine.rs

+16-19
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::deref_separator::deref_finder;
5858
use crate::errors;
5959
use crate::pass_manager as pm;
6060
use crate::simplify;
61-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
61+
use rustc_data_structures::fx::FxHashSet;
6262
use rustc_errors::pluralize;
6363
use rustc_hir as hir;
6464
use rustc_hir::lang_items::LangItem;
@@ -236,8 +236,7 @@ struct TransformVisitor<'tcx> {
236236
discr_ty: Ty<'tcx>,
237237

238238
// Mapping from Local to (type of local, coroutine struct index)
239-
// FIXME(eddyb) This should use `IndexVec<Local, Option<_>>`.
240-
remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, FieldIdx)>,
239+
remap: IndexVec<Local, Option<(Ty<'tcx>, VariantIdx, FieldIdx)>>,
241240

242241
// A map from a suspension point in a block to the locals which have live storage at that point
243242
storage_liveness: IndexVec<BasicBlock, Option<BitSet<Local>>>,
@@ -485,7 +484,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
485484
}
486485

487486
fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
488-
assert_eq!(self.remap.get(local), None);
487+
assert!(!self.remap.contains(*local));
489488
}
490489

491490
fn visit_place(
@@ -495,7 +494,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
495494
_location: Location,
496495
) {
497496
// Replace an Local in the remap with a coroutine struct access
498-
if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) {
497+
if let Some(&Some((ty, variant_index, idx))) = self.remap.get(place.local) {
499498
replace_base(place, self.make_field(variant_index, idx, ty), self.tcx);
500499
}
501500
}
@@ -504,7 +503,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
504503
// Remove StorageLive and StorageDead statements for remapped locals
505504
data.retain_statements(|s| match s.kind {
506505
StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => {
507-
!self.remap.contains_key(&l)
506+
!self.remap.contains(l)
508507
}
509508
_ => true,
510509
});
@@ -529,21 +528,17 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
529528

530529
// The resume arg target location might itself be remapped if its base local is
531530
// live across a yield.
532-
let resume_arg =
533-
if let Some(&(ty, variant, idx)) = self.remap.get(&resume_arg.local) {
534-
replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx);
535-
resume_arg
536-
} else {
537-
resume_arg
538-
};
531+
if let Some(&Some((ty, variant, idx))) = self.remap.get(resume_arg.local) {
532+
replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx);
533+
}
539534

540535
let storage_liveness: GrowableBitSet<Local> =
541536
self.storage_liveness[block].clone().unwrap().into();
542537

543538
for i in 0..self.always_live_locals.domain_size() {
544539
let l = Local::new(i);
545540
let needs_storage_dead = storage_liveness.contains(l)
546-
&& !self.remap.contains_key(&l)
541+
&& !self.remap.contains(l)
547542
&& !self.always_live_locals.contains(l);
548543
if needs_storage_dead {
549544
data.statements
@@ -1037,7 +1032,7 @@ fn compute_layout<'tcx>(
10371032
liveness: LivenessInfo,
10381033
body: &Body<'tcx>,
10391034
) -> (
1040-
FxHashMap<Local, (Ty<'tcx>, VariantIdx, FieldIdx)>,
1035+
IndexVec<Local, Option<(Ty<'tcx>, VariantIdx, FieldIdx)>>,
10411036
CoroutineLayout<'tcx>,
10421037
IndexVec<BasicBlock, Option<BitSet<Local>>>,
10431038
) {
@@ -1098,7 +1093,7 @@ fn compute_layout<'tcx>(
10981093
// Create a map from local indices to coroutine struct indices.
10991094
let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
11001095
iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect();
1101-
let mut remap = FxHashMap::default();
1096+
let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
11021097
for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
11031098
let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx);
11041099
let mut fields = IndexVec::new();
@@ -1109,7 +1104,7 @@ fn compute_layout<'tcx>(
11091104
// around inside coroutines, so it doesn't matter which variant
11101105
// index we access them by.
11111106
let idx = FieldIdx::from_usize(idx);
1112-
remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx));
1107+
remap[locals[saved_local]] = Some((tys[saved_local].ty, variant_index, idx));
11131108
}
11141109
variant_fields.push(fields);
11151110
variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]);
@@ -1121,7 +1116,9 @@ fn compute_layout<'tcx>(
11211116
for var in &body.var_debug_info {
11221117
let VarDebugInfoContents::Place(place) = &var.value else { continue };
11231118
let Some(local) = place.as_local() else { continue };
1124-
let Some(&(_, variant, field)) = remap.get(&local) else { continue };
1119+
let Some(&Some((_, variant, field))) = remap.get(local) else {
1120+
continue;
1121+
};
11251122

11261123
let saved_local = variant_fields[variant][field];
11271124
field_names.get_or_insert_with(saved_local, || var.name);
@@ -1524,7 +1521,7 @@ fn create_cases<'tcx>(
15241521
for i in 0..(body.local_decls.len()) {
15251522
let l = Local::new(i);
15261523
let needs_storage_live = point.storage_liveness.contains(l)
1527-
&& !transform.remap.contains_key(&l)
1524+
&& !transform.remap.contains(l)
15281525
&& !transform.always_live_locals.contains(l);
15291526
if needs_storage_live {
15301527
statements

0 commit comments

Comments
 (0)