Skip to content

Commit a454167

Browse files
committed
Auto merge of #56944 - alexcrichton:less-thin2, r=<try>
bootstrap: Link LLVM as a dylib with ThinLTO When building a distributed compiler on Linux where we use ThinLTO to create the LLVM shared object this commit switches the compiler to dynamically linking that LLVM artifact instead of statically linking to LLVM. The primary goal here is to reduce CI compile times, avoiding two+ ThinLTO builds of all of LLVM. By linking dynamically to LLVM we'll reuse the one ThinLTO step done by LLVM's build itself. Lots of discussion about this change can be found [here] and down. A perf run will show whether this is worth it or not! [here]: #53245 (comment)
2 parents 041254b + bd18a92 commit a454167

File tree

5 files changed

+17
-51
lines changed

5 files changed

+17
-51
lines changed

src/bootstrap/check.rs

-5
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ impl Step for Std {
4848
builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
4949
run_cargo(builder,
5050
&mut cargo,
51-
vec![],
5251
&libstd_stamp(builder, compiler, target),
5352
true);
5453

@@ -95,7 +94,6 @@ impl Step for Rustc {
9594
builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
9695
run_cargo(builder,
9796
&mut cargo,
98-
vec![],
9997
&librustc_stamp(builder, compiler, target),
10098
true);
10199

@@ -146,7 +144,6 @@ impl Step for CodegenBackend {
146144
let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
147145
run_cargo(builder,
148146
&mut cargo,
149-
vec![],
150147
&codegen_backend_stamp(builder, compiler, target, backend),
151148
true);
152149
}
@@ -184,7 +181,6 @@ impl Step for Test {
184181
builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
185182
run_cargo(builder,
186183
&mut cargo,
187-
vec![],
188184
&libtest_stamp(builder, compiler, target),
189185
true);
190186

@@ -232,7 +228,6 @@ impl Step for Rustdoc {
232228
println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
233229
run_cargo(builder,
234230
&mut cargo,
235-
vec![],
236231
&rustdoc_stamp(builder, compiler, target),
237232
true);
238233

src/bootstrap/compile.rs

+8-41
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use build_helper::{output, mtime, up_to_date};
2929
use filetime::FileTime;
3030
use serde_json;
3131

32+
use crate::dist;
3233
use crate::util::{exe, libdir, is_dylib};
3334
use crate::{Compiler, Mode, GitRepo};
3435
use crate::native;
@@ -114,7 +115,6 @@ impl Step for Std {
114115
&compiler.host, target));
115116
run_cargo(builder,
116117
&mut cargo,
117-
vec![],
118118
&libstd_stamp(builder, compiler, target),
119119
false);
120120

@@ -375,7 +375,6 @@ impl Step for Test {
375375
&compiler.host, target));
376376
run_cargo(builder,
377377
&mut cargo,
378-
vec![],
379378
&libtest_stamp(builder, compiler, target),
380379
false);
381380

@@ -503,7 +502,6 @@ impl Step for Rustc {
503502
compiler.stage, &compiler.host, target));
504503
run_cargo(builder,
505504
&mut cargo,
506-
vec![],
507505
&librustc_stamp(builder, compiler, target),
508506
false);
509507

@@ -646,47 +644,18 @@ impl Step for CodegenBackend {
646644

647645
let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
648646

649-
let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "rustc");
647+
let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "build");
650648
cargo.arg("--manifest-path")
651649
.arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
652650
rustc_cargo_env(builder, &mut cargo);
653651

654652
let features = build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
655653

656-
let mut cargo_tails_args = vec![];
657-
658-
if builder.config.llvm_thin_lto {
659-
cargo_tails_args.push("--".to_string());
660-
661-
let num_jobs = builder.jobs();
662-
663-
if !target.contains("msvc") {
664-
// Here we assume that the linker is clang. If it's not, there'll
665-
// be linker errors.
666-
cargo_tails_args.push("-Clink-arg=-fuse-ld=lld".to_string());
667-
cargo_tails_args.push("-Clink-arg=-flto=thin".to_string());
668-
669-
if builder.config.llvm_optimize {
670-
cargo_tails_args.push("-Clink-arg=-O2".to_string());
671-
}
672-
673-
// Let's make LLD respect the `-j` option.
674-
let num_jobs_arg = format!("-Clink-arg=-Wl,--thinlto-jobs={}", num_jobs);
675-
cargo_tails_args.push(num_jobs_arg);
676-
} else {
677-
// Here we assume that the linker is lld-link.exe. lld-link.exe
678-
// does not need the extra arguments except for num_jobs
679-
let num_jobs_arg = format!("-Clink-arg=/opt:lldltojobs={}", num_jobs);
680-
cargo_tails_args.push(num_jobs_arg);
681-
}
682-
}
683-
684654
let tmp_stamp = out_dir.join(".tmp.stamp");
685655

