Replace FxHashMap with IndexVec for local_map

Fixes #745
This commit is contained in:
bjorn3 2020-09-16 18:45:19 +02:00
parent a18a1948e0
commit 552991e17e
5 changed files with 31 additions and 33 deletions

View File

@ -325,7 +325,7 @@ impl<'tcx, B: Backend + 'static> FunctionCx<'_, 'tcx, B> {
} }
} }
fn local_place<'tcx>( fn make_local_place<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Backend>, fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
local: Local, local: Local,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
@ -344,9 +344,7 @@ fn local_place<'tcx>(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self::comments::add_local_place_comments(fx, place, local); self::comments::add_local_place_comments(fx, place, local);
let prev_place = fx.local_map.insert(local, place); place
debug_assert!(prev_place.is_none());
fx.local_map[&local]
} }
pub(crate) fn codegen_fn_prelude<'tcx>( pub(crate) fn codegen_fn_prelude<'tcx>(
@ -358,7 +356,8 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self::comments::add_args_header_comment(fx); self::comments::add_args_header_comment(fx);
self::returning::codegen_return_param(fx, &ssa_analyzed, start_block); let ret_place = self::returning::codegen_return_param(fx, &ssa_analyzed, start_block);
assert_eq!(fx.local_map.push(ret_place), RETURN_PLACE);
// None means pass_mode == NoPass // None means pass_mode == NoPass
enum ArgKind<'tcx> { enum ArgKind<'tcx> {
@ -441,8 +440,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self::comments::add_local_place_comments(fx, place, local); self::comments::add_local_place_comments(fx, place, local);
let prev_place = fx.local_map.insert(local, place); assert_eq!(fx.local_map.push(place), local);
debug_assert!(prev_place.is_none());
continue; continue;
} }
} }
@ -450,7 +448,8 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
_ => {} _ => {}
} }
let place = local_place(fx, local, layout, is_ssa); let place = make_local_place(fx, local, layout, is_ssa);
assert_eq!(fx.local_map.push(place), local);
match arg_kind { match arg_kind {
ArgKind::Normal(param) => { ArgKind::Normal(param) => {
@ -476,7 +475,8 @@ pub(crate) fn codegen_fn_prelude<'tcx>(
let is_ssa = ssa_analyzed[local] == crate::analyze::SsaKind::Ssa; let is_ssa = ssa_analyzed[local] == crate::analyze::SsaKind::Ssa;
local_place(fx, local, layout, is_ssa); let place = make_local_place(fx, local, layout, is_ssa);
assert_eq!(fx.local_map.push(place), local);
} }
fx.bcx fx.bcx

View File

@ -16,34 +16,28 @@ pub(crate) fn can_return_to_ssa_var<'tcx>(
} }
} }
pub(super) fn codegen_return_param( pub(super) fn codegen_return_param<'tcx>(
fx: &mut FunctionCx<'_, '_, impl Backend>, fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>, ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>,
start_block: Block, start_block: Block,
) { ) -> CPlace<'tcx> {
let ret_layout = return_layout(fx); let ret_layout = return_layout(fx);
let ret_pass_mode = get_pass_mode(fx.tcx, ret_layout); let ret_pass_mode = get_pass_mode(fx.tcx, ret_layout);
let ret_param = match ret_pass_mode { let (ret_place, ret_param) = match ret_pass_mode {
PassMode::NoPass => { PassMode::NoPass => (CPlace::no_place(ret_layout), Empty),
fx.local_map
.insert(RETURN_PLACE, CPlace::no_place(ret_layout));
Empty
}
PassMode::ByVal(_) | PassMode::ByValPair(_, _) => { PassMode::ByVal(_) | PassMode::ByValPair(_, _) => {
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa; let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
(
super::local_place(fx, RETURN_PLACE, ret_layout, is_ssa); super::make_local_place(fx, RETURN_PLACE, ret_layout, is_ssa),
Empty,
Empty )
} }
PassMode::ByRef { size: Some(_) } => { PassMode::ByRef { size: Some(_) } => {
let ret_param = fx.bcx.append_block_param(start_block, fx.pointer_type); let ret_param = fx.bcx.append_block_param(start_block, fx.pointer_type);
fx.local_map.insert( (
RETURN_PLACE,
CPlace::for_ptr(Pointer::new(ret_param), ret_layout), CPlace::for_ptr(Pointer::new(ret_param), ret_layout),
); Single(ret_param),
)
Single(ret_param)
} }
PassMode::ByRef { size: None } => todo!(), PassMode::ByRef { size: None } => todo!(),
}; };
@ -61,6 +55,8 @@ pub(super) fn codegen_return_param(
ret_pass_mode, ret_pass_mode,
ret_layout.ty, ret_layout.ty,
); );
ret_place
} }
pub(super) fn codegen_with_call_return_arg<'tcx, B: Backend, T>( pub(super) fn codegen_with_call_return_arg<'tcx, B: Backend, T>(

View File

@ -47,7 +47,7 @@ pub(crate) fn trans_fn<'tcx, B: Backend + 'static>(
bcx, bcx,
block_map, block_map,
local_map: FxHashMap::with_capacity_and_hasher(mir.local_decls.len(), Default::default()), local_map: IndexVec::with_capacity(mir.local_decls.len()),
caller_location: None, // set by `codegen_fn_prelude` caller_location: None, // set by `codegen_fn_prelude`
cold_blocks: EntitySet::new(), cold_blocks: EntitySet::new(),

View File

@ -297,7 +297,7 @@ pub(crate) struct FunctionCx<'clif, 'tcx, B: Backend + 'static> {
pub(crate) bcx: FunctionBuilder<'clif>, pub(crate) bcx: FunctionBuilder<'clif>,
pub(crate) block_map: IndexVec<BasicBlock, Block>, pub(crate) block_map: IndexVec<BasicBlock, Block>,
pub(crate) local_map: FxHashMap<Local, CPlace<'tcx>>, pub(crate) local_map: IndexVec<Local, CPlace<'tcx>>,
/// When `#[track_caller]` is used, the implicit caller location is stored in this variable. /// When `#[track_caller]` is used, the implicit caller location is stored in this variable.
pub(crate) caller_location: Option<CValue<'tcx>>, pub(crate) caller_location: Option<CValue<'tcx>>,
@ -383,7 +383,7 @@ impl<'tcx, B: Backend + 'static> FunctionCx<'_, 'tcx, B> {
} }
pub(crate) fn get_local_place(&mut self, local: Local) -> CPlace<'tcx> { pub(crate) fn get_local_place(&mut self, local: Local) -> CPlace<'tcx> {
*self.local_map.get(&local).unwrap_or_else(|| { *self.local_map.get(local).unwrap_or_else(|| {
panic!("Local {:?} doesn't exist", local); panic!("Local {:?} doesn't exist", local);
}) })
} }

