summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_llvm/src/attributes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/attributes.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs42
1 files changed, 35 insertions, 7 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 95baa95b0..651d644eb 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -62,7 +62,7 @@ pub fn sanitize_attrs<'ll>(
) -> SmallVec<[&'ll Attribute; 4]> {
let mut attrs = SmallVec::new();
let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize;
- if enabled.contains(SanitizerSet::ADDRESS) {
+ if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
}
if enabled.contains(SanitizerSet::MEMORY) {
@@ -118,7 +118,8 @@ pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attr
/// Tell LLVM what instrument function to insert.
#[inline]
-fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
+fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'ll Attribute; 4]> {
+ let mut attrs = SmallVec::new();
if cx.sess().opts.unstable_opts.instrument_mcount {
// Similar to `clang -pg` behavior. Handled by the
// `post-inline-ee-instrument` LLVM pass.
@@ -127,14 +128,41 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribu
// See test/CodeGen/mcount.c in clang.
let mcount_name = cx.sess().target.mcount.as_ref();
- Some(llvm::CreateAttrStringValue(
+ attrs.push(llvm::CreateAttrStringValue(
cx.llcx,
"instrument-function-entry-inlined",
&mcount_name,
- ))
- } else {
- None
+ ));
+ }
+ 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
}
fn nojumptables_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
@@ -441,7 +469,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
// the WebAssembly specification, which has this feature. This won't be
// needed when LLVM enables this `multivalue` feature by default.
if !cx.tcx.is_closure(instance.def_id()) {
- let abi = cx.tcx.fn_sig(instance.def_id()).abi();
+ let abi = cx.tcx.fn_sig(instance.def_id()).skip_binder().abi();
if abi == Abi::Wasm {
function_features.push("+multivalue".to_string());
}