686656
let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
687657
let files = run_cargo(builder,
688658
cargo.arg("--features").arg(features),
689-
cargo_tails_args,
690659
&tmp_stamp,
691660
false);
692661
if builder.config.dry_run {
@@ -759,7 +728,9 @@ pub fn build_codegen_backend(builder: &Builder,
759728
"libstdc++.a");
760729
cargo.env("LLVM_STATIC_STDCPP", file);
761730
}
762-
if builder.config.llvm_link_shared {
731+
if builder.config.llvm_link_shared ||
732+
(builder.config.llvm_thin_lto && backend != "emscripten")
733+
{
763734
cargo.env("LLVM_LINK_SHARED", "1");
764735
}
765736
}
@@ -999,6 +970,8 @@ impl Step for Assemble {
999970
copy_lld_to_sysroot(builder, target_compiler, &lld_install);
1000971
}
1001972

973+
dist::maybe_install_llvm_dylib(builder, target_compiler.host, &sysroot);
974+
1002975
// Link the compiler binary itself into place
1003976
let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
1004977
let rustc = out_dir.join(exe("rustc_binary", &*host));
@@ -1025,7 +998,6 @@ pub fn add_to_sysroot(builder: &Builder, sysroot_dst: &Path, stamp: &Path) {
1025998

1026999
pub fn run_cargo(builder: &Builder,
10271000
cargo: &mut Command,
1028-
tail_args: Vec<String>,
10291001
stamp: &Path,
10301002
is_check: bool)
10311003
-> Vec<PathBuf>
@@ -1048,7 +1020,7 @@ pub fn run_cargo(builder: &Builder,
10481020
// files we need to probe for later.
10491021
let mut deps = Vec::new();
10501022
let mut toplevel = Vec::new();
1051-
let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| {
1023+
let ok = stream_cargo(builder, cargo, &mut |msg| {
10521024
let filenames = match msg {
10531025
CargoMessage::CompilerArtifact { filenames, .. } => filenames,
10541026
_ => return,
@@ -1173,7 +1145,6 @@ pub fn run_cargo(builder: &Builder,
11731145
pub fn stream_cargo(
11741146
builder: &Builder,
11751147
cargo: &mut Command,
1176-
tail_args: Vec<String>,
11771148
cb: &mut dyn FnMut(CargoMessage),
11781149
) -> bool {
11791150
if builder.config.dry_run {
@@ -1184,10 +1155,6 @@ pub fn stream_cargo(
11841155
cargo.arg("--message-format").arg("json")
11851156
.stdout(Stdio::piped());
11861157

1187-
for arg in tail_args {
1188-
cargo.arg(arg);
1189-
}
1190-
11911158
builder.verbose(&format!("running: {:?}", cargo));
11921159
let mut child = match cargo.spawn() {
11931160
Ok(child) => child,

src/bootstrap/dist.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1888,13 +1888,13 @@ impl Step for HashSign {
18881888
// LLVM tools are linked dynamically.
18891889
// Note: This function does no yet support Windows but we also don't support
18901890
// linking LLVM tools dynamically on Windows yet.
1891-
fn maybe_install_llvm_dylib(builder: &Builder,
1892-
target: Interned<String>,
1893-
image: &Path) {
1891+
pub fn maybe_install_llvm_dylib(builder: &Builder,
1892+
target: Interned<String>,
1893+
sysroot: &Path) {
18941894
let src_libdir = builder
18951895
.llvm_out(target)
18961896
.join("lib");
1897-
let dst_libdir = image.join("lib/rustlib").join(&*target).join("lib");
1897+
let dst_libdir = sysroot.join("lib/rustlib").join(&*target).join("lib");
18981898
t!(fs::create_dir_all(&dst_libdir));
18991899

19001900
if target.contains("apple-darwin") {

src/bootstrap/tool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl Step for ToolBuild {
8787
let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
8888
builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target));
8989
let mut duplicates = Vec::new();
90-
let is_expected = compile::stream_cargo(builder, &mut cargo, vec![], &mut |msg| {
90+
let is_expected = compile::stream_cargo(builder, &mut cargo, &mut |msg| {
9191
// Only care about big things like the RLS/Cargo for now
9292
match tool {
9393
| "rls"

src/librustc_llvm/build.rs

+4
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ fn main() {
142142
continue;
143143
}
144144

145+
if flag.starts_with("-flto") {
146+
continue;
147+
}
148+
145149
// -Wdate-time is not supported by the netbsd cross compiler
146150
if is_crossed && target.contains("netbsd") && flag.contains("date-time") {
147151
continue;

0 commit comments

Comments
 (0)