1
Fork 0

Rollup merge of #71551 - gizmondo:gen-index-vec, r=jonas-schievink

Minor refactoring around IndexVec usage in generator transformation

Replace hash map with IndexVec for liveness data.
Utilize IndexVec::push return value to avoid redundant object creation.

r? @eddyb
This commit is contained in:
Dylan DPC 2020-04-26 21:02:36 +02:00 committed by GitHub
commit d1287746cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -210,8 +210,7 @@ struct TransformVisitor<'tcx> {
remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>, remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
// A map from a suspension point in a block to the locals which have live storage at that point // A map from a suspension point in a block to the locals which have live storage at that point
// FIXME(eddyb) This should use `IndexVec<BasicBlock, Option<_>>`. storage_liveness: IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,
// A list of suspension points, generated during the transform // A list of suspension points, generated during the transform
suspension_points: Vec<SuspensionPoint<'tcx>>, suspension_points: Vec<SuspensionPoint<'tcx>>,
@ -338,7 +337,7 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
resume, resume,
resume_arg, resume_arg,
drop, drop,
storage_liveness: self.storage_liveness.get(&block).unwrap().clone(), storage_liveness: self.storage_liveness[block].clone().unwrap(),
}); });
VariantIdx::new(state) VariantIdx::new(state)
@ -404,8 +403,7 @@ fn replace_local<'tcx>(
is_block_tail: None, is_block_tail: None,
local_info: LocalInfo::Other, local_info: LocalInfo::Other,
}; };
let new_local = Local::new(body.local_decls.len()); let new_local = body.local_decls.push(new_decl);
body.local_decls.push(new_decl);
body.local_decls.swap(local, new_local); body.local_decls.swap(local, new_local);
RenameLocalVisitor { from: local, to: new_local, tcx }.visit_body(body); RenameLocalVisitor { from: local, to: new_local, tcx }.visit_body(body);
@ -431,7 +429,7 @@ struct LivenessInfo {
/// For every suspending block, the locals which are storage-live across /// For every suspending block, the locals which are storage-live across
/// that suspension point. /// that suspension point.
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>, storage_liveness: IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
} }
fn locals_live_across_suspend_points( fn locals_live_across_suspend_points(
@ -472,7 +470,7 @@ fn locals_live_across_suspend_points(
let mut liveness = liveness::liveness_of_locals(body); let mut liveness = liveness::liveness_of_locals(body);
liveness::dump_mir(tcx, "generator_liveness", source, body_ref, &liveness); liveness::dump_mir(tcx, "generator_liveness", source, body_ref, &liveness);
let mut storage_liveness_map = FxHashMap::default(); let mut storage_liveness_map = IndexVec::from_elem(None, body.basic_blocks());
let mut live_locals_at_suspension_points = Vec::new(); let mut live_locals_at_suspension_points = Vec::new();
for (block, data) in body.basic_blocks().iter_enumerated() { for (block, data) in body.basic_blocks().iter_enumerated() {
@ -502,7 +500,7 @@ fn locals_live_across_suspend_points(
// Store the storage liveness for later use so we can restore the state // Store the storage liveness for later use so we can restore the state
// after a suspension point // after a suspension point
storage_liveness_map.insert(block, storage_liveness); storage_liveness_map[block] = Some(storage_liveness);
requires_storage_cursor.seek_before(loc); requires_storage_cursor.seek_before(loc);
let storage_required = requires_storage_cursor.get().clone(); let storage_required = requires_storage_cursor.get().clone();
@ -690,7 +688,7 @@ fn compute_layout<'tcx>(
) -> ( ) -> (
FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>, FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
GeneratorLayout<'tcx>, GeneratorLayout<'tcx>,
FxHashMap<BasicBlock, liveness::LiveVarSet>, IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
) { ) {
// Use a liveness analysis to compute locals which are live across a suspension point // Use a liveness analysis to compute locals which are live across a suspension point
let LivenessInfo { let LivenessInfo {
@ -925,14 +923,12 @@ fn create_generator_drop_shim<'tcx>(
} }
fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock {
let term_block = BasicBlock::new(body.basic_blocks().len());
let source_info = source_info(body); let source_info = source_info(body);
body.basic_blocks_mut().push(BasicBlockData { body.basic_blocks_mut().push(BasicBlockData {
statements: Vec::new(), statements: Vec::new(),
terminator: Some(Terminator { source_info, kind }), terminator: Some(Terminator { source_info, kind }),
is_cleanup: false, is_cleanup: false,
}); })
term_block
} }
fn insert_panic_block<'tcx>( fn insert_panic_block<'tcx>(
@ -1030,9 +1026,8 @@ fn create_generator_resume_function<'tcx>(
// Poison the generator when it unwinds // Poison the generator when it unwinds
if can_unwind { if can_unwind {
let poison_block = BasicBlock::new(body.basic_blocks().len());
let source_info = source_info(body); let source_info = source_info(body);
body.basic_blocks_mut().push(BasicBlockData { let poison_block = body.basic_blocks_mut().push(BasicBlockData {
statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)], statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)],
terminator: Some(Terminator { source_info, kind: TerminatorKind::Resume }), terminator: Some(Terminator { source_info, kind: TerminatorKind::Resume }),
is_cleanup: true, is_cleanup: true,
@ -1105,21 +1100,19 @@ fn source_info(body: &Body<'_>) -> SourceInfo {
fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock {
let return_block = insert_term_block(body, TerminatorKind::Return); let return_block = insert_term_block(body, TerminatorKind::Return);
// Create a block to destroy an unresumed generators. This can only destroy upvars.
let drop_clean = BasicBlock::new(body.basic_blocks().len());
let term = TerminatorKind::Drop { let term = TerminatorKind::Drop {
location: Place::from(SELF_ARG), location: Place::from(SELF_ARG),
target: return_block, target: return_block,
unwind: None, unwind: None,
}; };
let source_info = source_info(body); let source_info = source_info(body);
// Create a block to destroy an unresumed generators. This can only destroy upvars.
body.basic_blocks_mut().push(BasicBlockData { body.basic_blocks_mut().push(BasicBlockData {
statements: Vec::new(), statements: Vec::new(),
terminator: Some(Terminator { source_info, kind: term }), terminator: Some(Terminator { source_info, kind: term }),
is_cleanup: false, is_cleanup: false,
}); })
drop_clean
} }
/// An operation that can be performed on a generator. /// An operation that can be performed on a generator.
@ -1151,7 +1144,6 @@ fn create_cases<'tcx>(
.filter_map(|point| { .filter_map(|point| {
// Find the target for this suspension point, if applicable // Find the target for this suspension point, if applicable
operation.target_block(point).map(|target| { operation.target_block(point).map(|target| {
let block = BasicBlock::new(body.basic_blocks().len());
let mut statements = Vec::new(); let mut statements = Vec::new();
// Create StorageLive instructions for locals with live storage // Create StorageLive instructions for locals with live storage
@ -1186,7 +1178,7 @@ fn create_cases<'tcx>(
} }
// Then jump to the real target // Then jump to the real target
body.basic_blocks_mut().push(BasicBlockData { let block = body.basic_blocks_mut().push(BasicBlockData {
statements, statements,
terminator: Some(Terminator { terminator: Some(Terminator {
source_info, source_info,