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