Skip to content

Commit 1e9e177

Browse files
committed
Move some code around in codegen_call_terminator
1 parent 95a2212 commit 1e9e177

File tree

1 file changed

+103
-99
lines changed
  • compiler/rustc_codegen_ssa/src/mir

1 file changed

+103
-99
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 103 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::lang_items::LangItem;
88
use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason};
99
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1010
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
11-
use rustc_middle::ty::{self, Instance, Ty};
11+
use rustc_middle::ty::{self, Instance, List, Ty};
1212
use rustc_middle::{bug, span_bug};
1313
use rustc_session::config::OptLevel;
1414
use rustc_span::source_map::Spanned;
@@ -827,7 +827,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
827827
helper: &TerminatorCodegenHelper<'tcx>,
828828
bx: &mut Bx,
829829
intrinsic: ty::IntrinsicDef,
830-
instance: Option<Instance<'tcx>>,
830+
instance: Instance<'tcx>,
831831
source_info: mir::SourceInfo,
832832
target: Option<mir::BasicBlock>,
833833
unwind: mir::UnwindAction,
@@ -837,7 +837,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
837837
// These are intrinsics that compile to panics so that we can get a message
838838
// which mentions the offending type, even from a const context.
839839
if let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) {
840-
let ty = instance.unwrap().args.type_at(0);
840+
let ty = instance.args.type_at(0);
841841

842842
let do_panic = !bx
843843
.tcx()
@@ -910,35 +910,116 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
910910
let callee = self.codegen_operand(bx, func);
911911

912912
let (instance, mut llfn) = match *callee.layout.ty.kind() {
913-
ty::FnDef(def_id, args) => (
914-
Some(ty::Instance::expect_resolve(
913+
ty::FnDef(def_id, generic_args) => {
914+
let instance = ty::Instance::expect_resolve(
915915
bx.tcx(),
916916
bx.typing_env(),
917917
def_id,
918-
args,
918+
generic_args,
919919
fn_span,
920-
)),
921-
None,
922-
),
920+
);
921+
922+
let instance = match instance.def {
923+
// We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
924+
// it is `func returning noop future`
925+
ty::InstanceKind::DropGlue(_, None) => {
926+
// Empty drop glue; a no-op.
927+
let target = target.unwrap();
928+
return helper.funclet_br(self, bx, target, mergeable_succ);
929+
}
930+
ty::InstanceKind::Intrinsic(def_id) => {
931+
let intrinsic = bx.tcx().intrinsic(def_id).unwrap();
932+
if let Some(merging_succ) = self.codegen_panic_intrinsic(
933+
&helper,
934+
bx,
935+
intrinsic,
936+
instance,
937+
source_info,
938+
target,
939+
unwind,
940+
mergeable_succ,
941+
) {
942+
return merging_succ;
943+
}
944+
945+
let fn_abi = bx.fn_abi_of_instance(instance, List::empty());
946+
947+
let mut llargs = Vec::with_capacity(1);
948+
let ret_dest = self.make_return_dest(
949+
bx,
950+
destination,
951+
&fn_abi.ret,
952+
&mut llargs,
953+
Some(intrinsic),
954+
);
955+
let dest = match ret_dest {
956+
_ if fn_abi.ret.is_indirect() => llargs[0],
957+
ReturnDest::Nothing => bx.const_undef(bx.type_ptr()),
958+
ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => {
959+
dst.val.llval
960+
}
961+
ReturnDest::DirectOperand(_) => {
962+
bug!("Cannot use direct operand with an intrinsic call")
963+
}
964+
};
965+
966+
let args: Vec<_> =
967+
args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect();
968+
969+
if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. })
970+
{
971+
let location = self.get_caller_location(
972+
bx,
973+
mir::SourceInfo { span: fn_span, ..source_info },
974+
);
975+
976+
assert_eq!(llargs, []);
977+
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
978+
location.val.store(bx, tmp);
979+
}
980+
self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate());
981+
return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ);
982+
}
983+
984+
match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span)
985+
{
986+
Ok(()) => {
987+
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
988+
self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval);
989+
}
990+
991+
return if let Some(target) = target {
992+
helper.funclet_br(self, bx, target, mergeable_succ)
993+
} else {
994+
bx.unreachable();
995+
MergingSucc::False
996+
};
997+
}
998+
Err(instance) => {
999+
if intrinsic.must_be_overridden {
1000+
span_bug!(
1001+
span,
1002+
"intrinsic {} must be overridden by codegen backend, but isn't",
1003+
intrinsic.name,
1004+
);
1005+
}
1006+
instance
1007+
}
1008+
}
1009+
}
1010+
_ => instance,
1011+
};
1012+
1013+
(Some(instance), None)
1014+
}
9231015
ty::FnPtr(..) => (None, Some(callee.immediate())),
9241016
_ => bug!("{} is not callable", callee.layout.ty),
9251017
};
9261018

