diff --git a/src/base.rs b/src/base.rs index f001db4600d..4a3de4fa52b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -69,7 +69,9 @@ pub fn trans_mono_item<'a, 'tcx: 'a>( } => unimpl!("Unimplemented drop glue instance"), inst => unimpl!("Unimplemented instance {:?}", inst), }, - MonoItem::Static(def_id) => unimpl!("Unimplemented static mono item {:?}", def_id), + MonoItem::Static(def_id) => { + crate::constant::codegen_static(cx, def_id); + } MonoItem::GlobalAsm(node_id) => cx .tcx .sess @@ -860,9 +862,7 @@ pub fn trans_place<'a, 'tcx: 'a>( match place { Place::Local(local) => fx.get_local_place(*local), Place::Promoted(promoted) => crate::constant::trans_promoted(fx, promoted.0), - Place::Static(static_) => { - unimpl!("static place {:?} ty {:?}", static_.def_id, static_.ty); - } + Place::Static(static_) => crate::constant::codegen_static_ref(fx, static_), Place::Projection(projection) => { let base = trans_place(fx, &projection.base); match projection.elem { diff --git a/src/common.rs b/src/common.rs index 70e2d283f60..ad0fb3392ca 100644 --- a/src/common.rs +++ b/src/common.rs @@ -2,7 +2,7 @@ use std::fmt; use rustc_target::spec::{HasTargetSpec, Target}; -use cranelift_module::{DataId, Module}; +use cranelift_module::Module; use crate::prelude::*; @@ -361,7 +361,7 @@ pub struct FunctionCx<'a, 'tcx: 'a> { pub ebb_map: HashMap, pub local_map: HashMap>, pub comments: HashMap, - pub constants: &'a mut HashMap, + pub constants: &'a mut crate::constant::ConstantCx, } impl<'a, 'tcx: 'a> fmt::Debug for FunctionCx<'a, 'tcx> { diff --git a/src/constant.rs b/src/constant.rs index 91352744fe4..700a53bd645 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -2,7 +2,32 @@ use cranelift_module::*; use crate::prelude::*; use rustc::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalId}; use rustc::ty::Const; -use rustc_mir::interpret::{CompileTimeEvaluator, Memory, MemoryKind}; +use rustc_mir::interpret::{CompileTimeEvaluator, Memory}; + +#[derive(Default)] +pub struct ConstantCx { + constants: HashMap, + done: HashSet, +} + +impl ConstantCx { + pub fn finalize(mut self, module: &mut Module) { + for data_id in self.done.drain() { + module.finalize_data(data_id); + } + } +} + +pub fn codegen_static<'a, 'tcx: 'a, B: Backend>(_cx: &mut CodegenCx<'a, 'tcx, B>, def_id: DefId) { + unimpl!("Unimplemented static mono item {:?}", def_id); +} + +pub fn codegen_static_ref<'a, 'tcx: 'a>( + _fx: &mut FunctionCx<'a, 'tcx>, + static_: &Static<'tcx>, +) -> CPlace<'tcx> { + unimpl!("Unimplemented static mono item {:?}", static_.def_id); +} pub fn trans_promoted<'a, 'tcx: 'a>( fx: &mut FunctionCx<'a, 'tcx>, @@ -90,13 +115,15 @@ fn trans_const_place<'a, 'tcx: 'a>( // thus causing panics for some consts, so this disables it return CPlace::Addr(fx.bcx.ins().iconst(types::I64, 0), layout); } - let mut memory = Memory::::new(fx.tcx.at(DUMMY_SP), ()); let alloc = fx.tcx.const_value_to_allocation(const_); //println!("const value: {:?} allocation: {:?}", value, alloc); - let alloc_id = memory - .allocate_value(alloc.clone(), MemoryKind::Stack) - .unwrap(); - let data_id = get_global_for_alloc_id(fx, &memory, alloc_id); + let alloc_id = fx.tcx.alloc_map.lock().allocate(alloc); + let data_id = get_global_for_alloc_id( + fx.tcx, + fx.module, + fx.constants, + alloc_id, + ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); // TODO: does global_value return a ptr of a val? let global_ptr = fx.bcx.ins().global_value(types::I64, local_data_id); @@ -104,17 +131,17 @@ fn trans_const_place<'a, 'tcx: 'a>( } // If ret.1 is true, then the global didn't exist before -fn define_global_for_alloc_id( - fx: &mut FunctionCx, +fn define_global_for_alloc_id<'a, 'tcx: 'a, B: Backend>( + module: &mut Module, + cx: &mut ConstantCx,//<'a, 'tcx>, alloc_id: AllocId, todo: &mut HashMap, ) -> (DataId, bool) { use std::collections::hash_map::Entry; - match fx.constants.entry(alloc_id) { + match cx.constants.entry(alloc_id) { Entry::Occupied(mut occ) => (*occ.get_mut(), false), Entry::Vacant(vac) => { - let data_id = fx - .module + let data_id = module .declare_data(&alloc_id.0.to_string(), Linkage::Local, false) .unwrap(); todo.insert(alloc_id, data_id); @@ -124,18 +151,20 @@ fn define_global_for_alloc_id( } } -fn get_global_for_alloc_id( - fx: &mut FunctionCx, - memory: &Memory, +fn get_global_for_alloc_id<'a, 'tcx: 'a, B: Backend + 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + module: &mut Module, + cx: &mut ConstantCx,//<'a, 'tcx>, alloc_id: AllocId, ) -> DataId { - if let Some(data_id) = fx.constants.get(&alloc_id) { + if let Some(data_id) = cx.constants.get(&alloc_id) { return *data_id; } + let memory = Memory::::new(tcx.at(DUMMY_SP), ()); + let mut todo = HashMap::new(); - let mut done = HashSet::new(); - define_global_for_alloc_id(fx, alloc_id, &mut todo); + define_global_for_alloc_id(module, cx, alloc_id, &mut todo); while let Some((alloc_id, data_id)) = { let next = todo.drain().next(); @@ -143,10 +172,11 @@ fn get_global_for_alloc_id( } { println!( "cur: {:?}:{:?} todo: {:?} done: {:?}", - alloc_id, data_id, todo, done + alloc_id, data_id, todo, cx.done ); let alloc = memory.get(alloc_id).unwrap(); + //let alloc = tcx.alloc_map.lock().get(alloc_id).unwrap(); let mut data_ctx = DataContext::new(); data_ctx.define( @@ -155,26 +185,23 @@ fn get_global_for_alloc_id( ); for &(offset, reloc) in alloc.relocations.iter() { - let data_id = define_global_for_alloc_id(fx, reloc, &mut todo).0; + let data_id = define_global_for_alloc_id(module, cx, reloc, &mut todo).0; let reloc_offset = { let endianness = memory.endianness(); let offset = offset.bytes() as usize; - let ptr_size = fx.tcx.data_layout.pointer_size; + let ptr_size = tcx.data_layout.pointer_size; let bytes = &alloc.bytes[offset..offset + ptr_size.bytes() as usize]; read_target_uint(endianness, bytes).unwrap() }; // TODO: is this a correct usage of the api - let global_value = fx.module.declare_data_in_data(data_id, &mut data_ctx); + let global_value = module.declare_data_in_data(data_id, &mut data_ctx); data_ctx.write_data_addr(reloc_offset as u32, global_value, 0); } - fx.module.define_data(data_id, &data_ctx).unwrap(); - done.insert(data_id); + module.define_data(data_id, &data_ctx).unwrap(); + cx.done.insert(data_id); } - for data_id in done.drain() { - fx.module.finalize_data(data_id); - } - *fx.constants.get(&alloc_id).unwrap() + *cx.constants.get(&alloc_id).unwrap() } diff --git a/src/lib.rs b/src/lib.rs index bb51ba659c3..70b9418bf29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,7 +96,7 @@ use crate::prelude::*; pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub module: &'a mut Module, - pub constants: HashMap, + pub constants: crate::constant::ConstantCx, pub defined_functions: Vec, } @@ -251,7 +251,7 @@ impl CodegenBackend for CraneliftCodegenBackend { let mut cx = CodegenCx { tcx, module: &mut module, - constants: HashMap::new(), + constants: Default::default(), defined_functions: Vec::new(), }; @@ -280,10 +280,13 @@ impl CodegenBackend for CraneliftCodegenBackend { } } } + + cx.constants.finalize(&mut cx.module); + let after = ::std::time::Instant::now(); println!("time: {:?}", after - before); - std::mem::replace(&mut cx.defined_functions, Vec::new()) + cx.defined_functions }; tcx.sess.warn("Compiled everything");