Skip to content

Commit d013d1a

Browse files
committed
Auto merge of rust-lang#122703 - Urgau:lazy-targets, r=<try>
Lazify more work in builtins targets This PR make some fields in `Target` and `TargetOptions` lazy. This is done in order to reduce the impact of check-cfg which needs to load all the built-ins targets but doesn't need all the fields. In particular this PR introduce a `MaybeLazy<T>` struct to support a borrowed, owned and lazy state. ~~The fields that are changed are:~~ - ~~`LinkArgs` fields (access to env + allocate): 54 023 236 ins[^1] -> 53 478 072 ins~~ - ~~`CrtObjects` fields (allocate): 53 478 072 ins -> 53 127 832 ins~~ - ~~`llvm_name` field (access to env + allocate): 53 127 832 ins -> 53 057 110 ins~~ ~~This brings around -1 000 000 ins*tructions* and -0.2/0.3ms of less wall-time (with some measurement even having the same minimum wall-time with or without check-cfg) 🎉.~~ See the latest perf run for the actual improvements, rust-lang#122703 (comment). *This PR is also a step further to completely `static`-fying all the build-in targets, if we one day we decide to do it, but that's a separate conversion.* [^1]: This is the total number of instructions as measured with `cachegrind` for the entire `rustc` invocation on a cargo --lib hello world, variance was really low (<15 000 ins). In the scale of the check-cfg feature, last time I measured `CheckCfg::fill_well_known` was around ~2.8 millions ins. r? `@petrochenkov`
2 parents af3d100 + d7ef5e6 commit d013d1a

File tree

101 files changed

+757
-439
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+757
-439
lines changed

compiler/rustc_target/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1313
#![doc(rust_logo)]
1414
#![feature(assert_matches)]
15+
#![feature(fn_traits)]
1516
#![feature(iter_intersperse)]
1617
#![feature(let_chains)]
1718
#![feature(min_exhaustive_patterns)]
1819
#![feature(rustc_attrs)]
1920
#![feature(rustdoc_internals)]
21+
#![feature(unboxed_closures)]
2022
// tidy-alphabetical-end
2123

2224
use std::path::{Path, PathBuf};

compiler/rustc_target/src/spec/base/aix.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::abi::Endian;
2-
use crate::spec::{crt_objects, cvs, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions};
2+
use crate::spec::TargetOptions;
3+
use crate::spec::{crt_objects, cvs, Cc, CodeModel, LinkOutputKind, LinkerFlavor};
34

45
pub fn opts() -> TargetOptions {
56
TargetOptions {

compiler/rustc_target/src/spec/base/apple/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{borrow::Cow, env};
22

3-
use crate::spec::{add_link_args, add_link_args_iter};
3+
use crate::spec::link_args::LazyLinkArgsState;
4+
use crate::spec::{add_link_args, add_link_args_iter, MaybeLazy};
45
use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld};
56
use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions};
67

@@ -94,7 +95,10 @@ impl TargetAbi {
9495
}
9596
}
9697

