Pass UnwindAction to a couple of functions

In preparation for future unwinding support.

Part of rust-lang/rustc_codegen_cranelift#1567
This commit is contained in:
bjorn3 2025-04-09 13:50:59 +00:00
parent 420e44f578
commit ab514c9596
3 changed files with 46 additions and 18 deletions

View file

@ -20,6 +20,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_target::callconv::{Conv, FnAbi, PassMode};
use smallvec::SmallVec;
use self::pass_mode::*;
pub(crate) use self::returning::codegen_return;
@ -384,6 +385,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
args: &[Spanned<Operand<'tcx>>],
destination: Place<'tcx>,
target: Option<BasicBlock>,
_unwind: UnwindAction,
) {
let func = codegen_operand(fx, func);
let fn_sig = func.layout().ty.fn_sig(fx.tcx);
@ -588,12 +590,14 @@ pub(crate) fn codegen_terminator_call<'tcx>(
with_no_trimmed_paths!(fx.add_comment(nop_inst, format!("abi: {:?}", fn_abi)));
}
match func_ref {
let call_inst = match func_ref {
CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args),
CallTarget::Indirect(sig, func_ptr) => {
fx.bcx.ins().call_indirect(sig, func_ptr, &call_args)
}
}
};
fx.bcx.func.dfg.inst_results(call_inst).iter().copied().collect::<SmallVec<[Value; 2]>>()
});
if let Some(dest) = target {
@ -703,14 +707,17 @@ pub(crate) fn codegen_drop<'tcx>(
source_info: mir::SourceInfo,
drop_place: CPlace<'tcx>,
target: BasicBlock,
_unwind: UnwindAction,
) {
let ty = drop_place.layout().ty;
let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty);
let ret_block = fx.get_block(target);
if let ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) =
drop_instance.def
{
// we don't actually need to drop anything
fx.bcx.ins().jump(ret_block, &[]);
} else {
match ty.kind() {
ty::Dynamic(_, _, ty::Dyn) => {
@ -747,7 +754,9 @@ pub(crate) fn codegen_drop<'tcx>(
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig);
// FIXME implement cleanup on exceptions
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
fx.bcx.ins().jump(ret_block, &[]);
}
ty::Dynamic(_, _, ty::DynStar) => {
// IN THIS ARM, WE HAVE:
@ -791,6 +800,8 @@ pub(crate) fn codegen_drop<'tcx>(
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig);
fx.bcx.ins().call_indirect(sig, drop_fn, &[data]);
// FIXME implement cleanup on exceptions
fx.bcx.ins().jump(ret_block, &[]);
}
_ => {
assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _)));
@ -816,10 +827,9 @@ pub(crate) fn codegen_drop<'tcx>(
let func_ref = fx.get_function_ref(drop_instance);
fx.bcx.ins().call(func_ref, &call_args);
// FIXME implement cleanup on exceptions
fx.bcx.ins().jump(ret_block, &[]);
}
}
}
let target_block = fx.get_block(target);
fx.bcx.ins().jump(target_block, &[]);
}

View file

@ -46,7 +46,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
ret_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
ret_place: CPlace<'tcx>,
f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option<Value>) -> Inst,
f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option<Value>) -> SmallVec<[Value; 2]>,
) {
let (ret_temp_place, return_ptr) = match ret_arg_abi.mode {
PassMode::Ignore => (None, None),
@ -67,23 +67,21 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => (None, None),
};
let call_inst = f(fx, return_ptr);
let results = f(fx, return_ptr);
match ret_arg_abi.mode {
PassMode::Ignore => {}
PassMode::Direct(_) => {
let ret_val = fx.bcx.inst_results(call_inst)[0];
let ret_val = results[0];
ret_place.write_cvalue(fx, CValue::by_val(ret_val, ret_arg_abi.layout));
}
PassMode::Pair(_, _) => {
let ret_val_a = fx.bcx.inst_results(call_inst)[0];
let ret_val_b = fx.bcx.inst_results(call_inst)[1];
let ret_val_a = results[0];
let ret_val_b = results[1];
ret_place
.write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout));
}
PassMode::Cast { ref cast, .. } => {
let results =
fx.bcx.inst_results(call_inst).iter().copied().collect::<SmallVec<[Value; 2]>>();
let result =
super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast);
ret_place.write_cvalue(fx, result);

View file

@ -372,7 +372,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
TerminatorKind::Return => {
crate::abi::codegen_return(fx);
}
TerminatorKind::Assert { cond, expected, msg, target, unwind: _ } => {
TerminatorKind::Assert { cond, expected, msg, target, unwind } => {
if !fx.tcx.sess.overflow_checks() && msg.is_optional_overflow_check() {
let target = fx.get_block(*target);
fx.bcx.ins().jump(target, &[]);
@ -402,6 +402,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
fx,
rustc_hir::LangItem::PanicBoundsCheck,
&[index, len, location],
*unwind,
Some(source_info.span),
);
}
@ -414,6 +415,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
fx,
rustc_hir::LangItem::PanicMisalignedPointerDereference,
&[required, found, location],
*unwind,
Some(source_info.span),
);
}
@ -424,6 +426,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
fx,
rustc_hir::LangItem::PanicNullPointerDereference,
&[location],
*unwind,
Some(source_info.span),
)
}
@ -434,6 +437,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
fx,
msg.panic_function(),
&[location],
*unwind,
Some(source_info.span),
);
}
@ -492,7 +496,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
destination,
target,
fn_span,
unwind: _,
unwind,
call_source: _,
} => {
fx.tcx.prof.generic_activity("codegen call").run(|| {
@ -503,6 +507,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
args,
*destination,
*target,
*unwind,
)
});
}
@ -565,9 +570,9 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
| TerminatorKind::CoroutineDrop => {
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
}
TerminatorKind::Drop { place, target, unwind: _, replace: _ } => {
TerminatorKind::Drop { place, target, unwind, replace: _ } => {
let drop_place = codegen_place(fx, *place);
crate::abi::codegen_drop(fx, source_info, drop_place, *target);
crate::abi::codegen_drop(fx, source_info, drop_place, *target, *unwind);
}
};
}
@ -1089,7 +1094,13 @@ pub(crate) fn codegen_panic_nounwind<'tcx>(
let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
let args = [msg_ptr, msg_len];
codegen_panic_inner(fx, rustc_hir::LangItem::PanicNounwind, &args, span);
codegen_panic_inner(
fx,
rustc_hir::LangItem::PanicNounwind,
&args,
UnwindAction::Terminate(UnwindTerminateReason::Abi),
span,
);
}
pub(crate) fn codegen_unwind_terminate<'tcx>(
@ -1099,13 +1110,20 @@ pub(crate) fn codegen_unwind_terminate<'tcx>(
) {
let args = [];
codegen_panic_inner(fx, reason.lang_item(), &args, Some(source_info.span));
codegen_panic_inner(
fx,
reason.lang_item(),
&args,
UnwindAction::Terminate(UnwindTerminateReason::Abi),
Some(source_info.span),
);
}
fn codegen_panic_inner<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
lang_item: rustc_hir::LangItem,
args: &[Value],
_unwind: UnwindAction,
span: Option<Span>,
) {
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
@ -1121,6 +1139,8 @@ fn codegen_panic_inner<'tcx>(
let symbol_name = fx.tcx.symbol_name(instance).name;
// FIXME implement cleanup on exceptions
fx.lib_call(
symbol_name,
args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(),