Skip to content

Commit 198db08

Browse files
committed
Disable BOLT, enable PGO
1 parent e0efc14 commit 198db08

File tree

1 file changed

+101
-100
lines changed

1 file changed

+101
-100
lines changed

src/tools/opt-dist/src/main.rs

+101-100
Original file line numberDiff line numberDiff line change
@@ -42,116 +42,117 @@ fn execute_pipeline(
4242
// Stage 1: Build PGO instrumented rustc
4343
// We use a normal build of LLVM, because gathering PGO profiles for LLVM and `rustc` at the
4444
// same time can cause issues, because the host and in-tree LLVM versions can diverge.
45-
// let rustc_pgo_profile = timer.section("Stage 1 (Rustc PGO)", |stage| {
46-
// let rustc_profile_dir_root = env.opt_artifacts().join("rustc-pgo");
47-
//
48-
// stage.section("Build PGO instrumented rustc and LLVM", |section| {
49-
// let mut builder = Bootstrap::build(env).rustc_pgo_instrument(&rustc_profile_dir_root);
50-
//
51-
// if env.supports_shared_llvm() {
52-
// // This first LLVM that we build will be thrown away after this stage, and it
53-
// // doesn't really need LTO. Without LTO, it builds in ~1 minute thanks to sccache,
54-
// // with LTO it takes almost 10 minutes. It makes the followup Rustc PGO
55-
// // instrumented/optimized build a bit slower, but it seems to be worth it.
56-
// builder = builder.without_llvm_lto();
57-
// }
58-
//
59-
// builder.run(section)
60-
// })?;
61-
//
62-
// let profile = stage
63-
// .section("Gather profiles", |_| gather_rustc_profiles(env, &rustc_profile_dir_root))?;
64-
// print_free_disk_space()?;
65-
//
66-
// stage.section("Build PGO optimized rustc", |section| {
67-
// Bootstrap::build(env).rustc_pgo_optimize(&profile).run(section)
68-
// })?;
69-
//
70-
// Ok(profile)
71-
// })?;
45+
let rustc_pgo_profile = timer.section("Stage 1 (Rustc PGO)", |stage| {
46+
let rustc_profile_dir_root = env.opt_artifacts().join("rustc-pgo");
47+
48+
stage.section("Build PGO instrumented rustc and LLVM", |section| {
49+
let mut builder = Bootstrap::build(env).rustc_pgo_instrument(&rustc_profile_dir_root);
50+
51+
if env.supports_shared_llvm() {
52+
// This first LLVM that we build will be thrown away after this stage, and it
53+
// doesn't really need LTO. Without LTO, it builds in ~1 minute thanks to sccache,
54+
// with LTO it takes almost 10 minutes. It makes the followup Rustc PGO
55+
// instrumented/optimized build a bit slower, but it seems to be worth it.
56+
builder = builder.without_llvm_lto();
57+
}
58+
59+
builder.run(section)
60+
})?;
61+
62+
let profile = stage
63+
.section("Gather profiles", |_| gather_rustc_profiles(env, &rustc_profile_dir_root))?;
64+
print_free_disk_space()?;
65+
66+
stage.section("Build PGO optimized rustc", |section| {
67+
Bootstrap::build(env).rustc_pgo_optimize(&profile).run(section)
68+
})?;
69+
70+
Ok(profile)
71+
})?;
7272

7373
// Stage 2: Gather LLVM PGO profiles
7474
// Here we build a PGO instrumented LLVM, reusing the previously PGO optimized rustc.
7575
// Then we use the instrumented LLVM to gather LLVM PGO profiles.
76-
// let llvm_pgo_profile = timer.section("Stage 2 (LLVM PGO)", |stage| {
77-
// Remove the previous, uninstrumented build of LLVM.
78-
// clear_llvm_files(env)?;
79-
//
80-
// let llvm_profile_dir_root = env.opt_artifacts().join("llvm-pgo");
81-
//
82-
// stage.section("Build PGO instrumented LLVM", |section| {
83-
// Bootstrap::build(env)
84-
// .llvm_pgo_instrument(&llvm_profile_dir_root)
85-
// .avoid_rustc_rebuild()
86-
// .run(section)
87-
// })?;
88-
//
89-
// let profile = stage
90-
// .section("Gather profiles", |_| gather_llvm_profiles(env, &llvm_profile_dir_root))?;
91-
//
92-
// print_free_disk_space()?;
93-
94-
// Proactively delete the instrumented artifacts, to avoid using them by accident in
95-
// follow-up stages.
96-
// clear_llvm_files(env)?;
97-
//
98-
// Ok(profile)
99-
// })?;
100-
101-
// let llvm_bolt_profile = if env.supports_bolt() {
102-
// // Stage 3: Build BOLT instrumented LLVM
103-
// // We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
104-
// // Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
105-
// // BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
106-
// // therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
107-
// timer.section("Stage 3 (LLVM BOLT)", |stage| {
108-
// stage.section("Build PGO optimized LLVM", |stage| {
109-
// Bootstrap::build(env)
110-
// .with_llvm_bolt_ldflags()
111-
// .llvm_pgo_optimize(&llvm_pgo_profile)
112-
// .avoid_rustc_rebuild()
113-
// .run(stage)
114-
// })?;
115-
//
116-
// // Find the path to the `libLLVM.so` file
117-
// let llvm_lib = io::find_file_in_dir(
118-
// &env.build_artifacts().join("stage2").join("lib"),
119-
// "libLLVM",
120-
// ".so",
121-
// )?;
122-
//
123-
// // Instrument it and gather profiles
124-
// let profile = with_bolt_instrumented(&llvm_lib, || {
125-
// stage.section("Gather profiles", |_| gather_llvm_bolt_profiles(env))
126-
// })?;
127-
// print_free_disk_space()?;
128-
//
129-
// // Now optimize the library with BOLT. The `libLLVM-XXX.so` library is actually hard-linked
130-
// // from several places, and this specific path (`llvm_lib`) will *not* be packaged into
131-
// // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
132-
// // therefore it will actually optimize all the hard links, which means that the final
133-
// // packaged `libLLVM.so` file *will* be BOLT optimized.
134-
// bolt_optimize(&llvm_lib, &profile).context("Could not optimize LLVM with BOLT")?;
135-
//
136-
// // LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
137-
// Ok(Some(profile))
138-
// })?
139-
// } else {
140-
// None
141-
// };
142-
//
143-
let mut dist = Bootstrap::dist(env, &dist_args);
144-
// .llvm_pgo_optimize(&llvm_pgo_profile)
145-
// .rustc_pgo_optimize(&rustc_pgo_profile)
146-
// .avoid_rustc_rebuild();
76+
let llvm_pgo_profile = timer.section("Stage 2 (LLVM PGO)", |stage| {
77+
// Remove the previous, uninstrumented build of LLVM.
78+
clear_llvm_files(env)?;
79+
80+
let llvm_profile_dir_root = env.opt_artifacts().join("llvm-pgo");
81+
82+
stage.section("Build PGO instrumented LLVM", |section| {
83+
Bootstrap::build(env)
84+
.llvm_pgo_instrument(&llvm_profile_dir_root)
85+
.avoid_rustc_rebuild()
86+
.run(section)
87+
})?;
88+
89+
let profile = stage
90+
.section("Gather profiles", |_| gather_llvm_profiles(env, &llvm_profile_dir_root))?;
91+
92+
print_free_disk_space()?;
93+
94+
// Proactively delete the instrumented artifacts, to avoid using them by accident in
95+
// follow-up stages.
96+
clear_llvm_files(env)?;
97+
98+
Ok(profile)
99+
})?;
100+
101+
let llvm_bolt_profile = if false {
102+
//env.supports_bolt() {
103+
// Stage 3: Build BOLT instrumented LLVM
104+
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
105+
// Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
106+
// BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
107+
// therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
108+
timer.section("Stage 3 (LLVM BOLT)", |stage| {
109+
stage.section("Build PGO optimized LLVM", |stage| {
110+
Bootstrap::build(env)
111+
.with_llvm_bolt_ldflags()
112+
.llvm_pgo_optimize(&llvm_pgo_profile)
113+
.avoid_rustc_rebuild()
114+
.run(stage)
115+
})?;
116+
117+
// Find the path to the `libLLVM.so` file
118+
let llvm_lib = io::find_file_in_dir(
119+
&env.build_artifacts().join("stage2").join("lib"),
120+
"libLLVM",
121+
".so",
122+
)?;
123+
124+
// Instrument it and gather profiles
125+
let profile = with_bolt_instrumented(&llvm_lib, || {
126+
stage.section("Gather profiles", |_| gather_llvm_bolt_profiles(env))
127+
})?;
128+
print_free_disk_space()?;
129+
130+
// Now optimize the library with BOLT. The `libLLVM-XXX.so` library is actually hard-linked
131+
// from several places, and this specific path (`llvm_lib`) will *not* be packaged into
132+
// the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
133+
// therefore it will actually optimize all the hard links, which means that the final
134+
// packaged `libLLVM.so` file *will* be BOLT optimized.
135+
bolt_optimize(&llvm_lib, &profile).context("Could not optimize LLVM with BOLT")?;
136+
137+
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
138+
Ok(Some(profile))
139+
})?
140+
} else {
141+
None
142+
};
143+
144+
let mut dist = Bootstrap::dist(env, &dist_args)
145+
.llvm_pgo_optimize(&llvm_pgo_profile)
146+
.rustc_pgo_optimize(&rustc_pgo_profile)
147+
.avoid_rustc_rebuild();
147148

148149
// if let Some(llvm_bolt_profile) = llvm_bolt_profile {
149150
// dist = dist.with_bolt_profile(llvm_bolt_profile);
150151
// }
151152

152153
// WIP
153-
std::fs::write("foo.txt", "bar")?;
154-
dist = dist.with_bolt_profile(LlvmBoltProfile("foo.txt".into()));
154+
// std::fs::write(env.opt_artifacts().join("foo.txt"), "bar")?;
155+
// dist = dist.with_bolt_profile(LlvmBoltProfile(env.opt_artifacts().join("foo.txt")));
155156

156157
// Final stage: Assemble the dist artifacts
157158
// The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.

0 commit comments

Comments
 (0)