Cleanup codegen_terminator_call a bit

This commit is contained in:
bjorn3 2020-04-13 19:12:44 +02:00
parent 4bbae74458
commit af016640b6

View File

@ -435,14 +435,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
destination: Option<(Place<'tcx>, BasicBlock)>,
) {
let fn_ty = fx.monomorphize(&func.ty(fx.mir, fx.tcx));
let sig = fx
let fn_sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &fn_ty.fn_sig(fx.tcx));
let destination = destination
.map(|(place, bb)| (trans_place(fx, place), bb));
// FIXME mark the current block as cold when calling a `#[cold]` function.
if let ty::FnDef(def_id, substs) = fn_ty.kind {
let destination = destination.map(|(place, bb)| (trans_place(fx, place), bb));
// Handle special calls like instrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, substs) = fn_ty.kind {
let instance =
ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap();
@ -469,24 +471,29 @@ pub(crate) fn codegen_terminator_call<'tcx>(
fx.bcx.ins().jump(ret_block, &[]);
return;
}
_ => {}
_ => Some(instance)
}
}
} else {
None
};
// Unpack arguments tuple for closures
let args = if sig.abi == Abi::RustCall {
let args = if fn_sig.abi == Abi::RustCall {
assert_eq!(args.len(), 2, "rust-call abi requires two arguments");
let self_arg = trans_operand(fx, &args[0]);
let pack_arg = trans_operand(fx, &args[1]);
let mut args = Vec::new();
args.push(self_arg);
match pack_arg.layout().ty.kind {
let tupled_arguments = match pack_arg.layout().ty.kind {
ty::Tuple(ref tupled_arguments) => {
for (i, _) in tupled_arguments.iter().enumerate() {
args.push(pack_arg.value_field(fx, mir::Field::new(i)));
}
tupled_arguments
}
_ => bug!("argument to function with \"rust-call\" ABI is not a tuple"),
};
let mut args = Vec::with_capacity(1 + tupled_arguments.len());
args.push(self_arg);
for i in 0..tupled_arguments.len() {
args.push(pack_arg.value_field(fx, mir::Field::new(i)));
}
args
} else {
@ -495,18 +502,6 @@ pub(crate) fn codegen_terminator_call<'tcx>(
.collect::<Vec<_>>()
};
// FIXME mark the current block as cold when calling a `#[cold]` function.
let fn_sig = fx
.tcx
.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), &fn_ty.fn_sig(fx.tcx));
let instance = match fn_ty.kind {
ty::FnDef(def_id, substs) => {
Some(Instance::resolve(fx.tcx, ParamEnv::reveal_all(), def_id, substs).unwrap())
}
_ => None,
};
// | indirect call target
// | | the first argument to be passed
// v v v virtual calls are special cased below