@@ -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