summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/attributes.rs
diff options
context:
space:
mode:
authorOleksii Lozovskyi <me@ilammy.net>2022-09-24 22:05:25 +0900
committerOleksii Lozovskyi <me@ilammy.net>2023-02-09 12:28:00 +0900
commitbac15db1d0f3ccdb9b9f61ba808cd25fbf400e88 (patch)
tree4f0a6cdd8172693f1b0fc72b5466cede2b9f00e1 /compiler/rustc_codegen_llvm/src/attributes.rs
parentb3cadd2dcfe37836cdbfd6c5871bd8398748ac3f (diff)
downloadrust-bac15db1d0f3ccdb9b9f61ba808cd25fbf400e88.tar.gz
rust-bac15db1d0f3ccdb9b9f61ba808cd25fbf400e88.zip
Emit basic XRay instrumentation attributes
Add the attributes to functions according to the settings.

"xray-always" overrides "xray-never", and they both override
"xray-ignore-loops" and "xray-instruction-threshold", but we'll
let lints deal with warnings about silly attribute combinations.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/attributes.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 0494bd7a19b..7a4ec494c8e 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -134,6 +134,34 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'ll Attr
             &mcount_name,
         ));
     }
+    if let Some(options) = &cx.sess().opts.unstable_opts.instrument_xray {
+        // XRay instrumentation is similar to __cyg_profile_func_{enter,exit}.
+        // Function prologue and epilogue are instrumented with NOP sleds,
+        // a runtime library later replaces them with detours into tracing code.
+        if options.always {
+            attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-always"));
+        }
+        if options.never {
+            attrs.push(llvm::CreateAttrStringValue(cx.llcx, "function-instrument", "xray-never"));
+        }
+        if options.ignore_loops {
+            attrs.push(llvm::CreateAttrString(cx.llcx, "xray-ignore-loops"));
+        }
+        // LLVM will not choose the default for us, but rather requires specific
+        // threshold in absence of "xray-always". Use the same default as Clang.
+        let threshold = options.instruction_threshold.unwrap_or(200);
+        attrs.push(llvm::CreateAttrStringValue(
+            cx.llcx,
+            "xray-instruction-threshold",
+            &threshold.to_string(),
+        ));
+        if options.skip_entry {
+            attrs.push(llvm::CreateAttrString(cx.llcx, "xray-skip-entry"));
+        }
+        if options.skip_exit {
+            attrs.push(llvm::CreateAttrString(cx.llcx, "xray-skip-exit"));
+        }
+    }
     attrs
 }