summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_cranelift/src/abi/mod.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_codegen_cranelift/src/abi/mod.rs
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/abi/mod.rs')
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs102
1 files changed, 58 insertions, 44 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 74396a66f..91c085d3d 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -4,6 +4,8 @@ mod comments;
mod pass_mode;
mod returning;
+use std::borrow::Cow;
+
use cranelift_module::ModuleError;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::FnAbiOf;
@@ -25,7 +27,7 @@ fn clif_sig_from_fn_abi<'tcx>(
) -> Signature {
let call_conv = conv_to_call_conv(tcx.sess, fn_abi.conv, default_call_conv);
- let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
+ let inputs = fn_abi.args.iter().flat_map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter());
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.
@@ -116,7 +118,52 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
params: Vec<AbiParam>,
returns: Vec<AbiParam>,
args: &[Value],
- ) -> &[Value] {
+ ) -> Cow<'_, [Value]> {
+ if self.tcx.sess.target.is_like_windows {
+ let (mut params, mut args): (Vec<_>, Vec<_>) =
+ params
+ .into_iter()
+ .zip(args)
+ .map(|(param, &arg)| {
+ if param.value_type == types::I128 {
+ let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot(
+ StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 },
+ ));
+ arg_ptr.store(self, arg, MemFlags::trusted());
+ (AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
+ } else {
+ (param, arg)
+ }
+ })
+ .unzip();
+
+ let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
+
+ if indirect_ret_val {
+ params.insert(0, AbiParam::new(self.pointer_type));
+ let ret_ptr =
+ Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData {
+ kind: StackSlotKind::ExplicitSlot,
+ size: 16,
+ }));
+ args.insert(0, ret_ptr.get_addr(self));
+ self.lib_call_unadjusted(name, params, vec![], &args);
+ return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);
+ } else {
+ return self.lib_call_unadjusted(name, params, returns, &args);
+ }
+ }
+
+ self.lib_call_unadjusted(name, params, returns, args)
+ }
+
+ pub(crate) fn lib_call_unadjusted(
+ &mut self,
+ name: &str,
+ params: Vec<AbiParam>,
+ returns: Vec<AbiParam>,
+ args: &[Value],
+ ) -> Cow<'_, [Value]> {
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
@@ -125,41 +172,11 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
}
let call_inst = self.bcx.ins().call(func_ref, args);
if self.clif_comments.enabled() {
- self.add_comment(call_inst, format!("easy_call {}", name));
+ self.add_comment(call_inst, format!("lib_call {}", name));
}
let results = self.bcx.inst_results(call_inst);
assert!(results.len() <= 2, "{}", results.len());
- results
- }
-
- pub(crate) fn easy_call(
- &mut self,
- name: &str,
- args: &[CValue<'tcx>],
- return_ty: Ty<'tcx>,
- ) -> CValue<'tcx> {
- let (input_tys, args): (Vec<_>, Vec<_>) = args
- .iter()
- .map(|arg| {
- (AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self))
- })
- .unzip();
- let return_layout = self.layout_of(return_ty);
- let return_tys = if let ty::Tuple(tup) = return_ty.kind() {
- tup.iter().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect()
- } else {
- vec![AbiParam::new(self.clif_type(return_ty).unwrap())]
- };
- let ret_vals = self.lib_call(name, input_tys, return_tys, &args);
- match *ret_vals {
- [] => CValue::by_ref(
- Pointer::const_addr(self, i64::from(self.pointer_type.bytes())),
- return_layout,
- ),
- [val] => CValue::by_val(val, return_layout),
- [val, extra] => CValue::by_val_pair(val, extra, return_layout),
- _ => unreachable!(),
- }
+ Cow::Borrowed(results)
}
}
@@ -275,10 +292,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
self::comments::add_locals_header_comment(fx);
for (local, arg_kind, ty) in func_params {
- let layout = fx.layout_of(ty);
-
- let is_ssa = ssa_analyzed[local] == crate::analyze::SsaKind::Ssa;
-
// While this is normally an optimization to prevent an unnecessary copy when an argument is
// not mutated by the current function, this is necessary to support unsized arguments.
if let ArgKind::Normal(Some(val)) = arg_kind {
@@ -300,6 +313,8 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
}
}
+ let layout = fx.layout_of(ty);
+ let is_ssa = ssa_analyzed[local].is_ssa(fx, ty);
let place = make_local_place(fx, local, layout, is_ssa);
assert_eq!(fx.local_map.push(place), local);
@@ -312,7 +327,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
ArgKind::Spread(params) => {
for (i, param) in params.into_iter().enumerate() {
if let Some(param) = param {
- place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param);
+ place.place_field(fx, FieldIdx::new(i)).write_cvalue(fx, param);
}
}
}
@@ -323,7 +338,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
let ty = fx.monomorphize(fx.mir.local_decls[local].ty);
let layout = fx.layout_of(ty);
- let is_ssa = ssa_analyzed[local] == crate::analyze::SsaKind::Ssa;
+ let is_ssa = ssa_analyzed[local].is_ssa(fx, ty);
let place = make_local_place(fx, local, layout, is_ssa);
assert_eq!(fx.local_map.push(place), local);
@@ -445,7 +460,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
args.push(self_arg);
for i in 0..tupled_arguments.len() {
args.push(CallArgument {
- value: pack_arg.value.value_field(fx, mir::Field::new(i)),
+ value: pack_arg.value.value_field(fx, FieldIdx::new(i)),
is_owned: pack_arg.is_owned,
});
}
@@ -515,10 +530,9 @@ pub(crate) fn codegen_terminator_call<'tcx>(
args.into_iter()
.enumerate()
.skip(if first_arg_override.is_some() { 1 } else { 0 })
- .map(|(i, arg)| {
+ .flat_map(|(i, arg)| {
adjust_arg_for_abi(fx, arg.value, &fn_abi.args[i], arg.is_owned).into_iter()
- })
- .flatten(),
+ }),
)
.collect::<Vec<Value>>();