Skip to content

Commit 45071dc

Browse files
committed
Remove dependency on enable_multi_ret_implicit_sret
1 parent 0974099 commit 45071dc

File tree

4 files changed

+95
-39
lines changed

4 files changed

+95
-39
lines changed

src/abi/mod.rs

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_session::Session;
2121
use rustc_span::source_map::Spanned;
2222
use rustc_target::callconv::{Conv, FnAbi, PassMode};
2323

24+
pub(crate) use self::pass_mode::adjust_fn_abi_for_rust_abi_mistakes;
2425
use self::pass_mode::*;
2526
pub(crate) use self::returning::codegen_return;
2627
use crate::prelude::*;
@@ -80,7 +81,10 @@ pub(crate) fn get_function_sig<'tcx>(
8081
clif_sig_from_fn_abi(
8182
tcx,
8283
default_call_conv,
83-
&FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
84+
&adjust_fn_abi_for_rust_abi_mistakes(
85+
tcx,
86+
FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
87+
),
8488
)
8589
}
8690

@@ -126,7 +130,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
126130
args: &[Value],
127131
) -> Cow<'_, [Value]> {
128132
if self.tcx.sess.target.is_like_windows {
129-
let (mut params, mut args): (Vec<_>, Vec<_>) = params
133+
let (params, args): (Vec<_>, Vec<_>) = params
130134
.into_iter()
131135
.zip(args)
132136
.map(|(param, &arg)| {
@@ -140,29 +144,45 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
140144
})
141145
.unzip();
142146

143-
let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
147+
self.lib_call_unadjusted(name, params, returns, &args)
148+
} else {
149+
self.lib_call_unadjusted(name, params, returns, args)
150+
}
151+
}
144152

145-
if indirect_ret_val {
146-
params.insert(0, AbiParam::new(self.pointer_type));
147-
let ret_ptr = self.create_stack_slot(16, 16);
148-
args.insert(0, ret_ptr.get_addr(self));
149-
self.lib_call_unadjusted(name, params, vec![], &args);
150-
return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);
153+
pub(crate) fn lib_call_unadjusted(
154+
&mut self,
155+
name: &str,
156+
mut params: Vec<AbiParam>,
157+
returns: Vec<AbiParam>,
158+
args: &[Value],
159+
) -> Cow<'_, [Value]> {
160+
let adjust_ret_param =
161+
if self.tcx.sess.target.is_like_windows || self.tcx.sess.target.arch == "s390x" {
162+
returns.len() == 1 && returns[0].value_type == types::I128
151163
} else {
152-
return self.lib_call_unadjusted(name, params, returns, &args);
153-
}
164+
false
165+
};
166+
167+
if adjust_ret_param {
168+
params.insert(0, AbiParam::new(self.pointer_type));
169+
let ret_ptr = self.create_stack_slot(16, 16);
170+
let mut args = args.to_vec();
171+
args.insert(0, ret_ptr.get_addr(self));
172+
self.lib_call_inner(name, params, vec![], &args);
173+
Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())])
174+
} else {
175+
Cow::Borrowed(self.lib_call_inner(name, params, returns, &args))
154176
}
155-
156-
self.lib_call_unadjusted(name, params, returns, args)
157177
}
158178

159-
pub(crate) fn lib_call_unadjusted(
179+
fn lib_call_inner(
160180
&mut self,
161181
name: &str,
162182
params: Vec<AbiParam>,
163183
returns: Vec<AbiParam>,
164184
args: &[Value],
165-
) -> Cow<'_, [Value]> {
185+
) -> &[Value] {
166186
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
167187
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
168188
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
@@ -175,7 +195,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
175195
}
176196
let results = self.bcx.inst_results(call_inst);
177197
assert!(results.len() <= 2, "{}", results.len());
178-
Cow::Borrowed(results)
198+
results
179199
}
180200
}
181201

@@ -437,11 +457,14 @@ pub(crate) fn codegen_terminator_call<'tcx>(
437457
let extra_args = fx.tcx.mk_type_list_from_iter(
438458
extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.node.ty(fx.mir, fx.tcx))),
439459
);
440-
let fn_abi = if let Some(instance) = instance {
441-
FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
442-
} else {
443-
FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
444-
};
460+
let fn_abi = adjust_fn_abi_for_rust_abi_mistakes(
461+
fx.tcx,
462+
if let Some(instance) = instance {
463+
FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
464+
} else {
465+
FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
466+
},
467+
);
445468

446469
let is_cold = if fn_sig.abi() == ExternAbi::RustCold {
447470
true
@@ -721,8 +744,11 @@ pub(crate) fn codegen_drop<'tcx>(
721744
def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
722745
args: drop_instance.args,
723746
};
724-
let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
725-
.fn_abi_of_instance(virtual_drop, ty::List::empty());
747+
let fn_abi = adjust_fn_abi_for_rust_abi_mistakes(
748+
fx.tcx,
749+
FullyMonomorphizedLayoutCx(fx.tcx)
750+
.fn_abi_of_instance(virtual_drop, ty::List::empty()),
751+
);
726752

