mirror of https://github.com/rust-lang/rust.git
[WIP] Add arbitrary constant support
This commit is contained in:
parent
ee45f7d6bc
commit
af3234cfd7
|
@ -85,6 +85,7 @@ pub fn trans_fn<'a, 'tcx: 'a>(cx: &mut CodegenCx<'a, 'tcx, CurrentBackend>, f: &
|
|||
ebb_map,
|
||||
local_map: HashMap::new(),
|
||||
comments: HashMap::new(),
|
||||
constants: &mut cx.constants,
|
||||
};
|
||||
let fx = &mut fx;
|
||||
|
||||
|
@ -458,6 +459,8 @@ fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, l
|
|||
(BinOp::Shl, _) => fx.bcx.ins().ishl(lhs, rhs),
|
||||
(BinOp::Shr, false) => fx.bcx.ins().ushr(lhs, rhs),
|
||||
(BinOp::Shr, true) => fx.bcx.ins().sshr(lhs, rhs),
|
||||
|
||||
// TODO: cast b1 to u8
|
||||
(BinOp::Eq, _) => fx.bcx.ins().icmp(IntCC::Equal , lhs, rhs),
|
||||
(BinOp::Lt, false) => fx.bcx.ins().icmp(IntCC::UnsignedLessThan , lhs, rhs),
|
||||
(BinOp::Lt, true) => fx.bcx.ins().icmp(IntCC::SignedLessThan , lhs, rhs),
|
||||
|
@ -468,6 +471,7 @@ fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, l
|
|||
(BinOp::Ge, true) => fx.bcx.ins().icmp(IntCC::SignedGreaterThanOrEqual , lhs, rhs),
|
||||
(BinOp::Gt, false) => fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan , lhs, rhs),
|
||||
(BinOp::Gt, true) => fx.bcx.ins().icmp(IntCC::SignedGreaterThan , lhs, rhs),
|
||||
|
||||
(BinOp::Offset, _) => bug!("bin op Offset on non ptr lhs: {:?} rhs: {:?}", lhs, rhs),
|
||||
};
|
||||
// TODO: return correct value for checked binops
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::fmt;
|
|||
use syntax::ast::{IntTy, UintTy};
|
||||
use self::rustc_target::spec::{HasTargetSpec, Target};
|
||||
|
||||
use cranelift_module::{Module, Linkage, FuncId};
|
||||
use cranelift_module::{Module, Linkage, FuncId, DataId};
|
||||
|
||||
use prelude::*;
|
||||
|
||||
|
@ -56,7 +56,7 @@ fn cton_type_from_ty<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) ->
|
|||
return None;
|
||||
}
|
||||
}
|
||||
TypeVariants::TyParam(_) => bug!("{:?}", ty),
|
||||
TypeVariants::TyParam(_) => bug!("{:?}: {:?}", ty, ty.sty),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
@ -288,6 +288,7 @@ pub fn cton_sig_from_instance<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, inst: I
|
|||
|
||||
pub fn cton_sig_from_mono_fn_sig<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sig: PolyFnSig<'tcx>) -> Signature {
|
||||
// TODO: monomorphize signature
|
||||
// TODO: this should likely not use skip_binder()
|
||||
|
||||
let sig = sig.skip_binder();
|
||||
let inputs = sig.inputs();
|
||||
|
@ -334,6 +335,7 @@ pub struct FunctionCx<'a, 'tcx: 'a> {
|
|||
pub ebb_map: HashMap<BasicBlock, Ebb>,
|
||||
pub local_map: HashMap<Local, CPlace<'tcx>>,
|
||||
pub comments: HashMap<Inst, String>,
|
||||
pub constants: &'a mut HashMap<AllocId, DataId>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> fmt::Debug for FunctionCx<'a, 'tcx> {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use prelude::*;
|
||||
use rustc::mir::interpret::{GlobalId, AllocId, read_target_uint};
|
||||
use rustc_mir::interpret::{CompileTimeEvaluator, Memory, MemoryKind};
|
||||
use cranelift_module::*;
|
||||
|
||||
pub fn trans_constant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &Constant<'tcx>) -> CValue<'tcx> {
|
||||
use rustc::mir::interpret::{Scalar, ConstValue, GlobalId};
|
||||
|
||||
let value = match const_.literal {
|
||||
Literal::Value { value } => value,
|
||||
Literal::Promoted { index } => fx
|
||||
|
@ -32,6 +33,74 @@ pub fn trans_constant<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, const_: &Cons
|
|||
let func_ref = fx.get_function_ref(Instance::new(def_id, substs));
|
||||
CValue::Func(func_ref, fx.layout_of(const_.ty))
|
||||
}
|
||||
_ => unimplemented!("value {:?} ty {:?}", value, const_.ty),
|
||||
_ => {
|
||||
let mut memory = Memory::<CompileTimeEvaluator>::new(fx.tcx.at(DUMMY_SP), ());
|
||||
let alloc = fx.tcx.const_value_to_allocation(value);
|
||||
//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 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);
|
||||
CValue::ByRef(global_ptr, layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If ret.1 is true, then the global didn't exist before
|
||||
fn define_global_for_alloc_id(fx: &mut FunctionCx, alloc_id: AllocId, todo: &mut HashMap<AllocId, DataId>) -> (DataId, bool) {
|
||||
use std::collections::hash_map::Entry;
|
||||
match fx.constants.entry(alloc_id) {
|
||||
Entry::Occupied(mut occ) => {
|
||||
(*occ.get_mut(), false)
|
||||
}
|
||||
Entry::Vacant(vac) => {
|
||||
let data_id = fx.module.declare_data(&alloc_id.0.to_string(), Linkage::Local, false).unwrap();
|
||||
todo.insert(alloc_id, data_id);
|
||||
vac.insert(data_id);
|
||||
(data_id, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_global_for_alloc_id(fx: &mut FunctionCx, memory: &Memory<CompileTimeEvaluator>, alloc_id: AllocId) -> DataId {
|
||||
if let Some(data_id) = fx.constants.get(&alloc_id) {
|
||||
return *data_id;
|
||||
}
|
||||
|
||||
let mut todo = HashMap::new();
|
||||
let mut done = HashSet::new();
|
||||
define_global_for_alloc_id(fx, alloc_id, &mut todo);
|
||||
|
||||
while let Some((alloc_id, data_id)) = { let next = todo.drain().next(); next } {
|
||||
println!("cur: {:?}:{:?} todo: {:?} done: {:?}", alloc_id, data_id, todo, done);
|
||||
|
||||
let alloc = memory.get(alloc_id).unwrap();
|
||||
let mut data_ctx = DataContext::new();
|
||||
|
||||
data_ctx.define(alloc.bytes.to_vec().into_boxed_slice(), Writability::Readonly);
|
||||
|
||||
for &(offset, reloc) in alloc.relocations.iter() {
|
||||
let data_id = define_global_for_alloc_id(fx, 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 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);
|
||||
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);
|
||||
}
|
||||
for data_id in done.drain() {
|
||||
fx.module.finalize_data(data_id);
|
||||
}
|
||||
*fx.constants.get(&alloc_id).unwrap()
|
||||
}
|
||||
|
|
|
@ -40,12 +40,13 @@ mod pretty_clif;
|
|||
|
||||
mod prelude {
|
||||
pub use std::any::Any;
|
||||
pub use std::collections::HashMap;
|
||||
pub use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub use syntax::codemap::DUMMY_SP;
|
||||
pub use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
pub use rustc::mir;
|
||||
pub use rustc::mir::*;
|
||||
pub use rustc::mir::interpret::AllocId;
|
||||
pub use rustc::session::Session;
|
||||
pub use rustc::ty::layout::{self, LayoutOf, TyLayout, Size};
|
||||
pub use rustc::ty::{
|
||||
|
@ -60,7 +61,7 @@ mod prelude {
|
|||
};
|
||||
pub use cranelift::codegen::Context;
|
||||
pub use cranelift::prelude::*;
|
||||
pub use cranelift_module::{Module, Backend, FuncId, Linkage};
|
||||
pub use cranelift_module::{Module, Backend, FuncId, DataId, Linkage};
|
||||
pub use cranelift_simplejit::{SimpleJITBuilder, SimpleJITBackend};
|
||||
|
||||
pub use common::Variable;
|
||||
|
@ -75,6 +76,7 @@ pub struct CodegenCx<'a, 'tcx: 'a, B: Backend + 'a> {
|
|||
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub module: &'a mut Module<B>,
|
||||
pub def_id_fn_id_map: &'a mut HashMap<Instance<'tcx>, FuncId>,
|
||||
pub constants: HashMap<AllocId, DataId>,
|
||||
}
|
||||
|
||||
struct CraneliftCodegenBackend(());
|
||||
|
@ -176,6 +178,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||
tcx,
|
||||
module: &mut module,
|
||||
def_id_fn_id_map: &mut def_id_fn_id_map,
|
||||
constants: HashMap::new(),
|
||||
};
|
||||
|
||||
for mono_item in
|
||||
|
|
Loading…
Reference in New Issue