use rustc_middle::bug; use rustc_middle::ty::{self, GenericArg, IntrinsicDef, TyCtxt}; use crate::collector::{MonoItems, create_fn_mono_item}; // Here, we force both primal and diff function to be collected in // mono so this does not interfere in `autodiff` intrinsics // codegen process. If they are unused, LLVM will remove them when // compiling with O3. pub(crate) fn collect_autodiff_fn<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>, intrinsic: IntrinsicDef, output: &mut MonoItems<'tcx>, ) { if intrinsic.name != rustc_span::sym::autodiff { return; }; collect_autodiff_fn_from_arg(instance.args[0], tcx, output); } fn collect_autodiff_fn_from_arg<'tcx>( arg: GenericArg<'tcx>, tcx: TyCtxt<'tcx>, output: &mut MonoItems<'tcx>, ) { let (instance, span) = match arg.kind() { ty::GenericArgKind::Type(ty) => match ty.kind() { ty::FnDef(def_id, substs) => { let span = tcx.def_span(def_id); let instance = ty::Instance::expect_resolve( tcx, ty::TypingEnv::non_body_analysis(tcx, def_id), *def_id, substs, span, ); (instance, span) } _ => bug!("expected autodiff function"), }, _ => bug!("expected type when matching autodiff arg"), }; output.push(create_fn_mono_item(tcx, instance, span)); }