@@ -28,8 +28,9 @@ use crate::back::write::{
2828use crate :: errors:: {
2929 DynamicLinkingWithLTO , LlvmError , LtoBitcodeFromRlib , LtoDisallowed , LtoDylib , LtoProcMacro ,
3030} ;
31+ use crate :: llvm:: AttributePlace :: Function ;
3132use crate :: llvm:: { self , build_string} ;
32- use crate :: { LlvmCodegenBackend , ModuleLlvm } ;
33+ use crate :: { LlvmCodegenBackend , ModuleLlvm , SimpleCx , attributes } ;
3334
3435/// We keep track of the computed LTO cache keys from the previous
3536/// session to determine which CGUs we can reuse.
@@ -666,6 +667,33 @@ pub(crate) fn run_pass_manager(
666667 }
667668
668669 if cfg ! ( llvm_enzyme) && enable_ad && !thin {
670+ let cx =
671+ SimpleCx :: new ( module. module_llvm . llmod ( ) , & module. module_llvm . llcx , cgcx. pointer_size ) ;
672+
673+ for function in cx. get_functions ( ) {
674+ let enzyme_marker = CString :: new ( "enzyme_marker" ) . unwrap ( ) ;
675+ let marker_ptr = enzyme_marker. as_ptr ( ) ;
676+
677+ if attributes:: has_string_attr ( function, marker_ptr) {
678+ // Sanity check: Ensure 'noinline' is present before replacing it.
679+ assert ! (
680+ !attributes:: has_attr( function, Function , llvm:: AttributeKind :: NoInline ) ,
681+ "Expected __enzyme function to have 'noinline' before adding 'alwaysinline'"
682+ ) ;
683+
684+ attributes:: remove_from_llfn ( function, Function , llvm:: AttributeKind :: NoInline ) ;
685+ attributes:: remove_string_attr_from_llfn ( function, marker_ptr) ;
686+
687+ assert ! (
688+ !attributes:: has_string_attr( function, marker_ptr) ,
689+ "Expected function to not have 'enzyme_marker'"
690+ ) ;
691+
692+ let always_inline = llvm:: AttributeKind :: AlwaysInline . create_attr ( cx. llcx ) ;
693+ attributes:: apply_to_llfn ( function, Function , & [ always_inline] ) ;
694+ }
695+ }
696+
669697 let opt_stage = llvm:: OptStage :: FatLTO ;
670698 let stage = write:: AutodiffStage :: PostAD ;
671699 if !config. autodiff . contains ( & config:: AutoDiff :: NoPostopt ) {
0 commit comments