727753
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
728754
let sig = fx.bcx.import_signature(sig);
@@ -764,8 +790,11 @@ pub(crate) fn codegen_drop<'tcx>(
764790
def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
765791
args: drop_instance.args,
766792
};
767-
let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
768-
.fn_abi_of_instance(virtual_drop, ty::List::empty());
793+
let fn_abi = adjust_fn_abi_for_rust_abi_mistakes(
794+
fx.tcx,
795+
FullyMonomorphizedLayoutCx(fx.tcx)
796+
.fn_abi_of_instance(virtual_drop, ty::List::empty()),
797+
);
769798

770799
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
771800
let sig = fx.bcx.import_signature(sig);
@@ -774,8 +803,11 @@ pub(crate) fn codegen_drop<'tcx>(
774803
_ => {
775804
assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _)));
776805

777-
let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
778-
.fn_abi_of_instance(drop_instance, ty::List::empty());
806+
let fn_abi = adjust_fn_abi_for_rust_abi_mistakes(
807+
fx.tcx,
808+
FullyMonomorphizedLayoutCx(fx.tcx)
809+
.fn_abi_of_instance(drop_instance, ty::List::empty()),
810+
);
779811

780812
let arg_value = drop_place.place_ref(
781813
fx,

src/abi/pass_mode.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use cranelift_codegen::ir::{ArgumentExtension, ArgumentPurpose};
44
use rustc_abi::{Reg, RegKind};
55
use rustc_target::callconv::{
6-
ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, PassMode,
6+
ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, Conv, FnAbi, PassMode,
77
};
88
use smallvec::{SmallVec, smallvec};
99

@@ -302,3 +302,33 @@ pub(super) fn cvalue_for_param<'tcx>(
302302
}
303303
}
304304
}
305+
306+
pub(crate) fn adjust_fn_abi_for_rust_abi_mistakes<'tcx>(
307+
tcx: TyCtxt<'tcx>,
308+
fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
309+
) -> &'tcx FnAbi<'tcx, Ty<'tcx>> {
310+
if fn_abi.conv != Conv::Rust {
311+
// Non-Rust ABI's should be correctly implemented.
312+
return fn_abi;
313+
}
314+
315+
if !tcx.sess.target.is_like_windows && tcx.sess.target.arch != "s390x" {
316+
// Out of the targets cg_clif supports, only Windows and s390x don't have two return
317+
// registers.
318+
return fn_abi;
319+
}
320+
321+
match fn_abi.ret.mode {
322+
PassMode::Ignore | PassMode::Cast { .. } | PassMode::Indirect { .. } => return fn_abi,
323+
PassMode::Direct(_) => {
324+
if fn_abi.ret.layout.size <= tcx.data_layout.pointer_size {
325+
return fn_abi;
326+
}
327+
}
328+
PassMode::Pair(..) => {}
329+
}
330+
331+
let mut fn_abi = fn_abi.clone();
332+
fn_abi.ret.make_indirect();
333+
tcx.arena.alloc(fn_abi)
334+
}

src/base.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ pub(crate) fn codegen_fn<'tcx>(
105105
let block_map: IndexVec<BasicBlock, Block> =
106106
(0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect();
107107

108-
let fn_abi = FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty());
108+
let fn_abi = adjust_fn_abi_for_rust_abi_mistakes(
109+
tcx,
110+
FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()),
111+
);
109112

110113
// Make FunctionCx
111114
let target_config = module.target_config();
@@ -186,6 +189,7 @@ pub(crate) fn compile_fn(
186189
context.clear();
187190
context.func = codegened_func.func;
188191

192+
// FIXME run this code when define_function returns an error
189193
#[cfg(any())] // This is never true
190194
let _clif_guard = {
191195
use std::fmt::Write;

src/lib.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,6 @@ fn build_isa(sess: &Session) -> Arc<dyn TargetIsa + 'static> {
294294
}
295295
}
296296

297-
if let target_lexicon::OperatingSystem::Windows = target_triple.operating_system {
298-
// FIXME remove dependency on this from the Rust ABI. cc bytecodealliance/wasmtime#9510
299-
flags_builder.enable("enable_multi_ret_implicit_sret").unwrap();
300-
}
301-
302-
if let target_lexicon::Architecture::S390x = target_triple.architecture {
303-
// FIXME remove dependency on this from the Rust ABI. cc bytecodealliance/wasmtime#9510
304-
flags_builder.enable("enable_multi_ret_implicit_sret").unwrap();
305-
}
306-
307297
if let target_lexicon::Architecture::Aarch64(_)
308298
| target_lexicon::Architecture::Riscv64(_)
309299
| target_lexicon::Architecture::X86_64 = target_triple.architecture

0 commit comments

Comments
 (0)