View File

@ -4,6 +4,8 @@ mod unwind;
use crate::prelude::*; use crate::prelude::*;
use rustc_index::vec::IndexVec;
use cranelift_codegen::entity::EntityRef; use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc}; use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc};
use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::isa::TargetIsa;
@ -269,7 +271,7 @@ impl<'tcx> DebugContext<'tcx> {
isa: &dyn TargetIsa, isa: &dyn TargetIsa,
context: &Context, context: &Context,
source_info_set: &indexmap::IndexSet<SourceInfo>, source_info_set: &indexmap::IndexSet<SourceInfo>,
local_map: FxHashMap<mir::Local, CPlace<'tcx>>, local_map: IndexVec<mir::Local, CPlace<'tcx>>,
) { ) {
let symbol = func_id.as_u32() as usize; let symbol = func_id.as_u32() as usize;
let mir = self.tcx.instance_mir(instance.def); let mir = self.tcx.instance_mir(instance.def);
@ -390,7 +392,7 @@ fn place_location<'tcx>(
isa: &dyn TargetIsa, isa: &dyn TargetIsa,
symbol: usize, symbol: usize,
context: &Context, context: &Context,
local_map: &FxHashMap<mir::Local, CPlace<'tcx>>, local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
#[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap< #[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
ValueLabel, ValueLabel,
Vec<ValueLocRange>, Vec<ValueLocRange>,
@ -399,7 +401,7 @@ fn place_location<'tcx>(
) -> AttributeValue { ) -> AttributeValue {
assert!(place.projection.is_empty()); // FIXME implement them assert!(place.projection.is_empty()); // FIXME implement them
match local_map[&place.local].inner() { match local_map[place.local].inner() {
CPlaceInner::Var(_local, var) => { CPlaceInner::Var(_local, var) => {
let value_label = cranelift_codegen::ir::ValueLabel::new(var.index()); let value_label = cranelift_codegen::ir::ValueLabel::new(var.index());
if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) { if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) {