927-
let def = instance.map(|i| i.def);
928-
929-
// We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
930-
// it is `func returning noop future`
931-
if let Some(ty::InstanceKind::DropGlue(_, None)) = def {
932-
// Empty drop glue; a no-op.
933-
let target = target.unwrap();
934-
return helper.funclet_br(self, bx, target, mergeable_succ);
935-
}
936-
9371019
// FIXME(eddyb) avoid computing this if possible, when `instance` is
9381020
// available - right now `sig` is only needed for getting the `abi`
9391021
// and figuring out how many extra args were passed to a C-variadic `fn`.
9401022
let sig = callee.layout.ty.fn_sig(bx.tcx());
941-
let abi = sig.abi();
9421023

9431024
let extra_args = &args[sig.inputs().skip_binder().len()..];
9441025
let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| {
@@ -954,83 +1035,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
9541035
// The arguments we'll be passing. Plus one to account for outptr, if used.
9551036
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
9561037

957-
let instance = match def {
958-
Some(ty::InstanceKind::Intrinsic(def_id)) => {
959-
let intrinsic = bx.tcx().intrinsic(def_id).unwrap();
960-
if let Some(merging_succ) = self.codegen_panic_intrinsic(
961-
&helper,
962-
bx,
963-
intrinsic,
964-
instance,
965-
source_info,
966-
target,
967-
unwind,
968-
mergeable_succ,
969-
) {
970-
return merging_succ;
971-
}
972-
973-
let mut llargs = Vec::with_capacity(1);
974-
let ret_dest = self.make_return_dest(
975-
bx,
976-
destination,
977-
&fn_abi.ret,
978-
&mut llargs,
979-
Some(intrinsic),
980-
);
981-
let dest = match ret_dest {
982-
_ if fn_abi.ret.is_indirect() => llargs[0],
983-
ReturnDest::Nothing => bx.const_undef(bx.type_ptr()),
984-
ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.val.llval,
985-
ReturnDest::DirectOperand(_) => {
986-
bug!("Cannot use direct operand with an intrinsic call")
987-
}
988-
};
989-
990-
let args: Vec<_> =
991-
args.iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect();
992-
993-
if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) {
994-
let location = self
995-
.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
996-
997-
assert_eq!(llargs, []);
998-
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
999-
location.val.store(bx, tmp);
1000-
}
1001-
self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate());
1002-
return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ);
1003-
}
1004-
1005-
let instance = *instance.as_ref().unwrap();
1006-
match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) {
1007-
Ok(()) => {
1008-
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
1009-
self.store_return(bx, ret_dest, &fn_abi.ret, dst.val.llval);
1010-
}
1011-
1012-
return if let Some(target) = target {
1013-
helper.funclet_br(self, bx, target, mergeable_succ)
1014-
} else {
1015-
bx.unreachable();
1016-
MergingSucc::False
1017-
};
1018-
}
1019-
Err(instance) => {
1020-
if intrinsic.must_be_overridden {
1021-
span_bug!(
1022-
span,
1023-
"intrinsic {} must be overridden by codegen backend, but isn't",
1024-
intrinsic.name,
1025-
);
1026-
}
1027-
Some(instance)
1028-
}
1029-
}
1030-
}
1031-
_ => instance,
1032-
};
1033-
10341038
let mut llargs = Vec::with_capacity(arg_count);
10351039

10361040
// We still need to call `make_return_dest` even if there's no `target`, since
@@ -1040,7 +1044,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10401044
let destination = target.map(|target| (return_dest, target));
10411045

10421046
// Split the rust-call tupled arguments off.
1043-
let (first_args, untuple) = if abi == ExternAbi::RustCall
1047+
let (first_args, untuple) = if sig.abi() == ExternAbi::RustCall
10441048
&& let Some((tup, args)) = args.split_last()
10451049
{
10461050
(args, Some(tup))
@@ -1055,7 +1059,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10551059
'make_args: for (i, arg) in first_args.iter().enumerate() {
10561060
let mut op = self.codegen_operand(bx, &arg.node);
10571061

1058-
if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, def) {
1062+
if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, instance.map(|i| i.def)) {
10591063
match op.val {
10601064
Pair(data_ptr, meta) => {
10611065
// In the case of Rc<Self>, we need to explicitly pass a

0 commit comments

Comments
 (0)