Auto merge of #124762 - madsmtm:refactor-apple-target-abi, r=lcnr,BlackHoleFox

Refactor Apple `target_abi`

This was bundled together with `Arch`, which complicated a few code paths and meant we had to do more string matching than necessary.

CC `@BlackHoleFox` as you've worked on the Apple target spec before

Related: Is there a reason why `Target`/`TargetOptions` use `StaticCow` for so many things, instead of an enum with defined values (and perhaps a catch-all case for custom target json files)? Tagging `@Nilstrieb,` as you might know?
This commit is contained in:
bors 2024-05-11 08:32:35 +00:00
commit 2259028a70
24 changed files with 103 additions and 97 deletions

View File

@ -17,14 +17,9 @@ pub enum Arch {
Arm64e,
Arm64_32,
I386,
I386_sim,
I686,
X86_64,
X86_64h,
X86_64_sim,
X86_64_macabi,
Arm64_macabi,
Arm64_sim,
}
impl Arch {
@ -32,12 +27,12 @@ impl Arch {
match self {
Armv7k => "armv7k",
Armv7s => "armv7s",
Arm64 | Arm64_macabi | Arm64_sim => "arm64",
Arm64 => "arm64",
Arm64e => "arm64e",
Arm64_32 => "arm64_32",
I386 | I386_sim => "i386",
I386 => "i386",
I686 => "i686",
X86_64 | X86_64_sim | X86_64_macabi => "x86_64",
X86_64 => "x86_64",
X86_64h => "x86_64h",
}
}
@ -45,61 +40,70 @@ impl Arch {
pub fn target_arch(self) -> Cow<'static, str> {
Cow::Borrowed(match self {
Armv7k | Armv7s => "arm",
Arm64 | Arm64e | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64",
I386 | I386_sim | I686 => "x86",
X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64",
Arm64 | Arm64e | Arm64_32 => "aarch64",
I386 | I686 => "x86",
X86_64 | X86_64h => "x86_64",
})
}
fn target_abi(self) -> &'static str {
match self {
Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
X86_64_macabi | Arm64_macabi => "macabi",
I386_sim | Arm64_sim | X86_64_sim => "sim",
}
}
fn target_cpu(self) -> &'static str {
fn target_cpu(self, abi: TargetAbi) -> &'static str {
match self {
Armv7k => "cortex-a8",
Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher.
Arm64 => "apple-a7",
Arm64 => match abi {
TargetAbi::Normal => "apple-a7",
TargetAbi::Simulator => "apple-a12",
TargetAbi::MacCatalyst => "apple-a12",
},
Arm64e => "apple-a12",
Arm64_32 => "apple-s4",
// Only macOS 10.12+ is supported, which means
// all x86_64/x86 CPUs must be running at least penryn
// https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82
I386 | I386_sim | I686 => "penryn",
X86_64 | X86_64_sim => "penryn",
X86_64_macabi => "penryn",
I386 | I686 => "penryn",
X86_64 => "penryn",
// Note: `core-avx2` is slightly more advanced than `x86_64h`, see
// comments (and disabled features) in `x86_64h_apple_darwin` for
// details. It is a higher baseline then `penryn` however.
X86_64h => "core-avx2",
Arm64_macabi => "apple-a12",
Arm64_sim => "apple-a12",
}
}
fn stack_probes(self) -> StackProbeType {
match self {
Armv7k | Armv7s => StackProbeType::None,
Arm64 | Arm64e | Arm64_32 | I386 | I386_sim | I686 | X86_64 | X86_64h | X86_64_sim
| X86_64_macabi | Arm64_macabi | Arm64_sim => StackProbeType::Inline,
Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => StackProbeType::Inline,
}
}
}
fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
#[derive(Copy, Clone, PartialEq)]
pub enum TargetAbi {
Normal,
Simulator,
MacCatalyst,
}
impl TargetAbi {
fn target_abi(self) -> &'static str {
match self {
Self::Normal => "",
Self::MacCatalyst => "macabi",
Self::Simulator => "sim",
}
}
}
fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
let platform_name: StaticCow<str> = match abi {
"sim" => format!("{os}-simulator").into(),
"macabi" => "mac-catalyst".into(),
_ => os.into(),
TargetAbi::Normal => os.into(),
TargetAbi::Simulator => format!("{os}-simulator").into(),
TargetAbi::MacCatalyst => "mac-catalyst".into(),
};
let min_version: StaticCow<str> = {
let (major, minor) = match os {
"ios" => ios_deployment_target(arch, abi),
"ios" => ios_deployment_target(arch, abi.target_abi()),
"tvos" => tvos_deployment_target(),
"watchos" => watchos_deployment_target(),
"visionos" => visionos_deployment_target(),
@ -119,7 +123,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
LinkerFlavor::Darwin(Cc::No, Lld::No),
[platform_name, min_version, sdk_version].into_iter(),
);
if abi != "macabi" {
if abi != TargetAbi::MacCatalyst {
add_link_args(
&mut args,
LinkerFlavor::Darwin(Cc::Yes, Lld::No),
@ -136,13 +140,11 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
args
}
pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
let abi = arch.target_abi();
pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions {
TargetOptions {
abi: abi.into(),
abi: abi.target_abi().into(),
os: os.into(),
cpu: arch.target_cpu().into(),
cpu: arch.target_cpu(abi).into(),
link_env_remove: link_env_remove(os),
vendor: "apple".into(),
linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No),
@ -263,8 +265,7 @@ fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> {
fn macos_default_deployment_target(arch: Arch) -> (u32, u32) {
match arch {
// Note: Arm64_sim is not included since macOS has no simulator.
Arm64 | Arm64e | Arm64_macabi => (11, 0),
Arm64 | Arm64e => (11, 0),
_ => (10, 12),
}
}

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("macos", arch);
let mut base = opts("macos", arch, TargetAbi::Normal);
base.cpu = "apple-m1".into();
base.max_atomic_width = Some(128);

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{ios_llvm_target, opts, Arch};
use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("ios", arch);
let mut base = opts("ios", arch, TargetAbi::Normal);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
Target {

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch};
use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64_macabi;
let mut base = opts("ios", arch);
let arch = Arch::Arm64;
let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
Target {

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch};
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64_sim;
let mut base = opts("ios", arch);
let arch = Arch::Arm64;
let mut base = opts("ios", arch, TargetAbi::Simulator);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
Target {

View File

@ -1,4 +1,4 @@
use crate::spec::base::apple::{opts, tvos_llvm_target, Arch};
use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};
pub fn target() -> Target {
@ -18,7 +18,7 @@ pub fn target() -> Target {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts("tvos", arch)
..opts("tvos", arch, TargetAbi::Normal)
},
}
}

View File

@ -1,8 +1,8 @@
use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch};
use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64_sim;
let arch = Arch::Arm64;
Target {
llvm_target: tvos_sim_llvm_target(arch).into(),
metadata: crate::spec::TargetMetadata {
@ -18,7 +18,7 @@ pub fn target() -> Target {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts("tvos", arch)
..opts("tvos", arch, TargetAbi::Simulator)
},
}
}

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{opts, visionos_llvm_target, Arch};
use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("visionos", arch);
let mut base = opts("visionos", arch, TargetAbi::Normal);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
Target {

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch};
use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64_sim;
let mut base = opts("visionos", arch);
let arch = Arch::Arm64;
let mut base = opts("visionos", arch, TargetAbi::Simulator);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
Target {

View File

@ -1,8 +1,8 @@
use crate::spec::base::apple::{opts, Arch};
use crate::spec::base::apple::{opts, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let base = opts("watchos", Arch::Arm64);
let base = opts("watchos", Arch::Arm64, TargetAbi::Normal);
Target {
llvm_target: "aarch64-apple-watchos".into(),
metadata: crate::spec::TargetMetadata {

View File

@ -1,8 +1,8 @@
use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch};
use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64_sim;
let arch = Arch::Arm64;
Target {
// Clang automatically chooses a more specific target based on
// WATCHOS_DEPLOYMENT_TARGET.
@ -22,7 +22,7 @@ pub fn target() -> Target {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts("watchos", arch)
..opts("watchos", arch, TargetAbi::Simulator)
},
}
}

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{opts, watchos_llvm_target, Arch};
use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64_32;
let base = opts("watchos", arch);
let base = opts("watchos", arch, TargetAbi::Normal);
Target {
llvm_target: watchos_llvm_target(arch).into(),
metadata: crate::spec::TargetMetadata {

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64e;
let mut base = opts("macos", arch);
let mut base = opts("macos", arch, TargetAbi::Normal);
base.cpu = "apple-m1".into();
base.max_atomic_width = Some(128);

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{ios_llvm_target, opts, Arch};
use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::Arm64e;
let mut base = opts("ios", arch);
let mut base = opts("ios", arch, TargetAbi::Normal);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
Target {

View File

@ -1,4 +1,4 @@
use crate::spec::base::apple::{opts, Arch};
use crate::spec::base::apple::{opts, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
@ -19,7 +19,7 @@ pub fn target() -> Target {
max_atomic_width: Some(64),
dynamic_linking: false,
position_independent_executables: true,
..opts("watchos", arch)
..opts("watchos", arch, TargetAbi::Normal)
},
}
}

View File

@ -1,4 +1,4 @@
use crate::spec::base::apple::{ios_llvm_target, opts, Arch};
use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
@ -17,7 +17,7 @@ pub fn target() -> Target {
options: TargetOptions {
features: "+v7,+vfp4,+neon".into(),
max_atomic_width: Some(64),
..opts("ios", arch)
..opts("ios", arch, TargetAbi::Normal)
},
}
}

View File

@ -1,10 +1,11 @@
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch};
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::I386;
// i386-apple-ios is a simulator target, even though it isn't declared
// that way in the target name like the other ones...
let arch = Arch::I386_sim;
let abi = TargetAbi::Simulator;
Target {
// Clang automatically chooses a more specific target based on
// IPHONEOS_DEPLOYMENT_TARGET.
@ -22,6 +23,6 @@ pub fn target() -> Target {
i128:128-f64:32:64-f80:128-n8:16:32-S128"
.into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch) },
options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch, abi) },
}
}

View File

@ -1,10 +1,10 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions};
pub fn target() -> Target {
// ld64 only understands i386 and not i686
let arch = Arch::I386;
let mut base = opts("macos", arch);
let mut base = opts("macos", arch, TargetAbi::Normal);
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
base.frame_pointer = FramePointer::Always;

View File

@ -1,10 +1,10 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::X86_64;
let mut base = opts("macos", arch);
let mut base = opts("macos", arch, TargetAbi::Normal);
base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
base.frame_pointer = FramePointer::Always;
base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);

