@@ -201,35 +201,57 @@ fn function_return_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll
201201fn instrument_function_attr < ' ll > (
202202 cx : & SimpleCx < ' ll > ,
203203 sess : & Session ,
204+ instrument_fn : & Option < bool > ,
204205) -> SmallVec < [ & ' ll Attribute ; 4 ] > {
205206 let mut attrs = SmallVec :: new ( ) ;
206207 if sess. opts . unstable_opts . instrument_mcount {
207208 // Similar to `clang -pg` behavior. Handled by the
208209 // `post-inline-ee-instrument` LLVM pass.
209210
210- // The function name varies on platforms.
211- // See test/CodeGen/mcount.c in clang.
212- let mcount_name = match & sess. target . llvm_mcount_intrinsic {
213- Some ( llvm_mcount_intrinsic) => llvm_mcount_intrinsic. as_ref ( ) ,
214- None => sess. target . mcount . as_ref ( ) ,
215- } ;
211+ // #[instrument_fn], the default is on.
212+ let instrument_entry = instrument_fn. unwrap_or_else ( || true ) ;
216213
217- attrs. push ( llvm:: CreateAttrStringValue (
218- cx. llcx ,
219- "instrument-function-entry-inlined" ,
220- mcount_name,
221- ) ) ;
214+ if instrument_entry {
215+ // The function name varies on platforms.
216+ // See test/CodeGen/mcount.c in clang.
217+ let mcount_name = match & sess. target . llvm_mcount_intrinsic {
218+ Some ( llvm_mcount_intrinsic) => llvm_mcount_intrinsic. as_ref ( ) ,
219+ None => sess. target . mcount . as_ref ( ) ,
220+ } ;
221+
222+ attrs. push ( llvm:: CreateAttrStringValue (
223+ cx. llcx ,
224+ "instrument-function-entry-inlined" ,
225+ mcount_name,
226+ ) ) ;
227+ }
222228 }
223229 if let Some ( options) = & sess. opts . unstable_opts . instrument_xray {
224230 // XRay instrumentation is similar to __cyg_profile_func_{enter,exit}.
225231 // Function prologue and epilogue are instrumented with NOP sleds,
226232 // a runtime library later replaces them with detours into tracing code.
227- if options. always {
228- attrs. push ( llvm:: CreateAttrStringValue ( cx. llcx , "function-instrument" , "xray-always" ) ) ;
233+
234+ let mut never = options. never ;
235+ let mut always = options. always ;
236+
237+ // Apply optional #[instrument_fn] override.
238+ match instrument_fn {
239+ Some ( true ) => {
240+ always = true ;
241+ }
242+ Some ( false ) => {
243+ never = true ;
244+ }
245+ None => { }
229246 }
230- if options. never {
247+
248+ if never {
231249 attrs. push ( llvm:: CreateAttrStringValue ( cx. llcx , "function-instrument" , "xray-never" ) ) ;
232250 }
251+ if always {
252+ attrs. push ( llvm:: CreateAttrStringValue ( cx. llcx , "function-instrument" , "xray-always" ) ) ;
253+ }
254+
233255 if options. ignore_loops {
234256 attrs. push ( llvm:: CreateAttrString ( cx. llcx , "xray-ignore-loops" ) ) ;
235257 }
@@ -241,6 +263,7 @@ fn instrument_function_attr<'ll>(
241263 "xray-instruction-threshold" ,
242264 & threshold. to_string ( ) ,
243265 ) ) ;
266+
244267 if options. skip_entry {
245268 attrs. push ( llvm:: CreateAttrString ( cx. llcx , "xray-skip-entry" ) ) ;
246269 }
@@ -429,7 +452,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
429452 // FIXME: none of these functions interact with source level attributes.
430453 to_add. extend ( frame_pointer_type_attr ( cx, sess) ) ;
431454 to_add. extend ( function_return_attr ( cx, sess) ) ;
432- to_add. extend ( instrument_function_attr ( cx, sess) ) ;
455+ to_add. extend ( instrument_function_attr ( cx, sess, & codegen_fn_attrs . instrument_fn ) ) ;
433456 to_add. extend ( nojumptables_attr ( cx, sess) ) ;
434457 to_add. extend ( probestack_attr ( cx, tcx) ) ;
435458 to_add. extend ( stackprotector_attr ( cx, sess) ) ;
0 commit comments