Skip to content

Commit 88723b6

Browse files
authored
Merge pull request rust-lang#19585 from Kobzol/pgo-windows
Allow training PGO on a custom crate and enable it Windows on CI
2 parents a6e7f07 + 2110265 commit 88723b6

File tree

3 files changed

+53
-11
lines changed

3 files changed

+53
-11
lines changed

src/tools/rust-analyzer/.github/workflows/release.yaml

+4-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ jobs:
2929
- os: windows-latest
3030
target: x86_64-pc-windows-msvc
3131
code-target: win32-x64
32+
pgo: clap-rs/clap
3233
- os: windows-latest
3334
target: i686-pc-windows-msvc
35+
pgo: clap-rs/clap
3436
- os: windows-latest
3537
target: aarch64-pc-windows-msvc
3638
code-target: win32-arm64
@@ -96,11 +98,11 @@ jobs:
9698
9799
- name: Dist (plain)
98100
if: ${{ !matrix.zig_target }}
99-
run: cargo xtask dist --client-patch-version ${{ github.run_number }} ${{ matrix.pgo && '--pgo' || ''}}
101+
run: cargo xtask dist --client-patch-version ${{ github.run_number }} ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}}
100102

101103
- name: Dist (using zigbuild)
102104
if: ${{ matrix.zig_target }}
103-
run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig ${{ matrix.pgo && '--pgo' || ''}}
105+
run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}}
104106

105107
- run: npm ci
106108
working-directory: editors/code

src/tools/rust-analyzer/xtask/src/dist.rs

+28-7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use time::OffsetDateTime;
1212
use xshell::{Cmd, Shell, cmd};
1313
use zip::{DateTime, ZipWriter, write::SimpleFileOptions};
1414

15+
use crate::flags::PgoTrainingCrate;
1516
use crate::{
1617
date_iso,
1718
flags::{self, Malloc},
@@ -93,7 +94,7 @@ fn dist_server(
9394
target: &Target,
9495
allocator: Malloc,
9596
zig: bool,
96-
pgo: bool,
97+
pgo: Option<PgoTrainingCrate>,
9798
) -> anyhow::Result<()> {
9899
let _e = sh.push_env("CFG_RELEASE", release);
99100
let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin");
@@ -111,11 +112,12 @@ fn dist_server(
111112
let features = allocator.to_features();
112113
let command = if linux_target && zig { "zigbuild" } else { "build" };
113114

114-
let pgo_profile = if pgo {
115+
let pgo_profile = if let Some(train_crate) = pgo {
115116
Some(gather_pgo_profile(
116117
sh,
117118
build_command(sh, command, &target_name, features),
118119
&target_name,
120+
train_crate,
119121
)?)
120122
} else {
121123
None
@@ -155,8 +157,9 @@ fn gather_pgo_profile<'a>(
155157
sh: &'a Shell,
156158
ra_build_cmd: Cmd<'a>,
157159
target: &str,
160+
train_crate: PgoTrainingCrate,
158161
) -> anyhow::Result<PathBuf> {
159-
let pgo_dir = std::path::absolute("ra-pgo-profiles")?;
162+
let pgo_dir = std::path::absolute("rust-analyzer-pgo")?;
160163
// Clear out any stale profiles
161164
if pgo_dir.is_dir() {
162165
std::fs::remove_dir_all(&pgo_dir)?;
@@ -168,18 +171,25 @@ fn gather_pgo_profile<'a>(
168171
.read()
169172
.context("cannot resolve target-libdir from rustc")?;
170173
let target_bindir = PathBuf::from(target_libdir).parent().unwrap().join("bin");
171-
let llvm_profdata = target_bindir.join(format!("llvm-profdata{}", EXE_EXTENSION));
174+
let llvm_profdata = target_bindir.join("llvm-profdata").with_extension(EXE_EXTENSION);
172175

173176
// Build RA with PGO instrumentation
174177
let cmd_gather =
175178
ra_build_cmd.env("RUSTFLAGS", format!("-Cprofile-generate={}", pgo_dir.to_str().unwrap()));
176179
cmd_gather.run().context("cannot build rust-analyzer with PGO instrumentation")?;
177180

178-
// Run RA on itself to gather profiles
179-
let train_crate = ".";
181+
let (train_path, label) = match &train_crate {
182+
PgoTrainingCrate::RustAnalyzer => (PathBuf::from("."), "itself"),
183+
PgoTrainingCrate::GitHub(url) => {
184+
(download_crate_for_training(sh, &pgo_dir, url)?, url.as_str())
185+
}
186+
};
187+
188+
// Run RA either on itself or on a downloaded crate
189+
eprintln!("Training RA on {label}...");
180190
cmd!(
181191
sh,
182-
"target/{target}/release/rust-analyzer analysis-stats {train_crate} --run-all-ide-things"
192+
"target/{target}/release/rust-analyzer analysis-stats -q --run-all-ide-things {train_path}"
183193
)
184194
.run()
185195
.context("cannot generate PGO profiles")?;
@@ -201,6 +211,17 @@ fn gather_pgo_profile<'a>(
201211
Ok(merged_profile)
202212
}
203213

214+
/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it.
215+
fn download_crate_for_training(sh: &Shell, pgo_dir: &Path, url: &str) -> anyhow::Result<PathBuf> {
216+
let normalized_path = url.replace("/", "-");
217+
let target_path = pgo_dir.join(normalized_path);
218+
cmd!(sh, "git clone --depth 1 https://github.com/{url} {target_path}")
219+
.run()
220+
.with_context(|| "cannot download PGO training crate from {url}")?;
221+
222+
Ok(target_path)
223+
}
224+
204225
fn gzip(src_path: &Path, dest_path: &Path) -> anyhow::Result<()> {
205226
let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best());
206227
let mut input = io::BufReader::new(File::open(src_path)?);

src/tools/rust-analyzer/xtask/src/flags.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ xflags::xflags! {
6060
/// Use cargo-zigbuild
6161
optional --zig
6262
/// Apply PGO optimizations
63-
optional --pgo
63+
optional --pgo pgo: PgoTrainingCrate
6464
}
6565
/// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown.
6666
cmd publish-release-notes {
@@ -143,13 +143,32 @@ pub struct RustcPush {
143143
pub branch: Option<String>,
144144
}
145145

146+
#[derive(Debug)]
147+
pub enum PgoTrainingCrate {
148+
// Use RA's own sources for PGO training
149+
RustAnalyzer,
150+
// Download a Rust crate from `https://github.com/{0}` and use it for PGO training.
151+
GitHub(String),
152+
}
153+
154+
impl FromStr for PgoTrainingCrate {
155+
type Err = String;
156+
157+
fn from_str(s: &str) -> Result<Self, Self::Err> {
158+
match s {
159+
"rust-analyzer" => Ok(Self::RustAnalyzer),
160+
url => Ok(Self::GitHub(url.to_owned())),
161+
}
162+
}
163+
}
164+
146165
#[derive(Debug)]
147166
pub struct Dist {
148167
pub mimalloc: bool,
149168
pub jemalloc: bool,
150169
pub client_patch_version: Option<String>,
151170
pub zig: bool,
152-
pub pgo: bool,
171+
pub pgo: Option<PgoTrainingCrate>,
153172
}
154173

155174
#[derive(Debug)]

0 commit comments

Comments
 (0)