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
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back};
use rustc_log::tracing::info;
use rustc_middle::dep_graph::WorkProductMap;
use rustc_session::Session;
use rustc_session::config::OutputFilenames;
use rustc_session::config::{NATIVE_CPU, OutputFilenames};
use rustc_span::{Symbol, sym};
use rustc_target::spec::{Arch, CfgAbi, Env, Os};

Expand Down Expand Up @@ -341,7 +341,7 @@ fn build_isa(sess: &Session, jit: bool) -> Arc<dyn TargetIsa + 'static> {
let flags = settings::Flags::new(flags_builder);

let isa_builder = match sess.opts.cg.target_cpu.as_deref() {
Some("native") => cranelift_native::builder_with_options(true).unwrap(),
Some(NATIVE_CPU) => cranelift_native::builder_with_options(true).unwrap(),
Some(value) => {
let mut builder =
cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_gcc/src/gcc_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use gccjit::Context;
use rustc_codegen_ssa::target_features;
use rustc_data_structures::smallvec::{SmallVec, smallvec};
use rustc_session::Session;
use rustc_session::config::NATIVE_CPU;
use rustc_target::spec::Arch;

fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
Expand Down Expand Up @@ -115,7 +116,7 @@ fn arch_to_gcc(name: &str) -> &str {
}

fn handle_native(name: &str) -> &str {
if name != "native" {
if name != NATIVE_CPU {
return arch_to_gcc(name);
}

Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
use rustc_fs_util::path_to_c_string;
use rustc_middle::bug;
use rustc_session::Session;
use rustc_session::config::{PrintKind, PrintRequest};
use rustc_session::config::{NATIVE_CPU, PrintKind, PrintRequest};
use rustc_target::spec::{
Arch, CfgAbi, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport,
};
Expand Down Expand Up @@ -514,10 +514,12 @@ fn print_target_cpus(sess: &Session, tm: &llvm::TargetMachine, out: &mut String)

// Only print the "native" entry when host and target are the same arch,
// since otherwise it could be wrong or misleading.
if sess.host.arch == sess.target.arch {
// Also do not print it if `requires_consistent_cpu` is set, because in this case
// "native" would be rejected.
if sess.host.arch == sess.target.arch && !sess.target.requires_consistent_cpu {
let host = get_host_cpu_name();
cpus.push_front(Cpu {
cpu_name: "native",
cpu_name: NATIVE_CPU,
remark: format!(" - Select the CPU of the current host (currently {host})."),
});
}
Expand Down Expand Up @@ -612,7 +614,7 @@ fn get_host_cpu_name() -> &'static str {
/// LLVM. Otherwise, the string is returned as-is.
fn handle_native(cpu_name: &str) -> &str {
match cpu_name {
"native" => get_host_cpu_name(),
NATIVE_CPU => get_host_cpu_name(),
_ => cpu_name,
}
}
Expand Down Expand Up @@ -666,7 +668,7 @@ pub(crate) fn global_llvm_features(sess: &Session, only_base_features: bool) ->

// -Ctarget-cpu=native
match sess.opts.cg.target_cpu {
Some(ref s) if s == "native" => {
Some(ref s) if s == NATIVE_CPU => {
// We have already figured out the actual CPU name with `LLVMRustGetHostCPUName` and set
// that for LLVM, so the features implied by that CPU name will be available everywhere.
// However, that is not sufficient: e.g. `skylake` alone is not sufficient to tell if
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ impl CStore {
flag_name,
flag_name_prefixed,
extern_value: extern_value.to_string(),
has_extern_value: !extern_value.is_empty(),
})
}
(Some(local_value), None) => {
Expand All @@ -390,6 +391,7 @@ impl CStore {
flag_name,
flag_name_prefixed,
local_value: local_value.to_string(),
has_local_value: !local_value.is_empty(),
})
}
(None, None) => panic!("Incorrect target modifiers report_diff(None, None)"),
Expand Down
22 changes: 18 additions & 4 deletions compiler/rustc_metadata/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,16 @@ pub(crate) struct IncompatibleTargetModifiers {
"the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely"
)]
#[note(
"unset `{$flag_name_prefixed}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`"
"`{$flag_name_prefixed}` is unset in this crate which is incompatible with {$has_extern_value ->
[false] `{$flag_name_prefixed}` being set
*[other] `{$flag_name_prefixed}={$extern_value}`
} in dependency `{$extern_crate}`"
)]
#[help(
"set `{$flag_name_prefixed}={$extern_value}` in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`"
"set {$has_extern_value ->
[false] `{$flag_name_prefixed}`
*[other] `{$flag_name_prefixed}={$extern_value}`
} in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`"
)]
#[help(
"if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error"
Expand All @@ -622,6 +628,7 @@ pub(crate) struct IncompatibleTargetModifiersLMissed {
pub flag_name: String,
pub flag_name_prefixed: String,
pub extern_value: String,
pub has_extern_value: bool,
}

#[derive(Diagnostic)]
Expand All @@ -630,10 +637,16 @@ pub(crate) struct IncompatibleTargetModifiersLMissed {
"the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely"
)]
#[note(
"`{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}`"
"{$has_local_value ->
[false] `{$flag_name_prefixed}` being set
*[other] `{$flag_name_prefixed}={$local_value}`
} in this crate is incompatible with `{$flag_name_prefixed}` being unset in dependency `{$extern_crate}`"
)]
#[help(
"unset `{$flag_name_prefixed}` in this crate or set `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`"
"unset `{$flag_name_prefixed}` in this crate or set {$has_local_value ->
[false] `{$flag_name_prefixed}`
*[other] `{$flag_name_prefixed}={$local_value}`
} in `{$extern_crate}`"
)]
#[help(
"if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error"
Expand All @@ -646,6 +659,7 @@ pub(crate) struct IncompatibleTargetModifiersRMissed {
pub flag_name: String,
pub flag_name_prefixed: String,
pub local_value: String,
pub has_local_value: bool,
}

#[derive(Diagnostic)]
Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ impl MetadataBlob {
"lang_items".to_owned(),
"features".to_owned(),
"items".to_owned(),
"target_modifiers".to_owned(),
];
let ls_kinds = if ls_kinds.contains(&"all".to_owned()) { &all_ls_kinds } else { ls_kinds };

Expand Down Expand Up @@ -918,11 +919,28 @@ impl MetadataBlob {

write!(out, "\n")?;
}
"target_modifiers" => {
writeln!(out, "=Target modifiers=")?;

for modifier in root.decode_target_modifiers(self) {
let extended = modifier.extend();

writeln!(
out,
"-{}{}={} [{}]",
extended.prefix,
extended.name,
modifier.value_name,
extended.tech_value,
)?;
}
}

_ => {
writeln!(
out,
"unknown -Zls kind. allowed values are: all, root, lang_items, features, items"
"unknown -Zls kind. allowed values are: all, root, lang_items, features, items, \
target_modifiers"
)?;
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ mod native_libs;
mod print_request;
pub mod sigpipe;

/// Special CPU name requesting the CPU of the current host.
pub const NATIVE_CPU: &str = "native";

/// The different settings that the `-C strip` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum Strip {
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_session/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,3 +716,17 @@ pub(crate) struct ThinLtoNotSupportedByBackend;
#[derive(Diagnostic)]
#[diag("`-Zpacked-stack` is only supported on s390x")]
pub(crate) struct UnsupportedPackedStack;

#[derive(Diagnostic)]
#[diag("`-Ctarget-cpu=native` is not allowed for target `{$target_triple}`")]
#[note("this target requires consistent `-Ctarget-cpu` values across all crates")]
#[help(
"specify the target CPU explicitly {$need_explicit_cpu ->
[false] or leave it blank to use the default
*[other] {\"\"}
}"
)]
pub(crate) struct NativeTargetCpuNotAllowed<'a> {
pub(crate) target_triple: &'a TargetTuple,
pub(crate) need_explicit_cpu: bool,
}
30 changes: 28 additions & 2 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,28 @@ mod target_modifier_consistency_check {
}
true
}
pub(super) fn target_cpu(
sess: &Session,
l: &TargetModifier,
r: Option<&TargetModifier>,
) -> bool {
if !sess.target.requires_consistent_cpu {
return true;
}
let l_tech_value = l.extend().tech_value;
let r_tech_value = match r {
Some(r) => r.extend().tech_value,
// If only one of the two compared crates specifies the CPU
// explicitly we compare against the target's default CPU.
None => {
// We reuse the same parsing logic.
CodegenOptionsTargetModifiers::TargetCpu
.reparse(sess.target.cpu.as_ref())
.tech_value
}
};
l_tech_value == r_tech_value
}
}

impl TargetModifier {
Expand All @@ -152,7 +174,11 @@ impl TargetModifier {
}
_ => {}
},
_ => {}
OptionsTargetModifiers::CodegenOptions(codegen) => match codegen {
CodegenOptionsTargetModifiers::TargetCpu => {
return target_modifier_consistency_check::target_cpu(sess, self, other);
}
},
};
match other {
Some(other) => self.extend().tech_value == other.extend().tech_value,
Expand Down Expand Up @@ -2273,7 +2299,7 @@ options! {
symbol_mangling_version: Option<SymbolManglingVersion> = (None,
parse_symbol_mangling_version, [TRACKED],
"which mangling version to use for symbol names ('legacy', 'v0' (default), or 'hashed')"),
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED] { TARGET_MODIFIER: TargetCpu },
"select target processor (`rustc --print target-cpus` for details)"),
target_feature: String = (String::new(), parse_target_feature, [TRACKED],
"target specific attributes. (`rustc --print target-features` for details). \
Expand Down
13 changes: 11 additions & 2 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ 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, InstrumentMcount, OptLevel, OutFileName, OutputType,
PointerAuthOption, SwitchWithOptPath,
FunctionReturn, Input, InstrumentCoverage, InstrumentMcount, NATIVE_CPU, OptLevel, OutFileName,
OutputType, PointerAuthOption, SwitchWithOptPath,
};
use crate::filesearch::FileSearch;
use crate::lint::LintId;
Expand Down Expand Up @@ -1695,6 +1695,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
sess.dcx().emit_err(diagnostics::UnsupportedPackedStack);
}
}

if let Some(ref cpu_name) = sess.opts.cg.target_cpu {
if cpu_name == NATIVE_CPU && sess.target.requires_consistent_cpu {
sess.dcx().emit_fatal(diagnostics::NativeTargetCpuNotAllowed {
target_triple: &sess.opts.target_triple,
need_explicit_cpu: sess.target.need_explicit_cpu,
});
}
}
}

/// Holds data on the current incremental compilation session, if there is one.
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 @@ -116,6 +116,7 @@ impl Target {
forward!(asm_args);
forward!(cpu);
forward!(need_explicit_cpu);
forward!(requires_consistent_cpu);
forward!(unsupported_cpus);
forward!(features);
forward!(dynamic_linking);
Expand Down Expand Up @@ -321,6 +322,7 @@ impl ToJson for Target {
target_option_val!(asm_args);
target_option_val!(cpu);
target_option_val!(need_explicit_cpu);
target_option_val!(requires_consistent_cpu);
target_option_val!(unsupported_cpus);
target_option_val!(features);
target_option_val!(dynamic_linking);
Expand Down Expand Up @@ -543,6 +545,7 @@ struct TargetSpecJson {
asm_args: Option<StaticCow<[StaticCow<str>]>>,
cpu: Option<StaticCow<str>>,
need_explicit_cpu: Option<bool>,
requires_consistent_cpu: Option<bool>,
unsupported_cpus: Option<StaticCow<[StaticCow<str>]>>,
features: Option<StaticCow<str>>,
dynamic_linking: Option<bool>,
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ignore-tidy-filelength
//! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131)
//!
//! Rust targets a wide variety of usecases, and in the interest of flexibility,
Expand Down Expand Up @@ -2403,6 +2404,10 @@ pub struct TargetOptions {
/// Whether a cpu needs to be explicitly set.
/// Set to true if there is no default cpu. Defaults to false.
pub need_explicit_cpu: bool,
/// Whether `-Ctarget-cpu` is treated as a target modifier. If this is set
/// all crates that are linked together must have been compiled with the
/// same target-cpu. Defaults to false.
pub requires_consistent_cpu: bool,
/// A list of CPUs that are provided by LLVM but are considered unsupported by Rust.
/// These CPUs are omitted from `--print target-cpus` output and will cause an error
/// if used with `-Ctarget-cpu`.
Expand Down Expand Up @@ -2860,6 +2865,7 @@ impl Default for TargetOptions {
asm_args: cvs![],
cpu: "generic".into(),
need_explicit_cpu: false,
requires_consistent_cpu: false,
unsupported_cpus: cvs![],
features: "".into(),
direct_access_external_data: None,
Expand Down Expand Up @@ -3636,6 +3642,14 @@ impl Target {
}
}

// Check that the target cpu constraints make sense.
if self.need_explicit_cpu {
check!(
self.requires_consistent_cpu,
"if `need_explicit_cpu` is set, then `requires_consistent_cpu` must be set"
);
}

// Check that the given target-features string makes some basic sense.
if !self.features.is_empty() {
let mut features_enabled = FxHashSet::default();
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub(crate) fn target() -> Target {
// There are many CPUs, one for each hardware generation.
// Require to set one explicitly as there is no good default.
need_explicit_cpu: true,
// crates with different `target-cpu`s are not link-compatible for amdgcn
requires_consistent_cpu: true,

max_atomic_width: Some(64),

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/targets/avr_none.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub(crate) fn target() -> Target {
atomic_cas: false,
relocation_model: RelocModel::Static,
need_explicit_cpu: true,
// crates with different `target-cpu`s are not link-compatible for AVR
requires_consistent_cpu: true,
..TargetOptions::default()
},
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub(crate) fn target() -> Target {
"sm_60", "sm_61", "sm_62"
),

// crates with different `target-cpu`s are not link-compatible for NVPTX
requires_consistent_cpu: true,

// FIXME: create tests for the atomics.
max_atomic_width: Some(64),

Expand Down
Loading
Loading