97-
fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
98+
pub(crate) type ApplePreLinkArgs =
99+
(/*os:*/ &'static str, /*arch:*/ Arch, /*abi:*/ TargetAbi);
100+
101+
pub(crate) fn pre_link_args((os, arch, abi): ApplePreLinkArgs) -> LinkArgs {
98102
let platform_name: StaticCow<str> = match abi {
99103
TargetAbi::Normal => os.into(),
100104
TargetAbi::Simulator => format!("{os}-simulator").into(),
@@ -114,7 +118,9 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
114118
};
115119
let sdk_version = min_version.clone();
116120

117-
let mut args = TargetOptions::link_args(
121+
let mut args = LinkArgs::new();
122+
add_link_args(
123+
&mut args,
118124
LinkerFlavor::Darwin(Cc::No, Lld::No),
119125
&["-arch", arch.target_name(), "-platform_version"],
120126
);
@@ -151,7 +157,7 @@ pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions {
151157
// macOS has -dead_strip, which doesn't rely on function_sections
152158
function_sections: false,
153159
dynamic_linking: true,
154-
pre_link_args: pre_link_args(os, arch, abi),
160+
pre_link_args: MaybeLazy::lazied(LazyLinkArgsState::Apple((os, arch, abi))),
155161
families: cvs!["unix"],
156162
is_like_osx: true,
157163
// LLVM notes that macOS 10.11+ and iOS 9+ default

compiler/rustc_target/src/spec/base/avr_gnu.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use object::elf;
44
/// A base target for AVR devices using the GNU toolchain.
55
///
66
/// Requires GNU avr-gcc and avr-binutils on the host system.
7-
/// FIXME: Remove the second parameter when const string concatenation is possible.
8-
pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
7+
pub fn target(target_cpu: &'static str) -> Target {
98
Target {
109
arch: "avr".into(),
1110
metadata: crate::spec::TargetMetadata {
@@ -24,7 +23,10 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
2423

2524
linker: Some("avr-gcc".into()),
2625
eh_frame_header: false,
27-
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
26+
pre_link_args: TargetOptions::link_args(
27+
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
28+
&["-mmcu=atmega328"],
29+
),
2830
late_link_args: TargetOptions::link_args(
2931
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
3032
&["-lgcc"],

compiler/rustc_target/src/spec/base/teeos.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
use crate::spec::{add_link_args, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions};
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
5-
let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
6-
7-
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
8-
add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
4+
let pre_link_args = {
5+
const LLD_ARGS: &[&str] = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
6+
const CC_ARGS: &[&str] =
7+
&["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
8+
TargetOptions::link_args_list(&[
9+
(LinkerFlavor::Gnu(Cc::No, Lld::No), LLD_ARGS),
10+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), CC_ARGS),
11+
])
12+
};
913

1014
TargetOptions {
1115
os: "teeos".into(),

compiler/rustc_target/src/spec/base/uefi_msvc.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
1010
// code runs in the same environment, no process separation is supported.
1111

12-
use crate::spec::{base, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions};
12+
use crate::spec::{base, LinkerFlavor, Lld};
13+
use crate::spec::{PanicStrategy, StackProbeType, TargetOptions};
1314

1415
pub fn opts() -> TargetOptions {
1516
let mut base = base::msvc::opts();
1617

17-
base.add_pre_link_args(
18+
base.pre_link_args = TargetOptions::link_args(
1819
LinkerFlavor::Msvc(Lld::No),
1920
&[
2021
// Non-standard subsystems have no default entry-point in PE+ files. We have to define

compiler/rustc_target/src/spec/base/wasm.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use crate::spec::{
2-
add_link_args, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel,
3-
TargetOptions, TlsModel,
4-
};
1+
use crate::spec::{cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy};
2+
use crate::spec::{RelocModel, TargetOptions, TlsModel};
53

64
pub fn options() -> TargetOptions {
75
macro_rules! args {
@@ -48,8 +46,10 @@ pub fn options() -> TargetOptions {
4846
};
4947
}
5048

51-
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));
52-
add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
49+
let pre_link_args = TargetOptions::link_args_list(&[
50+
(LinkerFlavor::WasmLld(Cc::No), args!("")),
51+
(LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")),
52+
]);
5353

5454
TargetOptions {
5555
is_like_wasm: true,

compiler/rustc_target/src/spec/base/windows_gnu.rs

+63-61
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,80 @@
1+
use crate::spec::crt_objects;
12
use crate::spec::LinkSelfContainedDefault;
2-
use crate::spec::{add_link_args, crt_objects};
33
use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
44
use std::borrow::Cow;
55

66
pub fn opts() -> TargetOptions {
7-
let mut pre_link_args = TargetOptions::link_args(
8-
LinkerFlavor::Gnu(Cc::No, Lld::No),
9-
&[
10-
// Enable ASLR
11-
"--dynamicbase",
12-
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
13-
"--disable-auto-image-base",
14-
],
15-
);
16-
add_link_args(
17-
&mut pre_link_args,
18-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
19-
&[
20-
// Tell GCC to avoid linker plugins, because we are not bundling
21-
// them with Windows installer, and Rust does its own LTO anyways.
22-
"-fno-use-linker-plugin",
23-
"-Wl,--dynamicbase",
24-
"-Wl,--disable-auto-image-base",
25-
],
26-
);
7+
let pre_link_args = TargetOptions::link_args_list(&[
8+
(
9+
LinkerFlavor::Gnu(Cc::No, Lld::No),
10+
&[
11+
// Enable ASLR
12+
"--dynamicbase",
13+
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
14+
"--disable-auto-image-base",
15+
],
16+
),
17+
(
18+
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
19+
&[
20+
// Tell GCC to avoid linker plugins, because we are not bundling
21+
// them with Windows installer, and Rust does its own LTO anyways.
22+
"-fno-use-linker-plugin",
23+
"-Wl,--dynamicbase",
24+
"-Wl,--disable-auto-image-base",
25+
],
26+
),
27+
]);
2728

28-
// Order of `late_link_args*` was found through trial and error to work with various
29-
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
30-
let mingw_libs = &[
31-
"-lmsvcrt",
32-
"-lmingwex",
33-
"-lmingw32",
34-
"-lgcc", // alas, mingw* libraries above depend on libgcc
35-
// mingw's msvcrt is a weird hybrid import library and static library.
36-
// And it seems that the linker fails to use import symbols from msvcrt
37-
// that are required from functions in msvcrt in certain cases. For example
38-
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
39-
// The library is purposely listed twice to fix that.
40-
//
41-
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
42-
"-lmsvcrt",
43-
// Math functions missing in MSVCRT (they are present in UCRT) require
44-
// this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`.
45-
"-lmingwex",
46-
"-luser32",
47-
"-lkernel32",
48-
];
49-
let mut late_link_args =
50-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
51-
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
29+
let late_link_args = {
30+
// Order of `late_link_args*` was found through trial and error to work with various
31+
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
32+
const MINGW_LIBS: &[&str] = &[
33+
"-lmsvcrt",
34+
"-lmingwex",
35+
"-lmingw32",
36+
"-lgcc", // alas, mingw* libraries above depend on libgcc
37+
// mingw's msvcrt is a weird hybrid import library and static library.
38+
// And it seems that the linker fails to use import symbols from msvcrt
39+
// that are required from functions in msvcrt in certain cases. For example
40+
// `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
41+
// The library is purposely listed twice to fix that.
42+
//
43+
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
44+
"-lmsvcrt",
45+
// Math functions missing in MSVCRT (they are present in UCRT) require
46+
// this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`.
47+
"-lmingwex",
48+
"-luser32",
49+
"-lkernel32",
50+
];
51+
TargetOptions::link_args_list(&[
52+
(LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS),
53+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS),
54+
])
55+
};
5256
// If any of our crates are dynamically linked then we need to use
5357
// the shared libgcc_s-dw2-1.dll. This is required to support
5458
// unwinding across DLL boundaries.
55-
let dynamic_unwind_libs = &["-lgcc_s"];
56-
let mut late_link_args_dynamic =
57-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
58-
add_link_args(
59-
&mut late_link_args_dynamic,
60-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
61-
dynamic_unwind_libs,
62-
);
59+
let late_link_args_dynamic = {
60+
const DYNAMIC_UNWIND_LIBS: &[&str] = &["-lgcc_s"];
61+
TargetOptions::link_args_list(&[
62+
(LinkerFlavor::Gnu(Cc::No, Lld::No), DYNAMIC_UNWIND_LIBS),
63+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), DYNAMIC_UNWIND_LIBS),
64+
])
65+
};
6366
// If all of our crates are statically linked then we can get away
6467
// with statically linking the libgcc unwinding code. This allows
6568
// binaries to be redistributed without the libgcc_s-dw2-1.dll
6669
// dependency, but unfortunately break unwinding across DLL
6770
// boundaries when unwinding across FFI boundaries.
68-
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
69-
let mut late_link_args_static =
70-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
71-
add_link_args(
72-
&mut late_link_args_static,
73-
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
74-
static_unwind_libs,
75-
);
71+
let late_link_args_static = {
72+
const STATIC_UNWIND_LIBS: &[&str] = &["-lgcc_eh", "-l:libpthread.a"];
73+
TargetOptions::link_args_list(&[
74+
(LinkerFlavor::Gnu(Cc::No, Lld::No), STATIC_UNWIND_LIBS),
75+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), STATIC_UNWIND_LIBS),
76+
])
77+
};
7678

7779
TargetOptions {
7880
os: "windows".into(),

compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs

+21-18
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
use crate::spec::{add_link_args, base, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions};
1+
use crate::spec::{base, Cc, LinkerFlavor, Lld, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
44
let base = base::windows_gnu::opts();
55

6-
// FIXME: This should be updated for the exception machinery changes from #67502
7-
// and inherit from `windows_gnu_base`, at least partially.
8-
let mingw_libs = &[
9-
"-lwinstorecompat",
10-
"-lruntimeobject",
11-
"-lsynchronization",
12-
"-lvcruntime140_app",
13-
"-lucrt",
14-
"-lwindowsapp",
15-
"-lmingwex",
16-
"-lmingw32",
17-
];
18-
let mut late_link_args =
19-
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
20-
add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
6+
let late_link_args = {
7+
// FIXME: This should be updated for the exception machinery changes from #67502
8+
// and inherit from `windows_gnu_base`, at least partially.
9+
const MINGW_LIBS: &[&str] = &[
10+
"-lwinstorecompat",
11+
"-lruntimeobject",
12+
"-lsynchronization",
13+
"-lvcruntime140_app",
14+
"-lucrt",
15+
"-lwindowsapp",
16+
"-lmingwex",
17+
"-lmingw32",
18+
];
19+
TargetOptions::link_args_list(&[
20+
(LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS),
21+
(LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS),
22+
])
23+
};
2124
// Reset the flags back to empty until the FIXME above is addressed.
22-
let late_link_args_dynamic = LinkArgs::new();
23-
let late_link_args_static = LinkArgs::new();
25+
let late_link_args_dynamic = Default::default();
26+
let late_link_args_static = Default::default();
2427

2528
TargetOptions {
2629
abi: "uwp".into(),

compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ pub fn opts() -> TargetOptions {
55

66
opts.abi = "uwp".into();
77
opts.vendor = "uwp".into();
8-
opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]);
8+
opts.pre_link_args =
9+
TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]);
910

1011
opts
1112
}

0 commit comments

Comments
 (0)