From 4bfa4ee282430de44a440695d72807f725c671ab Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 6 May 2025 10:39:34 +0200 Subject: [PATCH 1/5] WIP: Add PGO for apple darwin targets --- src/bootstrap/src/core/build_steps/compile.rs | 17 +++++++--- src/ci/github-actions/jobs.yml | 2 +- src/tools/opt-dist/src/main.rs | 32 +++++++++++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 2e5865e509695..79adf92c8a162 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1388,12 +1388,19 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect // found. This is to avoid the linker errors about undefined references to // `__llvm_profile_instrument_memop` when linking `rustc_driver`. let mut llvm_linker_flags = String::new(); - if builder.config.llvm_profile_generate && target.is_msvc() { - if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl { - // Add clang's runtime library directory to the search path - let clang_rt_dir = get_clang_cl_resource_dir(builder, clang_cl_path); - llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display())); + if builder.config.llvm_profile_generate { + if target.is_msvc() { + if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl { + // Add clang's runtime library directory to the search path + let clang_rt_dir = get_clang_cl_resource_dir(builder, clang_cl_path); + llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display())); + } + } else { + + llvm_linker_flags.push_str("-L/opt/homebrew/Cellar/llvm/20.1.2/lib/clang/20/lib/darwin/lib -lclang_rt.profile_osx"); + } + } // The config can also specify its own llvm linker flags. diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index afcc092e78e8d..37b945b5845bc 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -425,7 +425,7 @@ auto: - name: dist-aarch64-apple env: - SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin + SCRIPT: ./x.py build --set rust.debug=true opt-dist && PGO_HOST=aarch64-apple-darwin ./build/aarch64-apple-darwin/stage0-tools-bin/opt-dist mac-ci -- python3 x.py dist bootstrap --include-default-paths RUST_CONFIGURE_ARGS: >- --enable-full-tools --enable-sanitizers diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index d2827ec01ca7d..a624e439e29b4 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -109,6 +109,10 @@ enum EnvironmentCmd { #[clap(flatten)] shared: SharedArgs, }, + MacCi { + #[clap(flatten)] + shared: SharedArgs, + } } /// For a fast try build, we want to only build the bare minimum of components to get a @@ -197,6 +201,26 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> (env, shared.build_args) } + EnvironmentCmd::MacCi { shared } => { + let target_triple = + std::env::var("PGO_HOST").expect("PGO_HOST environment variable missing"); + + let checkout_dir: Utf8PathBuf = std::env::current_dir()?.try_into()?; + let env = EnvironmentBuilder::default() + .host_tuple(target_triple) + .python_binary("python3".to_string()) + .checkout_dir(checkout_dir.clone()) + .host_llvm_dir("/opt/homebrew/Cellar/llvm/20.1.2".into()) + .artifact_dir(checkout_dir.join("opt-artifacts")) + .build_dir(checkout_dir) + .shared_llvm(false) + .use_bolt(false) + .run_tests(false) + .skipped_tests(vec![]) + .build()?; + + (env, shared.build_args) + } }; Ok((env, args)) } @@ -256,6 +280,9 @@ fn execute_pipeline( // Here we build a PGO instrumented LLVM, reusing the previously PGO optimized rustc. // Then we use the instrumented LLVM to gather LLVM PGO profiles. let llvm_pgo_profile = timer.section("Stage 2 (LLVM PGO)", |stage| { + if 1 + 1 == 2 { + return Err(anyhow::anyhow!("disabled")); + } // Remove the previous, uninstrumented build of LLVM. clear_llvm_files(env)?; @@ -278,7 +305,7 @@ fn execute_pipeline( clear_llvm_files(env)?; Ok(profile) - })?; + }); let bolt_profiles = if env.use_bolt() { // Stage 3: Build BOLT instrumented LLVM @@ -290,7 +317,7 @@ fn execute_pipeline( stage.section("Build PGO optimized LLVM", |stage| { Bootstrap::build(env) .with_llvm_bolt_ldflags() - .llvm_pgo_optimize(&llvm_pgo_profile) + .llvm_pgo_optimize(&llvm_pgo_profile?) .avoid_rustc_rebuild() .run(stage) })?; @@ -342,7 +369,6 @@ fn execute_pipeline( }; let mut dist = Bootstrap::dist(env, &dist_args) - .llvm_pgo_optimize(&llvm_pgo_profile) .rustc_pgo_optimize(&rustc_pgo_profile) .avoid_rustc_rebuild(); From 1be41d2c4e13da812568c9c481233df6befa546d Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 8 May 2025 23:03:38 +0200 Subject: [PATCH 2/5] Bring back PGO for LLVM itself --- src/tools/opt-dist/src/main.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index a624e439e29b4..ab2c184d34f42 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -280,9 +280,6 @@ fn execute_pipeline( // Here we build a PGO instrumented LLVM, reusing the previously PGO optimized rustc. // Then we use the instrumented LLVM to gather LLVM PGO profiles. let llvm_pgo_profile = timer.section("Stage 2 (LLVM PGO)", |stage| { - if 1 + 1 == 2 { - return Err(anyhow::anyhow!("disabled")); - } // Remove the previous, uninstrumented build of LLVM. clear_llvm_files(env)?; @@ -305,7 +302,7 @@ fn execute_pipeline( clear_llvm_files(env)?; Ok(profile) - }); + })?; let bolt_profiles = if env.use_bolt() { // Stage 3: Build BOLT instrumented LLVM @@ -317,7 +314,7 @@ fn execute_pipeline( stage.section("Build PGO optimized LLVM", |stage| { Bootstrap::build(env) .with_llvm_bolt_ldflags() - .llvm_pgo_optimize(&llvm_pgo_profile?) + .llvm_pgo_optimize(&llvm_pgo_profile) .avoid_rustc_rebuild() .run(stage) })?; @@ -369,6 +366,7 @@ fn execute_pipeline( }; let mut dist = Bootstrap::dist(env, &dist_args) + .llvm_pgo_optimize(&llvm_pgo_profile) .rustc_pgo_optimize(&rustc_pgo_profile) .avoid_rustc_rebuild(); From 87540fe88c324821a4931e303f4e348b677e17f2 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 8 May 2025 23:39:48 +0200 Subject: [PATCH 3/5] Fix PGO lld build --- src/bootstrap/src/core/build_steps/llvm.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 86af956535e5e..9c68412f9ed45 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1037,13 +1037,18 @@ impl Step for Lld { // when doing PGO on CI, cmake or clang-cl don't automatically link clang's // profiler runtime in. In that case, we need to manually ask cmake to do it, to avoid // linking errors, much like LLVM's cmake setup does in that situation. - if builder.config.llvm_profile_generate && target.is_msvc() { - if let Some(clang_cl_path) = builder.config.llvm_clang_cl.as_ref() { - // Find clang's runtime library directory and push that as a search path to the - // cmake linker flags. - let clang_rt_dir = get_clang_cl_resource_dir(builder, clang_cl_path); - ldflags.push_all(format!("/libpath:{}", clang_rt_dir.display())); + if builder.config.llvm_profile_generate { + if target.is_msvc() { + if let Some(clang_cl_path) = builder.config.llvm_clang_cl.as_ref() { + // Find clang's runtime library directory and push that as a search path to the + // cmake linker flags. + let clang_rt_dir = get_clang_cl_resource_dir(builder, clang_cl_path); + ldflags.push_all(format!("/libpath:{}", clang_rt_dir.display())); + } + } else { + ldflags.push_all("-L/opt/homebrew/Cellar/llvm/20.1.2/lib/clang/20/lib/darwin/lib -lclang_rt.profile_osx"); } + } // LLD is built as an LLVM tool, but is distributed outside of the `llvm-tools` component, From b8c37b9889be6a408c5ea1e475f6531d1c95077f Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 9 May 2025 00:03:06 +0200 Subject: [PATCH 4/5] Fix up build post-rebase --- src/tools/opt-dist/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index ab2c184d34f42..bcb15b4fe7b0b 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -217,6 +217,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> .use_bolt(false) .run_tests(false) .skipped_tests(vec![]) + .fast_try_build(is_fast_try_build) .build()?; (env, shared.build_args) From 23451abf52dacb9caf4186a5f9438ab3be31390f Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Fri, 9 May 2025 00:03:13 +0200 Subject: [PATCH 5/5] Fix paths --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/build_steps/llvm.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 79adf92c8a162..b1143d96497e7 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1397,7 +1397,7 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect } } else { - llvm_linker_flags.push_str("-L/opt/homebrew/Cellar/llvm/20.1.2/lib/clang/20/lib/darwin/lib -lclang_rt.profile_osx"); + llvm_linker_flags.push_str("-L/opt/homebrew/Cellar/llvm/20.1.2/lib/clang/20/lib/darwin -lclang_rt.profile_osx"); } diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 9c68412f9ed45..7bdd5acfcd19d 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1046,7 +1046,7 @@ impl Step for Lld { ldflags.push_all(format!("/libpath:{}", clang_rt_dir.display())); } } else { - ldflags.push_all("-L/opt/homebrew/Cellar/llvm/20.1.2/lib/clang/20/lib/darwin/lib -lclang_rt.profile_osx"); + ldflags.push_all("-L/opt/homebrew/Cellar/llvm/20.1.2/lib/clang/20/lib/darwin -lclang_rt.profile_osx"); } }