Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use rustc_middle::middle::codegen_fn_attrs::{
TargetFeature,
};
use rustc_middle::ty::{self, Instance, TyCtxt};
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
use rustc_session::config::{
BranchProtection, FunctionReturn, InstrumentMcount, OptLevel, PAuthKey, PacRet,
};
use rustc_span::sym;
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{Arch, FramePointer, SanitizerSet, StackProbeType, StackProtector};
Expand Down Expand Up @@ -177,7 +179,7 @@ pub(crate) fn frame_pointer(sess: &Session) -> FramePointer {
let opts = &sess.opts;
// "mcount" function relies on stack pointer.
// See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.
if opts.unstable_opts.instrument_mcount {
if opts.unstable_opts.instrument_mcount == InstrumentMcount::Mcount {
fp.ratchet(FramePointer::Always);
}
fp.ratchet(opts.cg.force_frame_pointers);
Expand Down Expand Up @@ -214,7 +216,7 @@ fn instrument_function_attr<'ll>(
instrument_fn: InstrumentFnAttr,
) -> SmallVec<[&'ll Attribute; 4]> {
let mut attrs = SmallVec::new();
if sess.opts.unstable_opts.instrument_mcount {
if sess.opts.unstable_opts.instrument_mcount != InstrumentMcount::Disabled {
// Similar to `clang -pg` behavior. Handled by the
// `post-inline-ee-instrument` LLVM pass.

Expand All @@ -224,18 +226,26 @@ fn instrument_function_attr<'ll>(
};

if instrument_entry {
// The function name varies on platforms.
// See test/CodeGen/mcount.c in clang.
let mcount_name = match &sess.target.llvm_mcount_intrinsic {
Some(llvm_mcount_intrinsic) => llvm_mcount_intrinsic.as_ref(),
None => sess.target.mcount.as_ref(),
};

attrs.push(llvm::CreateAttrStringValue(
cx.llcx,
"instrument-function-entry-inlined",
mcount_name,
));
match sess.opts.unstable_opts.instrument_mcount {
InstrumentMcount::Mcount => {
// The function name varies on platforms.
// See test/CodeGen/mcount.c in clang.
let mcount_name = match &sess.target.llvm_mcount_intrinsic {
Some(llvm_mcount_intrinsic) => llvm_mcount_intrinsic.as_ref(),
None => sess.target.mcount.as_ref(),
};

attrs.push(llvm::CreateAttrStringValue(
cx.llcx,
"instrument-function-entry-inlined",
mcount_name,
));
}
InstrumentMcount::Fentry => {
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "fentry-call", "true"));
}
InstrumentMcount::Disabled => {}
}
}
}
if let Some(options) = &sess.opts.unstable_opts.instrument_xray {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_session::config::{
self, CFGuard, CrateType, DebugInfo, LinkerFeaturesCli, OutFileName, OutputFilenames,
OutputType, PrintKind, SplitDwarfKind, Strip,
self, CFGuard, CrateType, DebugInfo, InstrumentMcount, LinkerFeaturesCli, OutFileName,
OutputFilenames, OutputType, PrintKind, SplitDwarfKind, Strip,
};
use rustc_session::lint::builtin::LINKER_MESSAGES;
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
Expand Down Expand Up @@ -2882,7 +2882,7 @@ fn add_order_independent_options(
cmd.pgo_gen();
}

if sess.opts.unstable_opts.instrument_mcount {
if sess.opts.unstable_opts.instrument_mcount != InstrumentMcount::Disabled {
cmd.enable_profiling();
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ use rustc_session::config::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CodegenRetagOptions, CoverageLevel,
CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation,
Externs, FmtDebug, FunctionReturn, IncrementalStateAssertion, InliningThreshold, Input,
InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli,
MirIncludeSpans, NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes,
PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration,
build_session_options, rustc_optgroups,
InstrumentCoverage, InstrumentMcount, InstrumentXRay, LinkSelfContained, LinkerPluginLto,
LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, Offload, Options, OutFileName,
OutputType, OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius,
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
build_configuration, build_session_options, rustc_optgroups,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
Expand Down Expand Up @@ -834,7 +834,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(inline_mir, Some(true));
tracked!(inline_mir_hint_threshold, Some(123));
tracked!(inline_mir_threshold, Some(123));
tracked!(instrument_mcount, true);
tracked!(instrument_mcount, InstrumentMcount::Mcount);
tracked!(instrument_xray, Some(InstrumentXRay::default()));
tracked!(link_directives, false);
tracked!(link_only, true);
Expand Down
22 changes: 17 additions & 5 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,17 @@ pub enum AnnotateMoves {
Enabled(Option<u64>),
}

/// The different settings that the `-Z Instrument-mcount` flag can have.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum InstrumentMcount {
/// `-Z instrument-mcount=no`
Disabled,
/// `-Z instrument-mcount=yes`
Mcount,
/// `-Z instrument-mcount=fentry`
Fentry,
}

/// Settings for `-Z instrument-xray` flag.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct InstrumentXRay {
Expand Down Expand Up @@ -3085,11 +3096,11 @@ pub(crate) mod dep_tracking {
use super::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CodegenRetagOptions,
CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug,
FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel,
OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks,
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
WasiExecModel,
FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentMcount, InstrumentXRay,
LinkerPluginLto, LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload,
OptLevel, OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius,
ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel,
};
use crate::lint;
use crate::utils::NativeLib;
Expand Down Expand Up @@ -3151,6 +3162,7 @@ pub(crate) mod dep_tracking {
TlsModel,
InstrumentCoverage,
CoverageOptions,
InstrumentMcount,
InstrumentXRay,
CrateType,
MergeFunctions,
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,8 @@ mod desc {
pub(crate) const parse_coverage_options: &str = "`block` | `branch` | `condition`";
pub(crate) const parse_codegen_retag_options: &str =
"either no value or a comma-separated list of settings: `no-precise-im`, `no-precise-pin`";
pub(crate) const parse_instrument_mcount: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `fentry` on supported targets.";
pub(crate) const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
pub(crate) const parse_unpretty: &str = "`string` or `string=string`";
pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
Expand Down Expand Up @@ -1565,6 +1567,19 @@ pub mod parse {
true
}

pub(crate) fn parse_instrument_mcount(slot: &mut InstrumentMcount, v: Option<&str>) -> bool {
let mut use_mcount = false;
if parse_bool(&mut use_mcount, v) {
*slot = if use_mcount { InstrumentMcount::Mcount } else { InstrumentMcount::Disabled };
true
} else if let Some("fentry") = v {
*slot = InstrumentMcount::Fentry;
true
} else {
false
}
}

pub(crate) fn parse_instrument_xray(
slot: &mut Option<InstrumentXRay>,
v: Option<&str>,
Expand Down Expand Up @@ -2433,7 +2448,7 @@ options! {
"a default MIR inlining threshold (default: 50)"),
input_stats: bool = (false, parse_bool, [UNTRACKED],
"print some statistics about AST and HIR (default: no)"),
instrument_mcount: bool = (false, parse_bool, [TRACKED],
instrument_mcount: InstrumentMcount = (InstrumentMcount::Disabled, parse_instrument_mcount, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),
instrument_xray: Option<InstrumentXRay> = (None, parse_instrument_xray, [TRACKED],
"insert function instrument code for XRay-based tracing (default: no)
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use crate::config::{
self, Cfg, CheckCfg, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType,
FunctionReturn, Input, InstrumentCoverage, OptLevel, OutFileName, OutputType,
FunctionReturn, Input, InstrumentCoverage, InstrumentMcount, OptLevel, OutFileName, OutputType,
SwitchWithOptPath,
};
use crate::filesearch::FileSearch;
Expand Down Expand Up @@ -1340,6 +1340,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}

if sess.opts.unstable_opts.instrument_mcount == InstrumentMcount::Fentry
&& !sess.target.options.supports_fentry
{
sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "fentry".to_string() });
}

if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ impl Target {
forward!(supports_stack_protector);
forward!(small_data_threshold_support);
forward!(entry_name);
forward!(supports_fentry);
forward!(supports_xray);

// we're going to run `update_from_cli`, but that won't change the target's AbiMap
Expand Down Expand Up @@ -407,6 +408,7 @@ impl ToJson for Target {
target_option_val!(small_data_threshold_support);
target_option_val!(entry_name);
target_option_val!(entry_abi);
target_option_val!(supports_fentry);
target_option_val!(supports_xray);

// Serializing `-Clink-self-contained` needs a dynamic key to support the
Expand Down Expand Up @@ -626,6 +628,7 @@ struct TargetSpecJson {
supports_stack_protector: Option<bool>,
small_data_threshold_support: Option<SmallDataThresholdSupport>,
entry_name: Option<StaticCow<str>>,
supports_fentry: Option<bool>,
supports_xray: Option<bool>,
entry_abi: Option<ExternAbiWrapper>,
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2688,6 +2688,9 @@ pub struct TargetOptions {
/// Default value is `CanonAbi::C`
pub entry_abi: CanonAbi,

/// Whether the target supports fentry instrumentation.
pub supports_fentry: bool,

/// Whether the target supports XRay instrumentation.
pub supports_xray: bool,

Expand Down Expand Up @@ -2929,6 +2932,7 @@ impl Default for TargetOptions {
supports_stack_protector: true,
entry_name: "main".into(),
entry_abi: CanonAbi::C,
supports_fentry: false,
supports_xray: false,
default_address_space: rustc_abi::AddressSpace::ZERO,
small_data_threshold_support: SmallDataThresholdSupport::DefaultForArch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
base.supported_sanitizers = SanitizerSet::ADDRESS;
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
base.stack_probes = StackProbeType::Inline;
base.supports_fentry = true;

Target {
llvm_target: "i686-unknown-linux-gnu".into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(crate) fn target() -> Target {
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]);
base.stack_probes = StackProbeType::Inline;
base.supports_fentry = true;
// FIXME(compiler-team#422): musl targets should be dynamically linked by default.
base.crt_static_default = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(crate) fn target() -> Target {
base.stack_probes = StackProbeType::Inline;
base.supported_sanitizers =
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
base.supports_fentry = true;

Target {
llvm_target: "s390x-unknown-linux-gnu".into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub(crate) fn target() -> Target {
base.stack_probes = StackProbeType::Inline;
base.supported_sanitizers =
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
base.supports_fentry = true;

Target {
llvm_target: "s390x-unknown-linux-musl".into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
rustc_abi: Some(RustcAbi::Softfloat),
stack_probes: StackProbeType::Inline,
supported_sanitizers: SanitizerSet::KERNELADDRESS,
supports_fentry: true,
..Default::default()
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub(crate) fn target() -> Target {
| SanitizerSet::SAFESTACK
| SanitizerSet::THREAD
| SanitizerSet::REALTIME;
base.supports_fentry = true;
base.supports_xray = true;

Target {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub(crate) fn target() -> Target {
| SanitizerSet::LEAK
| SanitizerSet::MEMORY
| SanitizerSet::THREAD;
base.supports_fentry = true;
base.supports_xray = true;
// FIXME(compiler-team#422): musl targets should be dynamically linked by default.
base.crt_static_default = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) fn target() -> Target {
base.linker_flavor = LinkerFlavor::Gnu(Cc::No, Lld::Yes);
base.linker = Some("rust-lld".into());
base.panic_strategy = PanicStrategy::Abort;
base.supports_fentry = true;

Target {
llvm_target: "x86_64-unknown-linux-none".into(),
Expand Down
25 changes: 25 additions & 0 deletions tests/assembly-llvm/fentry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ assembly-output: emit-asm
//@ compile-flags: -Zinstrument-mcount=fentry
//@ add-minicore

//@ revisions: X86 S390X
//@[X86] compile-flags: --target=x86_64-unknown-linux-gnu -Cllvm-args=-x86-asm-syntax=intel
//@[X86] needs-llvm-components: x86
//@[S390X] compile-flags: --target=s390x-unknown-linux-gnu
//@[S390X] needs-llvm-components: systemz

#![crate_type = "lib"]
#![feature(no_core)]
#![no_core]

extern crate minicore;

// CHECK-LABEL: mcount_func:
#[no_mangle]
pub fn mcount_func(a: isize, b: isize) -> isize {
// X86: call __fentry__
// S390X: brasl %r0, __fentry__@PLT
a + b
// X86: ret
// S390X: br %r14
}
25 changes: 25 additions & 0 deletions tests/codegen-llvm/instrument-fentry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ add-minicore
//@ compile-flags: -Z instrument-mcount=fentry -Copt-level=0
//
//@ revisions: x86_64-linux
//@[x86_64-linux] compile-flags: --target=x86_64-unknown-linux-gnu
//@[x86_64-linux] needs-llvm-components: x86
//
//@ revisions: x86-linux
//@[x86-linux] compile-flags: --target=i686-unknown-linux-gnu
//@[x86-linux] needs-llvm-components: x86
//
//@ revisions: s390x-linux
//@[s390x-linux] compile-flags: --target=s390x-unknown-linux-gnu
//@[s390x-linux] needs-llvm-components: systemz

#![feature(no_core)]
#![no_std]
#![no_core]
#![crate_type = "lib"]

extern crate minicore;
use minicore::*;

// CHECK: attributes #{{.*}} "fentry-call"="true"
pub fn foo() {}
Loading
Loading