View File

@ -1,11 +1,11 @@
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch};
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::X86_64;
// x86_64-apple-ios is a simulator target, even though it isn't declared
// that way in the target name like the other ones...
let arch = Arch::X86_64_sim;
let mut base = opts("ios", arch);
let mut base = opts("ios", arch, TargetAbi::Simulator);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
Target {

View File

@ -1,9 +1,9 @@
use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch};
use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::X86_64_macabi;
let mut base = opts("ios", arch);
let arch = Arch::X86_64;
let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
Target {

View File

@ -1,10 +1,11 @@
use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch};
use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::X86_64;
// x86_64-apple-tvos is a simulator target, even though it isn't declared
// that way in the target name like the other ones...
let arch = Arch::X86_64_sim;
let abi = TargetAbi::Simulator;
Target {
llvm_target: tvos_sim_llvm_target(arch).into(),
metadata: crate::spec::TargetMetadata {
@ -17,6 +18,6 @@ pub fn target() -> Target {
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch) },
options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch, abi) },
}
}

View File

@ -1,8 +1,8 @@
use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch};
use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::X86_64_sim;
let arch = Arch::X86_64;
Target {
llvm_target: watchos_sim_llvm_target(arch).into(),
metadata: crate::spec::TargetMetadata {
@ -15,6 +15,9 @@ pub fn target() -> Target {
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(128), ..opts("watchos", arch) },
options: TargetOptions {
max_atomic_width: Some(128),
..opts("watchos", arch, TargetAbi::Simulator)
},
}
}

View File

@ -1,10 +1,10 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch};
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let arch = Arch::X86_64h;
let mut base = opts("macos", arch);
let mut base = opts("macos", arch, TargetAbi::Normal);
base.max_atomic_width = Some(128);
base.frame_pointer = FramePointer::Always;
base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);