@@ -205,35 +205,57 @@ fn function_return_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll
205205fn instrument_function_attr < ' ll > (
206206 cx : & SimpleCx < ' ll > ,
207207 sess : & Session ,
208+ instrument_fn : & Option < bool > ,
208209) -> SmallVec < [ & ' ll Attribute ; 4 ] > {
209210 let mut attrs = SmallVec :: new ( ) ;
210211 if sess. opts . unstable_opts . instrument_mcount {
211212 // Similar to `clang -pg` behavior. Handled by the
212213 // `post-inline-ee-instrument` LLVM pass.
213214
214- // The function name varies on platforms.
215- // See test/CodeGen/mcount.c in clang.
216- let mcount_name = match & sess. target . llvm_mcount_intrinsic {
217- Some ( llvm_mcount_intrinsic) => llvm_mcount_intrinsic. as_ref ( ) ,
218- None => sess. target . mcount . as_ref ( ) ,
219- } ;
215+ // #[instrument_fn], the default is on.
216+ let instrument_entry = instrument_fn. unwrap_or_else ( || true ) ;
220217
221- attrs. push ( llvm:: CreateAttrStringValue (
222- cx. llcx ,
223- "instrument-function-entry-inlined" ,
224- mcount_name,
225- ) ) ;
218+ if instrument_entry {
219+ // The function name varies on platforms.
220+ // See test/CodeGen/mcount.c in clang.
221+ let mcount_name = match & sess. target . llvm_mcount_intrinsic {
222+ Some ( llvm_mcount_intrinsic) => llvm_mcount_intrinsic. as_ref ( ) ,
223+ None => sess. target . mcount . as_ref ( ) ,
224+ } ;
225+
226+ attrs. push ( llvm:: CreateAttrStringValue (
227+ cx. llcx ,
228+ "instrument-function-entry-inlined" ,
229+ mcount_name,
230+ ) ) ;
231+ }
226232 }
227233 if let Some ( options) = & sess. opts . unstable_opts . instrument_xray {
228234 // XRay instrumentation is similar to __cyg_profile_func_{enter,exit}.
229235 // Function prologue and epilogue are instrumented with NOP sleds,
230236 // a runtime library later replaces them with detours into tracing code.
231- if options. always {
232- attrs. push ( llvm:: CreateAttrStringValue ( cx. llcx , "function-instrument" , "xray-always" ) ) ;
237+
238+ let mut never = options. never ;
239+ let mut always = options. always ;
240+
241+ // Apply optional #[instrument_fn] override.
242+ match instrument_fn {
243+ Some ( true ) => {
244+ always = true ;
245+ }
246+ Some ( false ) => {
247+ never = true ;
248+ }
249+ None => { }
233250 }
234- if options. never {
251+
252+ if never {
235253 attrs. push ( llvm:: CreateAttrStringValue ( cx. llcx , "function-instrument" , "xray-never" ) ) ;
236254 }
255+ if always {
256+ attrs. push ( llvm:: CreateAttrStringValue ( cx. llcx , "function-instrument" , "xray-always" ) ) ;
257+ }
258+
237259 if options. ignore_loops {
238260 attrs. push ( llvm:: CreateAttrString ( cx. llcx , "xray-ignore-loops" ) ) ;
239261 }
@@ -245,6 +267,7 @@ fn instrument_function_attr<'ll>(
245267 "xray-instruction-threshold" ,
246268 & threshold. to_string ( ) ,
247269 ) ) ;
270+
248271 if options. skip_entry {
249272 attrs. push ( llvm:: CreateAttrString ( cx. llcx , "xray-skip-entry" ) ) ;
250273 }
@@ -437,7 +460,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
437460 // FIXME: none of these functions interact with source level attributes.
438461 to_add. extend ( frame_pointer_type_attr ( cx, sess) ) ;
439462 to_add. extend ( function_return_attr ( cx, sess) ) ;
440- to_add. extend ( instrument_function_attr ( cx, sess) ) ;
463+ to_add. extend ( instrument_function_attr ( cx, sess, & codegen_fn_attrs . instrument_fn ) ) ;
441464 to_add. extend ( nojumptables_attr ( cx, sess) ) ;
442465 to_add. extend ( probestack_attr ( cx, tcx) ) ;
443466 to_add. extend ( stackprotector_attr ( cx, sess) ) ;
0 commit comments