Rustfmt
This commit is contained in:
4
rustfmt.toml
Normal file
4
rustfmt.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Matches rustfmt.toml of rustc
|
||||||
|
version = "Two"
|
||||||
|
use_small_heuristics = "Max"
|
||||||
|
merge_derives = false
|
||||||
@@ -42,11 +42,7 @@ pub(super) fn add_arg_comment<'tcx>(
|
|||||||
[param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)),
|
[param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)),
|
||||||
params => Cow::Owned(format!(
|
params => Cow::Owned(format!(
|
||||||
"= {}",
|
"= {}",
|
||||||
params
|
params.iter().map(ToString::to_string).collect::<Vec<_>>().join(",")
|
||||||
.iter()
|
|
||||||
.map(ToString::to_string)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(",")
|
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,14 +71,8 @@ pub(super) fn add_local_place_comments<'tcx>(
|
|||||||
local: Local,
|
local: Local,
|
||||||
) {
|
) {
|
||||||
let TyAndLayout { ty, layout } = place.layout();
|
let TyAndLayout { ty, layout } = place.layout();
|
||||||
let rustc_target::abi::Layout {
|
let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } =
|
||||||
size,
|
layout;
|
||||||
align,
|
|
||||||
abi: _,
|
|
||||||
variants: _,
|
|
||||||
fields: _,
|
|
||||||
largest_niche: _,
|
|
||||||
} = layout;
|
|
||||||
|
|
||||||
let (kind, extra) = match *place.inner() {
|
let (kind, extra) = match *place.inner() {
|
||||||
CPlaceInner::Var(place_local, var) => {
|
CPlaceInner::Var(place_local, var) => {
|
||||||
@@ -91,10 +81,7 @@ pub(super) fn add_local_place_comments<'tcx>(
|
|||||||
}
|
}
|
||||||
CPlaceInner::VarPair(place_local, var1, var2) => {
|
CPlaceInner::VarPair(place_local, var1, var2) => {
|
||||||
assert_eq!(local, place_local);
|
assert_eq!(local, place_local);
|
||||||
(
|
("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())))
|
||||||
"ssa",
|
|
||||||
Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
|
CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
|
||||||
CPlaceInner::Addr(ptr, meta) => {
|
CPlaceInner::Addr(ptr, meta) => {
|
||||||
@@ -104,18 +91,15 @@ pub(super) fn add_local_place_comments<'tcx>(
|
|||||||
Cow::Borrowed("")
|
Cow::Borrowed("")
|
||||||
};
|
};
|
||||||
match ptr.base_and_offset() {
|
match ptr.base_and_offset() {
|
||||||
(crate::pointer::PointerBase::Addr(addr), offset) => (
|
(crate::pointer::PointerBase::Addr(addr), offset) => {
|
||||||
"reuse",
|
("reuse", format!("storage={}{}{}", addr, offset, meta).into())
|
||||||
format!("storage={}{}{}", addr, offset, meta).into(),
|
}
|
||||||
),
|
(crate::pointer::PointerBase::Stack(stack_slot), offset) => {
|
||||||
(crate::pointer::PointerBase::Stack(stack_slot), offset) => (
|
("stack", format!("storage={}{}{}", stack_slot, offset, meta).into())
|
||||||
"stack",
|
}
|
||||||
format!("storage={}{}{}", stack_slot, offset, meta).into(),
|
(crate::pointer::PointerBase::Dangling(align), offset) => {
|
||||||
),
|
("zst", format!("align={},offset={}", align.bytes(), offset).into())
|
||||||
(crate::pointer::PointerBase::Dangling(align), offset) => (
|
}
|
||||||
"zst",
|
|
||||||
format!("align={},offset={}", align.bytes(), offset).into(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -128,11 +112,7 @@ pub(super) fn add_local_place_comments<'tcx>(
|
|||||||
size.bytes(),
|
size.bytes(),
|
||||||
align.abi.bytes(),
|
align.abi.bytes(),
|
||||||
align.pref.bytes(),
|
align.pref.bytes(),
|
||||||
if extra.is_empty() {
|
if extra.is_empty() { "" } else { " " },
|
||||||
""
|
|
||||||
} else {
|
|
||||||
" "
|
|
||||||
},
|
|
||||||
extra,
|
extra,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
123
src/abi/mod.rs
123
src/abi/mod.rs
@@ -40,21 +40,13 @@ fn clif_sig_from_fn_abi<'tcx>(
|
|||||||
| Conv::AvrInterrupt
|
| Conv::AvrInterrupt
|
||||||
| Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv),
|
| Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv),
|
||||||
};
|
};
|
||||||
let inputs = fn_abi
|
let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
|
||||||
.args
|
|
||||||
.iter()
|
|
||||||
.map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter())
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
|
let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
|
||||||
// Sometimes the first param is an pointer to the place where the return value needs to be stored.
|
// Sometimes the first param is an pointer to the place where the return value needs to be stored.
|
||||||
let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
|
let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
|
||||||
|
|
||||||
Signature {
|
Signature { params, returns, call_conv }
|
||||||
params,
|
|
||||||
returns,
|
|
||||||
call_conv,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_function_sig<'tcx>(
|
pub(crate) fn get_function_sig<'tcx>(
|
||||||
@@ -63,11 +55,7 @@ pub(crate) fn get_function_sig<'tcx>(
|
|||||||
inst: Instance<'tcx>,
|
inst: Instance<'tcx>,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
assert!(!inst.substs.needs_infer());
|
assert!(!inst.substs.needs_infer());
|
||||||
clif_sig_from_fn_abi(
|
clif_sig_from_fn_abi(tcx, triple, &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]))
|
||||||
tcx,
|
|
||||||
triple,
|
|
||||||
&FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instance must be monomorphized
|
/// Instance must be monomorphized
|
||||||
@@ -78,19 +66,14 @@ pub(crate) fn import_function<'tcx>(
|
|||||||
) -> FuncId {
|
) -> FuncId {
|
||||||
let name = tcx.symbol_name(inst).name.to_string();
|
let name = tcx.symbol_name(inst).name.to_string();
|
||||||
let sig = get_function_sig(tcx, module.isa().triple(), inst);
|
let sig = get_function_sig(tcx, module.isa().triple(), inst);
|
||||||
module
|
module.declare_function(&name, Linkage::Import, &sig).unwrap()
|
||||||
.declare_function(&name, Linkage::Import, &sig)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||||
/// Instance must be monomorphized
|
/// Instance must be monomorphized
|
||||||
pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef {
|
pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef {
|
||||||
let func_id = import_function(self.tcx, self.cx.module, inst);
|
let func_id = import_function(self.tcx, self.cx.module, inst);
|
||||||
let func_ref = self
|
let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func);
|
||||||
.cx
|
|
||||||
.module
|
|
||||||
.declare_func_in_func(func_id, &mut self.bcx.func);
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
self.add_comment(func_ref, format!("{:?}", inst));
|
self.add_comment(func_ref, format!("{:?}", inst));
|
||||||
@@ -105,20 +88,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
returns: Vec<AbiParam>,
|
returns: Vec<AbiParam>,
|
||||||
args: &[Value],
|
args: &[Value],
|
||||||
) -> &[Value] {
|
) -> &[Value] {
|
||||||
let sig = Signature {
|
let sig = Signature { params, returns, call_conv: CallConv::triple_default(self.triple()) };
|
||||||
params,
|
let func_id = self.cx.module.declare_function(&name, Linkage::Import, &sig).unwrap();
|
||||||
returns,
|
let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func);
|
||||||
call_conv: CallConv::triple_default(self.triple()),
|
|
||||||
};
|
|
||||||
let func_id = self
|
|
||||||
.cx
|
|
||||||
.module
|
|
||||||
.declare_function(&name, Linkage::Import, &sig)
|
|
||||||
.unwrap();
|
|
||||||
let func_ref = self
|
|
||||||
.cx
|
|
||||||
.module
|
|
||||||
.declare_func_in_func(func_id, &mut self.bcx.func);
|
|
||||||
let call_inst = self.bcx.ins().call(func_ref, args);
|
let call_inst = self.bcx.ins().call(func_ref, args);
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
@@ -138,17 +110,12 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
let (input_tys, args): (Vec<_>, Vec<_>) = args
|
let (input_tys, args): (Vec<_>, Vec<_>) = args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
(
|
(AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self))
|
||||||
AbiParam::new(self.clif_type(arg.layout().ty).unwrap()),
|
|
||||||
arg.load_scalar(self),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
let return_layout = self.layout_of(return_ty);
|
let return_layout = self.layout_of(return_ty);
|
||||||
let return_tys = if let ty::Tuple(tup) = return_ty.kind() {
|
let return_tys = if let ty::Tuple(tup) = return_ty.kind() {
|
||||||
tup.types()
|
tup.types().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect()
|
||||||
.map(|ty| AbiParam::new(self.clif_type(ty).unwrap()))
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
vec![AbiParam::new(self.clif_type(return_ty).unwrap())]
|
vec![AbiParam::new(self.clif_type(return_ty).unwrap())]
|
||||||
};
|
};
|
||||||
@@ -199,13 +166,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
self::comments::add_args_header_comment(fx);
|
self::comments::add_args_header_comment(fx);
|
||||||
|
|
||||||
let mut block_params_iter = fx
|
let mut block_params_iter = fx.bcx.func.dfg.block_params(start_block).to_vec().into_iter();
|
||||||
.bcx
|
|
||||||
.func
|
|
||||||
.dfg
|
|
||||||
.block_params(start_block)
|
|
||||||
.to_vec()
|
|
||||||
.into_iter();
|
|
||||||
let ret_place =
|
let ret_place =
|
||||||
self::returning::codegen_return_param(fx, &ssa_analyzed, &mut block_params_iter);
|
self::returning::codegen_return_param(fx, &ssa_analyzed, &mut block_params_iter);
|
||||||
assert_eq!(fx.local_map.push(ret_place), RETURN_PLACE);
|
assert_eq!(fx.local_map.push(ret_place), RETURN_PLACE);
|
||||||
@@ -281,10 +242,10 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
|||||||
if let Some((addr, meta)) = val.try_to_ptr() {
|
if let Some((addr, meta)) = val.try_to_ptr() {
|
||||||
let local_decl = &fx.mir.local_decls[local];
|
let local_decl = &fx.mir.local_decls[local];
|
||||||
// v this ! is important
|
// v this ! is important
|
||||||
let internally_mutable = !val.layout().ty.is_freeze(
|
let internally_mutable = !val
|
||||||
fx.tcx.at(local_decl.source_info.span),
|
.layout()
|
||||||
ParamEnv::reveal_all(),
|
.ty
|
||||||
);
|
.is_freeze(fx.tcx.at(local_decl.source_info.span), ParamEnv::reveal_all());
|
||||||
if local_decl.mutability == mir::Mutability::Not && !internally_mutable {
|
if local_decl.mutability == mir::Mutability::Not && !internally_mutable {
|
||||||
// We wont mutate this argument, so it is fine to borrow the backing storage
|
// We wont mutate this argument, so it is fine to borrow the backing storage
|
||||||
// of this argument, to prevent a copy.
|
// of this argument, to prevent a copy.
|
||||||
@@ -316,9 +277,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
|||||||
ArgKind::Spread(params) => {
|
ArgKind::Spread(params) => {
|
||||||
for (i, param) in params.into_iter().enumerate() {
|
for (i, param) in params.into_iter().enumerate() {
|
||||||
if let Some(param) = param {
|
if let Some(param) = param {
|
||||||
place
|
place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param);
|
||||||
.place_field(fx, mir::Field::new(i))
|
|
||||||
.write_cvalue(fx, param);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,9 +294,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
|||||||
assert_eq!(fx.local_map.push(place), local);
|
assert_eq!(fx.local_map.push(place), local);
|
||||||
}
|
}
|
||||||
|
|
||||||
fx.bcx
|
fx.bcx.ins().jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]);
|
||||||
.ins()
|
|
||||||
.jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn codegen_terminator_call<'tcx>(
|
pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
@@ -349,9 +306,8 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
destination: Option<(Place<'tcx>, BasicBlock)>,
|
destination: Option<(Place<'tcx>, BasicBlock)>,
|
||||||
) {
|
) {
|
||||||
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
|
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
|
||||||
let fn_sig = fx
|
let fn_sig =
|
||||||
.tcx
|
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
|
||||||
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
|
|
||||||
|
|
||||||
let destination = destination.map(|(place, bb)| (codegen_place(fx, place), bb));
|
let destination = destination.map(|(place, bb)| (codegen_place(fx, place), bb));
|
||||||
|
|
||||||
@@ -399,20 +355,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
let fn_abi = if let Some(instance) = instance {
|
let fn_abi = if let Some(instance) = instance {
|
||||||
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
|
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
|
||||||
} else {
|
} else {
|
||||||
FnAbi::of_fn_ptr(
|
FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args)
|
||||||
&RevealAllLayoutCx(fx.tcx),
|
|
||||||
fn_ty.fn_sig(fx.tcx),
|
|
||||||
&extra_args,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_cold = instance
|
let is_cold = instance
|
||||||
.map(|inst| {
|
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
|
||||||
fx.tcx
|
|
||||||
.codegen_fn_attrs(inst.def_id())
|
|
||||||
.flags
|
|
||||||
.contains(CodegenFnAttrFlags::COLD)
|
|
||||||
})
|
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if is_cold {
|
if is_cold {
|
||||||
fx.cold_blocks.insert(current_block);
|
fx.cold_blocks.insert(current_block);
|
||||||
@@ -436,9 +383,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
}
|
}
|
||||||
args
|
args
|
||||||
} else {
|
} else {
|
||||||
args.iter()
|
args.iter().map(|arg| codegen_operand(fx, arg)).collect::<Vec<_>>()
|
||||||
.map(|arg| codegen_operand(fx, arg))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// | indirect call target
|
// | indirect call target
|
||||||
@@ -446,10 +391,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
// v v
|
// v v
|
||||||
let (func_ref, first_arg) = match instance {
|
let (func_ref, first_arg) = match instance {
|
||||||
// Trait object call
|
// Trait object call
|
||||||
Some(Instance {
|
Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => {
|
||||||
def: InstanceDef::Virtual(_, idx),
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let nop_inst = fx.bcx.ins().nop();
|
let nop_inst = fx.bcx.ins().nop();
|
||||||
@@ -506,10 +448,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
)
|
)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if instance
|
if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) {
|
||||||
.map(|inst| inst.def.requires_caller_location(fx.tcx))
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
// Pass the caller location for `#[track_caller]`.
|
// Pass the caller location for `#[track_caller]`.
|
||||||
let caller_location = fx.get_caller_location(span);
|
let caller_location = fx.get_caller_location(span);
|
||||||
call_args.extend(
|
call_args.extend(
|
||||||
@@ -538,10 +477,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
// FIXME find a cleaner way to support varargs
|
// FIXME find a cleaner way to support varargs
|
||||||
if fn_sig.c_variadic {
|
if fn_sig.c_variadic {
|
||||||
if fn_sig.abi != Abi::C {
|
if fn_sig.abi != Abi::C {
|
||||||
fx.tcx.sess.span_fatal(
|
fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi));
|
||||||
span,
|
|
||||||
&format!("Variadic call for non-C abi {:?}", fn_sig.abi),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
||||||
let abi_params = call_args
|
let abi_params = call_args
|
||||||
@@ -550,9 +486,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
let ty = fx.bcx.func.dfg.value_type(arg);
|
let ty = fx.bcx.func.dfg.value_type(arg);
|
||||||
if !ty.is_int() {
|
if !ty.is_int() {
|
||||||
// FIXME set %al to upperbound on float args once floats are supported
|
// FIXME set %al to upperbound on float args once floats are supported
|
||||||
fx.tcx
|
fx.tcx.sess.span_fatal(span, &format!("Non int ty {:?} for variadic call", ty));
|
||||||
.sess
|
|
||||||
.span_fatal(span, &format!("Non int ty {:?} for variadic call", ty));
|
|
||||||
}
|
}
|
||||||
AbiParam::new(ty)
|
AbiParam::new(ty)
|
||||||
})
|
})
|
||||||
@@ -606,10 +540,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
|||||||
fx,
|
fx,
|
||||||
fx.layout_of(fx.tcx.mk_ref(
|
fx.layout_of(fx.tcx.mk_ref(
|
||||||
&ty::RegionKind::ReErased,
|
&ty::RegionKind::ReErased,
|
||||||
TypeAndMut {
|
TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut },
|
||||||
ty,
|
|
||||||
mutbl: crate::rustc_hir::Mutability::Mut,
|
|
||||||
},
|
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0]);
|
let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0]);
|
||||||
|
|||||||
@@ -71,12 +71,7 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
|
|||||||
.prefix
|
.prefix
|
||||||
.iter()
|
.iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|&kind| {
|
.map(|&kind| reg_to_abi_param(Reg { kind, size: cast.prefix_chunk_size }))
|
||||||
reg_to_abi_param(Reg {
|
|
||||||
kind,
|
|
||||||
size: cast.prefix_chunk_size,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))
|
.chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)))
|
||||||
.collect::<SmallVec<_>>();
|
.collect::<SmallVec<_>>();
|
||||||
|
|
||||||
@@ -120,11 +115,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||||||
_ => unreachable!("{:?}", self.layout.abi),
|
_ => unreachable!("{:?}", self.layout.abi),
|
||||||
},
|
},
|
||||||
PassMode::Cast(cast) => cast_target_to_abi_params(cast),
|
PassMode::Cast(cast) => cast_target_to_abi_params(cast),
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
|
||||||
attrs,
|
|
||||||
extra_attrs: None,
|
|
||||||
on_stack,
|
|
||||||
} => {
|
|
||||||
if on_stack {
|
if on_stack {
|
||||||
let size = u32::try_from(self.layout.size.bytes()).unwrap();
|
let size = u32::try_from(self.layout.size.bytes()).unwrap();
|
||||||
smallvec![apply_arg_attrs_to_abi_param(
|
smallvec![apply_arg_attrs_to_abi_param(
|
||||||
@@ -132,17 +123,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||||||
attrs
|
attrs
|
||||||
)]
|
)]
|
||||||
} else {
|
} else {
|
||||||
smallvec![apply_arg_attrs_to_abi_param(
|
smallvec![apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)]
|
||||||
AbiParam::new(pointer_ty(tcx)),
|
|
||||||
attrs
|
|
||||||
)]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
|
||||||
attrs,
|
|
||||||
extra_attrs: Some(extra_attrs),
|
|
||||||
on_stack,
|
|
||||||
} => {
|
|
||||||
assert!(!on_stack);
|
assert!(!on_stack);
|
||||||
smallvec![
|
smallvec![
|
||||||
apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs),
|
apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs),
|
||||||
@@ -156,10 +140,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||||||
match self.mode {
|
match self.mode {
|
||||||
PassMode::Ignore => (None, vec![]),
|
PassMode::Ignore => (None, vec![]),
|
||||||
PassMode::Direct(_) => match &self.layout.abi {
|
PassMode::Direct(_) => match &self.layout.abi {
|
||||||
Abi::Scalar(scalar) => (
|
Abi::Scalar(scalar) => {
|
||||||
None,
|
(None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))])
|
||||||
vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))],
|
}
|
||||||
),
|
|
||||||
Abi::Vector { .. } => {
|
Abi::Vector { .. } => {
|
||||||
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
|
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
|
||||||
(None, vec![AbiParam::new(vector_ty)])
|
(None, vec![AbiParam::new(vector_ty)])
|
||||||
@@ -175,25 +158,13 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||||||
_ => unreachable!("{:?}", self.layout.abi),
|
_ => unreachable!("{:?}", self.layout.abi),
|
||||||
},
|
},
|
||||||
PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()),
|
PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()),
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => {
|
||||||
attrs: _,
|
|
||||||
extra_attrs: None,
|
|
||||||
on_stack,
|
|
||||||
} => {
|
|
||||||
assert!(!on_stack);
|
assert!(!on_stack);
|
||||||
(
|
(Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![])
|
||||||
Some(AbiParam::special(
|
}
|
||||||
pointer_ty(tcx),
|
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
|
||||||
ArgumentPurpose::StructReturn,
|
unreachable!("unsized return value")
|
||||||
)),
|
|
||||||
vec![],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
|
||||||
attrs: _,
|
|
||||||
extra_attrs: Some(_),
|
|
||||||
on_stack: _,
|
|
||||||
} => unreachable!("unsized return value"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,9 +180,7 @@ pub(super) fn to_casted_value<'tcx>(
|
|||||||
cast_target_to_abi_params(cast)
|
cast_target_to_abi_params(cast)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|param| {
|
.map(|param| {
|
||||||
let val = ptr
|
let val = ptr.offset_i64(fx, offset).load(fx, param.value_type, MemFlags::new());
|
||||||
.offset_i64(fx, offset)
|
|
||||||
.load(fx, param.value_type, MemFlags::new());
|
|
||||||
offset += i64::from(param.value_type.bytes());
|
offset += i64::from(param.value_type.bytes());
|
||||||
val
|
val
|
||||||
})
|
})
|
||||||
@@ -225,10 +194,7 @@ pub(super) fn from_casted_value<'tcx>(
|
|||||||
cast: CastTarget,
|
cast: CastTarget,
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
let abi_params = cast_target_to_abi_params(cast);
|
let abi_params = cast_target_to_abi_params(cast);
|
||||||
let abi_param_size: u32 = abi_params
|
let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();
|
||||||
.iter()
|
|
||||||
.map(|param| param.value_type.bytes())
|
|
||||||
.sum();
|
|
||||||
let layout_size = u32::try_from(layout.size.bytes()).unwrap();
|
let layout_size = u32::try_from(layout.size.bytes()).unwrap();
|
||||||
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
||||||
kind: StackSlotKind::ExplicitSlot,
|
kind: StackSlotKind::ExplicitSlot,
|
||||||
@@ -292,10 +258,7 @@ pub(super) fn cvalue_for_param<'tcx>(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|abi_param| {
|
.map(|abi_param| {
|
||||||
let block_param = block_params_iter.next().unwrap();
|
let block_param = block_params_iter.next().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(fx.bcx.func.dfg.value_type(block_param), abi_param.value_type);
|
||||||
fx.bcx.func.dfg.value_type(block_param),
|
|
||||||
abi_param.value_type
|
|
||||||
);
|
|
||||||
block_param
|
block_param
|
||||||
})
|
})
|
||||||
.collect::<SmallVec<[_; 2]>>();
|
.collect::<SmallVec<[_; 2]>>();
|
||||||
@@ -319,29 +282,14 @@ pub(super) fn cvalue_for_param<'tcx>(
|
|||||||
}
|
}
|
||||||
PassMode::Pair(_, _) => {
|
PassMode::Pair(_, _) => {
|
||||||
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
||||||
Some(CValue::by_val_pair(
|
Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout))
|
||||||
block_params[0],
|
|
||||||
block_params[1],
|
|
||||||
arg_abi.layout,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)),
|
PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)),
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
|
||||||
attrs: _,
|
|
||||||
extra_attrs: None,
|
|
||||||
on_stack: _,
|
|
||||||
} => {
|
|
||||||
assert_eq!(block_params.len(), 1, "{:?}", block_params);
|
assert_eq!(block_params.len(), 1, "{:?}", block_params);
|
||||||
Some(CValue::by_ref(
|
Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout))
|
||||||
Pointer::new(block_params[0]),
|
|
||||||
arg_abi.layout,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
|
||||||
attrs: _,
|
|
||||||
extra_attrs: Some(_),
|
|
||||||
on_stack: _,
|
|
||||||
} => {
|
|
||||||
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
||||||
Some(CValue::by_ref_unsized(
|
Some(CValue::by_ref_unsized(
|
||||||
Pointer::new(block_params[0]),
|
Pointer::new(block_params[0]),
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ pub(crate) fn can_return_to_ssa_var<'tcx>(
|
|||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
|
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
|
||||||
let fn_sig = fx
|
let fn_sig =
|
||||||
.tcx
|
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
|
||||||
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
|
|
||||||
|
|
||||||
// Handle special calls like instrinsics and empty drop glue.
|
// Handle special calls like instrinsics and empty drop glue.
|
||||||
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
|
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
|
||||||
@@ -42,11 +41,7 @@ pub(crate) fn can_return_to_ssa_var<'tcx>(
|
|||||||
let fn_abi = if let Some(instance) = instance {
|
let fn_abi = if let Some(instance) = instance {
|
||||||
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
|
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
|
||||||
} else {
|
} else {
|
||||||
FnAbi::of_fn_ptr(
|
FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args)
|
||||||
&RevealAllLayoutCx(fx.tcx),
|
|
||||||
fn_ty.fn_sig(fx.tcx),
|
|
||||||
&extra_args,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
match fn_abi.ret.mode {
|
match fn_abi.ret.mode {
|
||||||
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => true,
|
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => true,
|
||||||
@@ -63,10 +58,7 @@ pub(super) fn codegen_return_param<'tcx>(
|
|||||||
block_params_iter: &mut impl Iterator<Item = Value>,
|
block_params_iter: &mut impl Iterator<Item = Value>,
|
||||||
) -> CPlace<'tcx> {
|
) -> CPlace<'tcx> {
|
||||||
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode {
|
let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode {
|
||||||
PassMode::Ignore => (
|
PassMode::Ignore => (CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout), smallvec![]),
|
||||||
CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout),
|
|
||||||
smallvec![],
|
|
||||||
),
|
|
||||||
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => {
|
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => {
|
||||||
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
|
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
|
||||||
(
|
(
|
||||||
@@ -79,26 +71,17 @@ pub(super) fn codegen_return_param<'tcx>(
|
|||||||
smallvec![],
|
smallvec![],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
|
||||||
attrs: _,
|
|
||||||
extra_attrs: None,
|
|
||||||
on_stack: _,
|
|
||||||
} => {
|
|
||||||
let ret_param = block_params_iter.next().unwrap();
|
let ret_param = block_params_iter.next().unwrap();
|
||||||
assert_eq!(fx.bcx.func.dfg.value_type(ret_param), pointer_ty(fx.tcx));
|
assert_eq!(fx.bcx.func.dfg.value_type(ret_param), pointer_ty(fx.tcx));
|
||||||
(
|
(
|
||||||
CPlace::for_ptr(
|
CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout),
|
||||||
Pointer::new(ret_param),
|
|
||||||
fx.fn_abi.as_ref().unwrap().ret.layout,
|
|
||||||
),
|
|
||||||
smallvec![ret_param],
|
smallvec![ret_param],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
|
||||||
attrs: _,
|
unreachable!("unsized return value")
|
||||||
extra_attrs: Some(_),
|
}
|
||||||
on_stack: _,
|
|
||||||
} => unreachable!("unsized return value"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
@@ -128,19 +111,13 @@ pub(super) fn codegen_with_call_return_arg<'tcx, T>(
|
|||||||
) -> (Inst, T) {
|
) -> (Inst, T) {
|
||||||
let return_ptr = match ret_arg_abi.mode {
|
let return_ptr = match ret_arg_abi.mode {
|
||||||
PassMode::Ignore => None,
|
PassMode::Ignore => None,
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => match ret_place {
|
||||||
attrs: _,
|
|
||||||
extra_attrs: None,
|
|
||||||
on_stack: _,
|
|
||||||
} => match ret_place {
|
|
||||||
Some(ret_place) => Some(ret_place.to_ptr().get_addr(fx)),
|
Some(ret_place) => Some(ret_place.to_ptr().get_addr(fx)),
|
||||||
None => Some(fx.bcx.ins().iconst(fx.pointer_type, 43)), // FIXME allocate temp stack slot
|
None => Some(fx.bcx.ins().iconst(fx.pointer_type, 43)), // FIXME allocate temp stack slot
|
||||||
},
|
},
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
|
||||||
attrs: _,
|
unreachable!("unsized return value")
|
||||||
extra_attrs: Some(_),
|
}
|
||||||
on_stack: _,
|
|
||||||
} => unreachable!("unsized return value"),
|
|
||||||
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => None,
|
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -177,16 +154,10 @@ pub(super) fn codegen_with_call_return_arg<'tcx, T>(
|
|||||||
ret_place.write_cvalue(fx, result);
|
ret_place.write_cvalue(fx, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {}
|
||||||
attrs: _,
|
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
|
||||||
extra_attrs: None,
|
unreachable!("unsized return value")
|
||||||
on_stack: _,
|
}
|
||||||
} => {}
|
|
||||||
PassMode::Indirect {
|
|
||||||
attrs: _,
|
|
||||||
extra_attrs: Some(_),
|
|
||||||
on_stack: _,
|
|
||||||
} => unreachable!("unsized return value"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(call_inst, meta)
|
(call_inst, meta)
|
||||||
@@ -195,19 +166,12 @@ pub(super) fn codegen_with_call_return_arg<'tcx, T>(
|
|||||||
/// Codegen a return instruction with the right return value(s) if any.
|
/// Codegen a return instruction with the right return value(s) if any.
|
||||||
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
|
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||||
match fx.fn_abi.as_ref().unwrap().ret.mode {
|
match fx.fn_abi.as_ref().unwrap().ret.mode {
|
||||||
PassMode::Ignore
|
PassMode::Ignore | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
|
||||||
| PassMode::Indirect {
|
|
||||||
attrs: _,
|
|
||||||
extra_attrs: None,
|
|
||||||
on_stack: _,
|
|
||||||
} => {
|
|
||||||
fx.bcx.ins().return_(&[]);
|
fx.bcx.ins().return_(&[]);
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
|
||||||
attrs: _,
|
unreachable!("unsized return value")
|
||||||
extra_attrs: Some(_),
|
}
|
||||||
on_stack: _,
|
|
||||||
} => unreachable!("unsized return value"),
|
|
||||||
PassMode::Direct(_) => {
|
PassMode::Direct(_) => {
|
||||||
let place = fx.get_local_place(RETURN_PLACE);
|
let place = fx.get_local_place(RETURN_PLACE);
|
||||||
let ret_val = place.to_cvalue(fx).load_scalar(fx);
|
let ret_val = place.to_cvalue(fx).load_scalar(fx);
|
||||||
|
|||||||
@@ -66,13 +66,9 @@ fn codegen_inner(
|
|||||||
let callee_name = kind.fn_name(method.name);
|
let callee_name = kind.fn_name(method.name);
|
||||||
//eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);
|
//eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);
|
||||||
|
|
||||||
let func_id = module
|
let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap();
|
||||||
.declare_function(&caller_name, Linkage::Export, &sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let callee_func_id = module
|
let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
|
||||||
.declare_function(&callee_name, Linkage::Import, &sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut ctx = Context::new();
|
let mut ctx = Context::new();
|
||||||
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone());
|
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone());
|
||||||
@@ -96,11 +92,7 @@ fn codegen_inner(
|
|||||||
bcx.finalize();
|
bcx.finalize();
|
||||||
}
|
}
|
||||||
module
|
module
|
||||||
.define_function(
|
.define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {})
|
||||||
func_id,
|
|
||||||
&mut ctx,
|
|
||||||
&mut cranelift_codegen::binemit::NullTrapSink {},
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unwind_context.add_function(func_id, &ctx, module.isa());
|
unwind_context.add_function(func_id, &ctx, module.isa());
|
||||||
}
|
}
|
||||||
@@ -114,13 +106,10 @@ fn codegen_inner(
|
|||||||
let callee_name = kind.fn_name(sym::oom);
|
let callee_name = kind.fn_name(sym::oom);
|
||||||
//eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);
|
//eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns);
|
||||||
|
|
||||||
let func_id = module
|
let func_id =
|
||||||
.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig)
|
module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let callee_func_id = module
|
let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
|
||||||
.declare_function(&callee_name, Linkage::Import, &sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut ctx = Context::new();
|
let mut ctx = Context::new();
|
||||||
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig);
|
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig);
|
||||||
@@ -143,11 +132,7 @@ fn codegen_inner(
|
|||||||
bcx.finalize();
|
bcx.finalize();
|
||||||
}
|
}
|
||||||
module
|
module
|
||||||
.define_function(
|
.define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {})
|
||||||
func_id,
|
|
||||||
&mut ctx,
|
|
||||||
&mut cranelift_codegen::binemit::NullTrapSink {},
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unwind_context.add_function(func_id, &ctx, module.isa());
|
unwind_context.add_function(func_id, &ctx, module.isa());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec<Local, SsaKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &bb.terminator().kind {
|
match &bb.terminator().kind {
|
||||||
TerminatorKind::Call {
|
TerminatorKind::Call { destination, func, args, .. } => {
|
||||||
destination,
|
|
||||||
func,
|
|
||||||
args,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
if let Some((dest_place, _dest_bb)) = destination {
|
if let Some((dest_place, _dest_bb)) = destination {
|
||||||
if !crate::abi::can_return_to_ssa_var(fx, func, args) {
|
if !crate::abi::can_return_to_ssa_var(fx, func, args) {
|
||||||
not_ssa(&mut flag_map, dest_place.local)
|
not_ssa(&mut flag_map, dest_place.local)
|
||||||
|
|||||||
@@ -12,10 +12,7 @@ use object::{Object, ObjectSymbol, SymbolKind};
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ArchiveEntry {
|
enum ArchiveEntry {
|
||||||
FromArchive {
|
FromArchive { archive_index: usize, entry_index: usize },
|
||||||
archive_index: usize,
|
|
||||||
entry_index: usize,
|
|
||||||
},
|
|
||||||
File(PathBuf),
|
File(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,10 +42,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
|||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
entries.push((
|
entries.push((
|
||||||
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
|
String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
|
||||||
ArchiveEntry::FromArchive {
|
ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
|
||||||
archive_index: 0,
|
|
||||||
entry_index: i,
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
@@ -93,13 +87,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
|||||||
|
|
||||||
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) {
|
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) {
|
||||||
let location = find_library(name, &self.lib_search_paths, self.sess);
|
let location = find_library(name, &self.lib_search_paths, self.sess);
|
||||||
self.add_archive(location.clone(), |_| false)
|
self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| {
|
||||||
.unwrap_or_else(|e| {
|
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
|
||||||
panic!(
|
|
||||||
"failed to add native library {}: {}",
|
|
||||||
location.to_string_lossy(),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,10 +141,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
|||||||
// FIXME only read the symbol table of the object files to avoid having to keep all
|
// FIXME only read the symbol table of the object files to avoid having to keep all
|
||||||
// object files in memory at once, or read them twice.
|
// object files in memory at once, or read them twice.
|
||||||
let data = match entry {
|
let data = match entry {
|
||||||
ArchiveEntry::FromArchive {
|
ArchiveEntry::FromArchive { archive_index, entry_index } => {
|
||||||
archive_index,
|
|
||||||
entry_index,
|
|
||||||
} => {
|
|
||||||
// FIXME read symbols from symtab
|
// FIXME read symbols from symtab
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
let (ref _src_archive_path, ref mut src_archive) =
|
let (ref _src_archive_path, ref mut src_archive) =
|
||||||
@@ -221,10 +207,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
|||||||
err
|
err
|
||||||
));
|
));
|
||||||
}),
|
}),
|
||||||
entries
|
entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(),
|
||||||
.iter()
|
|
||||||
.map(|(name, _)| name.as_bytes().to_vec())
|
|
||||||
.collect(),
|
|
||||||
ar::GnuSymbolTableFormat::Size32,
|
ar::GnuSymbolTableFormat::Size32,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
)
|
)
|
||||||
@@ -267,8 +250,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
|||||||
.expect("Couldn't run ranlib");
|
.expect("Couldn't run ranlib");
|
||||||
|
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
self.sess
|
self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
|
||||||
.fatal(&format!("Ranlib exited with code {:?}", status.code()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,13 +270,8 @@ impl<'a> ArArchiveBuilder<'a> {
|
|||||||
let file_name = String::from_utf8(entry.header().identifier().to_vec())
|
let file_name = String::from_utf8(entry.header().identifier().to_vec())
|
||||||
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
|
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
|
||||||
if !skip(&file_name) {
|
if !skip(&file_name) {
|
||||||
self.entries.push((
|
self.entries
|
||||||
file_name,
|
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
|
||||||
ArchiveEntry::FromArchive {
|
|
||||||
archive_index,
|
|
||||||
entry_index: i,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ pub(crate) trait WriteMetadata {
|
|||||||
|
|
||||||
impl WriteMetadata for object::write::Object {
|
impl WriteMetadata for object::write::Object {
|
||||||
fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, _is_like_osx: bool) {
|
fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, _is_like_osx: bool) {
|
||||||
let segment = self
|
let segment = self.segment_name(object::write::StandardSegment::Data).to_vec();
|
||||||
.segment_name(object::write::StandardSegment::Data)
|
|
||||||
.to_vec();
|
|
||||||
let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data);
|
let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data);
|
||||||
let offset = self.append_section_data(section_id, &data, 1);
|
let offset = self.append_section_data(section_id, &data, 1);
|
||||||
// For MachO and probably PE this is necessary to prevent the linker from throwing away the
|
// For MachO and probably PE this is necessary to prevent the linker from throwing away the
|
||||||
@@ -74,11 +72,7 @@ impl WriteDebugInfo for ObjectProduct {
|
|||||||
let section_id = self.object.add_section(
|
let section_id = self.object.add_section(
|
||||||
segment,
|
segment,
|
||||||
name,
|
name,
|
||||||
if id == SectionId::EhFrame {
|
if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
|
||||||
SectionKind::ReadOnlyData
|
|
||||||
} else {
|
|
||||||
SectionKind::Debug
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
self.object
|
self.object
|
||||||
.section_mut(section_id)
|
.section_mut(section_id)
|
||||||
@@ -132,10 +126,9 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object
|
|||||||
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
|
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
|
||||||
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
|
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
|
||||||
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
|
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
|
||||||
architecture => sess.fatal(&format!(
|
architecture => {
|
||||||
"target architecture {:?} is unsupported",
|
sess.fatal(&format!("target architecture {:?} is unsupported", architecture,))
|
||||||
architecture,
|
}
|
||||||
)),
|
|
||||||
};
|
};
|
||||||
let endian = match triple.endianness().unwrap() {
|
let endian = match triple.endianness().unwrap() {
|
||||||
target_lexicon::Endianness::Little => object::Endianness::Little,
|
target_lexicon::Endianness::Little => object::Endianness::Little,
|
||||||
|
|||||||
148
src/base.rs
148
src/base.rs
@@ -38,9 +38,8 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||||||
|
|
||||||
// Predefine blocks
|
// Predefine blocks
|
||||||
let start_block = bcx.create_block();
|
let start_block = bcx.create_block();
|
||||||
let block_map: IndexVec<BasicBlock, Block> = (0..mir.basic_blocks().len())
|
let block_map: IndexVec<BasicBlock, Block> =
|
||||||
.map(|_| bcx.create_block())
|
(0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Make FunctionCx
|
// Make FunctionCx
|
||||||
let pointer_type = cx.module.target_config().pointer_type();
|
let pointer_type = cx.module.target_config().pointer_type();
|
||||||
@@ -68,27 +67,23 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||||||
inline_asm_index: 0,
|
inline_asm_index: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let arg_uninhabited = fx.mir.args_iter().any(|arg| {
|
let arg_uninhabited = fx
|
||||||
fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty))
|
.mir
|
||||||
.abi
|
.args_iter()
|
||||||
.is_uninhabited()
|
.any(|arg| fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
|
||||||
});
|
|
||||||
|
|
||||||
if !crate::constant::check_constants(&mut fx) {
|
if !crate::constant::check_constants(&mut fx) {
|
||||||
fx.bcx
|
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||||
.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
|
||||||
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
||||||
crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted");
|
crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted");
|
||||||
} else if arg_uninhabited {
|
} else if arg_uninhabited {
|
||||||
fx.bcx
|
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||||
.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
|
||||||
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
||||||
crate::trap::trap_unreachable(&mut fx, "function has uninhabited argument");
|
crate::trap::trap_unreachable(&mut fx, "function has uninhabited argument");
|
||||||
} else {
|
} else {
|
||||||
tcx.sess.time("codegen clif ir", || {
|
tcx.sess.time("codegen clif ir", || {
|
||||||
tcx.sess.time("codegen prelude", || {
|
tcx.sess
|
||||||
crate::abi::codegen_fn_prelude(&mut fx, start_block)
|
.time("codegen prelude", || crate::abi::codegen_fn_prelude(&mut fx, start_block));
|
||||||
});
|
|
||||||
codegen_fn_content(&mut fx);
|
codegen_fn_content(&mut fx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -136,11 +131,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||||||
let module = &mut cx.module;
|
let module = &mut cx.module;
|
||||||
tcx.sess.time("define function", || {
|
tcx.sess.time("define function", || {
|
||||||
module
|
module
|
||||||
.define_function(
|
.define_function(func_id, context, &mut cranelift_codegen::binemit::NullTrapSink {})
|
||||||
func_id,
|
|
||||||
context,
|
|
||||||
&mut cranelift_codegen::binemit::NullTrapSink {},
|
|
||||||
)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -202,8 +193,7 @@ pub(crate) fn verify_func(
|
|||||||
Some(Box::new(writer)),
|
Some(Box::new(writer)),
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
tcx.sess
|
tcx.sess.fatal(&format!("cranelift verify error:\n{}", pretty_error));
|
||||||
.fatal(&format!("cranelift verify error:\n{}", pretty_error));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -232,11 +222,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let mut terminator_head = "\n".to_string();
|
let mut terminator_head = "\n".to_string();
|
||||||
bb_data
|
bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
|
||||||
.terminator()
|
|
||||||
.kind
|
|
||||||
.fmt_head(&mut terminator_head)
|
|
||||||
.unwrap();
|
|
||||||
let inst = fx.bcx.func.layout.last_inst(block).unwrap();
|
let inst = fx.bcx.func.layout.last_inst(block).unwrap();
|
||||||
fx.add_comment(inst, terminator_head);
|
fx.add_comment(inst, terminator_head);
|
||||||
}
|
}
|
||||||
@@ -268,13 +254,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
TerminatorKind::Return => {
|
TerminatorKind::Return => {
|
||||||
crate::abi::codegen_return(fx);
|
crate::abi::codegen_return(fx);
|
||||||
}
|
}
|
||||||
TerminatorKind::Assert {
|
TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
|
||||||
cond,
|
|
||||||
expected,
|
|
||||||
msg,
|
|
||||||
target,
|
|
||||||
cleanup: _,
|
|
||||||
} => {
|
|
||||||
if !fx.tcx.sess.overflow_checks() {
|
if !fx.tcx.sess.overflow_checks() {
|
||||||
if let mir::AssertKind::OverflowNeg(_) = *msg {
|
if let mir::AssertKind::OverflowNeg(_) = *msg {
|
||||||
let target = fx.get_block(*target);
|
let target = fx.get_block(*target);
|
||||||
@@ -320,11 +300,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::SwitchInt {
|
TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
|
||||||
discr,
|
|
||||||
switch_ty,
|
|
||||||
targets,
|
|
||||||
} => {
|
|
||||||
let discr = codegen_operand(fx, discr).load_scalar(fx);
|
let discr = codegen_operand(fx, discr).load_scalar(fx);
|
||||||
|
|
||||||
let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind()
|
let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind()
|
||||||
@@ -434,11 +410,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
|||||||
| TerminatorKind::GeneratorDrop => {
|
| TerminatorKind::GeneratorDrop => {
|
||||||
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
|
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
|
||||||
}
|
}
|
||||||
TerminatorKind::Drop {
|
TerminatorKind::Drop { place, target, unwind: _ } => {
|
||||||
place,
|
|
||||||
target,
|
|
||||||
unwind: _,
|
|
||||||
} => {
|
|
||||||
let drop_place = codegen_place(fx, *place);
|
let drop_place = codegen_place(fx, *place);
|
||||||
crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place);
|
crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place);
|
||||||
|
|
||||||
@@ -471,10 +443,7 @@ fn codegen_stmt<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &stmt.kind {
|
match &stmt.kind {
|
||||||
StatementKind::SetDiscriminant {
|
StatementKind::SetDiscriminant { place, variant_index } => {
|
||||||
place,
|
|
||||||
variant_index,
|
|
||||||
} => {
|
|
||||||
let place = codegen_place(fx, **place);
|
let place = codegen_place(fx, **place);
|
||||||
crate::discriminant::codegen_set_discriminant(fx, place, *variant_index);
|
crate::discriminant::codegen_set_discriminant(fx, place, *variant_index);
|
||||||
}
|
}
|
||||||
@@ -597,14 +566,9 @@ fn codegen_stmt<'tcx>(
|
|||||||
|
|
||||||
fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
ty.builtin_deref(true)
|
ty.builtin_deref(true)
|
||||||
.map(
|
.map(|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| {
|
||||||
|ty::TypeAndMut {
|
|
||||||
ty: pointee_ty,
|
|
||||||
mutbl: _,
|
|
||||||
}| {
|
|
||||||
has_ptr_meta(fx.tcx, pointee_ty)
|
has_ptr_meta(fx.tcx, pointee_ty)
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,8 +664,7 @@ fn codegen_stmt<'tcx>(
|
|||||||
// FIXME use emit_small_memset where possible
|
// FIXME use emit_small_memset where possible
|
||||||
let addr = lval.to_ptr().get_addr(fx);
|
let addr = lval.to_ptr().get_addr(fx);
|
||||||
let val = operand.load_scalar(fx);
|
let val = operand.load_scalar(fx);
|
||||||
fx.bcx
|
fx.bcx.call_memset(fx.cx.module.target_config(), addr, val, times);
|
||||||
.call_memset(fx.cx.module.target_config(), addr, val, times);
|
|
||||||
} else {
|
} else {
|
||||||
let loop_block = fx.bcx.create_block();
|
let loop_block = fx.bcx.create_block();
|
||||||
let loop_block2 = fx.bcx.create_block();
|
let loop_block2 = fx.bcx.create_block();
|
||||||
@@ -736,18 +699,12 @@ fn codegen_stmt<'tcx>(
|
|||||||
let content_ty = fx.monomorphize(content_ty);
|
let content_ty = fx.monomorphize(content_ty);
|
||||||
let layout = fx.layout_of(content_ty);
|
let layout = fx.layout_of(content_ty);
|
||||||
let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64);
|
let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64);
|
||||||
let llalign = fx
|
let llalign = fx.bcx.ins().iconst(usize_type, layout.align.abi.bytes() as i64);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(usize_type, layout.align.abi.bytes() as i64);
|
|
||||||
let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
|
let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
|
||||||
|
|
||||||
// Allocate space:
|
// Allocate space:
|
||||||
let def_id = match fx
|
let def_id =
|
||||||
.tcx
|
match fx.tcx.lang_items().require(rustc_hir::LangItem::ExchangeMalloc) {
|
||||||
.lang_items()
|
|
||||||
.require(rustc_hir::LangItem::ExchangeMalloc)
|
|
||||||
{
|
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(s) => {
|
Err(s) => {
|
||||||
fx.tcx
|
fx.tcx
|
||||||
@@ -762,10 +719,11 @@ fn codegen_stmt<'tcx>(
|
|||||||
lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
|
lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
|
||||||
}
|
}
|
||||||
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
|
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
|
||||||
assert!(lval
|
assert!(
|
||||||
.layout()
|
lval.layout()
|
||||||
.ty
|
.ty
|
||||||
.is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all()));
|
.is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())
|
||||||
|
);
|
||||||
let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes();
|
let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes();
|
||||||
let val =
|
let val =
|
||||||
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into());
|
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into());
|
||||||
@@ -793,11 +751,7 @@ fn codegen_stmt<'tcx>(
|
|||||||
|
|
||||||
StatementKind::LlvmInlineAsm(asm) => {
|
StatementKind::LlvmInlineAsm(asm) => {
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
let LlvmInlineAsm {
|
let LlvmInlineAsm { asm, outputs, inputs } = &**asm;
|
||||||
asm,
|
|
||||||
outputs,
|
|
||||||
inputs,
|
|
||||||
} = &**asm;
|
|
||||||
let rustc_hir::LlvmInlineAsmInner {
|
let rustc_hir::LlvmInlineAsmInner {
|
||||||
asm: asm_code, // Name
|
asm: asm_code, // Name
|
||||||
outputs: output_names, // Vec<LlvmInlineAsmOutput>
|
outputs: output_names, // Vec<LlvmInlineAsmOutput>
|
||||||
@@ -813,15 +767,9 @@ fn codegen_stmt<'tcx>(
|
|||||||
// Black box
|
// Black box
|
||||||
}
|
}
|
||||||
"mov %rbx, %rsi\n cpuid\n xchg %rbx, %rsi" => {
|
"mov %rbx, %rsi\n cpuid\n xchg %rbx, %rsi" => {
|
||||||
assert_eq!(
|
assert_eq!(input_names, &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]);
|
||||||
input_names,
|
|
||||||
&[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]
|
|
||||||
);
|
|
||||||
assert_eq!(output_names.len(), 4);
|
assert_eq!(output_names.len(), 4);
|
||||||
for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"])
|
for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]).iter().enumerate() {
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
{
|
|
||||||
assert_eq!(&output_names[i].constraint.as_str(), c);
|
assert_eq!(&output_names[i].constraint.as_str(), c);
|
||||||
assert!(!output_names[i].is_rw);
|
assert!(!output_names[i].is_rw);
|
||||||
assert!(!output_names[i].is_indirect);
|
assert!(!output_names[i].is_indirect);
|
||||||
@@ -867,12 +815,7 @@ fn codegen_stmt<'tcx>(
|
|||||||
crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported");
|
crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported");
|
||||||
}
|
}
|
||||||
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
||||||
_ if fx
|
_ if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") => {
|
||||||
.tcx
|
|
||||||
.symbol_name(fx.instance)
|
|
||||||
.name
|
|
||||||
.starts_with("___chkstk") =>
|
|
||||||
{
|
|
||||||
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
||||||
}
|
}
|
||||||
_ if fx.tcx.symbol_name(fx.instance).name == "__alloca" => {
|
_ if fx.tcx.symbol_name(fx.instance).name == "__alloca" => {
|
||||||
@@ -895,15 +838,12 @@ fn codegen_stmt<'tcx>(
|
|||||||
fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value {
|
fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value {
|
||||||
match *place.layout().ty.kind() {
|
match *place.layout().ty.kind() {
|
||||||
ty::Array(_elem_ty, len) => {
|
ty::Array(_elem_ty, len) => {
|
||||||
let len = fx
|
let len = fx.monomorphize(len).eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64;
|
||||||
.monomorphize(len)
|
|
||||||
.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64;
|
|
||||||
fx.bcx.ins().iconst(fx.pointer_type, len)
|
fx.bcx.ins().iconst(fx.pointer_type, len)
|
||||||
}
|
}
|
||||||
ty::Slice(_elem_ty) => place
|
ty::Slice(_elem_ty) => {
|
||||||
.to_ptr_maybe_unsized()
|
place.to_ptr_maybe_unsized().1.expect("Length metadata for slice place")
|
||||||
.1
|
}
|
||||||
.expect("Length metadata for slice place"),
|
|
||||||
_ => bug!("Rvalue::Len({:?})", place),
|
_ => bug!("Rvalue::Len({:?})", place),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -926,11 +866,7 @@ pub(crate) fn codegen_place<'tcx>(
|
|||||||
let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx);
|
let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx);
|
||||||
cplace = cplace.place_index(fx, index);
|
cplace = cplace.place_index(fx, index);
|
||||||
}
|
}
|
||||||
PlaceElem::ConstantIndex {
|
PlaceElem::ConstantIndex { offset, min_length: _, from_end } => {
|
||||||
offset,
|
|
||||||
min_length: _,
|
|
||||||
from_end,
|
|
||||||
} => {
|
|
||||||
let offset: u64 = offset;
|
let offset: u64 = offset;
|
||||||
let index = if !from_end {
|
let index = if !from_end {
|
||||||
fx.bcx.ins().iconst(fx.pointer_type, offset as i64)
|
fx.bcx.ins().iconst(fx.pointer_type, offset as i64)
|
||||||
@@ -997,10 +933,7 @@ pub(crate) fn codegen_panic<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &s
|
|||||||
let location = fx.get_caller_location(span).load_scalar(fx);
|
let location = fx.get_caller_location(span).load_scalar(fx);
|
||||||
|
|
||||||
let msg_ptr = fx.anonymous_str("assert", msg_str);
|
let msg_ptr = fx.anonymous_str("assert", msg_str);
|
||||||
let msg_len = fx
|
let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
|
|
||||||
let args = [msg_ptr, msg_len, location];
|
let args = [msg_ptr, msg_len, location];
|
||||||
|
|
||||||
codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span);
|
codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span);
|
||||||
@@ -1012,11 +945,8 @@ pub(crate) fn codegen_panic_inner<'tcx>(
|
|||||||
args: &[Value],
|
args: &[Value],
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let def_id = fx
|
let def_id =
|
||||||
.tcx
|
fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s));
|
||||||
.lang_items()
|
|
||||||
.require(lang_item)
|
|
||||||
.unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s));
|
|
||||||
|
|
||||||
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
|
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
|
||||||
let symbol_name = fx.tcx.symbol_name(instance).name;
|
let symbol_name = fx.tcx.symbol_name(instance).name;
|
||||||
|
|||||||
@@ -27,13 +27,7 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
|
|||||||
config.opts.cg.panic = Some(PanicStrategy::Abort);
|
config.opts.cg.panic = Some(PanicStrategy::Abort);
|
||||||
config.opts.debugging_opts.panic_abort_tests = true;
|
config.opts.debugging_opts.panic_abort_tests = true;
|
||||||
config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| {
|
config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| {
|
||||||
std::env::current_exe()
|
std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned()
|
||||||
.unwrap()
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.to_owned()
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,15 +46,8 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
|
|||||||
|
|
||||||
config.opts.cg.panic = Some(PanicStrategy::Abort);
|
config.opts.cg.panic = Some(PanicStrategy::Abort);
|
||||||
config.opts.debugging_opts.panic_abort_tests = true;
|
config.opts.debugging_opts.panic_abort_tests = true;
|
||||||
config.opts.maybe_sysroot = Some(
|
config.opts.maybe_sysroot =
|
||||||
std::env::current_exe()
|
Some(std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned());
|
||||||
.unwrap()
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.to_owned(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
src/cast.rs
30
src/cast.rs
@@ -40,11 +40,7 @@ pub(crate) fn clif_intcast(
|
|||||||
// reduce
|
// reduce
|
||||||
(types::I128, _) => {
|
(types::I128, _) => {
|
||||||
let (lsb, _msb) = fx.bcx.ins().isplit(val);
|
let (lsb, _msb) = fx.bcx.ins().isplit(val);
|
||||||
if to == types::I64 {
|
if to == types::I64 { lsb } else { fx.bcx.ins().ireduce(to, lsb) }
|
||||||
lsb
|
|
||||||
} else {
|
|
||||||
fx.bcx.ins().ireduce(to, lsb)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(_, _) => fx.bcx.ins().ireduce(to, val),
|
(_, _) => fx.bcx.ins().ireduce(to, val),
|
||||||
}
|
}
|
||||||
@@ -87,11 +83,7 @@ pub(crate) fn clif_int_or_float_cast(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let from_rust_ty = if from_signed {
|
let from_rust_ty = if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
|
||||||
fx.tcx.types.i128
|
|
||||||
} else {
|
|
||||||
fx.tcx.types.u128
|
|
||||||
};
|
|
||||||
|
|
||||||
let to_rust_ty = match to_ty {
|
let to_rust_ty = match to_ty {
|
||||||
types::F32 => fx.tcx.types.f32,
|
types::F32 => fx.tcx.types.f32,
|
||||||
@@ -100,11 +92,7 @@ pub(crate) fn clif_int_or_float_cast(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return fx
|
return fx
|
||||||
.easy_call(
|
.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
|
||||||
&name,
|
|
||||||
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
|
|
||||||
to_rust_ty,
|
|
||||||
)
|
|
||||||
.load_scalar(fx);
|
.load_scalar(fx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,18 +126,10 @@ pub(crate) fn clif_int_or_float_cast(
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let to_rust_ty = if to_signed {
|
let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
|
||||||
fx.tcx.types.i128
|
|
||||||
} else {
|
|
||||||
fx.tcx.types.u128
|
|
||||||
};
|
|
||||||
|
|
||||||
return fx
|
return fx
|
||||||
.easy_call(
|
.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
|
||||||
&name,
|
|
||||||
&[CValue::by_val(from, fx.layout_of(from_rust_ty))],
|
|
||||||
to_rust_ty,
|
|
||||||
)
|
|
||||||
.load_scalar(fx);
|
.load_scalar(fx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,7 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||||||
}
|
}
|
||||||
BinOp::Add | BinOp::Sub if !checked => None,
|
BinOp::Add | BinOp::Sub if !checked => None,
|
||||||
BinOp::Mul if !checked => {
|
BinOp::Mul if !checked => {
|
||||||
let val_ty = if is_signed {
|
let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
|
||||||
fx.tcx.types.i128
|
|
||||||
} else {
|
|
||||||
fx.tcx.types.u128
|
|
||||||
};
|
|
||||||
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
|
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
|
||||||
}
|
}
|
||||||
BinOp::Add | BinOp::Sub | BinOp::Mul => {
|
BinOp::Add | BinOp::Sub | BinOp::Mul => {
|
||||||
@@ -47,11 +43,7 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||||||
AbiParam::new(types::I128),
|
AbiParam::new(types::I128),
|
||||||
AbiParam::new(types::I128),
|
AbiParam::new(types::I128),
|
||||||
];
|
];
|
||||||
let args = [
|
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
|
||||||
out_place.to_ptr().get_addr(fx),
|
|
||||||
lhs.load_scalar(fx),
|
|
||||||
rhs.load_scalar(fx),
|
|
||||||
];
|
|
||||||
let name = match (bin_op, is_signed) {
|
let name = match (bin_op, is_signed) {
|
||||||
(BinOp::Add, false) => "__rust_u128_addo",
|
(BinOp::Add, false) => "__rust_u128_addo",
|
||||||
(BinOp::Add, true) => "__rust_i128_addo",
|
(BinOp::Add, true) => "__rust_i128_addo",
|
||||||
|
|||||||
@@ -54,11 +54,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
|
|||||||
FloatTy::F64 => types::F64,
|
FloatTy::F64 => types::F64,
|
||||||
},
|
},
|
||||||
ty::FnPtr(_) => pointer_ty(tcx),
|
ty::FnPtr(_) => pointer_ty(tcx),
|
||||||
ty::RawPtr(TypeAndMut {
|
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
|
||||||
ty: pointee_ty,
|
|
||||||
mutbl: _,
|
|
||||||
})
|
|
||||||
| ty::Ref(_, pointee_ty, _) => {
|
|
||||||
if has_ptr_meta(tcx, pointee_ty) {
|
if has_ptr_meta(tcx, pointee_ty) {
|
||||||
return None;
|
return None;
|
||||||
} else {
|
} else {
|
||||||
@@ -97,11 +93,7 @@ fn clif_pair_type_from_ty<'tcx>(
|
|||||||
}
|
}
|
||||||
(a, b)
|
(a, b)
|
||||||
}
|
}
|
||||||
ty::RawPtr(TypeAndMut {
|
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
|
||||||
ty: pointee_ty,
|
|
||||||
mutbl: _,
|
|
||||||
})
|
|
||||||
| ty::Ref(_, pointee_ty, _) => {
|
|
||||||
if has_ptr_meta(tcx, pointee_ty) {
|
if has_ptr_meta(tcx, pointee_ty) {
|
||||||
(pointer_ty(tcx), pointer_ty(tcx))
|
(pointer_ty(tcx), pointer_ty(tcx))
|
||||||
} else {
|
} else {
|
||||||
@@ -114,15 +106,8 @@ fn clif_pair_type_from_ty<'tcx>(
|
|||||||
|
|
||||||
/// Is a pointer to this type a fat ptr?
|
/// Is a pointer to this type a fat ptr?
|
||||||
pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
let ptr_ty = tcx.mk_ptr(TypeAndMut {
|
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc_hir::Mutability::Not });
|
||||||
ty,
|
match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi {
|
||||||
mutbl: rustc_hir::Mutability::Not,
|
|
||||||
});
|
|
||||||
match &tcx
|
|
||||||
.layout_of(ParamEnv::reveal_all().and(ptr_ty))
|
|
||||||
.unwrap()
|
|
||||||
.abi
|
|
||||||
{
|
|
||||||
Abi::Scalar(_) => false,
|
Abi::Scalar(_) => false,
|
||||||
Abi::ScalarPair(_, _) => true,
|
Abi::ScalarPair(_, _) => true,
|
||||||
abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi),
|
abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi),
|
||||||
@@ -369,12 +354,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
let msg_id = self
|
let msg_id = self
|
||||||
.cx
|
.cx
|
||||||
.module
|
.module
|
||||||
.declare_data(
|
.declare_data(&format!("__{}_{:08x}", prefix, msg_hash), Linkage::Local, false, false)
|
||||||
&format!("__{}_{:08x}", prefix, msg_hash),
|
|
||||||
Linkage::Local,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Ignore DuplicateDefinition error, as the data will be the same
|
// Ignore DuplicateDefinition error, as the data will be the same
|
||||||
@@ -397,9 +377,7 @@ impl<'tcx> LayoutOf for RevealAllLayoutCx<'tcx> {
|
|||||||
|
|
||||||
fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> {
|
fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> {
|
||||||
assert!(!ty.still_further_specializable());
|
assert!(!ty.still_further_specializable());
|
||||||
self.0
|
self.0.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap_or_else(|e| {
|
||||||
.layout_of(ParamEnv::reveal_all().and(&ty))
|
|
||||||
.unwrap_or_else(|e| {
|
|
||||||
if let layout::LayoutError::SizeOverflow(_) = e {
|
if let layout::LayoutError::SizeOverflow(_) = e {
|
||||||
self.0.sess.fatal(&e.to_string())
|
self.0.sess.fatal(&e.to_string())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -44,15 +44,12 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
|
|||||||
ConstKind::Value(_) => {}
|
ConstKind::Value(_) => {}
|
||||||
ConstKind::Unevaluated(def, ref substs, promoted) => {
|
ConstKind::Unevaluated(def, ref substs, promoted) => {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
fx.tcx
|
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
|
||||||
.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
|
|
||||||
{
|
{
|
||||||
all_constants_ok = false;
|
all_constants_ok = false;
|
||||||
match err {
|
match err {
|
||||||
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {
|
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {
|
||||||
fx.tcx
|
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
|
||||||
.sess
|
|
||||||
.span_err(constant.span, "erroneous constant encountered");
|
|
||||||
}
|
}
|
||||||
ErrorHandled::TooGeneric => {
|
ErrorHandled::TooGeneric => {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
@@ -131,16 +128,10 @@ pub(crate) fn codegen_constant<'tcx>(
|
|||||||
.to_cvalue(fx);
|
.to_cvalue(fx);
|
||||||
}
|
}
|
||||||
ConstKind::Unevaluated(def, ref substs, promoted) => {
|
ConstKind::Unevaluated(def, ref substs, promoted) => {
|
||||||
match fx
|
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
|
||||||
.tcx
|
|
||||||
.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
|
|
||||||
{
|
|
||||||
Ok(const_val) => const_val,
|
Ok(const_val) => const_val,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
span_bug!(
|
span_bug!(constant.span, "erroneous constant not captured by required_consts");
|
||||||
constant.span,
|
|
||||||
"erroneous constant not captured by required_consts"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,9 +162,7 @@ pub(crate) fn codegen_const_value<'tcx>(
|
|||||||
if fx.clif_type(layout.ty).is_none() {
|
if fx.clif_type(layout.ty).is_none() {
|
||||||
let (size, align) = (layout.size, layout.align.pref);
|
let (size, align) = (layout.size, layout.align.pref);
|
||||||
let mut alloc = Allocation::from_bytes(
|
let mut alloc = Allocation::from_bytes(
|
||||||
std::iter::repeat(0)
|
std::iter::repeat(0).take(size.bytes_usize()).collect::<Vec<u8>>(),
|
||||||
.take(size.bytes_usize())
|
|
||||||
.collect::<Vec<u8>>(),
|
|
||||||
align,
|
align,
|
||||||
);
|
);
|
||||||
let ptr = Pointer::new(AllocId(!0), Size::ZERO); // The alloc id is never used
|
let ptr = Pointer::new(AllocId(!0), Size::ZERO); // The alloc id is never used
|
||||||
@@ -216,9 +205,7 @@ pub(crate) fn codegen_const_value<'tcx>(
|
|||||||
None => bug!("missing allocation {:?}", ptr.alloc_id),
|
None => bug!("missing allocation {:?}", ptr.alloc_id),
|
||||||
};
|
};
|
||||||
let val = if ptr.offset.bytes() != 0 {
|
let val = if ptr.offset.bytes() != 0 {
|
||||||
fx.bcx
|
fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
|
||||||
.ins()
|
|
||||||
.iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
|
|
||||||
} else {
|
} else {
|
||||||
base_addr
|
base_addr
|
||||||
};
|
};
|
||||||
@@ -235,10 +222,10 @@ pub(crate) fn codegen_const_value<'tcx>(
|
|||||||
let ptr = pointer_for_allocation(fx, data)
|
let ptr = pointer_for_allocation(fx, data)
|
||||||
.offset_i64(fx, i64::try_from(start).unwrap())
|
.offset_i64(fx, i64::try_from(start).unwrap())
|
||||||
.get_addr(fx);
|
.get_addr(fx);
|
||||||
let len = fx.bcx.ins().iconst(
|
let len = fx
|
||||||
fx.pointer_type,
|
.bcx
|
||||||
i64::try_from(end.checked_sub(start).unwrap()).unwrap(),
|
.ins()
|
||||||
);
|
.iconst(fx.pointer_type, i64::try_from(end.checked_sub(start).unwrap()).unwrap());
|
||||||
CValue::by_val_pair(ptr, len, layout)
|
CValue::by_val_pair(ptr, len, layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,12 +286,7 @@ fn data_id_for_static(
|
|||||||
} else {
|
} else {
|
||||||
!ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all())
|
!ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all())
|
||||||
};
|
};
|
||||||
let align = tcx
|
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
|
||||||
.layout_of(ParamEnv::reveal_all().and(ty))
|
|
||||||
.unwrap()
|
|
||||||
.align
|
|
||||||
.pref
|
|
||||||
.bytes();
|
|
||||||
|
|
||||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||||
|
|
||||||
@@ -327,17 +309,11 @@ fn data_id_for_static(
|
|||||||
// zero.
|
// zero.
|
||||||
|
|
||||||
let ref_name = format!("_rust_extern_with_linkage_{}", symbol_name);
|
let ref_name = format!("_rust_extern_with_linkage_{}", symbol_name);
|
||||||
let ref_data_id = module
|
let ref_data_id = module.declare_data(&ref_name, Linkage::Local, false, false).unwrap();
|
||||||
.declare_data(&ref_name, Linkage::Local, false, false)
|
|
||||||
.unwrap();
|
|
||||||
let mut data_ctx = DataContext::new();
|
let mut data_ctx = DataContext::new();
|
||||||
data_ctx.set_align(align);
|
data_ctx.set_align(align);
|
||||||
let data = module.declare_data_in_data(data_id, &mut data_ctx);
|
let data = module.declare_data_in_data(data_id, &mut data_ctx);
|
||||||
data_ctx.define(
|
data_ctx.define(std::iter::repeat(0).take(pointer_ty(tcx).bytes() as usize).collect());
|
||||||
std::iter::repeat(0)
|
|
||||||
.take(pointer_ty(tcx).bytes() as usize)
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
data_ctx.write_data_addr(0, data, 0);
|
data_ctx.write_data_addr(0, data, 0);
|
||||||
match module.define_data(ref_data_id, &data_ctx) {
|
match module.define_data(ref_data_id, &data_ctx) {
|
||||||
// Every time the static is referenced there will be another definition of this global,
|
// Every time the static is referenced there will be another definition of this global,
|
||||||
@@ -366,10 +342,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||||||
TodoItem::Static(def_id) => {
|
TodoItem::Static(def_id) => {
|
||||||
//println!("static {:?}", def_id);
|
//println!("static {:?}", def_id);
|
||||||
|
|
||||||
let section_name = tcx
|
let section_name = tcx.codegen_fn_attrs(def_id).link_section.map(|s| s.as_str());
|
||||||
.codegen_fn_attrs(def_id)
|
|
||||||
.link_section
|
|
||||||
.map(|s| s.as_str());
|
|
||||||
|
|
||||||
let alloc = tcx.eval_static_initializer(def_id).unwrap();
|
let alloc = tcx.eval_static_initializer(def_id).unwrap();
|
||||||
|
|
||||||
@@ -391,9 +364,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||||||
data_ctx.set_segment_section("", &*section_name);
|
data_ctx.set_segment_section("", &*section_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes = alloc
|
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
|
||||||
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
|
|
||||||
.to_vec();
|
|
||||||
data_ctx.define(bytes.into_boxed_slice());
|
data_ctx.define(bytes.into_boxed_slice());
|
||||||
|
|
||||||
for &(offset, (_tag, reloc)) in alloc.relocations().iter() {
|
for &(offset, (_tag, reloc)) in alloc.relocations().iter() {
|
||||||
@@ -421,10 +392,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
|||||||
data_id_for_alloc_id(module, reloc, target_alloc.mutability)
|
data_id_for_alloc_id(module, reloc, target_alloc.mutability)
|
||||||
}
|
}
|
||||||
GlobalAlloc::Static(def_id) => {
|
GlobalAlloc::Static(def_id) => {
|
||||||
if tcx
|
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
|
||||||
.codegen_fn_attrs(def_id)
|
|
||||||
.flags
|
|
||||||
.contains(CodegenFnAttrFlags::THREAD_LOCAL)
|
|
||||||
{
|
{
|
||||||
tcx.sess.fatal(&format!(
|
tcx.sess.fatal(&format!(
|
||||||
"Allocation {:?} contains reference to TLS value {:?}",
|
"Allocation {:?} contains reference to TLS value {:?}",
|
||||||
@@ -457,9 +425,8 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
|
|||||||
) -> Option<&'tcx Const<'tcx>> {
|
) -> Option<&'tcx Const<'tcx>> {
|
||||||
match operand {
|
match operand {
|
||||||
Operand::Copy(_) | Operand::Move(_) => None,
|
Operand::Copy(_) | Operand::Move(_) => None,
|
||||||
Operand::Constant(const_) => Some(
|
Operand::Constant(const_) => {
|
||||||
fx.monomorphize(const_.literal)
|
Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all()))
|
||||||
.eval(fx.tcx, ParamEnv::reveal_all()),
|
}
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ impl DebugContext<'_> {
|
|||||||
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
|
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
|
||||||
let root = self.dwarf.unit.root();
|
let root = self.dwarf.unit.root();
|
||||||
let root = self.dwarf.unit.get_mut(root);
|
let root = self.dwarf.unit.get_mut(root);
|
||||||
root.set(
|
root.set(gimli::DW_AT_ranges, AttributeValue::RangeListRef(unit_range_list_id));
|
||||||
gimli::DW_AT_ranges,
|
|
||||||
AttributeValue::RangeListRef(unit_range_list_id),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut sections = Sections::new(WriterRelocate::new(self.endian));
|
let mut sections = Sections::new(WriterRelocate::new(self.endian));
|
||||||
self.dwarf.write(&mut sections).unwrap();
|
self.dwarf.write(&mut sections).unwrap();
|
||||||
@@ -66,10 +63,7 @@ pub(super) struct WriterRelocate {
|
|||||||
|
|
||||||
impl WriterRelocate {
|
impl WriterRelocate {
|
||||||
pub(super) fn new(endian: RunTimeEndian) -> Self {
|
pub(super) fn new(endian: RunTimeEndian) -> Self {
|
||||||
WriterRelocate {
|
WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endian) }
|
||||||
relocs: Vec::new(),
|
|
||||||
writer: EndianVec::new(endian),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform the collected relocations to be usable for JIT usage.
|
/// Perform the collected relocations to be usable for JIT usage.
|
||||||
@@ -85,9 +79,7 @@ impl WriterRelocate {
|
|||||||
cranelift_module::FuncId::from_u32(sym.try_into().unwrap()),
|
cranelift_module::FuncId::from_u32(sym.try_into().unwrap()),
|
||||||
);
|
);
|
||||||
let val = (addr as u64 as i64 + reloc.addend) as u64;
|
let val = (addr as u64 as i64 + reloc.addend) as u64;
|
||||||
self.writer
|
self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap();
|
||||||
.write_udata_at(reloc.offset as usize, val, reloc.size)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,11 +53,7 @@ pub(crate) fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
|
|||||||
if hash.kind == SourceFileHashAlgorithm::Md5 {
|
if hash.kind == SourceFileHashAlgorithm::Md5 {
|
||||||
let mut buf = [0u8; MD5_LEN];
|
let mut buf = [0u8; MD5_LEN];
|
||||||
buf.copy_from_slice(hash.hash_bytes());
|
buf.copy_from_slice(hash.hash_bytes());
|
||||||
Some(FileInfo {
|
Some(FileInfo { timestamp: 0, size: 0, md5: buf })
|
||||||
timestamp: 0,
|
|
||||||
size: 0,
|
|
||||||
md5: buf,
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -112,19 +108,10 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
|
|
||||||
let entry = self.dwarf.unit.get_mut(entry_id);
|
let entry = self.dwarf.unit.get_mut(entry_id);
|
||||||
|
|
||||||
entry.set(
|
entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
|
||||||
gimli::DW_AT_decl_file,
|
entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(loc.line as u64));
|
||||||
AttributeValue::FileIndex(Some(file_id)),
|
|
||||||
);
|
|
||||||
entry.set(
|
|
||||||
gimli::DW_AT_decl_line,
|
|
||||||
AttributeValue::Udata(loc.line as u64),
|
|
||||||
);
|
|
||||||
// FIXME: probably omit this
|
// FIXME: probably omit this
|
||||||
entry.set(
|
entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(loc.col.to_usize() as u64));
|
||||||
gimli::DW_AT_decl_column,
|
|
||||||
AttributeValue::Udata(loc.col.to_usize() as u64),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn create_debug_lines(
|
pub(super) fn create_debug_lines(
|
||||||
@@ -223,10 +210,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
gimli::DW_AT_low_pc,
|
gimli::DW_AT_low_pc,
|
||||||
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
|
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
|
||||||
);
|
);
|
||||||
entry.set(
|
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
|
||||||
gimli::DW_AT_high_pc,
|
|
||||||
AttributeValue::Udata(u64::from(func_end)),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.emit_location(entry_id, function_span);
|
self.emit_location(entry_id, function_span);
|
||||||
|
|
||||||
|
|||||||
@@ -90,20 +90,11 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
|
|
||||||
let root = dwarf.unit.root();
|
let root = dwarf.unit.root();
|
||||||
let root = dwarf.unit.get_mut(root);
|
let root = dwarf.unit.get_mut(root);
|
||||||
root.set(
|
root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer)));
|
||||||
gimli::DW_AT_producer,
|
root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust));
|
||||||
AttributeValue::StringRef(dwarf.strings.add(producer)),
|
|
||||||
);
|
|
||||||
root.set(
|
|
||||||
gimli::DW_AT_language,
|
|
||||||
AttributeValue::Language(gimli::DW_LANG_Rust),
|
|
||||||
);
|
|
||||||
root.set(gimli::DW_AT_name, AttributeValue::StringRef(name));
|
root.set(gimli::DW_AT_name, AttributeValue::StringRef(name));
|
||||||
root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir));
|
root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir));
|
||||||
root.set(
|
root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0)));
|
||||||
gimli::DW_AT_low_pc,
|
|
||||||
AttributeValue::Address(Address::Constant(0)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugContext {
|
DebugContext {
|
||||||
@@ -142,10 +133,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed),
|
ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed),
|
||||||
ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float),
|
ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float),
|
||||||
ty::Ref(_, pointee_ty, _mutbl)
|
ty::Ref(_, pointee_ty, _mutbl)
|
||||||
| ty::RawPtr(ty::TypeAndMut {
|
| ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl: _mutbl }) => {
|
||||||
ty: pointee_ty,
|
|
||||||
mutbl: _mutbl,
|
|
||||||
}) => {
|
|
||||||
let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type);
|
let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type);
|
||||||
|
|
||||||
// Ensure that type is inserted before recursing to avoid duplicates
|
// Ensure that type is inserted before recursing to avoid duplicates
|
||||||
@@ -172,10 +160,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
let field_offset = layout.fields.offset(field_idx);
|
let field_offset = layout.fields.offset(field_idx);
|
||||||
let field_layout = layout
|
let field_layout = layout
|
||||||
.field(
|
.field(
|
||||||
&layout::LayoutCx {
|
&layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
|
||||||
tcx: self.tcx,
|
|
||||||
param_env: ParamEnv::reveal_all(),
|
|
||||||
},
|
|
||||||
field_idx,
|
field_idx,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -204,10 +189,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
let type_entry = self.dwarf.unit.get_mut(type_id);
|
let type_entry = self.dwarf.unit.get_mut(type_id);
|
||||||
|
|
||||||
type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
|
type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
|
||||||
type_entry.set(
|
type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
|
||||||
gimli::DW_AT_byte_size,
|
|
||||||
AttributeValue::Udata(layout.size.bytes()),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.types.insert(ty, type_id);
|
self.types.insert(ty, type_id);
|
||||||
|
|
||||||
@@ -247,10 +229,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
let name_id = self.dwarf.strings.add(name);
|
let name_id = self.dwarf.strings.add(name);
|
||||||
// Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
|
// Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
|
||||||
entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
|
entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
|
||||||
entry.set(
|
entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id));
|
||||||
gimli::DW_AT_linkage_name,
|
|
||||||
AttributeValue::StringRef(name_id),
|
|
||||||
);
|
|
||||||
|
|
||||||
let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set);
|
let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set);
|
||||||
|
|
||||||
@@ -287,10 +266,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
context,
|
context,
|
||||||
&local_map,
|
&local_map,
|
||||||
&value_labels_ranges,
|
&value_labels_ranges,
|
||||||
Place {
|
Place { local, projection: ty::List::empty() },
|
||||||
local,
|
|
||||||
projection: ty::List::empty(),
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let var_entry = self.dwarf.unit.get_mut(var_id);
|
let var_entry = self.dwarf.unit.get_mut(var_id);
|
||||||
@@ -328,10 +304,7 @@ fn place_location<'tcx>(
|
|||||||
symbol,
|
symbol,
|
||||||
addend: i64::from(value_loc_range.start),
|
addend: i64::from(value_loc_range.start),
|
||||||
},
|
},
|
||||||
end: Address::Symbol {
|
end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
|
||||||
symbol,
|
|
||||||
addend: i64::from(value_loc_range.end),
|
|
||||||
},
|
|
||||||
data: translate_loc(
|
data: translate_loc(
|
||||||
isa,
|
isa,
|
||||||
value_loc_range.loc,
|
value_loc_range.loc,
|
||||||
|
|||||||
@@ -28,11 +28,7 @@ impl<'tcx> UnwindContext<'tcx> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
UnwindContext {
|
UnwindContext { tcx, frame_table, cie_id }
|
||||||
tcx,
|
|
||||||
frame_table,
|
|
||||||
cie_id,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
|
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
|
||||||
@@ -46,10 +42,8 @@ impl<'tcx> UnwindContext<'tcx> {
|
|||||||
UnwindInfo::SystemV(unwind_info) => {
|
UnwindInfo::SystemV(unwind_info) => {
|
||||||
self.frame_table.add_fde(
|
self.frame_table.add_fde(
|
||||||
self.cie_id.unwrap(),
|
self.cie_id.unwrap(),
|
||||||
unwind_info.to_fde(Address::Symbol {
|
unwind_info
|
||||||
symbol: func_id.as_u32() as usize,
|
.to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }),
|
||||||
addend: 0,
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
UnwindInfo::WindowsX64(_) => {
|
UnwindInfo::WindowsX64(_) => {
|
||||||
@@ -60,9 +54,8 @@ impl<'tcx> UnwindContext<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
|
pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
|
||||||
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(
|
let mut eh_frame =
|
||||||
self.tcx,
|
EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
|
||||||
)));
|
|
||||||
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
|
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
|
||||||
|
|
||||||
if !eh_frame.0.writer.slice().is_empty() {
|
if !eh_frame.0.writer.slice().is_empty() {
|
||||||
@@ -82,9 +75,8 @@ impl<'tcx> UnwindContext<'tcx> {
|
|||||||
self,
|
self,
|
||||||
jit_module: &cranelift_jit::JITModule,
|
jit_module: &cranelift_jit::JITModule,
|
||||||
) -> Option<UnwindRegistry> {
|
) -> Option<UnwindRegistry> {
|
||||||
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(
|
let mut eh_frame =
|
||||||
self.tcx,
|
EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
|
||||||
)));
|
|
||||||
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
|
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
|
||||||
|
|
||||||
if eh_frame.0.writer.slice().is_empty() {
|
if eh_frame.0.writer.slice().is_empty() {
|
||||||
@@ -130,10 +122,7 @@ impl<'tcx> UnwindContext<'tcx> {
|
|||||||
registrations.push(ptr as usize);
|
registrations.push(ptr as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(UnwindRegistry {
|
Some(UnwindRegistry { _frame_table: eh_frame, registrations })
|
||||||
_frame_table: eh_frame,
|
|
||||||
registrations,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
|
|||||||
variants: _,
|
variants: _,
|
||||||
} => {
|
} => {
|
||||||
let ptr = place.place_field(fx, mir::Field::new(tag_field));
|
let ptr = place.place_field(fx, mir::Field::new(tag_field));
|
||||||
let to = layout
|
let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val;
|
||||||
.ty
|
|
||||||
.discriminant_for_variant(fx.tcx, variant_index)
|
|
||||||
.unwrap()
|
|
||||||
.val;
|
|
||||||
let to = if ptr.layout().abi.is_signed() {
|
let to = if ptr.layout().abi.is_signed() {
|
||||||
ty::ScalarInt::try_from_int(
|
ty::ScalarInt::try_from_int(
|
||||||
ptr.layout().size.sign_extend(to) as i128,
|
ptr.layout().size.sign_extend(to) as i128,
|
||||||
@@ -46,12 +42,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
|
|||||||
Variants::Multiple {
|
Variants::Multiple {
|
||||||
tag: _,
|
tag: _,
|
||||||
tag_field,
|
tag_field,
|
||||||
tag_encoding:
|
tag_encoding: TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
|
||||||
TagEncoding::Niche {
|
|
||||||
dataful_variant,
|
|
||||||
ref niche_variants,
|
|
||||||
niche_start,
|
|
||||||
},
|
|
||||||
variants: _,
|
variants: _,
|
||||||
} => {
|
} => {
|
||||||
if variant_index != dataful_variant {
|
if variant_index != dataful_variant {
|
||||||
@@ -101,12 +92,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
|||||||
};
|
};
|
||||||
return CValue::const_val(fx, dest_layout, discr_val);
|
return CValue::const_val(fx, dest_layout, discr_val);
|
||||||
}
|
}
|
||||||
Variants::Multiple {
|
Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => {
|
||||||
tag,
|
(tag, *tag_field, tag_encoding)
|
||||||
tag_field,
|
}
|
||||||
tag_encoding,
|
|
||||||
variants: _,
|
|
||||||
} => (tag, *tag_field, tag_encoding),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
|
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
|
||||||
@@ -125,11 +113,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
|||||||
let val = clif_intcast(fx, tag, cast_to, signed);
|
let val = clif_intcast(fx, tag, cast_to, signed);
|
||||||
CValue::by_val(val, dest_layout)
|
CValue::by_val(val, dest_layout)
|
||||||
}
|
}
|
||||||
TagEncoding::Niche {
|
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
|
||||||
dataful_variant,
|
|
||||||
ref niche_variants,
|
|
||||||
niche_start,
|
|
||||||
} => {
|
|
||||||
// Rebase from niche values to discriminants, and check
|
// Rebase from niche values to discriminants, and check
|
||||||
// whether the result is in range for the niche variants.
|
// whether the result is in range for the niche variants.
|
||||||
|
|
||||||
@@ -146,9 +130,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
|||||||
tag
|
tag
|
||||||
} else {
|
} else {
|
||||||
// FIXME handle niche_start > i64::MAX
|
// FIXME handle niche_start > i64::MAX
|
||||||
fx.bcx
|
fx.bcx.ins().iadd_imm(tag, -i64::try_from(niche_start).unwrap())
|
||||||
.ins()
|
|
||||||
.iadd_imm(tag, -i64::try_from(niche_start).unwrap())
|
|
||||||
};
|
};
|
||||||
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
|
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
|
||||||
let is_niche = {
|
let is_niche = {
|
||||||
@@ -176,15 +158,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
|||||||
} else {
|
} else {
|
||||||
clif_intcast(fx, relative_discr, cast_to, false)
|
clif_intcast(fx, relative_discr, cast_to, false)
|
||||||
};
|
};
|
||||||
fx.bcx
|
fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
|
||||||
.ins()
|
|
||||||
.iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let dataful_variant = fx
|
let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(cast_to, i64::from(dataful_variant.as_u32()));
|
|
||||||
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
|
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
|
||||||
CValue::by_val(discr, dest_layout)
|
CValue::by_val(discr, dest_layout)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,13 +46,10 @@ fn emit_module(
|
|||||||
|
|
||||||
unwind_context.emit(&mut product);
|
unwind_context.emit(&mut product);
|
||||||
|
|
||||||
let tmp_file = tcx
|
let tmp_file = tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(&name));
|
||||||
.output_filenames(LOCAL_CRATE)
|
|
||||||
.temp_path(OutputType::Object, Some(&name));
|
|
||||||
let obj = product.object.write().unwrap();
|
let obj = product.object.write().unwrap();
|
||||||
if let Err(err) = std::fs::write(&tmp_file, obj) {
|
if let Err(err) = std::fs::write(&tmp_file, obj) {
|
||||||
tcx.sess
|
tcx.sess.fatal(&format!("error writing object file: {}", err));
|
||||||
.fatal(&format!("error writing object file: {}", err));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() {
|
let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() {
|
||||||
@@ -66,13 +63,7 @@ fn emit_module(
|
|||||||
};
|
};
|
||||||
|
|
||||||
ModuleCodegenResult(
|
ModuleCodegenResult(
|
||||||
CompiledModule {
|
CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None },
|
||||||
name,
|
|
||||||
kind,
|
|
||||||
object: Some(tmp_file),
|
|
||||||
dwarf_object: None,
|
|
||||||
bytecode: None,
|
|
||||||
},
|
|
||||||
work_product,
|
work_product,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -132,9 +123,7 @@ fn module_codegen(
|
|||||||
let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility);
|
let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility);
|
||||||
match mono_item {
|
match mono_item {
|
||||||
MonoItem::Fn(inst) => {
|
MonoItem::Fn(inst) => {
|
||||||
cx.tcx.sess.time("codegen fn", || {
|
cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage));
|
||||||
crate::base::codegen_fn(&mut cx, inst, linkage)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
MonoItem::Static(def_id) => {
|
MonoItem::Static(def_id) => {
|
||||||
crate::constant::codegen_static(&mut cx.constants_cx, def_id)
|
crate::constant::codegen_static(&mut cx.constants_cx, def_id)
|
||||||
@@ -194,9 +183,7 @@ pub(super) fn run_aot(
|
|||||||
cgus.iter()
|
cgus.iter()
|
||||||
.map(|cgu| {
|
.map(|cgu| {
|
||||||
let cgu_reuse = determine_cgu_reuse(tcx, cgu);
|
let cgu_reuse = determine_cgu_reuse(tcx, cgu);
|
||||||
tcx.sess
|
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
|
||||||
.cgu_reuse_tracker
|
|
||||||
.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
|
|
||||||
|
|
||||||
match cgu_reuse {
|
match cgu_reuse {
|
||||||
_ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {}
|
_ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {}
|
||||||
@@ -269,8 +256,7 @@ pub(super) fn run_aot(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Err(err) = std::fs::write(&tmp_file, obj) {
|
if let Err(err) = std::fs::write(&tmp_file, obj) {
|
||||||
tcx.sess
|
tcx.sess.fatal(&format!("error writing metadata object file: {}", err));
|
||||||
.fatal(&format!("error writing metadata object file: {}", err));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(metadata_cgu_name, tmp_file)
|
(metadata_cgu_name, tmp_file)
|
||||||
@@ -324,8 +310,7 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
|
|||||||
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
|
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
tcx.sess
|
tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
|
||||||
.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,19 +320,12 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
|
|||||||
// Remove all LLVM style comments
|
// Remove all LLVM style comments
|
||||||
let global_asm = global_asm
|
let global_asm = global_asm
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| {
|
.map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
|
||||||
if let Some(index) = line.find("//") {
|
|
||||||
&line[0..index]
|
|
||||||
} else {
|
|
||||||
line
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
|
||||||
let output_object_file = tcx
|
let output_object_file =
|
||||||
.output_filenames(LOCAL_CRATE)
|
tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(cgu_name));
|
||||||
.temp_path(OutputType::Object, Some(cgu_name));
|
|
||||||
|
|
||||||
// Assemble `global_asm`
|
// Assemble `global_asm`
|
||||||
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
|
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
|
||||||
@@ -357,16 +335,10 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
|
|||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("Failed to spawn `as`.");
|
.expect("Failed to spawn `as`.");
|
||||||
child
|
child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
|
||||||
.stdin
|
|
||||||
.take()
|
|
||||||
.unwrap()
|
|
||||||
.write_all(global_asm.as_bytes())
|
|
||||||
.unwrap();
|
|
||||||
let status = child.wait().expect("Failed to wait for `as`.");
|
let status = child.wait().expect("Failed to wait for `as`.");
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
tcx.sess
|
tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm));
|
||||||
.fatal(&format!("Failed to assemble `{}`", global_asm));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link the global asm and main object file together
|
// Link the global asm and main object file together
|
||||||
@@ -410,11 +382,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
|
|||||||
}
|
}
|
||||||
|
|
||||||
let work_product_id = &cgu.work_product_id();
|
let work_product_id = &cgu.work_product_id();
|
||||||
if tcx
|
if tcx.dep_graph.previous_work_product(work_product_id).is_none() {
|
||||||
.dep_graph
|
|
||||||
.previous_work_product(work_product_id)
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
// We don't have anything cached for this CGU. This can happen
|
// We don't have anything cached for this CGU. This can happen
|
||||||
// if the CGU did not exist in the previous session.
|
// if the CGU did not exist in the previous session.
|
||||||
return CguReuse::No;
|
return CguReuse::No;
|
||||||
@@ -433,9 +401,5 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
|
|||||||
cgu.name()
|
cgu.name()
|
||||||
);
|
);
|
||||||
|
|
||||||
if tcx.try_mark_green(&dep_node) {
|
if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No }
|
||||||
CguReuse::PreLto
|
|
||||||
} else {
|
|
||||||
CguReuse::No
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,8 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||||||
|
|
||||||
let imported_symbols = load_imported_symbols_for_jit(tcx);
|
let imported_symbols = load_imported_symbols_for_jit(tcx);
|
||||||
|
|
||||||
let mut jit_builder = JITBuilder::with_isa(
|
let mut jit_builder =
|
||||||
crate::build_isa(tcx.sess),
|
JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names());
|
||||||
cranelift_module::default_libcall_names(),
|
|
||||||
);
|
|
||||||
jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy));
|
jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy));
|
||||||
jit_builder.symbols(imported_symbols);
|
jit_builder.symbols(imported_symbols);
|
||||||
let mut jit_module = JITModule::new(jit_builder);
|
let mut jit_module = JITModule::new(jit_builder);
|
||||||
@@ -39,14 +37,10 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||||||
AbiParam::new(jit_module.target_config().pointer_type()),
|
AbiParam::new(jit_module.target_config().pointer_type()),
|
||||||
AbiParam::new(jit_module.target_config().pointer_type()),
|
AbiParam::new(jit_module.target_config().pointer_type()),
|
||||||
],
|
],
|
||||||
returns: vec![AbiParam::new(
|
returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
|
||||||
jit_module.target_config().pointer_type(), /*isize*/
|
|
||||||
)],
|
|
||||||
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
|
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
|
||||||
};
|
};
|
||||||
let main_func_id = jit_module
|
let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap();
|
||||||
.declare_function("main", Linkage::Import, &sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
||||||
let mono_items = cgus
|
let mono_items = cgus
|
||||||
@@ -67,9 +61,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||||||
MonoItem::Fn(inst) => match backend_config.codegen_mode {
|
MonoItem::Fn(inst) => match backend_config.codegen_mode {
|
||||||
CodegenMode::Aot => unreachable!(),
|
CodegenMode::Aot => unreachable!(),
|
||||||
CodegenMode::Jit => {
|
CodegenMode::Jit => {
|
||||||
cx.tcx.sess.time("codegen fn", || {
|
cx.tcx
|
||||||
crate::base::codegen_fn(&mut cx, inst, linkage)
|
.sess
|
||||||
});
|
.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage));
|
||||||
}
|
}
|
||||||
CodegenMode::JitLazy => codegen_shim(&mut cx, inst),
|
CodegenMode::JitLazy => codegen_shim(&mut cx, inst),
|
||||||
},
|
},
|
||||||
@@ -78,8 +72,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||||||
}
|
}
|
||||||
MonoItem::GlobalAsm(item_id) => {
|
MonoItem::GlobalAsm(item_id) => {
|
||||||
let item = cx.tcx.hir().item(item_id);
|
let item = cx.tcx.hir().item(item_id);
|
||||||
tcx.sess
|
tcx.sess.span_fatal(item.span, "Global asm is not supported in JIT mode");
|
||||||
.span_fatal(item.span, "Global asm is not supported in JIT mode");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +97,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||||||
|
|
||||||
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
|
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
|
||||||
|
|
||||||
println!("Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed");
|
println!(
|
||||||
|
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
|
||||||
|
);
|
||||||
|
|
||||||
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
|
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
|
||||||
unsafe { ::std::mem::transmute(finalized_main) };
|
unsafe { ::std::mem::transmute(finalized_main) };
|
||||||
@@ -121,10 +116,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
|||||||
argv.push(std::ptr::null());
|
argv.push(std::ptr::null());
|
||||||
|
|
||||||
BACKEND_CONFIG.with(|tls_backend_config| {
|
BACKEND_CONFIG.with(|tls_backend_config| {
|
||||||
assert!(tls_backend_config
|
assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none())
|
||||||
.borrow_mut()
|
|
||||||
.replace(backend_config)
|
|
||||||
.is_none())
|
|
||||||
});
|
});
|
||||||
CURRENT_MODULE
|
CURRENT_MODULE
|
||||||
.with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none()));
|
.with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none()));
|
||||||
@@ -148,15 +140,12 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8
|
|||||||
|
|
||||||
let name = tcx.symbol_name(instance).name.to_string();
|
let name = tcx.symbol_name(instance).name.to_string();
|
||||||
let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
|
let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
|
||||||
let func_id = jit_module
|
let func_id = jit_module.declare_function(&name, Linkage::Export, &sig).unwrap();
|
||||||
.declare_function(&name, Linkage::Export, &sig)
|
|
||||||
.unwrap();
|
|
||||||
jit_module.prepare_for_function_redefine(func_id).unwrap();
|
jit_module.prepare_for_function_redefine(func_id).unwrap();
|
||||||
|
|
||||||
let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false);
|
let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false);
|
||||||
tcx.sess.time("codegen fn", || {
|
tcx.sess
|
||||||
crate::base::codegen_fn(&mut cx, instance, Linkage::Export)
|
.time("codegen fn", || crate::base::codegen_fn(&mut cx, instance, Linkage::Export));
|
||||||
});
|
|
||||||
|
|
||||||
let (global_asm, _debug_context, unwind_context) = cx.finalize();
|
let (global_asm, _debug_context, unwind_context) = cx.finalize();
|
||||||
assert!(global_asm.is_empty());
|
assert!(global_asm.is_empty());
|
||||||
@@ -185,9 +174,8 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
|
|||||||
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
|
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
|
||||||
Linkage::Static => {
|
Linkage::Static => {
|
||||||
let name = tcx.crate_name(cnum);
|
let name = tcx.crate_name(cnum);
|
||||||
let mut err = tcx
|
let mut err =
|
||||||
.sess
|
tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
|
||||||
.struct_err(&format!("Can't load static lib {}", name.as_str()));
|
|
||||||
err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
|
err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
@@ -239,10 +227,7 @@ pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'t
|
|||||||
|
|
||||||
let name = tcx.symbol_name(inst).name.to_string();
|
let name = tcx.symbol_name(inst).name.to_string();
|
||||||
let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), inst);
|
let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), inst);
|
||||||
let func_id = cx
|
let func_id = cx.module.declare_function(&name, Linkage::Export, &sig).unwrap();
|
||||||
.module
|
|
||||||
.declare_function(&name, Linkage::Export, &sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let instance_ptr = Box::into_raw(Box::new(inst));
|
let instance_ptr = Box::into_raw(Box::new(inst));
|
||||||
|
|
||||||
@@ -263,28 +248,18 @@ pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'t
|
|||||||
let mut builder_ctx = FunctionBuilderContext::new();
|
let mut builder_ctx = FunctionBuilderContext::new();
|
||||||
let mut trampoline_builder = FunctionBuilder::new(&mut trampoline, &mut builder_ctx);
|
let mut trampoline_builder = FunctionBuilder::new(&mut trampoline, &mut builder_ctx);
|
||||||
|
|
||||||
let jit_fn = cx
|
let jit_fn = cx.module.declare_func_in_func(jit_fn, trampoline_builder.func);
|
||||||
.module
|
|
||||||
.declare_func_in_func(jit_fn, trampoline_builder.func);
|
|
||||||
let sig_ref = trampoline_builder.func.import_signature(sig);
|
let sig_ref = trampoline_builder.func.import_signature(sig);
|
||||||
|
|
||||||
let entry_block = trampoline_builder.create_block();
|
let entry_block = trampoline_builder.create_block();
|
||||||
trampoline_builder.append_block_params_for_function_params(entry_block);
|
trampoline_builder.append_block_params_for_function_params(entry_block);
|
||||||
let fn_args = trampoline_builder
|
let fn_args = trampoline_builder.func.dfg.block_params(entry_block).to_vec();
|
||||||
.func
|
|
||||||
.dfg
|
|
||||||
.block_params(entry_block)
|
|
||||||
.to_vec();
|
|
||||||
|
|
||||||
trampoline_builder.switch_to_block(entry_block);
|
trampoline_builder.switch_to_block(entry_block);
|
||||||
let instance_ptr = trampoline_builder
|
let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64);
|
||||||
.ins()
|
|
||||||
.iconst(pointer_type, instance_ptr as u64 as i64);
|
|
||||||
let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]);
|
let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]);
|
||||||
let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0];
|
let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0];
|
||||||
let call_inst = trampoline_builder
|
let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args);
|
||||||
.ins()
|
|
||||||
.call_indirect(sig_ref, jitted_fn, &fn_args);
|
|
||||||
let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();
|
let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();
|
||||||
trampoline_builder.ins().return_(&ret_vals);
|
trampoline_builder.ins().return_(&ret_vals);
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,8 @@ pub(crate) fn codegen_crate(
|
|||||||
match backend_config.codegen_mode {
|
match backend_config.codegen_mode {
|
||||||
CodegenMode::Aot => aot::run_aot(tcx, backend_config, metadata, need_metadata_module),
|
CodegenMode::Aot => aot::run_aot(tcx, backend_config, metadata, need_metadata_module),
|
||||||
CodegenMode::Jit | CodegenMode::JitLazy => {
|
CodegenMode::Jit | CodegenMode::JitLazy => {
|
||||||
let is_executable = tcx
|
let is_executable =
|
||||||
.sess
|
tcx.sess.crate_types().contains(&rustc_session::config::CrateType::Executable);
|
||||||
.crate_types()
|
|
||||||
.contains(&rustc_session::config::CrateType::Executable);
|
|
||||||
if !is_executable {
|
if !is_executable {
|
||||||
tcx.sess.fatal("can't jit non-executable crate");
|
tcx.sess.fatal("can't jit non-executable crate");
|
||||||
}
|
}
|
||||||
@@ -36,8 +34,7 @@ pub(crate) fn codegen_crate(
|
|||||||
let _: ! = jit::run_jit(tcx, backend_config);
|
let _: ! = jit::run_jit(tcx, backend_config);
|
||||||
|
|
||||||
#[cfg(not(feature = "jit"))]
|
#[cfg(not(feature = "jit"))]
|
||||||
tcx.sess
|
tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
|
||||||
.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,21 +60,12 @@ fn predefine_mono_items<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn time<R>(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R {
|
fn time<R>(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R {
|
||||||
if std::env::var("CG_CLIF_DISPLAY_CG_TIME")
|
if std::env::var("CG_CLIF_DISPLAY_CG_TIME").as_ref().map(|val| &**val) == Ok("1") {
|
||||||
.as_ref()
|
|
||||||
.map(|val| &**val)
|
|
||||||
== Ok("1")
|
|
||||||
{
|
|
||||||
println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name);
|
println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name);
|
||||||
let before = std::time::Instant::now();
|
let before = std::time::Instant::now();
|
||||||
let res = tcx.sess.time(name, f);
|
let res = tcx.sess.time(name, f);
|
||||||
let after = std::time::Instant::now();
|
let after = std::time::Instant::now();
|
||||||
println!(
|
println!("[{:<30}: {}] end time: {:?}", tcx.crate_name(LOCAL_CRATE), name, after - before);
|
||||||
"[{:<30}: {}] end time: {:?}",
|
|
||||||
tcx.crate_name(LOCAL_CRATE),
|
|
||||||
name,
|
|
||||||
after - before
|
|
||||||
);
|
|
||||||
res
|
res
|
||||||
} else {
|
} else {
|
||||||
tcx.sess.time(name, f)
|
tcx.sess.time(name, f)
|
||||||
|
|||||||
@@ -53,11 +53,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
|||||||
crate::base::codegen_operand(fx, value).load_scalar(fx),
|
crate::base::codegen_operand(fx, value).load_scalar(fx),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
InlineAsmOperand::Out {
|
InlineAsmOperand::Out { reg, late: _, place } => {
|
||||||
reg,
|
|
||||||
late: _,
|
|
||||||
place,
|
|
||||||
} => {
|
|
||||||
let reg = expect_reg(reg);
|
let reg = expect_reg(reg);
|
||||||
clobbered_regs.push((reg, new_slot(reg.reg_class())));
|
clobbered_regs.push((reg, new_slot(reg.reg_class())));
|
||||||
if let Some(place) = place {
|
if let Some(place) = place {
|
||||||
@@ -68,12 +64,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InlineAsmOperand::InOut {
|
InlineAsmOperand::InOut { reg, late: _, ref in_value, out_place } => {
|
||||||
reg,
|
|
||||||
late: _,
|
|
||||||
ref in_value,
|
|
||||||
out_place,
|
|
||||||
} => {
|
|
||||||
let reg = expect_reg(reg);
|
let reg = expect_reg(reg);
|
||||||
clobbered_regs.push((reg, new_slot(reg.reg_class())));
|
clobbered_regs.push((reg, new_slot(reg.reg_class())));
|
||||||
inputs.push((
|
inputs.push((
|
||||||
@@ -97,11 +88,8 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
|||||||
|
|
||||||
let inline_asm_index = fx.inline_asm_index;
|
let inline_asm_index = fx.inline_asm_index;
|
||||||
fx.inline_asm_index += 1;
|
fx.inline_asm_index += 1;
|
||||||
let asm_name = format!(
|
let asm_name =
|
||||||
"{}__inline_asm_{}",
|
format!("{}__inline_asm_{}", fx.tcx.symbol_name(fx.instance).name, inline_asm_index);
|
||||||
fx.tcx.symbol_name(fx.instance).name,
|
|
||||||
inline_asm_index
|
|
||||||
);
|
|
||||||
|
|
||||||
let generated_asm = generate_asm_wrapper(
|
let generated_asm = generate_asm_wrapper(
|
||||||
&asm_name,
|
&asm_name,
|
||||||
@@ -129,12 +117,7 @@ fn generate_asm_wrapper(
|
|||||||
let mut generated_asm = String::new();
|
let mut generated_asm = String::new();
|
||||||
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
|
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
|
||||||
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
|
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
|
||||||
writeln!(
|
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
|
||||||
generated_asm,
|
|
||||||
".section .text.{},\"ax\",@progbits",
|
|
||||||
asm_name
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
||||||
|
|
||||||
generated_asm.push_str(".intel_syntax noprefix\n");
|
generated_asm.push_str(".intel_syntax noprefix\n");
|
||||||
@@ -164,11 +147,7 @@ fn generate_asm_wrapper(
|
|||||||
InlineAsmTemplatePiece::String(s) => {
|
InlineAsmTemplatePiece::String(s) => {
|
||||||
generated_asm.push_str(s);
|
generated_asm.push_str(s);
|
||||||
}
|
}
|
||||||
InlineAsmTemplatePiece::Placeholder {
|
InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span: _ } => todo!(),
|
||||||
operand_idx: _,
|
|
||||||
modifier: _,
|
|
||||||
span: _,
|
|
||||||
} => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generated_asm.push('\n');
|
generated_asm.push('\n');
|
||||||
@@ -230,17 +209,12 @@ fn call_inline_asm<'tcx>(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let inline_asm_func = fx
|
let inline_asm_func = fx.cx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func);
|
||||||
.cx
|
|
||||||
.module
|
|
||||||
.declare_func_in_func(inline_asm_func, &mut fx.bcx.func);
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
fx.add_comment(inline_asm_func, asm_name);
|
fx.add_comment(inline_asm_func, asm_name);
|
||||||
|
|
||||||
for (_reg, offset, value) in inputs {
|
for (_reg, offset, value) in inputs {
|
||||||
fx.bcx
|
fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
|
||||||
.ins()
|
|
||||||
.stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
|
let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
|
||||||
@@ -248,10 +222,7 @@ fn call_inline_asm<'tcx>(
|
|||||||
|
|
||||||
for (_reg, offset, place) in outputs {
|
for (_reg, offset, place) in outputs {
|
||||||
let ty = fx.clif_type(place.layout().ty).unwrap();
|
let ty = fx.clif_type(place.layout().ty).unwrap();
|
||||||
let value = fx
|
let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
|
|
||||||
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
|
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,8 +238,7 @@ fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsm
|
|||||||
match arch {
|
match arch {
|
||||||
InlineAsmArch::X86_64 => {
|
InlineAsmArch::X86_64 => {
|
||||||
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
|
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
|
||||||
reg.emit(generated_asm, InlineAsmArch::X86_64, None)
|
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
||||||
.unwrap();
|
|
||||||
generated_asm.push('\n');
|
generated_asm.push('\n');
|
||||||
}
|
}
|
||||||
_ => unimplemented!("save_register for {:?}", arch),
|
_ => unimplemented!("save_register for {:?}", arch),
|
||||||
@@ -284,8 +254,7 @@ fn restore_register(
|
|||||||
match arch {
|
match arch {
|
||||||
InlineAsmArch::X86_64 => {
|
InlineAsmArch::X86_64 => {
|
||||||
generated_asm.push_str(" mov ");
|
generated_asm.push_str(" mov ");
|
||||||
reg.emit(generated_asm, InlineAsmArch::X86_64, None)
|
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
||||||
.unwrap();
|
|
||||||
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
|
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
|
||||||
}
|
}
|
||||||
_ => unimplemented!("restore_register for {:?}", arch),
|
_ => unimplemented!("restore_register for {:?}", arch),
|
||||||
|
|||||||
@@ -31,54 +31,28 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
|
|||||||
|
|
||||||
fx.bcx.switch_to_block(leaf_0);
|
fx.bcx.switch_to_block(leaf_0);
|
||||||
let max_basic_leaf = fx.bcx.ins().iconst(types::I32, 1);
|
let max_basic_leaf = fx.bcx.ins().iconst(types::I32, 1);
|
||||||
let vend0 = fx
|
let vend0 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu")));
|
||||||
.bcx
|
let vend2 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI")));
|
||||||
.ins()
|
let vend1 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel")));
|
||||||
.iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu")));
|
fx.bcx.ins().jump(dest, &[max_basic_leaf, vend0, vend1, vend2]);
|
||||||
let vend2 = fx
|
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI")));
|
|
||||||
let vend1 = fx
|
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel")));
|
|
||||||
fx.bcx
|
|
||||||
.ins()
|
|
||||||
.jump(dest, &[max_basic_leaf, vend0, vend1, vend2]);
|
|
||||||
|
|
||||||
fx.bcx.switch_to_block(leaf_1);
|
fx.bcx.switch_to_block(leaf_1);
|
||||||
let cpu_signature = fx.bcx.ins().iconst(types::I32, 0);
|
let cpu_signature = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
let additional_information = fx.bcx.ins().iconst(types::I32, 0);
|
let additional_information = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
let ecx_features = fx.bcx.ins().iconst(types::I32, 0);
|
let ecx_features = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
let edx_features = fx
|
let edx_features = fx.bcx.ins().iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */);
|
||||||
.bcx
|
fx.bcx.ins().jump(dest, &[cpu_signature, additional_information, ecx_features, edx_features]);
|
||||||
.ins()
|
|
||||||
.iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */);
|
|
||||||
fx.bcx.ins().jump(
|
|
||||||
dest,
|
|
||||||
&[
|
|
||||||
cpu_signature,
|
|
||||||
additional_information,
|
|
||||||
ecx_features,
|
|
||||||
edx_features,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
fx.bcx.switch_to_block(leaf_8000_0000);
|
fx.bcx.switch_to_block(leaf_8000_0000);
|
||||||
let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0);
|
let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
let zero = fx.bcx.ins().iconst(types::I32, 0);
|
let zero = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
fx.bcx
|
fx.bcx.ins().jump(dest, &[extended_max_basic_leaf, zero, zero, zero]);
|
||||||
.ins()
|
|
||||||
.jump(dest, &[extended_max_basic_leaf, zero, zero, zero]);
|
|
||||||
|
|
||||||
fx.bcx.switch_to_block(leaf_8000_0001);
|
fx.bcx.switch_to_block(leaf_8000_0001);
|
||||||
let zero = fx.bcx.ins().iconst(types::I32, 0);
|
let zero = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
let proc_info_ecx = fx.bcx.ins().iconst(types::I32, 0);
|
let proc_info_ecx = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
let proc_info_edx = fx.bcx.ins().iconst(types::I32, 0);
|
let proc_info_edx = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
fx.bcx
|
fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
|
||||||
.ins()
|
|
||||||
.jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
|
|
||||||
|
|
||||||
fx.bcx.switch_to_block(unsupported_leaf);
|
fx.bcx.switch_to_block(unsupported_leaf);
|
||||||
crate::trap::trap_unreachable(
|
crate::trap::trap_unreachable(
|
||||||
|
|||||||
@@ -227,9 +227,8 @@ fn simd_reduce<'tcx>(
|
|||||||
|
|
||||||
let mut res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
|
let mut res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
|
||||||
for lane_idx in 1..lane_count {
|
for lane_idx in 1..lane_count {
|
||||||
let lane = val
|
let lane =
|
||||||
.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap()))
|
val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx);
|
||||||
.load_scalar(fx);
|
|
||||||
res_val = f(fx, lane_layout, res_val, lane);
|
res_val = f(fx, lane_layout, res_val, lane);
|
||||||
}
|
}
|
||||||
let res = CValue::by_val(res_val, lane_layout);
|
let res = CValue::by_val(res_val, lane_layout);
|
||||||
@@ -248,9 +247,8 @@ fn simd_reduce_bool<'tcx>(
|
|||||||
let res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
|
let res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
|
||||||
let mut res_val = fx.bcx.ins().band_imm(res_val, 1); // mask to boolean
|
let mut res_val = fx.bcx.ins().band_imm(res_val, 1); // mask to boolean
|
||||||
for lane_idx in 1..lane_count {
|
for lane_idx in 1..lane_count {
|
||||||
let lane = val
|
let lane =
|
||||||
.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap()))
|
val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx);
|
||||||
.load_scalar(fx);
|
|
||||||
let lane = fx.bcx.ins().band_imm(lane, 1); // mask to boolean
|
let lane = fx.bcx.ins().band_imm(lane, 1); // mask to boolean
|
||||||
res_val = f(fx, res_val, lane);
|
res_val = f(fx, res_val, lane);
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/lib.rs
16
src/lib.rs
@@ -149,11 +149,8 @@ impl<'m, 'tcx> CodegenCx<'m, 'tcx> {
|
|||||||
module.isa(),
|
module.isa(),
|
||||||
matches!(backend_config.codegen_mode, CodegenMode::Aot),
|
matches!(backend_config.codegen_mode, CodegenMode::Aot),
|
||||||
);
|
);
|
||||||
let debug_context = if debug_info {
|
let debug_context =
|
||||||
Some(DebugContext::new(tcx, module.isa()))
|
if debug_info { Some(DebugContext::new(tcx, module.isa())) } else { None };
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
CodegenCx {
|
CodegenCx {
|
||||||
tcx,
|
tcx,
|
||||||
module,
|
module,
|
||||||
@@ -303,14 +300,7 @@ fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
|
|||||||
flags_builder.enable("is_pic").unwrap();
|
flags_builder.enable("is_pic").unwrap();
|
||||||
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
|
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
|
||||||
flags_builder
|
flags_builder
|
||||||
.set(
|
.set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" })
|
||||||
"enable_verifier",
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
"true"
|
|
||||||
} else {
|
|
||||||
"false"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let tls_model = match target_triple.binary_format {
|
let tls_model = match target_triple.binary_format {
|
||||||
|
|||||||
@@ -26,13 +26,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_entry_fn(
|
create_entry_fn(tcx, module, unwind_context, main_def_id, use_start_lang_item);
|
||||||
tcx,
|
|
||||||
module,
|
|
||||||
unwind_context,
|
|
||||||
main_def_id,
|
|
||||||
use_start_lang_item,
|
|
||||||
);
|
|
||||||
|
|
||||||
fn create_entry_fn(
|
fn create_entry_fn(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
@@ -54,23 +48,17 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
AbiParam::new(m.target_config().pointer_type()),
|
AbiParam::new(m.target_config().pointer_type()),
|
||||||
AbiParam::new(m.target_config().pointer_type()),
|
AbiParam::new(m.target_config().pointer_type()),
|
||||||
],
|
],
|
||||||
returns: vec![AbiParam::new(
|
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
|
||||||
m.target_config().pointer_type(), /*isize*/
|
|
||||||
)],
|
|
||||||
call_conv: CallConv::triple_default(m.isa().triple()),
|
call_conv: CallConv::triple_default(m.isa().triple()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let cmain_func_id = m
|
let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();
|
||||||
.declare_function("main", Linkage::Export, &cmain_sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
|
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
|
||||||
|
|
||||||
let main_name = tcx.symbol_name(instance).name.to_string();
|
let main_name = tcx.symbol_name(instance).name.to_string();
|
||||||
let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
|
let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
|
||||||
let main_func_id = m
|
let main_func_id = m.declare_function(&main_name, Linkage::Import, &main_sig).unwrap();
|
||||||
.declare_function(&main_name, Linkage::Import, &main_sig)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut ctx = Context::new();
|
let mut ctx = Context::new();
|
||||||
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig);
|
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig);
|
||||||
@@ -98,9 +86,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
|||||||
.polymorphize(tcx);
|
.polymorphize(tcx);
|
||||||
let start_func_id = import_function(tcx, m, start_instance);
|
let start_func_id = import_function(tcx, m, start_instance);
|
||||||
|
|
||||||
let main_val = bcx
|
let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref);
|
||||||
.ins()
|
|
||||||
.func_addr(m.target_config().pointer_type(), main_func_ref);
|
|
||||||
|
|
||||||
let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func);
|
let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func);
|
||||||
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv])
|
bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv])
|
||||||
|
|||||||
@@ -94,9 +94,7 @@ pub(crate) fn write_metadata<P: WriteMetadata>(
|
|||||||
|
|
||||||
assert!(kind == MetadataKind::Compressed);
|
assert!(kind == MetadataKind::Compressed);
|
||||||
let mut compressed = tcx.metadata_encoding_version();
|
let mut compressed = tcx.metadata_encoding_version();
|
||||||
FrameEncoder::new(&mut compressed)
|
FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
|
||||||
.write_all(&metadata.raw_data)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
product.add_rustc_section(
|
product.add_rustc_section(
|
||||||
rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),
|
rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),
|
||||||
|
|||||||
49
src/num.rs
49
src/num.rs
@@ -93,12 +93,7 @@ pub(crate) fn codegen_binop<'tcx>(
|
|||||||
ty::Uint(_) | ty::Int(_) => crate::num::codegen_int_binop(fx, bin_op, in_lhs, in_rhs),
|
ty::Uint(_) | ty::Int(_) => crate::num::codegen_int_binop(fx, bin_op, in_lhs, in_rhs),
|
||||||
ty::Float(_) => crate::num::codegen_float_binop(fx, bin_op, in_lhs, in_rhs),
|
ty::Float(_) => crate::num::codegen_float_binop(fx, bin_op, in_lhs, in_rhs),
|
||||||
ty::RawPtr(..) | ty::FnPtr(..) => crate::num::codegen_ptr_binop(fx, bin_op, in_lhs, in_rhs),
|
ty::RawPtr(..) | ty::FnPtr(..) => crate::num::codegen_ptr_binop(fx, bin_op, in_lhs, in_rhs),
|
||||||
_ => unreachable!(
|
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty),
|
||||||
"{:?}({:?}, {:?})",
|
|
||||||
bin_op,
|
|
||||||
in_lhs.layout().ty,
|
|
||||||
in_rhs.layout().ty
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,12 +180,7 @@ pub(crate) fn codegen_int_binop<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Compare binops handles by `codegen_binop`.
|
// Compare binops handles by `codegen_binop`.
|
||||||
_ => unreachable!(
|
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty),
|
||||||
"{:?}({:?}, {:?})",
|
|
||||||
bin_op,
|
|
||||||
in_lhs.layout().ty,
|
|
||||||
in_rhs.layout().ty
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CValue::by_val(val, in_lhs.layout())
|
CValue::by_val(val, in_lhs.layout())
|
||||||
@@ -268,9 +258,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
|
|||||||
let rhs = fx.bcx.ins().sextend(ty.double_width().unwrap(), rhs);
|
let rhs = fx.bcx.ins().sextend(ty.double_width().unwrap(), rhs);
|
||||||
let val = fx.bcx.ins().imul(lhs, rhs);
|
let val = fx.bcx.ins().imul(lhs, rhs);
|
||||||
let has_underflow =
|
let has_underflow =
|
||||||
fx.bcx
|
fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1)));
|
||||||
.ins()
|
|
||||||
.icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1)));
|
|
||||||
let has_overflow = fx.bcx.ins().icmp_imm(
|
let has_overflow = fx.bcx.ins().icmp_imm(
|
||||||
IntCC::SignedGreaterThan,
|
IntCC::SignedGreaterThan,
|
||||||
val,
|
val,
|
||||||
@@ -309,10 +297,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
|
|||||||
let val = fx.bcx.ins().ishl(lhs, actual_shift);
|
let val = fx.bcx.ins().ishl(lhs, actual_shift);
|
||||||
let ty = fx.bcx.func.dfg.value_type(val);
|
let ty = fx.bcx.func.dfg.value_type(val);
|
||||||
let max_shift = i64::from(ty.bits()) - 1;
|
let max_shift = i64::from(ty.bits()) - 1;
|
||||||
let has_overflow = fx
|
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
|
|
||||||
(val, has_overflow)
|
(val, has_overflow)
|
||||||
}
|
}
|
||||||
BinOp::Shr => {
|
BinOp::Shr => {
|
||||||
@@ -326,26 +311,15 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
|
|||||||
};
|
};
|
||||||
let ty = fx.bcx.func.dfg.value_type(val);
|
let ty = fx.bcx.func.dfg.value_type(val);
|
||||||
let max_shift = i64::from(ty.bits()) - 1;
|
let max_shift = i64::from(ty.bits()) - 1;
|
||||||
let has_overflow = fx
|
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
|
|
||||||
(val, has_overflow)
|
(val, has_overflow)
|
||||||
}
|
}
|
||||||
_ => bug!(
|
_ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs),
|
||||||
"binop {:?} on checked int/uint lhs: {:?} rhs: {:?}",
|
|
||||||
bin_op,
|
|
||||||
in_lhs,
|
|
||||||
in_rhs
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow);
|
let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow);
|
||||||
|
|
||||||
let out_layout = fx.layout_of(
|
let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()));
|
||||||
fx.tcx
|
|
||||||
.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()),
|
|
||||||
);
|
|
||||||
CValue::by_val_pair(res, has_overflow, out_layout)
|
CValue::by_val_pair(res, has_overflow, out_layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,9 +419,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
|
|||||||
let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr);
|
let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr);
|
||||||
|
|
||||||
let ptr_cmp =
|
let ptr_cmp =
|
||||||
fx.bcx
|
fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
|
||||||
.ins()
|
|
||||||
.icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr);
|
|
||||||
let extra_cmp = fx.bcx.ins().icmp(
|
let extra_cmp = fx.bcx.ins().icmp(
|
||||||
bin_op_to_intcc(bin_op, false).unwrap(),
|
bin_op_to_intcc(bin_op, false).unwrap(),
|
||||||
lhs_extra,
|
lhs_extra,
|
||||||
@@ -459,9 +431,6 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
|
|||||||
_ => panic!("bin_op {:?} on ptr", bin_op),
|
_ => panic!("bin_op {:?} on ptr", bin_op),
|
||||||
};
|
};
|
||||||
|
|
||||||
CValue::by_val(
|
CValue::by_val(fx.bcx.ins().bint(types::I8, res), fx.layout_of(fx.tcx.types.bool))
|
||||||
fx.bcx.ins().bint(types::I8, res),
|
|
||||||
fx.layout_of(fx.tcx.types.bool),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet<Block
|
|||||||
// bytecodealliance/cranelift#1339 is implemented.
|
// bytecodealliance/cranelift#1339 is implemented.
|
||||||
|
|
||||||
let mut block_insts = FxHashMap::default();
|
let mut block_insts = FxHashMap::default();
|
||||||
for block in cold_blocks
|
for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) {
|
||||||
.keys()
|
|
||||||
.filter(|&block| cold_blocks.contains(block))
|
|
||||||
{
|
|
||||||
let insts = ctx.func.layout.block_insts(block).collect::<Vec<_>>();
|
let insts = ctx.func.layout.block_insts(block).collect::<Vec<_>>();
|
||||||
for &inst in &insts {
|
for &inst in &insts {
|
||||||
ctx.func.layout.remove_inst(inst);
|
ctx.func.layout.remove_inst(inst);
|
||||||
@@ -28,10 +25,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet<Block
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And then append them at the back again.
|
// And then append them at the back again.
|
||||||
for block in cold_blocks
|
for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) {
|
||||||
.keys()
|
|
||||||
.filter(|&block| cold_blocks.contains(block))
|
|
||||||
{
|
|
||||||
ctx.func.layout.append_block(block);
|
ctx.func.layout.append_block(block);
|
||||||
for inst in block_insts.remove(&block).unwrap() {
|
for inst in block_insts.remove(&block).unwrap() {
|
||||||
ctx.func.layout.append_inst(inst, block);
|
ctx.func.layout.append_inst(inst, block);
|
||||||
|
|||||||
@@ -10,10 +10,7 @@ use cranelift_frontend::FunctionBuilder;
|
|||||||
pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value {
|
pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value {
|
||||||
if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
|
if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
|
||||||
match bcx.func.dfg[arg_inst] {
|
match bcx.func.dfg[arg_inst] {
|
||||||
InstructionData::Unary {
|
InstructionData::Unary { opcode: Opcode::Bint, arg } => arg,
|
||||||
opcode: Opcode::Bint,
|
|
||||||
arg,
|
|
||||||
} => arg,
|
|
||||||
_ => arg,
|
_ => arg,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -54,12 +51,7 @@ pub(crate) fn make_branchable_value(bcx: &mut FunctionBuilder<'_>, arg: Value) -
|
|||||||
|
|
||||||
match bcx.func.dfg[arg_inst] {
|
match bcx.func.dfg[arg_inst] {
|
||||||
// This is the lowering of Rvalue::Not
|
// This is the lowering of Rvalue::Not
|
||||||
InstructionData::Load {
|
InstructionData::Load { opcode: Opcode::Load, arg: ptr, flags, offset } => {
|
||||||
opcode: Opcode::Load,
|
|
||||||
arg: ptr,
|
|
||||||
flags,
|
|
||||||
offset,
|
|
||||||
} => {
|
|
||||||
// Using `load.i8 + uextend.i32` would legalize to `uload8 + ireduce.i8 +
|
// Using `load.i8 + uextend.i32` would legalize to `uload8 + ireduce.i8 +
|
||||||
// uextend.i32`. Just `uload8` is much faster.
|
// uextend.i32`. Just `uload8` is much faster.
|
||||||
match bcx.func.dfg.ctrl_typevar(arg_inst) {
|
match bcx.func.dfg.ctrl_typevar(arg_inst) {
|
||||||
@@ -95,20 +87,14 @@ pub(crate) fn maybe_known_branch_taken(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match bcx.func.dfg[arg_inst] {
|
match bcx.func.dfg[arg_inst] {
|
||||||
InstructionData::UnaryBool {
|
InstructionData::UnaryBool { opcode: Opcode::Bconst, imm } => {
|
||||||
opcode: Opcode::Bconst,
|
|
||||||
imm,
|
|
||||||
} => {
|
|
||||||
if test_zero {
|
if test_zero {
|
||||||
Some(!imm)
|
Some(!imm)
|
||||||
} else {
|
} else {
|
||||||
Some(imm)
|
Some(imm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstructionData::UnaryImm {
|
InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => {
|
||||||
opcode: Opcode::Iconst,
|
|
||||||
imm,
|
|
||||||
} => {
|
|
||||||
if test_zero {
|
if test_zero {
|
||||||
Some(imm.bits() == 0)
|
Some(imm.bits() == 0)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -175,16 +175,14 @@ impl<'a> OptimizeContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OptimizeContext {
|
OptimizeContext { ctx, stack_slot_usage_map }
|
||||||
ctx,
|
|
||||||
stack_slot_usage_map,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn optimize_function(
|
pub(super) fn optimize_function(
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
#[cfg_attr(not(debug_assertions), allow(unused_variables))] clif_comments: &mut crate::pretty_clif::CommentWriter,
|
#[cfg_attr(not(debug_assertions), allow(unused_variables))]
|
||||||
|
clif_comments: &mut crate::pretty_clif::CommentWriter,
|
||||||
) {
|
) {
|
||||||
combine_stack_addr_with_load_store(&mut ctx.func);
|
combine_stack_addr_with_load_store(&mut ctx.func);
|
||||||
|
|
||||||
@@ -296,12 +294,7 @@ fn combine_stack_addr_with_load_store(func: &mut Function) {
|
|||||||
while let Some(_block) = cursor.next_block() {
|
while let Some(_block) = cursor.next_block() {
|
||||||
while let Some(inst) = cursor.next_inst() {
|
while let Some(inst) = cursor.next_inst() {
|
||||||
match cursor.func.dfg[inst] {
|
match cursor.func.dfg[inst] {
|
||||||
InstructionData::Load {
|
InstructionData::Load { opcode: Opcode::Load, arg: addr, flags: _, offset } => {
|
||||||
opcode: Opcode::Load,
|
|
||||||
arg: addr,
|
|
||||||
flags: _,
|
|
||||||
offset,
|
|
||||||
} => {
|
|
||||||
if cursor.func.dfg.ctrl_typevar(inst) == types::I128
|
if cursor.func.dfg.ctrl_typevar(inst) == types::I128
|
||||||
|| cursor.func.dfg.ctrl_typevar(inst).is_vector()
|
|| cursor.func.dfg.ctrl_typevar(inst).is_vector()
|
||||||
{
|
{
|
||||||
@@ -391,20 +384,14 @@ fn remove_unused_stack_addr_and_stack_load(opt_ctx: &mut OptimizeContext<'_>) {
|
|||||||
stack_slot_users
|
stack_slot_users
|
||||||
.stack_addr
|
.stack_addr
|
||||||
.drain_filter(|inst| {
|
.drain_filter(|inst| {
|
||||||
stack_addr_load_insts_users
|
stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true)
|
||||||
.get(inst)
|
|
||||||
.map(|users| users.is_empty())
|
|
||||||
.unwrap_or(true)
|
|
||||||
})
|
})
|
||||||
.for_each(|inst| StackSlotUsage::remove_unused_stack_addr(&mut func, inst));
|
.for_each(|inst| StackSlotUsage::remove_unused_stack_addr(&mut func, inst));
|
||||||
|
|
||||||
stack_slot_users
|
stack_slot_users
|
||||||
.stack_load
|
.stack_load
|
||||||
.drain_filter(|inst| {
|
.drain_filter(|inst| {
|
||||||
stack_addr_load_insts_users
|
stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true)
|
||||||
.get(inst)
|
|
||||||
.map(|users| users.is_empty())
|
|
||||||
.unwrap_or(true)
|
|
||||||
})
|
})
|
||||||
.for_each(|inst| StackSlotUsage::remove_unused_load(&mut func, inst));
|
.for_each(|inst| StackSlotUsage::remove_unused_load(&mut func, inst));
|
||||||
}
|
}
|
||||||
@@ -415,11 +402,8 @@ fn try_get_stack_slot_and_offset_for_addr(
|
|||||||
addr: Value,
|
addr: Value,
|
||||||
) -> Option<(StackSlot, Offset32)> {
|
) -> Option<(StackSlot, Offset32)> {
|
||||||
if let ValueDef::Result(addr_inst, 0) = func.dfg.value_def(addr) {
|
if let ValueDef::Result(addr_inst, 0) = func.dfg.value_def(addr) {
|
||||||
if let InstructionData::StackLoad {
|
if let InstructionData::StackLoad { opcode: Opcode::StackAddr, stack_slot, offset } =
|
||||||
opcode: Opcode::StackAddr,
|
func.dfg[addr_inst]
|
||||||
stack_slot,
|
|
||||||
offset,
|
|
||||||
} = func.dfg[addr_inst]
|
|
||||||
{
|
{
|
||||||
return Some((stack_slot, offset));
|
return Some((stack_slot, offset));
|
||||||
}
|
}
|
||||||
@@ -437,16 +421,8 @@ enum SpatialOverlap {
|
|||||||
fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap {
|
fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap {
|
||||||
fn inst_info(func: &Function, inst: Inst) -> (StackSlot, Offset32, u32) {
|
fn inst_info(func: &Function, inst: Inst) -> (StackSlot, Offset32, u32) {
|
||||||
match func.dfg[inst] {
|
match func.dfg[inst] {
|
||||||
InstructionData::StackLoad {
|
InstructionData::StackLoad { opcode: Opcode::StackAddr, stack_slot, offset }
|
||||||
opcode: Opcode::StackAddr,
|
| InstructionData::StackLoad { opcode: Opcode::StackLoad, stack_slot, offset }
|
||||||
stack_slot,
|
|
||||||
offset,
|
|
||||||
}
|
|
||||||
| InstructionData::StackLoad {
|
|
||||||
opcode: Opcode::StackLoad,
|
|
||||||
stack_slot,
|
|
||||||
offset,
|
|
||||||
}
|
|
||||||
| InstructionData::StackStore {
|
| InstructionData::StackStore {
|
||||||
opcode: Opcode::StackStore,
|
opcode: Opcode::StackStore,
|
||||||
stack_slot,
|
stack_slot,
|
||||||
@@ -471,10 +447,7 @@ fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let src_end: i64 = src_offset.try_add_i64(i64::from(src_size)).unwrap().into();
|
let src_end: i64 = src_offset.try_add_i64(i64::from(src_size)).unwrap().into();
|
||||||
let dest_end: i64 = dest_offset
|
let dest_end: i64 = dest_offset.try_add_i64(i64::from(dest_size)).unwrap().into();
|
||||||
.try_add_i64(i64::from(dest_size))
|
|
||||||
.unwrap()
|
|
||||||
.into();
|
|
||||||
if src_end <= dest_offset.into() || dest_end <= src_offset.into() {
|
if src_end <= dest_offset.into() || dest_end <= src_offset.into() {
|
||||||
return SpatialOverlap::No;
|
return SpatialOverlap::No;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,32 +23,20 @@ pub(crate) enum PointerBase {
|
|||||||
|
|
||||||
impl Pointer {
|
impl Pointer {
|
||||||
pub(crate) fn new(addr: Value) -> Self {
|
pub(crate) fn new(addr: Value) -> Self {
|
||||||
Pointer {
|
Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) }
|
||||||
base: PointerBase::Addr(addr),
|
|
||||||
offset: Offset32::new(0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn stack_slot(stack_slot: StackSlot) -> Self {
|
pub(crate) fn stack_slot(stack_slot: StackSlot) -> Self {
|
||||||
Pointer {
|
Pointer { base: PointerBase::Stack(stack_slot), offset: Offset32::new(0) }
|
||||||
base: PointerBase::Stack(stack_slot),
|
|
||||||
offset: Offset32::new(0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn const_addr(fx: &mut FunctionCx<'_, '_, '_>, addr: i64) -> Self {
|
pub(crate) fn const_addr(fx: &mut FunctionCx<'_, '_, '_>, addr: i64) -> Self {
|
||||||
let addr = fx.bcx.ins().iconst(fx.pointer_type, addr);
|
let addr = fx.bcx.ins().iconst(fx.pointer_type, addr);
|
||||||
Pointer {
|
Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) }
|
||||||
base: PointerBase::Addr(addr),
|
|
||||||
offset: Offset32::new(0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn dangling(align: Align) -> Self {
|
pub(crate) fn dangling(align: Align) -> Self {
|
||||||
Pointer {
|
Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) }
|
||||||
base: PointerBase::Dangling(align),
|
|
||||||
offset: Offset32::new(0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -60,21 +48,14 @@ impl Pointer {
|
|||||||
match self.base {
|
match self.base {
|
||||||
PointerBase::Addr(base_addr) => {
|
PointerBase::Addr(base_addr) => {
|
||||||
let offset: i64 = self.offset.into();
|
let offset: i64 = self.offset.into();
|
||||||
if offset == 0 {
|
if offset == 0 { base_addr } else { fx.bcx.ins().iadd_imm(base_addr, offset) }
|
||||||
base_addr
|
|
||||||
} else {
|
|
||||||
fx.bcx.ins().iadd_imm(base_addr, offset)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PointerBase::Stack(stack_slot) => {
|
PointerBase::Stack(stack_slot) => {
|
||||||
fx.bcx
|
fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, self.offset)
|
||||||
.ins()
|
}
|
||||||
.stack_addr(fx.pointer_type, stack_slot, self.offset)
|
PointerBase::Dangling(align) => {
|
||||||
|
fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap())
|
||||||
}
|
}
|
||||||
PointerBase::Dangling(align) => fx
|
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,10 +65,7 @@ impl Pointer {
|
|||||||
|
|
||||||
pub(crate) fn offset_i64(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: i64) -> Self {
|
pub(crate) fn offset_i64(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: i64) -> Self {
|
||||||
if let Some(new_offset) = self.offset.try_add_i64(extra_offset) {
|
if let Some(new_offset) = self.offset.try_add_i64(extra_offset) {
|
||||||
Pointer {
|
Pointer { base: self.base, offset: new_offset }
|
||||||
base: self.base,
|
|
||||||
offset: new_offset,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let base_offset: i64 = self.offset.into();
|
let base_offset: i64 = self.offset.into();
|
||||||
if let Some(new_offset) = base_offset.checked_add(extra_offset) {
|
if let Some(new_offset) = base_offset.checked_add(extra_offset) {
|
||||||
@@ -96,16 +74,12 @@ impl Pointer {
|
|||||||
PointerBase::Stack(stack_slot) => {
|
PointerBase::Stack(stack_slot) => {
|
||||||
fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0)
|
fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0)
|
||||||
}
|
}
|
||||||
PointerBase::Dangling(align) => fx
|
PointerBase::Dangling(align) => {
|
||||||
.bcx
|
fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap())
|
||||||
.ins()
|
}
|
||||||
.iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()),
|
|
||||||
};
|
};
|
||||||
let addr = fx.bcx.ins().iadd_imm(base_addr, new_offset);
|
let addr = fx.bcx.ins().iadd_imm(base_addr, new_offset);
|
||||||
Pointer {
|
Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) }
|
||||||
base: PointerBase::Addr(addr),
|
|
||||||
offset: Offset32::new(0),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
panic!(
|
panic!(
|
||||||
"self.offset ({}) + extra_offset ({}) not representable in i64",
|
"self.offset ({}) + extra_offset ({}) not representable in i64",
|
||||||
@@ -122,20 +96,15 @@ impl Pointer {
|
|||||||
offset: self.offset,
|
offset: self.offset,
|
||||||
},
|
},
|
||||||
PointerBase::Stack(stack_slot) => {
|
PointerBase::Stack(stack_slot) => {
|
||||||
let base_addr = fx
|
let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, self.offset);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.stack_addr(fx.pointer_type, stack_slot, self.offset);
|
|
||||||
Pointer {
|
Pointer {
|
||||||
base: PointerBase::Addr(fx.bcx.ins().iadd(base_addr, extra_offset)),
|
base: PointerBase::Addr(fx.bcx.ins().iadd(base_addr, extra_offset)),
|
||||||
offset: Offset32::new(0),
|
offset: Offset32::new(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PointerBase::Dangling(align) => {
|
PointerBase::Dangling(align) => {
|
||||||
let addr = fx
|
let addr =
|
||||||
.bcx
|
fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap());
|
||||||
.ins()
|
|
||||||
.iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap());
|
|
||||||
Pointer {
|
Pointer {
|
||||||
base: PointerBase::Addr(fx.bcx.ins().iadd(addr, extra_offset)),
|
base: PointerBase::Addr(fx.bcx.ins().iadd(addr, extra_offset)),
|
||||||
offset: self.offset,
|
offset: self.offset,
|
||||||
|
|||||||
@@ -79,20 +79,14 @@ impl CommentWriter {
|
|||||||
vec![
|
vec![
|
||||||
format!("symbol {}", tcx.symbol_name(instance).name),
|
format!("symbol {}", tcx.symbol_name(instance).name),
|
||||||
format!("instance {:?}", instance),
|
format!("instance {:?}", instance),
|
||||||
format!(
|
format!("abi {:?}", FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])),
|
||||||
"abi {:?}",
|
|
||||||
FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])
|
|
||||||
),
|
|
||||||
String::new(),
|
String::new(),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
CommentWriter {
|
CommentWriter { global_comments, entity_comments: FxHashMap::default() }
|
||||||
global_comments,
|
|
||||||
entity_comments: FxHashMap::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,10 +195,7 @@ impl FunctionCx<'_, '_, '_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool {
|
pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool {
|
||||||
tcx.sess
|
tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly)
|
||||||
.opts
|
|
||||||
.output_types
|
|
||||||
.contains_key(&OutputType::LlvmAssembly)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn write_ir_file<'tcx>(
|
pub(crate) fn write_ir_file<'tcx>(
|
||||||
@@ -243,15 +234,9 @@ pub(crate) fn write_clif_file<'tcx>(
|
|||||||
context: &cranelift_codegen::Context,
|
context: &cranelift_codegen::Context,
|
||||||
mut clif_comments: &CommentWriter,
|
mut clif_comments: &CommentWriter,
|
||||||
) {
|
) {
|
||||||
write_ir_file(
|
write_ir_file(tcx, &format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix), |file| {
|
||||||
tcx,
|
let value_ranges =
|
||||||
&format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
|
isa.map(|isa| context.build_value_labels_ranges(isa).expect("value location ranges"));
|
||||||
|file| {
|
|
||||||
let value_ranges = isa.map(|isa| {
|
|
||||||
context
|
|
||||||
.build_value_labels_ranges(isa)
|
|
||||||
.expect("value location ranges")
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut clif = String::new();
|
let mut clif = String::new();
|
||||||
cranelift_codegen::write::decorate_function(
|
cranelift_codegen::write::decorate_function(
|
||||||
@@ -272,8 +257,7 @@ pub(crate) fn write_clif_file<'tcx>(
|
|||||||
writeln!(file)?;
|
writeln!(file)?;
|
||||||
file.write_all(clif.as_bytes())?;
|
file.write_all(clif.as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for FunctionCx<'_, '_, '_> {
|
impl fmt::Debug for FunctionCx<'_, '_, '_> {
|
||||||
|
|||||||
@@ -71,10 +71,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
|||||||
flavor,
|
flavor,
|
||||||
)),
|
)),
|
||||||
(Some(linker), None) => {
|
(Some(linker), None) => {
|
||||||
let stem = linker
|
let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
|
||||||
.file_stem()
|
|
||||||
.and_then(|stem| stem.to_str())
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
sess.fatal("couldn't extract file stem from specified linker")
|
sess.fatal("couldn't extract file stem from specified linker")
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -105,11 +102,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
|||||||
|
|
||||||
// linker and linker flavor specified via command line have precedence over what the target
|
// linker and linker flavor specified via command line have precedence over what the target
|
||||||
// specification specifies
|
// specification specifies
|
||||||
if let Some(ret) = infer_from(
|
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
|
||||||
sess,
|
|
||||||
sess.opts.cg.linker.clone(),
|
|
||||||
sess.opts.cg.linker_flavor,
|
|
||||||
) {
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,13 +19,12 @@ pub(crate) fn unsized_info<'tcx>(
|
|||||||
old_info: Option<Value>,
|
old_info: Option<Value>,
|
||||||
) -> Value {
|
) -> Value {
|
||||||
let (source, target) =
|
let (source, target) =
|
||||||
fx.tcx
|
fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
|
||||||
.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all());
|
|
||||||
match (&source.kind(), &target.kind()) {
|
match (&source.kind(), &target.kind()) {
|
||||||
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
|
(&ty::Array(_, len), &ty::Slice(_)) => fx
|
||||||
fx.pointer_type,
|
.bcx
|
||||||
len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64,
|
.ins()
|
||||||
),
|
.iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
|
||||||
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
|
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
|
||||||
// For now, upcasts are limited to changes in marker
|
// For now, upcasts are limited to changes in marker
|
||||||
// traits, and hence never actually require an actual
|
// traits, and hence never actually require an actual
|
||||||
@@ -35,11 +34,7 @@ pub(crate) fn unsized_info<'tcx>(
|
|||||||
(_, &ty::Dynamic(ref data, ..)) => {
|
(_, &ty::Dynamic(ref data, ..)) => {
|
||||||
crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal())
|
crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal())
|
||||||
}
|
}
|
||||||
_ => bug!(
|
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
|
||||||
"unsized_info: invalid unsizing {:?} -> {:?}",
|
|
||||||
source,
|
|
||||||
target
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,10 +91,8 @@ pub(crate) fn coerce_unsized_into<'tcx>(
|
|||||||
let src_ty = src.layout().ty;
|
let src_ty = src.layout().ty;
|
||||||
let dst_ty = dst.layout().ty;
|
let dst_ty = dst.layout().ty;
|
||||||
let mut coerce_ptr = || {
|
let mut coerce_ptr = || {
|
||||||
let (base, info) = if fx
|
let (base, info) =
|
||||||
.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty)
|
if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty).is_unsized() {
|
||||||
.is_unsized()
|
|
||||||
{
|
|
||||||
// fat-ptr to fat-ptr unsize preserves the vtable
|
// fat-ptr to fat-ptr unsize preserves the vtable
|
||||||
// i.e., &'a fmt::Debug+Send => &'a fmt::Debug
|
// i.e., &'a fmt::Debug+Send => &'a fmt::Debug
|
||||||
src.load_scalar_pair(fx)
|
src.load_scalar_pair(fx)
|
||||||
@@ -131,11 +124,7 @@ pub(crate) fn coerce_unsized_into<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => bug!(
|
_ => bug!("coerce_unsized_into: invalid coercion {:?} -> {:?}", src_ty, dst_ty),
|
||||||
"coerce_unsized_into: invalid coercion {:?} -> {:?}",
|
|
||||||
src_ty,
|
|
||||||
dst_ty
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,23 +136,14 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
|||||||
info: Value,
|
info: Value,
|
||||||
) -> (Value, Value) {
|
) -> (Value, Value) {
|
||||||
if !layout.is_unsized() {
|
if !layout.is_unsized() {
|
||||||
let size = fx
|
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
|
||||||
.bcx
|
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
|
||||||
.ins()
|
|
||||||
.iconst(fx.pointer_type, layout.size.bytes() as i64);
|
|
||||||
let align = fx
|
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
|
|
||||||
return (size, align);
|
return (size, align);
|
||||||
}
|
}
|
||||||
match layout.ty.kind() {
|
match layout.ty.kind() {
|
||||||
ty::Dynamic(..) => {
|
ty::Dynamic(..) => {
|
||||||
// load size/align from vtable
|
// load size/align from vtable
|
||||||
(
|
(crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info))
|
||||||
crate::vtable::size_of_obj(fx, info),
|
|
||||||
crate::vtable::min_align_of_obj(fx, info),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
ty::Slice(_) | ty::Str => {
|
ty::Slice(_) | ty::Str => {
|
||||||
let unit = layout.field(fx, 0);
|
let unit = layout.field(fx, 0);
|
||||||
@@ -171,9 +151,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
|||||||
// times the unit size.
|
// times the unit size.
|
||||||
(
|
(
|
||||||
fx.bcx.ins().imul_imm(info, unit.size.bytes() as i64),
|
fx.bcx.ins().imul_imm(info, unit.size.bytes() as i64),
|
||||||
fx.bcx
|
fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
|
||||||
.ins()
|
|
||||||
.iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -211,10 +189,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
|||||||
|
|
||||||
// Choose max of two known alignments (combined value must
|
// Choose max of two known alignments (combined value must
|
||||||
// be aligned according to more restrictive of the two).
|
// be aligned according to more restrictive of the two).
|
||||||
let cmp = fx
|
let cmp = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align);
|
|
||||||
let align = fx.bcx.ins().select(cmp, sized_align, unsized_align);
|
let align = fx.bcx.ins().select(cmp, sized_align, unsized_align);
|
||||||
|
|
||||||
// Issue #27023: must add any necessary padding to `size`
|
// Issue #27023: must add any necessary padding to `size`
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ fn codegen_field<'tcx>(
|
|||||||
let field_layout = layout.field(&*fx, field.index());
|
let field_layout = layout.field(&*fx, field.index());
|
||||||
|
|
||||||
let simple = |fx: &mut FunctionCx<'_, '_, '_>| {
|
let simple = |fx: &mut FunctionCx<'_, '_, '_>| {
|
||||||
(
|
(base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()), field_layout)
|
||||||
base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()),
|
|
||||||
field_layout,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(extra) = extra {
|
if let Some(extra) = extra {
|
||||||
@@ -58,10 +55,7 @@ fn scalar_pair_calculate_b_offset(
|
|||||||
a_scalar: &Scalar,
|
a_scalar: &Scalar,
|
||||||
b_scalar: &Scalar,
|
b_scalar: &Scalar,
|
||||||
) -> Offset32 {
|
) -> Offset32 {
|
||||||
let b_offset = a_scalar
|
let b_offset = a_scalar.value.size(&tcx).align_to(b_scalar.value.align(&tcx).abi);
|
||||||
.value
|
|
||||||
.size(&tcx)
|
|
||||||
.align_to(b_scalar.value.align(&tcx).abi);
|
|
||||||
Offset32::new(b_offset.bytes().try_into().unwrap())
|
Offset32::new(b_offset.bytes().try_into().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,13 +217,7 @@ impl<'tcx> CValue<'tcx> {
|
|||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'tcx>,
|
||||||
const_val: ty::ScalarInt,
|
const_val: ty::ScalarInt,
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
assert_eq!(
|
assert_eq!(const_val.size(), layout.size, "{:#?}: {:?}", const_val, layout);
|
||||||
const_val.size(),
|
|
||||||
layout.size,
|
|
||||||
"{:#?}: {:?}",
|
|
||||||
const_val,
|
|
||||||
layout
|
|
||||||
);
|
|
||||||
use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
|
use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
|
||||||
|
|
||||||
let clif_ty = fx.clif_type(layout.ty).unwrap();
|
let clif_ty = fx.clif_type(layout.ty).unwrap();
|
||||||
@@ -246,18 +234,11 @@ impl<'tcx> CValue<'tcx> {
|
|||||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||||
let const_val = const_val.to_bits(layout.size).unwrap();
|
let const_val = const_val.to_bits(layout.size).unwrap();
|
||||||
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
|
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
|
||||||
let msb = fx
|
let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(types::I64, (const_val >> 64) as u64 as i64);
|
|
||||||
fx.bcx.ins().iconcat(lsb, msb)
|
fx.bcx.ins().iconcat(lsb, msb)
|
||||||
}
|
}
|
||||||
ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..)
|
ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..) | ty::RawPtr(..) => {
|
||||||
| ty::RawPtr(..) => {
|
fx.bcx.ins().iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64)
|
||||||
fx
|
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64)
|
|
||||||
}
|
}
|
||||||
ty::Float(FloatTy::F32) => {
|
ty::Float(FloatTy::F32) => {
|
||||||
fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap()))
|
fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap()))
|
||||||
@@ -275,14 +256,8 @@ impl<'tcx> CValue<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn cast_pointer_to(self, layout: TyAndLayout<'tcx>) -> Self {
|
pub(crate) fn cast_pointer_to(self, layout: TyAndLayout<'tcx>) -> Self {
|
||||||
assert!(matches!(
|
assert!(matches!(self.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..)));
|
||||||
self.layout().ty.kind(),
|
assert!(matches!(layout.ty.kind(), ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..)));
|
||||||
ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..)
|
|
||||||
));
|
|
||||||
assert!(matches!(
|
|
||||||
layout.ty.kind(),
|
|
||||||
ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..)
|
|
||||||
));
|
|
||||||
assert_eq!(self.layout().abi, layout.abi);
|
assert_eq!(self.layout().abi, layout.abi);
|
||||||
CValue(self.0, layout)
|
CValue(self.0, layout)
|
||||||
}
|
}
|
||||||
@@ -313,10 +288,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn no_place(layout: TyAndLayout<'tcx>) -> CPlace<'tcx> {
|
pub(crate) fn no_place(layout: TyAndLayout<'tcx>) -> CPlace<'tcx> {
|
||||||
CPlace {
|
CPlace { inner: CPlaceInner::Addr(Pointer::dangling(layout.align.pref), None), layout }
|
||||||
inner: CPlaceInner::Addr(Pointer::dangling(layout.align.pref), None),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_stack_slot(
|
pub(crate) fn new_stack_slot(
|
||||||
@@ -335,10 +307,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16,
|
size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16,
|
||||||
offset: None,
|
offset: None,
|
||||||
});
|
});
|
||||||
CPlace {
|
CPlace { inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), layout }
|
||||||
inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_var(
|
pub(crate) fn new_var(
|
||||||
@@ -349,10 +318,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
let var = Variable::with_u32(fx.next_ssa_var);
|
let var = Variable::with_u32(fx.next_ssa_var);
|
||||||
fx.next_ssa_var += 1;
|
fx.next_ssa_var += 1;
|
||||||
fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap());
|
fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap());
|
||||||
CPlace {
|
CPlace { inner: CPlaceInner::Var(local, var), layout }
|
||||||
inner: CPlaceInner::Var(local, var),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_var_pair(
|
pub(crate) fn new_var_pair(
|
||||||
@@ -368,17 +334,11 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap();
|
let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap();
|
||||||
fx.bcx.declare_var(var1, ty1);
|
fx.bcx.declare_var(var1, ty1);
|
||||||
fx.bcx.declare_var(var2, ty2);
|
fx.bcx.declare_var(var2, ty2);
|
||||||
CPlace {
|
CPlace { inner: CPlaceInner::VarPair(local, var1, var2), layout }
|
||||||
inner: CPlaceInner::VarPair(local, var1, var2),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn for_ptr(ptr: Pointer, layout: TyAndLayout<'tcx>) -> CPlace<'tcx> {
|
pub(crate) fn for_ptr(ptr: Pointer, layout: TyAndLayout<'tcx>) -> CPlace<'tcx> {
|
||||||
CPlace {
|
CPlace { inner: CPlaceInner::Addr(ptr, None), layout }
|
||||||
inner: CPlaceInner::Addr(ptr, None),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn for_ptr_with_extra(
|
pub(crate) fn for_ptr_with_extra(
|
||||||
@@ -386,10 +346,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
extra: Value,
|
extra: Value,
|
||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'tcx>,
|
||||||
) -> CPlace<'tcx> {
|
) -> CPlace<'tcx> {
|
||||||
CPlace {
|
CPlace { inner: CPlaceInner::Addr(ptr, Some(extra)), layout }
|
||||||
inner: CPlaceInner::Addr(ptr, Some(extra)),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CValue<'tcx> {
|
pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CValue<'tcx> {
|
||||||
@@ -397,23 +354,19 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
match self.inner {
|
match self.inner {
|
||||||
CPlaceInner::Var(_local, var) => {
|
CPlaceInner::Var(_local, var) => {
|
||||||
let val = fx.bcx.use_var(var);
|
let val = fx.bcx.use_var(var);
|
||||||
fx.bcx
|
fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||||
.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
|
||||||
CValue::by_val(val, layout)
|
CValue::by_val(val, layout)
|
||||||
}
|
}
|
||||||
CPlaceInner::VarPair(_local, var1, var2) => {
|
CPlaceInner::VarPair(_local, var1, var2) => {
|
||||||
let val1 = fx.bcx.use_var(var1);
|
let val1 = fx.bcx.use_var(var1);
|
||||||
fx.bcx
|
fx.bcx.set_val_label(val1, cranelift_codegen::ir::ValueLabel::new(var1.index()));
|
||||||
.set_val_label(val1, cranelift_codegen::ir::ValueLabel::new(var1.index()));
|
|
||||||
let val2 = fx.bcx.use_var(var2);
|
let val2 = fx.bcx.use_var(var2);
|
||||||
fx.bcx
|
fx.bcx.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index()));
|
||||||
.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index()));
|
|
||||||
CValue::by_val_pair(val1, val2, layout)
|
CValue::by_val_pair(val1, val2, layout)
|
||||||
}
|
}
|
||||||
CPlaceInner::VarLane(_local, var, lane) => {
|
CPlaceInner::VarLane(_local, var, lane) => {
|
||||||
let val = fx.bcx.use_var(var);
|
let val = fx.bcx.use_var(var);
|
||||||
fx.bcx
|
fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||||
.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
|
||||||
let val = fx.bcx.ins().extractlane(val, lane);
|
let val = fx.bcx.ins().extractlane(val, lane);
|
||||||
CValue::by_val(val, layout)
|
CValue::by_val(val, layout)
|
||||||
}
|
}
|
||||||
@@ -503,8 +456,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
}
|
}
|
||||||
_ => unreachable!("write_cvalue_transmute: {:?} -> {:?}", src_ty, dst_ty),
|
_ => unreachable!("write_cvalue_transmute: {:?} -> {:?}", src_ty, dst_ty),
|
||||||
};
|
};
|
||||||
fx.bcx
|
fx.bcx.set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||||
.set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
|
||||||
fx.bcx.def_var(var, data);
|
fx.bcx.def_var(var, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,15 +502,13 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
|
|
||||||
// First get the old vector
|
// First get the old vector
|
||||||
let vector = fx.bcx.use_var(var);
|
let vector = fx.bcx.use_var(var);
|
||||||
fx.bcx
|
fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||||
.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
|
||||||
|
|
||||||
// Next insert the written lane into the vector
|
// Next insert the written lane into the vector
|
||||||
let vector = fx.bcx.ins().insertlane(vector, data, lane);
|
let vector = fx.bcx.ins().insertlane(vector, data, lane);
|
||||||
|
|
||||||
// Finally write the new vector
|
// Finally write the new vector
|
||||||
fx.bcx
|
fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
||||||
.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
|
|
||||||
fx.bcx.def_var(var, vector);
|
fx.bcx.def_var(var, vector);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -596,10 +546,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
to_ptr.store(fx, val, flags);
|
to_ptr.store(fx, val, flags);
|
||||||
}
|
}
|
||||||
CValueInner::ByValPair(_, _) => {
|
CValueInner::ByValPair(_, _) => {
|
||||||
bug!(
|
bug!("Non ScalarPair abi {:?} for ByValPair CValue", dst_layout.abi);
|
||||||
"Non ScalarPair abi {:?} for ByValPair CValue",
|
|
||||||
dst_layout.abi
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
CValueInner::ByRef(from_ptr, None) => {
|
CValueInner::ByRef(from_ptr, None) => {
|
||||||
let from_addr = from_ptr.get_addr(fx);
|
let from_addr = from_ptr.get_addr(fx);
|
||||||
@@ -642,18 +589,8 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
let layout = layout.field(&*fx, field.index());
|
let layout = layout.field(&*fx, field.index());
|
||||||
|
|
||||||
match field.as_u32() {
|
match field.as_u32() {
|
||||||
0 => {
|
0 => return CPlace { inner: CPlaceInner::Var(local, var1), layout },
|
||||||
return CPlace {
|
1 => return CPlace { inner: CPlaceInner::Var(local, var2), layout },
|
||||||
inner: CPlaceInner::Var(local, var1),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
return CPlace {
|
|
||||||
inner: CPlaceInner::Var(local, var2),
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!("field should be 0 or 1"),
|
_ => unreachable!("field should be 0 or 1"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -681,10 +618,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
_ => bug!("place_index({:?})", self.layout().ty),
|
_ => bug!("place_index({:?})", self.layout().ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
let offset = fx
|
let offset = fx.bcx.ins().imul_imm(index, elem_layout.size.bytes() as i64);
|
||||||
.bcx
|
|
||||||
.ins()
|
|
||||||
.imul_imm(index, elem_layout.size.bytes() as i64);
|
|
||||||
|
|
||||||
CPlace::for_ptr(ptr.offset_value(fx, offset), elem_layout)
|
CPlace::for_ptr(ptr.offset_value(fx, offset), elem_layout)
|
||||||
}
|
}
|
||||||
@@ -695,10 +629,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
|
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
|
||||||
CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout)
|
CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout)
|
||||||
} else {
|
} else {
|
||||||
CPlace::for_ptr(
|
CPlace::for_ptr(Pointer::new(self.to_cvalue(fx).load_scalar(fx)), inner_layout)
|
||||||
Pointer::new(self.to_cvalue(fx).load_scalar(fx)),
|
|
||||||
inner_layout,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,10 +657,7 @@ impl<'tcx> CPlace<'tcx> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
assert!(!self.layout().is_unsized());
|
assert!(!self.layout().is_unsized());
|
||||||
let layout = self.layout().for_variant(fx, variant);
|
let layout = self.layout().for_variant(fx, variant);
|
||||||
CPlace {
|
CPlace { inner: self.inner, layout }
|
||||||
inner: self.inner,
|
|
||||||
layout,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,12 +696,9 @@ pub(crate) fn assert_assignable<'tcx>(
|
|||||||
}
|
}
|
||||||
(&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => {
|
(&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => {
|
||||||
for (from, to) in from_traits.iter().zip(to_traits) {
|
for (from, to) in from_traits.iter().zip(to_traits) {
|
||||||
let from = fx
|
let from =
|
||||||
.tcx
|
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from);
|
||||||
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from);
|
let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to);
|
||||||
let to = fx
|
|
||||||
.tcx
|
|
||||||
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from, to,
|
from, to,
|
||||||
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
|
"Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}",
|
||||||
|
|||||||
@@ -165,11 +165,8 @@ fn build_vtable<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_usize(tcx: TyCtxt<'_>, buf: &mut [u8], idx: usize, num: u64) {
|
fn write_usize(tcx: TyCtxt<'_>, buf: &mut [u8], idx: usize, num: u64) {
|
||||||
let pointer_size = tcx
|
let pointer_size =
|
||||||
.layout_of(ParamEnv::reveal_all().and(tcx.types.usize))
|
tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.usize)).unwrap().size.bytes() as usize;
|
||||||
.unwrap()
|
|
||||||
.size
|
|
||||||
.bytes() as usize;
|
|
||||||
let target = &mut buf[idx * pointer_size..(idx + 1) * pointer_size];
|
let target = &mut buf[idx * pointer_size..(idx + 1) * pointer_size];
|
||||||
|
|
||||||
match tcx.data_layout.endian {
|
match tcx.data_layout.endian {
|
||||||
|
|||||||
Reference in New Issue
Block a user