@@ -13,7 +13,7 @@ use crate::builder::{Builder, PlaceRef, UNNAMED};
13
13
use crate :: context:: SimpleCx ;
14
14
use crate :: declare:: declare_simple_fn;
15
15
use crate :: llvm;
16
- use crate :: llvm:: { Metadata , TRUE , Type } ;
16
+ use crate :: llvm:: { TRUE , Type } ;
17
17
use crate :: value:: Value ;
18
18
19
19
pub ( crate ) fn adjust_activity_to_abi < ' tcx > (
@@ -159,32 +159,36 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>(
159
159
let mut outer_pos: usize = 0 ;
160
160
let mut activity_pos = 0 ;
161
161
162
- let enzyme_const = cx. create_metadata ( b"enzyme_const" ) ;
163
- let enzyme_out = cx. create_metadata ( b"enzyme_out" ) ;
164
- let enzyme_dup = cx. create_metadata ( b"enzyme_dup" ) ;
165
- let enzyme_dupv = cx. create_metadata ( b"enzyme_dupv" ) ;
166
- let enzyme_dupnoneed = cx. create_metadata ( b"enzyme_dupnoneed" ) ;
167
- let enzyme_dupnoneedv = cx. create_metadata ( b"enzyme_dupnoneedv" ) ;
162
+ // We used to use llvm's metadata to instruct enzyme how to differentiate a function.
163
+ // In debug mode we would use incremental compilation which caused the metadata to be
164
+ // dropped. This is prevented by now using named globals, which are also understood
165
+ // by Enzyme.
166
+ let global_const = cx. declare_global ( "enzyme_const" , cx. type_ptr ( ) ) ;
167
+ let global_out = cx. declare_global ( "enzyme_out" , cx. type_ptr ( ) ) ;
168
+ let global_dup = cx. declare_global ( "enzyme_dup" , cx. type_ptr ( ) ) ;
169
+ let global_dupv = cx. declare_global ( "enzyme_dupv" , cx. type_ptr ( ) ) ;
170
+ let global_dupnoneed = cx. declare_global ( "enzyme_dupnoneed" , cx. type_ptr ( ) ) ;
171
+ let global_dupnoneedv = cx. declare_global ( "enzyme_dupnoneedv" , cx. type_ptr ( ) ) ;
168
172
169
173
while activity_pos < inputs. len ( ) {
170
174
let diff_activity = inputs[ activity_pos as usize ] ;
171
175
// Duplicated arguments received a shadow argument, into which enzyme will write the
172
176
// gradient.
173
- let ( activity, duplicated) : ( & Metadata , bool ) = match diff_activity {
177
+ let ( activity, duplicated) : ( & llvm :: Value , bool ) = match diff_activity {
174
178
DiffActivity :: None => panic ! ( "not a valid input activity" ) ,
175
- DiffActivity :: Const => ( enzyme_const , false ) ,
176
- DiffActivity :: Active => ( enzyme_out , false ) ,
177
- DiffActivity :: ActiveOnly => ( enzyme_out , false ) ,
178
- DiffActivity :: Dual => ( enzyme_dup , true ) ,
179
- DiffActivity :: Dualv => ( enzyme_dupv , true ) ,
180
- DiffActivity :: DualOnly => ( enzyme_dupnoneed , true ) ,
181
- DiffActivity :: DualvOnly => ( enzyme_dupnoneedv , true ) ,
182
- DiffActivity :: Duplicated => ( enzyme_dup , true ) ,
183
- DiffActivity :: DuplicatedOnly => ( enzyme_dupnoneed , true ) ,
184
- DiffActivity :: FakeActivitySize ( _) => ( enzyme_const , false ) ,
179
+ DiffActivity :: Const => ( global_const , false ) ,
180
+ DiffActivity :: Active => ( global_out , false ) ,
181
+ DiffActivity :: ActiveOnly => ( global_out , false ) ,
182
+ DiffActivity :: Dual => ( global_dup , true ) ,
183
+ DiffActivity :: Dualv => ( global_dupv , true ) ,
184
+ DiffActivity :: DualOnly => ( global_dupnoneed , true ) ,
185
+ DiffActivity :: DualvOnly => ( global_dupnoneedv , true ) ,
186
+ DiffActivity :: Duplicated => ( global_dup , true ) ,
187
+ DiffActivity :: DuplicatedOnly => ( global_dupnoneed , true ) ,
188
+ DiffActivity :: FakeActivitySize ( _) => ( global_const , false ) ,
185
189
} ;
186
190
let outer_arg = outer_args[ outer_pos] ;
187
- args. push ( cx . get_metadata_value ( activity) ) ;
191
+ args. push ( activity) ;
188
192
if matches ! ( diff_activity, DiffActivity :: Dualv ) {
189
193
let next_outer_arg = outer_args[ outer_pos + 1 ] ;
190
194
let elem_bytes_size: u64 = match inputs[ activity_pos + 1 ] {
@@ -244,7 +248,7 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>(
244
248
assert_eq ! ( cx. type_kind( next_outer_ty3) , TypeKind :: Integer ) ;
245
249
args. push ( next_outer_arg2) ;
246
250
}
247
- args. push ( cx . get_metadata_value ( enzyme_const ) ) ;
251
+ args. push ( global_const ) ;
248
252
args. push ( next_outer_arg) ;
249
253
outer_pos += 2 + 2 * iterations;
250
254
activity_pos += 2 ;
@@ -353,13 +357,13 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
353
357
let mut args = Vec :: with_capacity ( num_args as usize + 1 ) ;
354
358
args. push ( fn_to_diff) ;
355
359
356
- let enzyme_primal_ret = cx. create_metadata ( b "enzyme_primal_return") ;
360
+ let global_primal_ret = cx. declare_global ( "enzyme_primal_return" , cx . type_ptr ( ) ) ;
357
361
if matches ! ( attrs. ret_activity, DiffActivity :: Dual | DiffActivity :: Active ) {
358
- args. push ( cx . get_metadata_value ( enzyme_primal_ret ) ) ;
362
+ args. push ( global_primal_ret ) ;
359
363
}
360
364
if attrs. width > 1 {
361
- let enzyme_width = cx. create_metadata ( b "enzyme_width") ;
362
- args. push ( cx . get_metadata_value ( enzyme_width ) ) ;
365
+ let global_width = cx. declare_global ( "enzyme_width" , cx . type_ptr ( ) ) ;
366
+ args. push ( global_width ) ;
363
367
args. push ( cx. get_const_int ( cx. type_i64 ( ) , attrs. width as u64 ) ) ;
364
368
}
365
369
0 commit comments