Replace EmptySinglePair with SmallVec
This commit is contained in:
parent
fc595f1a55
commit
d263447878
6 changed files with 66 additions and 100 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -333,6 +333,7 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"libloading",
|
"libloading",
|
||||||
"object",
|
"object",
|
||||||
|
"smallvec",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ object = { version = "0.22.0", default-features = false, features = ["std", "rea
|
||||||
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
libloading = { version = "0.6.0", optional = true }
|
libloading = { version = "0.6.0", optional = true }
|
||||||
|
smallvec = "1.6.1"
|
||||||
|
|
||||||
# Uncomment to use local checkout of cranelift
|
# Uncomment to use local checkout of cranelift
|
||||||
#[patch."https://github.com/bytecodealliance/wasmtime/"]
|
#[patch."https://github.com/bytecodealliance/wasmtime/"]
|
||||||
|
|
|
@ -8,7 +8,6 @@ use rustc_target::abi::call::PassMode;
|
||||||
|
|
||||||
use cranelift_codegen::entity::EntityRef;
|
use cranelift_codegen::entity::EntityRef;
|
||||||
|
|
||||||
use crate::abi::pass_mode::*;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) {
|
pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) {
|
||||||
|
@ -22,7 +21,7 @@ pub(super) fn add_arg_comment<'tcx>(
|
||||||
kind: &str,
|
kind: &str,
|
||||||
local: Option<mir::Local>,
|
local: Option<mir::Local>,
|
||||||
local_field: Option<usize>,
|
local_field: Option<usize>,
|
||||||
params: EmptySinglePair<Value>,
|
params: &[Value],
|
||||||
arg_abi_mode: PassMode,
|
arg_abi_mode: PassMode,
|
||||||
arg_layout: TyAndLayout<'tcx>,
|
arg_layout: TyAndLayout<'tcx>,
|
||||||
) {
|
) {
|
||||||
|
@ -38,9 +37,17 @@ pub(super) fn add_arg_comment<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let params = match params {
|
let params = match params {
|
||||||
Empty => Cow::Borrowed("-"),
|
[] => Cow::Borrowed("-"),
|
||||||
Single(param) => Cow::Owned(format!("= {:?}", param)),
|
[param] => Cow::Owned(format!("= {:?}", param)),
|
||||||
Pair(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
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",")
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let pass_mode = format!("{:?}", arg_abi_mode);
|
let pass_mode = format!("{:?}", arg_abi_mode);
|
||||||
|
|
|
@ -11,6 +11,7 @@ use rustc_target::abi::call::{Conv, FnAbi};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use cranelift_codegen::ir::AbiParam;
|
use cranelift_codegen::ir::AbiParam;
|
||||||
|
use smallvec::smallvec;
|
||||||
|
|
||||||
use self::pass_mode::*;
|
use self::pass_mode::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -534,7 +535,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0], idx);
|
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0], idx);
|
||||||
(Some(method), Single(ptr))
|
(Some(method), smallvec![ptr])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal call
|
// Normal call
|
||||||
|
@ -542,7 +543,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
None,
|
None,
|
||||||
args.get(0)
|
args.get(0)
|
||||||
.map(|arg| adjust_arg_for_abi(fx, *arg, &fn_abi.args[0]))
|
.map(|arg| adjust_arg_for_abi(fx, *arg, &fn_abi.args[0]))
|
||||||
.unwrap_or(Empty),
|
.unwrap_or(smallvec![]),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Indirect call
|
// Indirect call
|
||||||
|
@ -557,7 +558,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
Some(func),
|
Some(func),
|
||||||
args.get(0)
|
args.get(0)
|
||||||
.map(|arg| adjust_arg_for_abi(fx, *arg, &fn_abi.args[0]))
|
.map(|arg| adjust_arg_for_abi(fx, *arg, &fn_abi.args[0]))
|
||||||
.unwrap_or(Empty),
|
.unwrap_or(smallvec![]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,78 +5,24 @@ use crate::value_and_place::assert_assignable;
|
||||||
|
|
||||||
use cranelift_codegen::ir::ArgumentPurpose;
|
use cranelift_codegen::ir::ArgumentPurpose;
|
||||||
use rustc_target::abi::call::{ArgAbi, PassMode};
|
use rustc_target::abi::call::{ArgAbi, PassMode};
|
||||||
pub(super) use EmptySinglePair::*;
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub(super) enum EmptySinglePair<T> {
|
|
||||||
Empty,
|
|
||||||
Single(T),
|
|
||||||
Pair(T, T),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> EmptySinglePair<T> {
|
|
||||||
pub(super) fn into_iter(self) -> EmptySinglePairIter<T> {
|
|
||||||
EmptySinglePairIter(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn map<U>(self, mut f: impl FnMut(T) -> U) -> EmptySinglePair<U> {
|
|
||||||
match self {
|
|
||||||
Empty => Empty,
|
|
||||||
Single(v) => Single(f(v)),
|
|
||||||
Pair(a, b) => Pair(f(a), f(b)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) struct EmptySinglePairIter<T>(EmptySinglePair<T>);
|
|
||||||
|
|
||||||
impl<T> Iterator for EmptySinglePairIter<T> {
|
|
||||||
type Item = T;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<T> {
|
|
||||||
match std::mem::replace(&mut self.0, Empty) {
|
|
||||||
Empty => None,
|
|
||||||
Single(v) => Some(v),
|
|
||||||
Pair(a, b) => {
|
|
||||||
self.0 = Single(b);
|
|
||||||
Some(a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: std::fmt::Debug> EmptySinglePair<T> {
|
|
||||||
pub(super) fn assert_single(self) -> T {
|
|
||||||
match self {
|
|
||||||
Single(v) => v,
|
|
||||||
_ => panic!("Called assert_single on {:?}", self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn assert_pair(self) -> (T, T) {
|
|
||||||
match self {
|
|
||||||
Pair(a, b) => (a, b),
|
|
||||||
_ => panic!("Called assert_pair on {:?}", self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) trait ArgAbiExt<'tcx> {
|
pub(super) trait ArgAbiExt<'tcx> {
|
||||||
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> EmptySinglePair<AbiParam>;
|
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]>;
|
||||||
fn get_abi_return(&self, tcx: TyCtxt<'tcx>) -> (Option<AbiParam>, Vec<AbiParam>);
|
fn get_abi_return(&self, tcx: TyCtxt<'tcx>) -> (Option<AbiParam>, Vec<AbiParam>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> EmptySinglePair<AbiParam> {
|
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]> {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
PassMode::Ignore => EmptySinglePair::Empty,
|
PassMode::Ignore => smallvec![],
|
||||||
PassMode::Direct(_) => match &self.layout.abi {
|
PassMode::Direct(_) => match &self.layout.abi {
|
||||||
Abi::Scalar(scalar) => {
|
Abi::Scalar(scalar) => {
|
||||||
EmptySinglePair::Single(AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())))
|
smallvec![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();
|
||||||
EmptySinglePair::Single(AbiParam::new(vector_ty))
|
smallvec![AbiParam::new(vector_ty)]
|
||||||
}
|
}
|
||||||
_ => unreachable!("{:?}", self.layout.abi),
|
_ => unreachable!("{:?}", self.layout.abi),
|
||||||
},
|
},
|
||||||
|
@ -84,11 +30,11 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
Abi::ScalarPair(a, b) => {
|
Abi::ScalarPair(a, b) => {
|
||||||
let a = scalar_to_clif_type(tcx, a.clone());
|
let a = scalar_to_clif_type(tcx, a.clone());
|
||||||
let b = scalar_to_clif_type(tcx, b.clone());
|
let b = scalar_to_clif_type(tcx, b.clone());
|
||||||
EmptySinglePair::Pair(AbiParam::new(a), AbiParam::new(b))
|
smallvec![AbiParam::new(a), AbiParam::new(b)]
|
||||||
}
|
}
|
||||||
_ => unreachable!("{:?}", self.layout.abi),
|
_ => unreachable!("{:?}", self.layout.abi),
|
||||||
},
|
},
|
||||||
PassMode::Cast(_) => EmptySinglePair::Single(AbiParam::new(pointer_ty(tcx))),
|
PassMode::Cast(_) => smallvec![AbiParam::new(pointer_ty(tcx))],
|
||||||
PassMode::Indirect {
|
PassMode::Indirect {
|
||||||
attrs: _,
|
attrs: _,
|
||||||
extra_attrs: None,
|
extra_attrs: None,
|
||||||
|
@ -96,12 +42,12 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
} => {
|
} => {
|
||||||
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();
|
||||||
EmptySinglePair::Single(AbiParam::special(
|
smallvec![AbiParam::special(
|
||||||
pointer_ty(tcx),
|
pointer_ty(tcx),
|
||||||
ArgumentPurpose::StructArgument(size),
|
ArgumentPurpose::StructArgument(size),
|
||||||
))
|
)]
|
||||||
} else {
|
} else {
|
||||||
EmptySinglePair::Single(AbiParam::new(pointer_ty(tcx)))
|
smallvec![AbiParam::new(pointer_ty(tcx))]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect {
|
||||||
|
@ -110,10 +56,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
||||||
on_stack,
|
on_stack,
|
||||||
} => {
|
} => {
|
||||||
assert!(!on_stack);
|
assert!(!on_stack);
|
||||||
EmptySinglePair::Pair(
|
smallvec![
|
||||||
AbiParam::new(pointer_ty(tcx)),
|
AbiParam::new(pointer_ty(tcx)),
|
||||||
AbiParam::new(pointer_ty(tcx)),
|
AbiParam::new(pointer_ty(tcx)),
|
||||||
)
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,18 +122,18 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
|
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
|
||||||
arg: CValue<'tcx>,
|
arg: CValue<'tcx>,
|
||||||
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
||||||
) -> EmptySinglePair<Value> {
|
) -> SmallVec<[Value; 2]> {
|
||||||
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
|
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
|
||||||
match arg_abi.mode {
|
match arg_abi.mode {
|
||||||
PassMode::Ignore => Empty,
|
PassMode::Ignore => smallvec![],
|
||||||
PassMode::Direct(_) => Single(arg.load_scalar(fx)),
|
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
|
||||||
PassMode::Pair(_, _) => {
|
PassMode::Pair(_, _) => {
|
||||||
let (a, b) = arg.load_scalar_pair(fx);
|
let (a, b) = arg.load_scalar_pair(fx);
|
||||||
Pair(a, b)
|
smallvec![a, b]
|
||||||
}
|
}
|
||||||
PassMode::Cast(_) | PassMode::Indirect { .. } => match arg.force_stack(fx) {
|
PassMode::Cast(_) | PassMode::Indirect { .. } => match arg.force_stack(fx) {
|
||||||
(ptr, None) => Single(ptr.get_addr(fx)),
|
(ptr, None) => smallvec![ptr.get_addr(fx)],
|
||||||
(ptr, Some(meta)) => Pair(ptr.get_addr(fx), meta),
|
(ptr, Some(meta)) => smallvec![ptr.get_addr(fx), meta],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,8 +148,10 @@ pub(super) fn cvalue_for_param<'tcx>(
|
||||||
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
||||||
) -> Option<CValue<'tcx>> {
|
) -> Option<CValue<'tcx>> {
|
||||||
let clif_types = arg_abi.get_abi_param(fx.tcx);
|
let clif_types = arg_abi.get_abi_param(fx.tcx);
|
||||||
let block_params =
|
let block_params = clif_types
|
||||||
clif_types.map(|abi_param| fx.bcx.append_block_param(start_block, abi_param.value_type));
|
.into_iter()
|
||||||
|
.map(|abi_param| fx.bcx.append_block_param(start_block, abi_param.value_type))
|
||||||
|
.collect::<SmallVec<[_; 2]>>();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
crate::abi::comments::add_arg_comment(
|
crate::abi::comments::add_arg_comment(
|
||||||
|
@ -211,7 +159,7 @@ pub(super) fn cvalue_for_param<'tcx>(
|
||||||
"arg",
|
"arg",
|
||||||
local,
|
local,
|
||||||
local_field,
|
local_field,
|
||||||
block_params,
|
&block_params,
|
||||||
arg_abi.mode,
|
arg_abi.mode,
|
||||||
arg_abi.layout,
|
arg_abi.layout,
|
||||||
);
|
);
|
||||||
|
@ -219,30 +167,38 @@ pub(super) fn cvalue_for_param<'tcx>(
|
||||||
match arg_abi.mode {
|
match arg_abi.mode {
|
||||||
PassMode::Ignore => None,
|
PassMode::Ignore => None,
|
||||||
PassMode::Direct(_) => {
|
PassMode::Direct(_) => {
|
||||||
Some(CValue::by_val(block_params.assert_single(), arg_abi.layout))
|
assert_eq!(block_params.len(), 1, "{:?}", block_params);
|
||||||
|
Some(CValue::by_val(block_params[0], arg_abi.layout))
|
||||||
}
|
}
|
||||||
PassMode::Pair(_, _) => {
|
PassMode::Pair(_, _) => {
|
||||||
let (a, b) = block_params.assert_pair();
|
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
||||||
Some(CValue::by_val_pair(a, b, arg_abi.layout))
|
Some(CValue::by_val_pair(
|
||||||
|
block_params[0],
|
||||||
|
block_params[1],
|
||||||
|
arg_abi.layout,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
PassMode::Cast(_)
|
PassMode::Cast(_)
|
||||||
| PassMode::Indirect {
|
| PassMode::Indirect {
|
||||||
attrs: _,
|
attrs: _,
|
||||||
extra_attrs: None,
|
extra_attrs: None,
|
||||||
on_stack: _,
|
on_stack: _,
|
||||||
} => Some(CValue::by_ref(
|
} => {
|
||||||
Pointer::new(block_params.assert_single()),
|
assert_eq!(block_params.len(), 1, "{:?}", block_params);
|
||||||
arg_abi.layout,
|
Some(CValue::by_ref(
|
||||||
)),
|
Pointer::new(block_params[0]),
|
||||||
|
arg_abi.layout,
|
||||||
|
))
|
||||||
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect {
|
||||||
attrs: _,
|
attrs: _,
|
||||||
extra_attrs: Some(_),
|
extra_attrs: Some(_),
|
||||||
on_stack: _,
|
on_stack: _,
|
||||||
} => {
|
} => {
|
||||||
let (ptr, meta) = block_params.assert_pair();
|
assert_eq!(block_params.len(), 2, "{:?}", block_params);
|
||||||
Some(CValue::by_ref_unsized(
|
Some(CValue::by_ref_unsized(
|
||||||
Pointer::new(ptr),
|
Pointer::new(block_params[0]),
|
||||||
meta,
|
block_params[1],
|
||||||
arg_abi.layout,
|
arg_abi.layout,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//! Return value handling
|
//! Return value handling
|
||||||
|
|
||||||
use crate::abi::pass_mode::*;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use rustc_middle::ty::layout::FnAbiExt;
|
use rustc_middle::ty::layout::FnAbiExt;
|
||||||
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
|
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
|
||||||
|
use smallvec::{SmallVec, smallvec};
|
||||||
|
|
||||||
/// Can the given type be returned into an ssa var or does it need to be returned on the stack.
|
/// Can the given type be returned into an ssa var or does it need to be returned on the stack.
|
||||||
pub(crate) fn can_return_to_ssa_var<'tcx>(
|
pub(crate) fn can_return_to_ssa_var<'tcx>(
|
||||||
|
@ -62,10 +62,10 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||||
ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>,
|
ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>,
|
||||||
start_block: Block,
|
start_block: Block,
|
||||||
) -> CPlace<'tcx> {
|
) -> CPlace<'tcx> {
|
||||||
let (ret_place, ret_param) = 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),
|
CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout),
|
||||||
Empty,
|
smallvec![],
|
||||||
),
|
),
|
||||||
PassMode::Direct(_) | PassMode::Pair(_, _) => {
|
PassMode::Direct(_) | PassMode::Pair(_, _) => {
|
||||||
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
|
let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa;
|
||||||
|
@ -76,7 +76,7 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||||
fx.fn_abi.as_ref().unwrap().ret.layout,
|
fx.fn_abi.as_ref().unwrap().ret.layout,
|
||||||
is_ssa,
|
is_ssa,
|
||||||
),
|
),
|
||||||
Empty,
|
smallvec![],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
PassMode::Cast(_)
|
PassMode::Cast(_)
|
||||||
|
@ -91,7 +91,7 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||||
Pointer::new(ret_param),
|
Pointer::new(ret_param),
|
||||||
fx.fn_abi.as_ref().unwrap().ret.layout,
|
fx.fn_abi.as_ref().unwrap().ret.layout,
|
||||||
),
|
),
|
||||||
Single(ret_param),
|
smallvec![ret_param],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Indirect {
|
||||||
|
@ -110,7 +110,7 @@ pub(super) fn codegen_return_param<'tcx>(
|
||||||
"ret",
|
"ret",
|
||||||
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,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue