diff options
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/constant.rs')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/constant.rs | 66 | 
1 files changed, 34 insertions, 32 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index fc9b0f6ef02..635ed6c8e88 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -6,17 +6,16 @@ use cranelift_module::*; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar}; -use rustc_middle::ty::ScalarInt; +use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt}; use crate::prelude::*; pub(crate) struct ConstantCx { todo: Vec<TodoItem>, - done: FxHashSet<DataId>, anon_allocs: FxHashMap<AllocId, DataId>, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] enum TodoItem { Alloc(AllocId), Static(DefId), @@ -24,19 +23,24 @@ enum TodoItem { impl ConstantCx { pub(crate) fn new() -> Self { - ConstantCx { todo: vec![], done: FxHashSet::default(), anon_allocs: FxHashMap::default() } + ConstantCx { todo: vec![], anon_allocs: FxHashMap::default() } } pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) { define_all_allocs(tcx, module, &mut self); - self.done.clear(); } } -pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) { +pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) -> DataId { let mut constants_cx = ConstantCx::new(); constants_cx.todo.push(TodoItem::Static(def_id)); constants_cx.finalize(tcx, module); + + data_id_for_static( + tcx, module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ) } pub(crate) fn codegen_tls_ref<'tcx>( @@ -153,14 +157,12 @@ pub(crate) fn codegen_const_value<'tcx>( fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); - let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - // FIXME: factor this common code with the `Memory` arm into a function? - let data_id = data_id_for_alloc_id( + let data_id = data_id_for_vtable( + fx.tcx, &mut fx.constants_cx, fx.module, - alloc_id, - alloc.inner().mutability, + ty, + trait_ref, ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); @@ -208,12 +210,8 @@ fn pointer_for_allocation<'tcx>( alloc_id: AllocId, ) -> crate::pointer::Pointer { let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - let data_id = data_id_for_alloc_id( - &mut fx.constants_cx, - &mut *fx.module, - alloc_id, - alloc.inner().mutability, - ); + let data_id = + data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { @@ -235,6 +233,17 @@ pub(crate) fn data_id_for_alloc_id( .or_insert_with(|| module.declare_anonymous_data(mutability.is_mut(), false).unwrap()) } +pub(crate) fn data_id_for_vtable<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut ConstantCx, + module: &mut dyn Module, + ty: Ty<'tcx>, + trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>, +) -> DataId { + let alloc_id = tcx.vtable_allocation((ty, trait_ref)); + data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) +} + fn data_id_for_static( tcx: TyCtxt<'_>, module: &mut dyn Module, @@ -327,7 +336,12 @@ fn data_id_for_static( } fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { + let mut done = FxHashSet::default(); while let Some(todo_item) = cx.todo.pop() { + if !done.insert(todo_item) { + continue; + } + let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { let alloc = match tcx.global_alloc(alloc_id) { @@ -358,10 +372,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } }; - if cx.done.contains(&data_id) { - continue; - } - let mut data = DataDescription::new(); let alloc = alloc.inner(); data.set_align(alloc.align.bytes()); @@ -384,13 +394,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec(); - if bytes.is_empty() { - // FIXME(bytecodealliance/wasmtime#7918) cranelift-jit has a bug where it causes UB on - // empty data objects - data.define(Box::new([0])); - } else { - data.define(bytes.into_boxed_slice()); - } + data.define(bytes.into_boxed_slice()); for &(offset, prov) in alloc.provenance().ptrs().iter() { let alloc_id = prov.alloc_id(); @@ -418,8 +422,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability) } GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = tcx.vtable_allocation((ty, trait_ref)); - data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) + data_id_for_vtable(tcx, cx, module, ty, trait_ref) } GlobalAlloc::Static(def_id) => { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) @@ -446,7 +449,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } module.define_data(data_id, &data).unwrap(); - cx.done.insert(data_id); } assert!(cx.todo.is_empty(), "{:?}", cx.todo);  | 
