1- use std:: str:: FromStr ;
2-
31use rustc_abi:: { Align , ExternAbi } ;
4- use rustc_ast:: expand:: autodiff_attrs:: { AutoDiffAttrs , DiffActivity , DiffMode } ;
5- use rustc_ast:: { LitKind , MetaItem , MetaItemInner } ;
62use rustc_hir:: attrs:: {
73 AttributeKind , EiiImplResolution , InlineAttr , Linkage , RtsanSetting , UsedBy ,
84} ;
@@ -14,7 +10,6 @@ use rustc_middle::middle::codegen_fn_attrs::{
1410} ;
1511use rustc_middle:: mir:: mono:: Visibility ;
1612use rustc_middle:: query:: Providers ;
17- use rustc_middle:: span_bug;
1813use rustc_middle:: ty:: { self as ty, TyCtxt } ;
1914use rustc_session:: lint;
2015use rustc_session:: parse:: feature_err;
@@ -614,116 +609,6 @@ fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
614609 tcx. codegen_fn_attrs ( tcx. trait_item_of ( def_id) ?) . alignment
615610}
616611
617- /// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
618- /// macros. There are two forms. The pure one without args to mark primal functions (the functions
619- /// being differentiated). The other form is #[rustc_autodiff(Mode, ActivityList)] on top of the
620- /// placeholder functions. We wrote the rustc_autodiff attributes ourself, so this should never
621- /// panic, unless we introduced a bug when parsing the autodiff macro.
622- //FIXME(jdonszelmann): put in the main loop. No need to have two..... :/ Let's do that when we make autodiff parsed.
623- pub fn autodiff_attrs ( tcx : TyCtxt < ' _ > , id : DefId ) -> Option < AutoDiffAttrs > {
624- #[ allow( deprecated) ]
625- let attrs = tcx. get_attrs ( id, sym:: rustc_autodiff) ;
626-
627- let attrs = attrs. filter ( |attr| attr. has_name ( sym:: rustc_autodiff) ) . collect :: < Vec < _ > > ( ) ;
628-
629- // check for exactly one autodiff attribute on placeholder functions.
630- // There should only be one, since we generate a new placeholder per ad macro.
631- let attr = match & attrs[ ..] {
632- [ ] => return None ,
633- [ attr] => attr,
634- _ => {
635- span_bug ! ( attrs[ 1 ] . span( ) , "cg_ssa: rustc_autodiff should only exist once per source" ) ;
636- }
637- } ;
638-
639- let list = attr. meta_item_list ( ) . unwrap_or_default ( ) ;
640-
641- // empty autodiff attribute macros (i.e. `#[autodiff]`) are used to mark source functions
642- if list. is_empty ( ) {
643- return Some ( AutoDiffAttrs :: source ( ) ) ;
644- }
645-
646- let [ mode, width_meta, input_activities @ .., ret_activity] = & list[ ..] else {
647- span_bug ! ( attr. span( ) , "rustc_autodiff attribute must contain mode, width and activities" ) ;
648- } ;
649- let mode = if let MetaItemInner :: MetaItem ( MetaItem { path : p1, .. } ) = mode {
650- p1. segments . first ( ) . unwrap ( ) . ident
651- } else {
652- span_bug ! ( attr. span( ) , "rustc_autodiff attribute must contain mode" ) ;
653- } ;
654-
655- // parse mode
656- let mode = match mode. as_str ( ) {
657- "Forward" => DiffMode :: Forward ,
658- "Reverse" => DiffMode :: Reverse ,
659- _ => {
660- span_bug ! ( mode. span, "rustc_autodiff attribute contains invalid mode" ) ;
661- }
662- } ;
663-
664- let width: u32 = match width_meta {
665- MetaItemInner :: MetaItem ( MetaItem { path : p1, .. } ) => {
666- let w = p1. segments . first ( ) . unwrap ( ) . ident ;
667- match w. as_str ( ) . parse ( ) {
668- Ok ( val) => val,
669- Err ( _) => {
670- span_bug ! ( w. span, "rustc_autodiff width should fit u32" ) ;
671- }
672- }
673- }
674- MetaItemInner :: Lit ( lit) => {
675- if let LitKind :: Int ( val, _) = lit. kind {
676- match val. get ( ) . try_into ( ) {
677- Ok ( val) => val,
678- Err ( _) => {
679- span_bug ! ( lit. span, "rustc_autodiff width should fit u32" ) ;
680- }
681- }
682- } else {
683- span_bug ! ( lit. span, "rustc_autodiff width should be an integer" ) ;
684- }
685- }
686- } ;
687-
688- // First read the ret symbol from the attribute
689- let MetaItemInner :: MetaItem ( MetaItem { path : p1, .. } ) = ret_activity else {
690- span_bug ! ( attr. span( ) , "rustc_autodiff attribute must contain the return activity" ) ;
691- } ;
692- let ret_symbol = p1. segments . first ( ) . unwrap ( ) . ident ;
693-
694- // Then parse it into an actual DiffActivity
695- let Ok ( ret_activity) = DiffActivity :: from_str ( ret_symbol. as_str ( ) ) else {
696- span_bug ! ( ret_symbol. span, "invalid return activity" ) ;
697- } ;
698-
699- // Now parse all the intermediate (input) activities
700- let mut arg_activities: Vec < DiffActivity > = vec ! [ ] ;
701- for arg in input_activities {
702- let arg_symbol = if let MetaItemInner :: MetaItem ( MetaItem { path : p2, .. } ) = arg {
703- match p2. segments . first ( ) {
704- Some ( x) => x. ident ,
705- None => {
706- span_bug ! (
707- arg. span( ) ,
708- "rustc_autodiff attribute must contain the input activity"
709- ) ;
710- }
711- }
712- } else {
713- span_bug ! ( arg. span( ) , "rustc_autodiff attribute must contain the input activity" ) ;
714- } ;
715-
716- match DiffActivity :: from_str ( arg_symbol. as_str ( ) ) {
717- Ok ( arg_activity) => arg_activities. push ( arg_activity) ,
718- Err ( _) => {
719- span_bug ! ( arg_symbol. span, "invalid input activity" ) ;
720- }
721- }
722- }
723-
724- Some ( AutoDiffAttrs { mode, width, ret_activity, input_activity : arg_activities } )
725- }
726-
727612pub ( crate ) fn provide ( providers : & mut Providers ) {
728613 * providers = Providers {
729614 codegen_fn_attrs,
0 commit comments