Box CastTarget
within PassMode
.
Because `PassMode::Cast` is by far the largest variant, but is relatively rare. This requires making `PassMode` not impl `Copy`, and `Clone` is no longer necessary. This causes lots of sigil adjusting, but nothing very notable.
This commit is contained in:
parent
263c426bfd
commit
e4bf113027
11 changed files with 57 additions and 57 deletions
|
@ -24,7 +24,7 @@ pub(super) fn add_arg_comment<'tcx>(
|
||||||
local: Option<mir::Local>,
|
local: Option<mir::Local>,
|
||||||
local_field: Option<usize>,
|
local_field: Option<usize>,
|
||||||
params: &[Value],
|
params: &[Value],
|
||||||
arg_abi_mode: PassMode,
|
arg_abi_mode: &PassMode,
|
||||||
arg_layout: TyAndLayout<'tcx>,
|
arg_layout: TyAndLayout<'tcx>,
|
||||||
) {
|
) {
|
||||||
if !fx.clif_comments.enabled() {
|
if !fx.clif_comments.enabled() {
|
||||||
|
|
|
@ -38,7 +38,7 @@ fn apply_arg_attrs_to_abi_param(mut param: AbiParam, arg_attrs: ArgAttributes) -
|
||||||
param
|
param
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
|
fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[AbiParam; 2]> {
|
||||||
let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 {
|
let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 {
|
||||||
(0, 0)
|
(0, 0)
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,7 +100,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(ref cast) => cast_target_to_abi_params(cast),
|
||||||
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
|
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
|
||||||
if on_stack {
|
if on_stack {
|
||||||
// Abi requires aligning struct size to pointer size
|
// Abi requires aligning struct size to pointer size
|
||||||
|
@ -145,7 +145,9 @@ 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(ref cast) => {
|
||||||
|
(None, cast_target_to_abi_params(cast).into_iter().collect())
|
||||||
|
}
|
||||||
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => {
|
PassMode::Indirect { 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), ArgumentPurpose::StructReturn)), vec![])
|
||||||
|
@ -160,7 +162,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
pub(super) fn to_casted_value<'tcx>(
|
pub(super) fn to_casted_value<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
arg: CValue<'tcx>,
|
arg: CValue<'tcx>,
|
||||||
cast: CastTarget,
|
cast: &CastTarget,
|
||||||
) -> SmallVec<[Value; 2]> {
|
) -> SmallVec<[Value; 2]> {
|
||||||
let (ptr, meta) = arg.force_stack(fx);
|
let (ptr, meta) = arg.force_stack(fx);
|
||||||
assert!(meta.is_none());
|
assert!(meta.is_none());
|
||||||
|
@ -179,7 +181,7 @@ pub(super) fn from_casted_value<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
block_params: &[Value],
|
block_params: &[Value],
|
||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'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.iter().map(|param| param.value_type.bytes()).sum();
|
let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();
|
||||||
|
@ -224,7 +226,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
|
||||||
let (a, b) = arg.load_scalar_pair(fx);
|
let (a, b) = arg.load_scalar_pair(fx);
|
||||||
smallvec![a, b]
|
smallvec![a, b]
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast) => to_casted_value(fx, arg, cast),
|
PassMode::Cast(ref cast) => to_casted_value(fx, arg, cast),
|
||||||
PassMode::Indirect { .. } => {
|
PassMode::Indirect { .. } => {
|
||||||
if is_owned {
|
if is_owned {
|
||||||
match arg.force_stack(fx) {
|
match arg.force_stack(fx) {
|
||||||
|
@ -268,7 +270,7 @@ pub(super) fn cvalue_for_param<'tcx>(
|
||||||
local,
|
local,
|
||||||
local_field,
|
local_field,
|
||||||
&block_params,
|
&block_params,
|
||||||
arg_abi.mode,
|
&arg_abi.mode,
|
||||||
arg_abi.layout,
|
arg_abi.layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -282,7 +284,9 @@ pub(super) fn cvalue_for_param<'tcx>(
|
||||||
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
||||||
Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout))
|
Some(CValue::by_val_pair(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(ref cast) => {
|
||||||
|
Some(from_casted_value(fx, &block_params, arg_abi.layout, cast))
|
||||||
|
}
|
||||||
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
|
PassMode::Indirect { 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(Pointer::new(block_params[0]), arg_abi.layout))
|
Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout))
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||||
Some(RETURN_PLACE),
|
Some(RETURN_PLACE),
|
||||||
None,
|
None,
|
||||||
&ret_param,
|
&ret_param,
|
||||||
fx.fn_abi.as_ref().unwrap().ret.mode,
|
&fx.fn_abi.as_ref().unwrap().ret.mode,
|
||||||
fx.fn_abi.as_ref().unwrap().ret.layout,
|
fx.fn_abi.as_ref().unwrap().ret.layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
|
||||||
ret_place
|
ret_place
|
||||||
.write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout));
|
.write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout));
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast) => {
|
PassMode::Cast(ref cast) => {
|
||||||
let results =
|
let results =
|
||||||
fx.bcx.inst_results(call_inst).iter().copied().collect::<SmallVec<[Value; 2]>>();
|
fx.bcx.inst_results(call_inst).iter().copied().collect::<SmallVec<[Value; 2]>>();
|
||||||
let result =
|
let result =
|
||||||
|
@ -131,7 +131,7 @@ pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||||
let (ret_val_a, ret_val_b) = place.to_cvalue(fx).load_scalar_pair(fx);
|
let (ret_val_a, ret_val_b) = place.to_cvalue(fx).load_scalar_pair(fx);
|
||||||
fx.bcx.ins().return_(&[ret_val_a, ret_val_b]);
|
fx.bcx.ins().return_(&[ret_val_a, ret_val_b]);
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast) => {
|
PassMode::Cast(ref cast) => {
|
||||||
let place = fx.get_local_place(RETURN_PLACE);
|
let place = fx.get_local_place(RETURN_PLACE);
|
||||||
let ret_val = place.to_cvalue(fx);
|
let ret_val = place.to_cvalue(fx);
|
||||||
let ret_vals = super::pass_mode::to_casted_value(fx, ret_val, cast);
|
let ret_vals = super::pass_mode::to_casted_value(fx, ret_val, cast);
|
||||||
|
|
|
@ -133,7 +133,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
match self.ret.mode {
|
match self.ret.mode {
|
||||||
PassMode::Ignore => cx.type_void(),
|
PassMode::Ignore => cx.type_void(),
|
||||||
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx),
|
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx),
|
||||||
PassMode::Cast(cast) => cast.gcc_type(cx),
|
PassMode::Cast(ref cast) => cast.gcc_type(cx),
|
||||||
PassMode::Indirect { .. } => {
|
PassMode::Indirect { .. } => {
|
||||||
argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
|
argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
|
||||||
cx.type_void()
|
cx.type_void()
|
||||||
|
@ -157,7 +157,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
PassMode::Indirect { extra_attrs: Some(_), .. } => {
|
PassMode::Indirect { extra_attrs: Some(_), .. } => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast) => cast.gcc_type(cx),
|
PassMode::Cast(ref cast) => cast.gcc_type(cx),
|
||||||
PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => {
|
PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => {
|
||||||
on_stack_param_indices.insert(argument_tys.len());
|
on_stack_param_indices.insert(argument_tys.len());
|
||||||
arg.memory_ty(cx)
|
arg.memory_ty(cx)
|
||||||
|
|
|
@ -130,7 +130,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
let mut ptr = args[0].immediate();
|
let mut ptr = args[0].immediate();
|
||||||
if let PassMode::Cast(ty) = fn_abi.ret.mode {
|
if let PassMode::Cast(ty) = &fn_abi.ret.mode {
|
||||||
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
||||||
}
|
}
|
||||||
let load = self.volatile_load(ptr.get_type(), ptr);
|
let load = self.volatile_load(ptr.get_type(), ptr);
|
||||||
|
@ -320,7 +320,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !fn_abi.ret.is_ignore() {
|
if !fn_abi.ret.is_ignore() {
|
||||||
if let PassMode::Cast(ty) = fn_abi.ret.mode {
|
if let PassMode::Cast(ty) = &fn_abi.ret.mode {
|
||||||
let ptr_llty = self.type_ptr_to(ty.gcc_type(self));
|
let ptr_llty = self.type_ptr_to(ty.gcc_type(self));
|
||||||
let ptr = self.pointercast(result.llval, ptr_llty);
|
let ptr = self.pointercast(result.llval, ptr_llty);
|
||||||
self.store(llval, ptr, result.align);
|
self.store(llval, ptr, result.align);
|
||||||
|
@ -416,7 +416,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
else if self.is_unsized_indirect() {
|
else if self.is_unsized_indirect() {
|
||||||
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
|
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
|
||||||
}
|
}
|
||||||
else if let PassMode::Cast(cast) = self.mode {
|
else if let PassMode::Cast(ref cast) = self.mode {
|
||||||
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
|
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
|
||||||
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
|
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
|
||||||
let can_store_through_cast_ptr = false;
|
let can_store_through_cast_ptr = false;
|
||||||
|
|
|
@ -213,7 +213,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst)
|
OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst)
|
||||||
} else if self.is_unsized_indirect() {
|
} else if self.is_unsized_indirect() {
|
||||||
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
|
bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
|
||||||
} else if let PassMode::Cast(cast) = self.mode {
|
} else if let PassMode::Cast(cast) = &self.mode {
|
||||||
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
|
// FIXME(eddyb): Figure out when the simpler Store is safe, clang
|
||||||
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
|
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
|
||||||
let can_store_through_cast_ptr = false;
|
let can_store_through_cast_ptr = false;
|
||||||
|
@ -335,7 +335,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } + args_capacity,
|
if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } + args_capacity,
|
||||||
);
|
);
|
||||||
|
|
||||||
let llreturn_ty = match self.ret.mode {
|
let llreturn_ty = match &self.ret.mode {
|
||||||
PassMode::Ignore => cx.type_void(),
|
PassMode::Ignore => cx.type_void(),
|
||||||
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx),
|
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx),
|
||||||
PassMode::Cast(cast) => cast.llvm_type(cx),
|
PassMode::Cast(cast) => cast.llvm_type(cx),
|
||||||
|
@ -351,7 +351,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
llargument_tys.push(ty.llvm_type(cx));
|
llargument_tys.push(ty.llvm_type(cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
let llarg_ty = match arg.mode {
|
let llarg_ty = match &arg.mode {
|
||||||
PassMode::Ignore => continue,
|
PassMode::Ignore => continue,
|
||||||
PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx),
|
PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx),
|
||||||
PassMode::Pair(..) => {
|
PassMode::Pair(..) => {
|
||||||
|
@ -426,11 +426,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
i += 1;
|
i += 1;
|
||||||
i - 1
|
i - 1
|
||||||
};
|
};
|
||||||
match self.ret.mode {
|
match &self.ret.mode {
|
||||||
PassMode::Direct(ref attrs) => {
|
PassMode::Direct(attrs) => {
|
||||||
attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
|
attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
|
||||||
}
|
}
|
||||||
PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
|
PassMode::Indirect { attrs, extra_attrs: _, on_stack } => {
|
||||||
assert!(!on_stack);
|
assert!(!on_stack);
|
||||||
let i = apply(attrs);
|
let i = apply(attrs);
|
||||||
let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx));
|
let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx));
|
||||||
|
@ -445,23 +445,23 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
if arg.pad.is_some() {
|
if arg.pad.is_some() {
|
||||||
apply(&ArgAttributes::new());
|
apply(&ArgAttributes::new());
|
||||||
}
|
}
|
||||||
match arg.mode {
|
match &arg.mode {
|
||||||
PassMode::Ignore => {}
|
PassMode::Ignore => {}
|
||||||
PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => {
|
PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
|
||||||
let i = apply(attrs);
|
let i = apply(attrs);
|
||||||
let byval = llvm::CreateByValAttr(cx.llcx, arg.layout.llvm_type(cx));
|
let byval = llvm::CreateByValAttr(cx.llcx, arg.layout.llvm_type(cx));
|
||||||
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]);
|
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]);
|
||||||
}
|
}
|
||||||
PassMode::Direct(ref attrs)
|
PassMode::Direct(attrs)
|
||||||
| PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => {
|
| PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
|
||||||
apply(attrs);
|
apply(attrs);
|
||||||
}
|
}
|
||||||
PassMode::Indirect { ref attrs, extra_attrs: Some(ref extra_attrs), on_stack } => {
|
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
|
||||||
assert!(!on_stack);
|
assert!(!on_stack);
|
||||||
apply(attrs);
|
apply(attrs);
|
||||||
apply(extra_attrs);
|
apply(extra_attrs);
|
||||||
}
|
}
|
||||||
PassMode::Pair(ref a, ref b) => {
|
PassMode::Pair(a, b) => {
|
||||||
apply(a);
|
apply(a);
|
||||||
apply(b);
|
apply(b);
|
||||||
}
|
}
|
||||||
|
@ -488,11 +488,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
i += 1;
|
i += 1;
|
||||||
i - 1
|
i - 1
|
||||||
};
|
};
|
||||||
match self.ret.mode {
|
match &self.ret.mode {
|
||||||
PassMode::Direct(ref attrs) => {
|
PassMode::Direct(attrs) => {
|
||||||
attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, bx.cx, callsite);
|
attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, bx.cx, callsite);
|
||||||
}
|
}
|
||||||
PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
|
PassMode::Indirect { attrs, extra_attrs: _, on_stack } => {
|
||||||
assert!(!on_stack);
|
assert!(!on_stack);
|
||||||
let i = apply(bx.cx, attrs);
|
let i = apply(bx.cx, attrs);
|
||||||
let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx));
|
let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx));
|
||||||
|
@ -521,9 +521,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
if arg.pad.is_some() {
|
if arg.pad.is_some() {
|
||||||
apply(bx.cx, &ArgAttributes::new());
|
apply(bx.cx, &ArgAttributes::new());
|
||||||
}
|
}
|
||||||
match arg.mode {
|
match &arg.mode {
|
||||||
PassMode::Ignore => {}
|
PassMode::Ignore => {}
|
||||||
PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => {
|
PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
|
||||||
let i = apply(bx.cx, attrs);
|
let i = apply(bx.cx, attrs);
|
||||||
let byval = llvm::CreateByValAttr(bx.cx.llcx, arg.layout.llvm_type(bx));
|
let byval = llvm::CreateByValAttr(bx.cx.llcx, arg.layout.llvm_type(bx));
|
||||||
attributes::apply_to_callsite(
|
attributes::apply_to_callsite(
|
||||||
|
@ -532,19 +532,15 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
&[byval],
|
&[byval],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
PassMode::Direct(ref attrs)
|
PassMode::Direct(attrs)
|
||||||
| PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => {
|
| PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
|
||||||
apply(bx.cx, attrs);
|
apply(bx.cx, attrs);
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack: _ } => {
|
||||||
ref attrs,
|
|
||||||
extra_attrs: Some(ref extra_attrs),
|
|
||||||
on_stack: _,
|
|
||||||
} => {
|
|
||||||
apply(bx.cx, attrs);
|
apply(bx.cx, attrs);
|
||||||
apply(bx.cx, extra_attrs);
|
apply(bx.cx, extra_attrs);
|
||||||
}
|
}
|
||||||
PassMode::Pair(ref a, ref b) => {
|
PassMode::Pair(a, b) => {
|
||||||
apply(bx.cx, a);
|
apply(bx.cx, a);
|
||||||
apply(bx.cx, b);
|
apply(bx.cx, b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
let ptr = args[0].immediate();
|
let ptr = args[0].immediate();
|
||||||
let load = if let PassMode::Cast(ty) = fn_abi.ret.mode {
|
let load = if let PassMode::Cast(ty) = &fn_abi.ret.mode {
|
||||||
let llty = ty.llvm_type(self);
|
let llty = ty.llvm_type(self);
|
||||||
let ptr = self.pointercast(ptr, self.type_ptr_to(llty));
|
let ptr = self.pointercast(ptr, self.type_ptr_to(llty));
|
||||||
self.volatile_load(llty, ptr)
|
self.volatile_load(llty, ptr)
|
||||||
|
@ -374,7 +374,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !fn_abi.ret.is_ignore() {
|
if !fn_abi.ret.is_ignore() {
|
||||||
if let PassMode::Cast(ty) = fn_abi.ret.mode {
|
if let PassMode::Cast(ty) = &fn_abi.ret.mode {
|
||||||
let ptr_llty = self.type_ptr_to(ty.llvm_type(self));
|
let ptr_llty = self.type_ptr_to(ty.llvm_type(self));
|
||||||
let ptr = self.pointercast(result.llval, ptr_llty);
|
let ptr = self.pointercast(result.llval, ptr_llty);
|
||||||
self.store(llval, ptr, result.align);
|
self.store(llval, ptr, result.align);
|
||||||
|
|
|
@ -324,7 +324,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bx.unreachable();
|
bx.unreachable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let llval = match self.fn_abi.ret.mode {
|
let llval = match &self.fn_abi.ret.mode {
|
||||||
PassMode::Ignore | PassMode::Indirect { .. } => {
|
PassMode::Ignore | PassMode::Indirect { .. } => {
|
||||||
bx.ret_void();
|
bx.ret_void();
|
||||||
return;
|
return;
|
||||||
|
@ -360,7 +360,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
llval
|
llval
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ty = bx.cast_backend_type(&cast_ty);
|
let ty = bx.cast_backend_type(cast_ty);
|
||||||
let addr = bx.pointercast(llslot, bx.type_ptr_to(ty));
|
let addr = bx.pointercast(llslot, bx.type_ptr_to(ty));
|
||||||
bx.load(ty, addr, self.fn_abi.ret.layout.align.abi)
|
bx.load(ty, addr, self.fn_abi.ret.layout.align.abi)
|
||||||
}
|
}
|
||||||
|
@ -1222,8 +1222,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
|
|
||||||
if by_ref && !arg.is_indirect() {
|
if by_ref && !arg.is_indirect() {
|
||||||
// Have to load the argument, maybe while casting it.
|
// Have to load the argument, maybe while casting it.
|
||||||
if let PassMode::Cast(ty) = arg.mode {
|
if let PassMode::Cast(ty) = &arg.mode {
|
||||||
let llty = bx.cast_backend_type(&ty);
|
let llty = bx.cast_backend_type(ty);
|
||||||
let addr = bx.pointercast(llval, bx.type_ptr_to(llty));
|
let addr = bx.pointercast(llval, bx.type_ptr_to(llty));
|
||||||
llval = bx.load(llty, addr, align.min(arg.layout.align.abi));
|
llval = bx.load(llty, addr, align.min(arg.layout.align.abi));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -597,8 +597,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !fn_abi.ret.is_ignore() {
|
if !fn_abi.ret.is_ignore() {
|
||||||
if let PassMode::Cast(ty) = fn_abi.ret.mode {
|
if let PassMode::Cast(ty) = &fn_abi.ret.mode {
|
||||||
let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(&ty));
|
let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(ty));
|
||||||
let ptr = bx.pointercast(result.llval, ptr_llty);
|
let ptr = bx.pointercast(result.llval, ptr_llty);
|
||||||
bx.store(llval, ptr, result.align);
|
bx.store(llval, ptr, result.align);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Padding must be fully equal.
|
// Padding must be fully equal.
|
||||||
let pad_compat = || caller_abi.pad == callee_abi.pad;
|
let pad_compat = || caller_abi.pad == callee_abi.pad;
|
||||||
// When comparing the PassMode, we have to be smart about comparing the attributes.
|
// When comparing the PassMode, we have to be smart about comparing the attributes.
|
||||||
let arg_attr_compat = |a1: ArgAttributes, a2: ArgAttributes| {
|
let arg_attr_compat = |a1: &ArgAttributes, a2: &ArgAttributes| {
|
||||||
// There's only one regular attribute that matters for the call ABI: InReg.
|
// There's only one regular attribute that matters for the call ABI: InReg.
|
||||||
// Everything else is things like noalias, dereferencable, nonnull, ...
|
// Everything else is things like noalias, dereferencable, nonnull, ...
|
||||||
// (This also applies to pointee_size, pointee_align.)
|
// (This also applies to pointee_size, pointee_align.)
|
||||||
|
@ -233,7 +233,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let mode_compat = || match (caller_abi.mode, callee_abi.mode) {
|
let mode_compat = || match (&caller_abi.mode, &callee_abi.mode) {
|
||||||
(PassMode::Ignore, PassMode::Ignore) => true,
|
(PassMode::Ignore, PassMode::Ignore) => true,
|
||||||
(PassMode::Direct(a1), PassMode::Direct(a2)) => arg_attr_compat(a1, a2),
|
(PassMode::Direct(a1), PassMode::Direct(a2)) => arg_attr_compat(a1, a2),
|
||||||
(PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => {
|
(PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => {
|
||||||
|
|
|
@ -26,7 +26,7 @@ mod x86;
|
||||||
mod x86_64;
|
mod x86_64;
|
||||||
mod x86_win64;
|
mod x86_win64;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
|
#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
|
||||||
pub enum PassMode {
|
pub enum PassMode {
|
||||||
/// Ignore the argument.
|
/// Ignore the argument.
|
||||||
///
|
///
|
||||||
|
@ -42,7 +42,7 @@ pub enum PassMode {
|
||||||
Pair(ArgAttributes, ArgAttributes),
|
Pair(ArgAttributes, ArgAttributes),
|
||||||
/// Pass the argument after casting it, to either
|
/// Pass the argument after casting it, to either
|
||||||
/// a single uniform or a pair of registers.
|
/// a single uniform or a pair of registers.
|
||||||
Cast(CastTarget),
|
Cast(Box<CastTarget>),
|
||||||
/// Pass the argument indirectly via a hidden pointer.
|
/// Pass the argument indirectly via a hidden pointer.
|
||||||
/// The `extra_attrs` value, if any, is for the extra data (vtable or length)
|
/// The `extra_attrs` value, if any, is for the extra data (vtable or length)
|
||||||
/// which indicates that it refers to an unsized rvalue.
|
/// which indicates that it refers to an unsized rvalue.
|
||||||
|
@ -548,7 +548,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
|
pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
|
||||||
self.mode = PassMode::Cast(target.into());
|
self.mode = PassMode::Cast(Box::new(target.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pad_with(&mut self, reg: Reg) {
|
pub fn pad_with(&mut self, reg: Reg) {
|
||||||
|
@ -737,6 +737,6 @@ mod size_asserts {
|
||||||
use super::*;
|
use super::*;
|
||||||
use rustc_data_structures::static_assert_size;
|
use rustc_data_structures::static_assert_size;
|
||||||
// These are in alphabetical order, which is easy to maintain.
|
// These are in alphabetical order, which is easy to maintain.
|
||||||
static_assert_size!(ArgAbi<'_, usize>, 208);
|
static_assert_size!(ArgAbi<'_, usize>, 72);
|
||||||
static_assert_size!(FnAbi<'_, usize>, 248);
|
static_assert_size!(FnAbi<'_, usize>, 112);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue