Skip to content

Enable AutoFDO. - #87918

Merged
bors merged 1 commit into
rust-lang:masterfrom
mikebenfield:pr-afdo
Oct 8, 2021
Merged

bors merged 1 commit into
rust-lang:masterfrom
mikebenfield:pr-afdo

Conversation

@mikebenfield

Copy link
Copy Markdown
Contributor

This largely involves implementing the options debug-info-for-profiling
and profile-sample-use and forwarding them on to LLVM.

AutoFDO can be used on x86-64 Linux like this:
rustc -O -Clink-arg='Wl,--no-rosegment' -Cdebug-info-for-profiling main.rs -o main
perf record -b ./main
create_llvm_prof --binary=main --out=code.prof
rustc -O -Cprofile-sample-use=code.prof main.rs -o main2

Now main2 will have feedback directed optimization applied to it.

The create_llvm_prof tool can be obtained from this github repository:
https://github.com/google/autofdo

The option -Clink-arg='Wl,--no-rosegment' is necessary to avoid lld
putting an extra RO segment before the executable code, which would make
the binary silently incompatible with create_llvm_prof.

@rust-highfive

Copy link
Copy Markdown
Contributor

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @cjgillot (or someone else) soon.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 10, 2021
@rust-log-analyzer

This comment has been minimized.

@mikebenfield

Copy link
Copy Markdown
Contributor Author

I ran clang-format on the diff in PassWrapper.cpp, which reordered the includes. I can revert that part if desired.

@rust-log-analyzer

This comment has been minimized.

Comment thread compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp Outdated
@bjorn3

bjorn3 commented Aug 11, 2021

Copy link
Copy Markdown
Member

The option -Clink-arg='Wl,--no-rosegment' is necessary to avoid lld putting an extra RO segment before the executable code, which would make the binary silently incompatible with create_llvm_prof.

This will make read-only data executable, which depending on what program you have may or may not be a bad idea.

@mikebenfield

Copy link
Copy Markdown
Contributor Author

This will make read-only data executable, which depending on what program you have may or may not be a bad idea.

Indeed. Unfortunately it's the only way to deal with a current limitation of the create_llvm_prof tool, which can't deal with that RO segment. I've been told they plan to remove that limitation eventually, but that it won't happen in the immediate future.

@mikebenfield

Copy link
Copy Markdown
Contributor Author

Rebased, undid formatting in PassWrapper.cpp, fixed formatting in config.rs.

@mikebenfield

Copy link
Copy Markdown
Contributor Author

And fixed the commit message.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@cjgillot

Copy link
Copy Markdown
Contributor

I don't know anything about LLVM.
r? @nikic

@rust-highfive rust-highfive assigned nikic and unassigned cjgillot Aug 14, 2021
@inquisitivecrystal inquisitivecrystal added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 24, 2021
@bors

bors commented Aug 26, 2021

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #88069) made this pull request unmergeable. Please resolve the merge conflicts.

@mikebenfield

Copy link
Copy Markdown
Contributor Author

A fix is in the works for the create_llvm_prof tool so it will no longer require --no-rosegment, so I removed that from the commit message.

@mikebenfield

Copy link
Copy Markdown
Contributor Author

@nikic Would you mind taking a look at this?

@nikic nikic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty straightforward and seems to mirror what clang does. Some high-level notes:

  • New options are always introduced as unstable -Z options first, and then stabilized as -C options. You should switch the new options to use -Z and open a tracking issue for this feature.
  • Not strictly required, but adding some basic docs on how to use this to src/doc/unstable-book/src/compiler-flags wouldn't hurt. You'll find profile.md and instrument_coverage.md there for related functionality. This could basically just be what you have in your PR description, maybe with an introduction on what this is actually about (it's easy to get lost in all these profiling, coverage and instrumentation options...)
  • It would be great to have some kind of testing for this. I see that the dependence on create_llvm_prof would make an end-to-end test inconvenient. If nothing else, we can test that -Cdebuginfo-for-profiling adds the function attribute using a test in src/test/codegen.

Comment thread compiler/rustc_session/src/options.rs Outdated
Comment thread src/bootstrap/compile.rs Outdated
Comment thread compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp Outdated
Comment thread compiler/rustc_codegen_llvm/src/callee.rs Outdated
Comment thread compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp Outdated
@mikebenfield

Copy link
Copy Markdown
Contributor Author

I addressed both recent comments.

@rust-log-analyzer

This comment has been minimized.

@nikic nikic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, can you please squash the commits?

@mikebenfield

Copy link
Copy Markdown
Contributor Author

Squashed.

This largely involves implementing the options debug-info-for-profiling
and profile-sample-use and forwarding them on to LLVM.

AutoFDO can be used on x86-64 Linux like this:
rustc -O -Cdebug-info-for-profiling main.rs -o main
perf record -b ./main
create_llvm_prof --binary=main --out=code.prof
rustc -O -Cprofile-sample-use=code.prof main.rs -o main2

Now `main2` will have feedback directed optimization applied to it.

The create_llvm_prof tool can be obtained from this github repository:
https://github.com/google/autofdo

Fixes rust-lang#64892.
@mikebenfield

Copy link
Copy Markdown
Contributor Author

And fixed the commit message.

@nikic

nikic commented Oct 6, 2021

Copy link
Copy Markdown
Contributor

@bors r+

@bors

bors commented Oct 6, 2021

Copy link
Copy Markdown
Collaborator

📌 Commit a17193d has been approved by nikic

@bors

bors commented Oct 6, 2021

Copy link
Copy Markdown
Collaborator

🌲 The tree is currently closed for pull requests below priority 100. This pull request will be tested once the tree is reopened.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 6, 2021
Manishearth added a commit to Manishearth/rust that referenced this pull request Oct 7, 2021
Enable AutoFDO.

This largely involves implementing the options debug-info-for-profiling
and profile-sample-use and forwarding them on to LLVM.

AutoFDO can be used on x86-64 Linux like this:
rustc -O -Clink-arg='Wl,--no-rosegment' -Cdebug-info-for-profiling main.rs -o main
perf record -b ./main
create_llvm_prof --binary=main --out=code.prof
rustc -O -Cprofile-sample-use=code.prof main.rs -o main2

Now `main2` will have feedback directed optimization applied to it.

The create_llvm_prof tool can be obtained from this github repository:
https://github.com/google/autofdo

The option -Clink-arg='Wl,--no-rosegment' is necessary to avoid lld
putting an extra RO segment before the executable code, which would make
the binary silently incompatible with create_llvm_prof.
Manishearth added a commit to Manishearth/rust that referenced this pull request Oct 8, 2021
Enable AutoFDO.

This largely involves implementing the options debug-info-for-profiling
and profile-sample-use and forwarding them on to LLVM.

AutoFDO can be used on x86-64 Linux like this:
rustc -O -Clink-arg='Wl,--no-rosegment' -Cdebug-info-for-profiling main.rs -o main
perf record -b ./main
create_llvm_prof --binary=main --out=code.prof
rustc -O -Cprofile-sample-use=code.prof main.rs -o main2

Now `main2` will have feedback directed optimization applied to it.

The create_llvm_prof tool can be obtained from this github repository:
https://github.com/google/autofdo

The option -Clink-arg='Wl,--no-rosegment' is necessary to avoid lld
putting an extra RO segment before the executable code, which would make
the binary silently incompatible with create_llvm_prof.
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 8, 2021
…ingjubilee

Rollup of 8 pull requests

Successful merges:

 - rust-lang#87918 (Enable AutoFDO.)
 - rust-lang#88137 (On macOS, make strip="symbols" not pass any options to strip)
 - rust-lang#88772 (Fixed confusing wording on Result::map_or_else.)
 - rust-lang#89025 (Implement `#[link_ordinal(n)]`)
 - rust-lang#89082 (Implement rust-lang#85440 (Random test ordering))
 - rust-lang#89288 (Wrapper for `-Z gcc-ld=lld` to invoke rust-lld with the correct flavor)
 - rust-lang#89476 (Correct decoding of foreign expansions during incr. comp.)
 - rust-lang#89622 (Use correct edition for panic in [debug_]assert!().)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 6c2d4bf into rust-lang:master Oct 8, 2021
@rustbot rustbot added this to the 1.57.0 milestone Oct 8, 2021
jhpratt added a commit to jhpratt/rust that referenced this pull request Aug 17, 2026
…e-use-and-debug-info-for-profiling, r=folkertdev

Stabilize `-Zprofile-sample-use`

Tracking issue: rust-lang#155668

# Stabilization report

## Summary

Sample Profile-Guided Optimization (Sample PGO or SPGO) is an alternative way to perform feedback-directed optimization (FDO). Rustc already supports Instrumented PGO (with the `-Cprofile-generate` / `-Cprofile-use` flags). Downside of the instrumented approach include that it requires a separate compilation and that the instrumentation has significant runtime overhead. SPGO instead uses the output of external profilers like `perf` during the compilation process to perform more aggressive compiler optimizations. This approach is described in [this paper](https://dl.acm.org/doi/abs/10.1145/2854038.2854044).

I propose stabilizing `-Zprofile-sample-use` as `-Cprofile-sample-use`

More information can be found in the updated by the PR "Profile-guided Optimization" guide or Clang PGO [guide](https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers).

These flags are documented as:

> - `profile-sample-use`:
>
> This flag specifies the profiling data file to be used for sample-based
> profile-guided optimization (SPGO). The flag takes a mandatory argument which
> is the path to a valid `.prof` file. See the chapter on
> [profile-guided optimization] for more information.
> The `-Zdebuginfo-for-profiling` flag can be used to
> improve the quality of the profiling data.

For more details about the flag and their usage - check the Profile-guided Optimization guide [change](https://github.com/rust-lang/rust/pull/155942/changes#diff-da79c0293559274602ced76b0d50ab4d56d4eec4dcbb8b59d515b9ae94f26c42).

### What is stabilized

One compiler flag: `-Zprofile-sample-use`.

### What isn't stabilized

I think this is the right section to compare Sample-based PGO (SPGO) implementation in Rustc vs its "big brother" - Sample-based PGO in Clang.

Besides `-Zprofile-sample-use` in Rustc / `-fprofile_sample_use` in Clang and `-Zdebug-info-for-profiling` in Rustc (which we decided to **not** stabilize at the moment) / `-fdebug-info-for-profiling, -fno-debug-info-for-profiling` in Clang, Clang additionally supports the following SPGO-related switches:

* `-fpseudo-probe-for-profiling, -fno-pseudo-probe-for-profiling` [flags](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpseudo-probe-for-profiling). According to the Clang's PGO [guide](https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers), this switch is optional for SPGO. This switch has originals from an extension of SPGO that is called "Context-sensitive Sample PGO with Pseudo-Instrumentation" or simply "CSSPGO". Here is original [RFC](https://groups.google.com/g/llvm-dev/c/1p1rdYbL93s?pli=1) for the thing, also I can link some LLVM commits/discussions about the topic. This flag is not required for regular SPGO - it's just an improvement idea over regular SPGO, and could be added later to the Rustc in a different process (initially to unstable, than later promoted to stable). But that's another story and we can consider it later.
* `-f[no-]unique-internal-linkage-names` [switch](https://clang.llvm.org/docs/UsersManual.html#cmdoption-f-no-unique-internal-linkage-names) is also mentioned in the Clang PGO guide. I don't think that the switch is applicable to Rustc. Correct me if I am wrong pls.
* `-fsample-profile-use-profi, -fno-sample-profile-use-profi` [switch](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fsample-profile-use-profi). This switch is also marked as optional in the Clang PGO guide. This switch is an attempt to improve some inaccuracies in SPGO profile with some heuristics. SPGO in Rustc can be easily stabilized without this flag, since it's just a non-critical for regular SPGO usage heuristic. If we decide to add support for this switch to Rustc too - we can do in a separate activity without blocking with stabilization process. Check rust-lang#156898 for more details.
* `-fprofile-sample-accurate, -fauto-profile-accurate, -fno-profile-sample-accurate` [switch](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-sample-accurate). This switch is not mentioned even by the Clang PGO guide :) This flag resolves [this](llvm/llvm-project#63024) issue/feature request from LLVM upstream in SPGO use case. According to the description from Clang: "Specifies that the sample profile is accurate. If the sample profile is accurate, callsites without profile samples are marked as cold. Otherwise, treat callsites without profile samples as if we have no profile". Since we don't specify the flag in Rustc, branches without profile samples are now considered as branches without a profile and optimized as regular release code. Having support for this in Rustc would be definitely a nice addition to be on par with Clang, since there are good use cases for that. But I do not think that this could be a blocker for stabilization of SPGO in Rustc without this functionality - we can add it later. As a proof that SPGO in Rustc works completely okay without it you can use Rust-for-Linux bench [results](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/) with SPGO via AutoFDO.

I am not aware about any other SPGO-related flags in Clang.

We definitely have a gap in SPGO-related flags in Rustc compared to Clang, but none of these gaps is a blocker for stabilization `-Zprofile-sample-use` right now. However, it would be nice to resolve these gaps later: add them in unstable form, test, and later stabilize them to be on par with Clang from SPGO optimization perspective. Right now all the flags above are missing in Rustc even in the unstable form. Stabilization of `-Zprofile-sample-use` **does not** prevent adding all missing SPGO related features later.

## Design

### RFC history

No RFC was created for these options. All original discussions for Unstable were done in the original Unstable PR: rust-lang#87918

### Post-RFC changes

> What other user-visible changes have occurred since the RFC was accepted? Describe both changes that the lang team accepted (and link to those decisions) as well as changes that are being presented to the team for the first time in this stabilization report.

Compared to the unstable (RFC-like) state, I've made the following changes:

* I extended the Rustc's PGO [guide](https://doc.rust-lang.org/beta/rustc/profile-guided-optimization.html) with Sample-based PGO information and instructions, how to use it. This change will resolve rust-lang#117023 . My changes are highly-inspired / cautiously copy-pasted (only needed parts) from the Clang guide. From licensing perspective it should be fine. If it's a problem in any way - I can do some rewording (but I would like to avoid such things). I decided to do some documentation copy due to Sample-based PGO incompatibilities between Clang and Rustc (Clang supports more options at very least). I believe that current version is more user-friendly and easier to use, compared to just referring to the Clang PGO guide.
* I changed help message and corresponding documentation for `-Zdebug_info_for_profiling` switch to be in the same way as Clang already [has](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fdebug-info-for-profiling). It's kinda difficult to describe clearly, what the option does without exposing too much LLVM details - that's why I linked the documentation to the corresponding LLVM pass in the Reference for this option.

### Key points

No arguments were raised during stabilization discussion of the feature in any place yet, including Zulip discussion: [#t-compiler > Stabilizing Sample PGO (SPGO): &rust-lang#96;-Zprofile-sample-use&rust-lang#96;](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Stabilizing.20Sample.20PGO.20.28SPGO.29.3A.20.60-Zprofile-sample-use.60/with/590356923)

### Nightly extensions

I am not aware of any other unstable SPGO-related switches.

### Doors closed

> What doors does this stabilization close for later changes to the language? E.g., does this stabilization make any other RFCs, lang experiments, or known in-flight proposals more difficult or impossible to do later?

* Removing Sample-based PGO support from Rustc will be harder. But the technology itself is used on large scales in other ecosystems like Clang (heavily-used in big tech companies internally), and Rust-for-Linux already started to use it even with Rustc. I don't think will be a need to remove it in near future.
* Renaming flags will be harder. But current naming is done to be consistent with Clang. Clang proved robustness of this naming, so it shouldn't be a concern either.

No other proposals/experiments/etc. are affected.

## Feedback

### Call for testing

Call for testing **wasn't** done - it was slightly discussed [#t-compiler > Stabilizing Sample PGO (SPGO): &rust-lang#96;-Zprofile-sample-use&rust-lang#96; @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Stabilizing.20Sample.20PGO.20.28SPGO.29.3A.20.60-Zprofile-sample-use.60/near/590581795). However, no negative feedback was received for stabilization of this feature.

Right now this feature is already tested personally by me (local experiments with assembly changes verification before/after applying SPGO on an Intel-based (with LBR) Linux machine in some sample apps with `llvm-profgen` tool and by Rust-for-Linux project in this [patch](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/). Additionally, this feature was in unstable state for 5 years (since 2021) with no concerns (due to no bugs or no users - who knows. At least it was implemented for a reason 5 years ).

I think that's enough verification for such kind of feature.

### Nightly use

The only publicly-known user of this feature is Rust-for-Linux project (see [this](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/) commit). Besides that, no other users were found on GitHub via GitHub search for `"-Zprofile-sample-use"` query: almost all found entries are various copies of the Unstable book with the documentation for the option, and other places are related to the Linux kernel. Two found issues are related to the tracking [issue](rust-lang#155668) of these two flags, and corresponding tracking [issue](Rust-for-Linux/linux#2) in Rust-for-Linux.

I am not personally aware of any closed-source users of this feature. Probably Google (Sampled-based PGO biggest user at least for C++) and other big techs use it somewhere internally too but it's just a guess.

## Implementation

### Major parts

- rust-lang#87918 - unstable original implementation
- rust-lang#155942 - this PR, stabilization with some minor changes

No significant developments on the Rustc side - just propagating in a proper way SPGO profile to the LLVM part of the compiler.

### Coverage

* For `-Cprofile-sample-use` we have only UI tests. We haven't implemented e2e tests since it's will be hard to add them to the current test suite (see the [comment](rust-lang#155942 (comment)))

### Breaking changes

No breaking changes are expected from this stabilization.

## History

- rust-lang#87918 - initial implementation
- rust-lang#156887 - renaming `-Zdebug_info_for_profiling` into `-Zdebuginfo_for_profiling` + adding more tests for the feature (left for the history)
- rust-lang#155668 - tracking issue

## Acknowledgments

* [Michael Benfield](https://github.com/mikebenfield) - author of the original PR for Unstable
* [Jakub Beránek](https://github.com/Kobzol/) - the "PGO guy" in Rustc and `cargo-pgo` author
* [Miguel Ojeda](https://github.com/ojeda) - Rust-for-Linux maintainer (they already use Sample-based PGO in Rust-for-Linux)
* [Alexander Zaitsev](https://github.com/zamazan4ik) - me

I am not aware of any person, who is against stabilization of these two flags.

## Open items

I am not aware of any open issue, that is a blocker for stabilization of this feature.

List of SPGO-related things, which are **not** stabilization blockers in my opinion:

* rust-lang#155525 - this could improve SPGO UX with Rustc, but it's not a strict requirement - an externally-installed `llvm-profgen` can be used instead (I've tested it locally by using `llvm-profgen-21` for SPGO with Rustc 1.95, which is LLVM 22-based
jhpratt added a commit to jhpratt/rust that referenced this pull request Aug 17, 2026
…e-use-and-debug-info-for-profiling, r=folkertdev

Stabilize `-Zprofile-sample-use`

Tracking issue: rust-lang#155668

# Stabilization report

## Summary

Sample Profile-Guided Optimization (Sample PGO or SPGO) is an alternative way to perform feedback-directed optimization (FDO). Rustc already supports Instrumented PGO (with the `-Cprofile-generate` / `-Cprofile-use` flags). Downside of the instrumented approach include that it requires a separate compilation and that the instrumentation has significant runtime overhead. SPGO instead uses the output of external profilers like `perf` during the compilation process to perform more aggressive compiler optimizations. This approach is described in [this paper](https://dl.acm.org/doi/abs/10.1145/2854038.2854044).

I propose stabilizing `-Zprofile-sample-use` as `-Cprofile-sample-use`

More information can be found in the updated by the PR "Profile-guided Optimization" guide or Clang PGO [guide](https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers).

These flags are documented as:

> - `profile-sample-use`:
>
> This flag specifies the profiling data file to be used for sample-based
> profile-guided optimization (SPGO). The flag takes a mandatory argument which
> is the path to a valid `.prof` file. See the chapter on
> [profile-guided optimization] for more information.
> The `-Zdebuginfo-for-profiling` flag can be used to
> improve the quality of the profiling data.

For more details about the flag and their usage - check the Profile-guided Optimization guide [change](https://github.com/rust-lang/rust/pull/155942/changes#diff-da79c0293559274602ced76b0d50ab4d56d4eec4dcbb8b59d515b9ae94f26c42).

### What is stabilized

One compiler flag: `-Zprofile-sample-use`.

### What isn't stabilized

I think this is the right section to compare Sample-based PGO (SPGO) implementation in Rustc vs its "big brother" - Sample-based PGO in Clang.

Besides `-Zprofile-sample-use` in Rustc / `-fprofile_sample_use` in Clang and `-Zdebug-info-for-profiling` in Rustc (which we decided to **not** stabilize at the moment) / `-fdebug-info-for-profiling, -fno-debug-info-for-profiling` in Clang, Clang additionally supports the following SPGO-related switches:

* `-fpseudo-probe-for-profiling, -fno-pseudo-probe-for-profiling` [flags](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpseudo-probe-for-profiling). According to the Clang's PGO [guide](https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers), this switch is optional for SPGO. This switch has originals from an extension of SPGO that is called "Context-sensitive Sample PGO with Pseudo-Instrumentation" or simply "CSSPGO". Here is original [RFC](https://groups.google.com/g/llvm-dev/c/1p1rdYbL93s?pli=1) for the thing, also I can link some LLVM commits/discussions about the topic. This flag is not required for regular SPGO - it's just an improvement idea over regular SPGO, and could be added later to the Rustc in a different process (initially to unstable, than later promoted to stable). But that's another story and we can consider it later.
* `-f[no-]unique-internal-linkage-names` [switch](https://clang.llvm.org/docs/UsersManual.html#cmdoption-f-no-unique-internal-linkage-names) is also mentioned in the Clang PGO guide. I don't think that the switch is applicable to Rustc. Correct me if I am wrong pls.
* `-fsample-profile-use-profi, -fno-sample-profile-use-profi` [switch](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fsample-profile-use-profi). This switch is also marked as optional in the Clang PGO guide. This switch is an attempt to improve some inaccuracies in SPGO profile with some heuristics. SPGO in Rustc can be easily stabilized without this flag, since it's just a non-critical for regular SPGO usage heuristic. If we decide to add support for this switch to Rustc too - we can do in a separate activity without blocking with stabilization process. Check rust-lang#156898 for more details.
* `-fprofile-sample-accurate, -fauto-profile-accurate, -fno-profile-sample-accurate` [switch](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-sample-accurate). This switch is not mentioned even by the Clang PGO guide :) This flag resolves [this](llvm/llvm-project#63024) issue/feature request from LLVM upstream in SPGO use case. According to the description from Clang: "Specifies that the sample profile is accurate. If the sample profile is accurate, callsites without profile samples are marked as cold. Otherwise, treat callsites without profile samples as if we have no profile". Since we don't specify the flag in Rustc, branches without profile samples are now considered as branches without a profile and optimized as regular release code. Having support for this in Rustc would be definitely a nice addition to be on par with Clang, since there are good use cases for that. But I do not think that this could be a blocker for stabilization of SPGO in Rustc without this functionality - we can add it later. As a proof that SPGO in Rustc works completely okay without it you can use Rust-for-Linux bench [results](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/) with SPGO via AutoFDO.

I am not aware about any other SPGO-related flags in Clang.

We definitely have a gap in SPGO-related flags in Rustc compared to Clang, but none of these gaps is a blocker for stabilization `-Zprofile-sample-use` right now. However, it would be nice to resolve these gaps later: add them in unstable form, test, and later stabilize them to be on par with Clang from SPGO optimization perspective. Right now all the flags above are missing in Rustc even in the unstable form. Stabilization of `-Zprofile-sample-use` **does not** prevent adding all missing SPGO related features later.

## Design

### RFC history

No RFC was created for these options. All original discussions for Unstable were done in the original Unstable PR: rust-lang#87918

### Post-RFC changes

> What other user-visible changes have occurred since the RFC was accepted? Describe both changes that the lang team accepted (and link to those decisions) as well as changes that are being presented to the team for the first time in this stabilization report.

Compared to the unstable (RFC-like) state, I've made the following changes:

* I extended the Rustc's PGO [guide](https://doc.rust-lang.org/beta/rustc/profile-guided-optimization.html) with Sample-based PGO information and instructions, how to use it. This change will resolve rust-lang#117023 . My changes are highly-inspired / cautiously copy-pasted (only needed parts) from the Clang guide. From licensing perspective it should be fine. If it's a problem in any way - I can do some rewording (but I would like to avoid such things). I decided to do some documentation copy due to Sample-based PGO incompatibilities between Clang and Rustc (Clang supports more options at very least). I believe that current version is more user-friendly and easier to use, compared to just referring to the Clang PGO guide.
* I changed help message and corresponding documentation for `-Zdebug_info_for_profiling` switch to be in the same way as Clang already [has](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fdebug-info-for-profiling). It's kinda difficult to describe clearly, what the option does without exposing too much LLVM details - that's why I linked the documentation to the corresponding LLVM pass in the Reference for this option.

### Key points

No arguments were raised during stabilization discussion of the feature in any place yet, including Zulip discussion: [#t-compiler > Stabilizing Sample PGO (SPGO): &rust-lang#96;-Zprofile-sample-use&rust-lang#96;](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Stabilizing.20Sample.20PGO.20.28SPGO.29.3A.20.60-Zprofile-sample-use.60/with/590356923)

### Nightly extensions

I am not aware of any other unstable SPGO-related switches.

### Doors closed

> What doors does this stabilization close for later changes to the language? E.g., does this stabilization make any other RFCs, lang experiments, or known in-flight proposals more difficult or impossible to do later?

* Removing Sample-based PGO support from Rustc will be harder. But the technology itself is used on large scales in other ecosystems like Clang (heavily-used in big tech companies internally), and Rust-for-Linux already started to use it even with Rustc. I don't think will be a need to remove it in near future.
* Renaming flags will be harder. But current naming is done to be consistent with Clang. Clang proved robustness of this naming, so it shouldn't be a concern either.

No other proposals/experiments/etc. are affected.

## Feedback

### Call for testing

Call for testing **wasn't** done - it was slightly discussed [#t-compiler > Stabilizing Sample PGO (SPGO): &rust-lang#96;-Zprofile-sample-use&rust-lang#96; @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Stabilizing.20Sample.20PGO.20.28SPGO.29.3A.20.60-Zprofile-sample-use.60/near/590581795). However, no negative feedback was received for stabilization of this feature.

Right now this feature is already tested personally by me (local experiments with assembly changes verification before/after applying SPGO on an Intel-based (with LBR) Linux machine in some sample apps with `llvm-profgen` tool and by Rust-for-Linux project in this [patch](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/). Additionally, this feature was in unstable state for 5 years (since 2021) with no concerns (due to no bugs or no users - who knows. At least it was implemented for a reason 5 years ).

I think that's enough verification for such kind of feature.

### Nightly use

The only publicly-known user of this feature is Rust-for-Linux project (see [this](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/) commit). Besides that, no other users were found on GitHub via GitHub search for `"-Zprofile-sample-use"` query: almost all found entries are various copies of the Unstable book with the documentation for the option, and other places are related to the Linux kernel. Two found issues are related to the tracking [issue](rust-lang#155668) of these two flags, and corresponding tracking [issue](Rust-for-Linux/linux#2) in Rust-for-Linux.

I am not personally aware of any closed-source users of this feature. Probably Google (Sampled-based PGO biggest user at least for C++) and other big techs use it somewhere internally too but it's just a guess.

## Implementation

### Major parts

- rust-lang#87918 - unstable original implementation
- rust-lang#155942 - this PR, stabilization with some minor changes

No significant developments on the Rustc side - just propagating in a proper way SPGO profile to the LLVM part of the compiler.

### Coverage

* For `-Cprofile-sample-use` we have only UI tests. We haven't implemented e2e tests since it's will be hard to add them to the current test suite (see the [comment](rust-lang#155942 (comment)))

### Breaking changes

No breaking changes are expected from this stabilization.

## History

- rust-lang#87918 - initial implementation
- rust-lang#156887 - renaming `-Zdebug_info_for_profiling` into `-Zdebuginfo_for_profiling` + adding more tests for the feature (left for the history)
- rust-lang#155668 - tracking issue

## Acknowledgments

* [Michael Benfield](https://github.com/mikebenfield) - author of the original PR for Unstable
* [Jakub Beránek](https://github.com/Kobzol/) - the "PGO guy" in Rustc and `cargo-pgo` author
* [Miguel Ojeda](https://github.com/ojeda) - Rust-for-Linux maintainer (they already use Sample-based PGO in Rust-for-Linux)
* [Alexander Zaitsev](https://github.com/zamazan4ik) - me

I am not aware of any person, who is against stabilization of these two flags.

## Open items

I am not aware of any open issue, that is a blocker for stabilization of this feature.

List of SPGO-related things, which are **not** stabilization blockers in my opinion:

* rust-lang#155525 - this could improve SPGO UX with Rustc, but it's not a strict requirement - an externally-installed `llvm-profgen` can be used instead (I've tested it locally by using `llvm-profgen-21` for SPGO with Rustc 1.95, which is LLVM 22-based
rust-bors Bot pushed a commit that referenced this pull request Aug 17, 2026
Rollup merge of #155942 - zamazan4ik:stabilize-profile-sample-use-and-debug-info-for-profiling, r=folkertdev

Stabilize `-Zprofile-sample-use`

Tracking issue: #155668

# Stabilization report

## Summary

Sample Profile-Guided Optimization (Sample PGO or SPGO) is an alternative way to perform feedback-directed optimization (FDO). Rustc already supports Instrumented PGO (with the `-Cprofile-generate` / `-Cprofile-use` flags). Downside of the instrumented approach include that it requires a separate compilation and that the instrumentation has significant runtime overhead. SPGO instead uses the output of external profilers like `perf` during the compilation process to perform more aggressive compiler optimizations. This approach is described in [this paper](https://dl.acm.org/doi/abs/10.1145/2854038.2854044).

I propose stabilizing `-Zprofile-sample-use` as `-Cprofile-sample-use`

More information can be found in the updated by the PR "Profile-guided Optimization" guide or Clang PGO [guide](https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers).

These flags are documented as:

> - `profile-sample-use`:
>
> This flag specifies the profiling data file to be used for sample-based
> profile-guided optimization (SPGO). The flag takes a mandatory argument which
> is the path to a valid `.prof` file. See the chapter on
> [profile-guided optimization] for more information.
> The `-Zdebuginfo-for-profiling` flag can be used to
> improve the quality of the profiling data.

For more details about the flag and their usage - check the Profile-guided Optimization guide [change](https://github.com/rust-lang/rust/pull/155942/changes#diff-da79c0293559274602ced76b0d50ab4d56d4eec4dcbb8b59d515b9ae94f26c42).

### What is stabilized

One compiler flag: `-Zprofile-sample-use`.

### What isn't stabilized

I think this is the right section to compare Sample-based PGO (SPGO) implementation in Rustc vs its "big brother" - Sample-based PGO in Clang.

Besides `-Zprofile-sample-use` in Rustc / `-fprofile_sample_use` in Clang and `-Zdebug-info-for-profiling` in Rustc (which we decided to **not** stabilize at the moment) / `-fdebug-info-for-profiling, -fno-debug-info-for-profiling` in Clang, Clang additionally supports the following SPGO-related switches:

* `-fpseudo-probe-for-profiling, -fno-pseudo-probe-for-profiling` [flags](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpseudo-probe-for-profiling). According to the Clang's PGO [guide](https://clang.llvm.org/docs/UsersManual.html#using-sampling-profilers), this switch is optional for SPGO. This switch has originals from an extension of SPGO that is called "Context-sensitive Sample PGO with Pseudo-Instrumentation" or simply "CSSPGO". Here is original [RFC](https://groups.google.com/g/llvm-dev/c/1p1rdYbL93s?pli=1) for the thing, also I can link some LLVM commits/discussions about the topic. This flag is not required for regular SPGO - it's just an improvement idea over regular SPGO, and could be added later to the Rustc in a different process (initially to unstable, than later promoted to stable). But that's another story and we can consider it later.
* `-f[no-]unique-internal-linkage-names` [switch](https://clang.llvm.org/docs/UsersManual.html#cmdoption-f-no-unique-internal-linkage-names) is also mentioned in the Clang PGO guide. I don't think that the switch is applicable to Rustc. Correct me if I am wrong pls.
* `-fsample-profile-use-profi, -fno-sample-profile-use-profi` [switch](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fsample-profile-use-profi). This switch is also marked as optional in the Clang PGO guide. This switch is an attempt to improve some inaccuracies in SPGO profile with some heuristics. SPGO in Rustc can be easily stabilized without this flag, since it's just a non-critical for regular SPGO usage heuristic. If we decide to add support for this switch to Rustc too - we can do in a separate activity without blocking with stabilization process. Check #156898 for more details.
* `-fprofile-sample-accurate, -fauto-profile-accurate, -fno-profile-sample-accurate` [switch](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fprofile-sample-accurate). This switch is not mentioned even by the Clang PGO guide :) This flag resolves [this](llvm/llvm-project#63024) issue/feature request from LLVM upstream in SPGO use case. According to the description from Clang: "Specifies that the sample profile is accurate. If the sample profile is accurate, callsites without profile samples are marked as cold. Otherwise, treat callsites without profile samples as if we have no profile". Since we don't specify the flag in Rustc, branches without profile samples are now considered as branches without a profile and optimized as regular release code. Having support for this in Rustc would be definitely a nice addition to be on par with Clang, since there are good use cases for that. But I do not think that this could be a blocker for stabilization of SPGO in Rustc without this functionality - we can add it later. As a proof that SPGO in Rustc works completely okay without it you can use Rust-for-Linux bench [results](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/) with SPGO via AutoFDO.

I am not aware about any other SPGO-related flags in Clang.

We definitely have a gap in SPGO-related flags in Rustc compared to Clang, but none of these gaps is a blocker for stabilization `-Zprofile-sample-use` right now. However, it would be nice to resolve these gaps later: add them in unstable form, test, and later stabilize them to be on par with Clang from SPGO optimization perspective. Right now all the flags above are missing in Rustc even in the unstable form. Stabilization of `-Zprofile-sample-use` **does not** prevent adding all missing SPGO related features later.

## Design

### RFC history

No RFC was created for these options. All original discussions for Unstable were done in the original Unstable PR: #87918

### Post-RFC changes

> What other user-visible changes have occurred since the RFC was accepted? Describe both changes that the lang team accepted (and link to those decisions) as well as changes that are being presented to the team for the first time in this stabilization report.

Compared to the unstable (RFC-like) state, I've made the following changes:

* I extended the Rustc's PGO [guide](https://doc.rust-lang.org/beta/rustc/profile-guided-optimization.html) with Sample-based PGO information and instructions, how to use it. This change will resolve #117023 . My changes are highly-inspired / cautiously copy-pasted (only needed parts) from the Clang guide. From licensing perspective it should be fine. If it's a problem in any way - I can do some rewording (but I would like to avoid such things). I decided to do some documentation copy due to Sample-based PGO incompatibilities between Clang and Rustc (Clang supports more options at very least). I believe that current version is more user-friendly and easier to use, compared to just referring to the Clang PGO guide.
* I changed help message and corresponding documentation for `-Zdebug_info_for_profiling` switch to be in the same way as Clang already [has](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fdebug-info-for-profiling). It's kinda difficult to describe clearly, what the option does without exposing too much LLVM details - that's why I linked the documentation to the corresponding LLVM pass in the Reference for this option.

### Key points

No arguments were raised during stabilization discussion of the feature in any place yet, including Zulip discussion: [#t-compiler > Stabilizing Sample PGO (SPGO): `-Zprofile-sample-use`](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Stabilizing.20Sample.20PGO.20.28SPGO.29.3A.20.60-Zprofile-sample-use.60/with/590356923)

### Nightly extensions

I am not aware of any other unstable SPGO-related switches.

### Doors closed

> What doors does this stabilization close for later changes to the language? E.g., does this stabilization make any other RFCs, lang experiments, or known in-flight proposals more difficult or impossible to do later?

* Removing Sample-based PGO support from Rustc will be harder. But the technology itself is used on large scales in other ecosystems like Clang (heavily-used in big tech companies internally), and Rust-for-Linux already started to use it even with Rustc. I don't think will be a need to remove it in near future.
* Renaming flags will be harder. But current naming is done to be consistent with Clang. Clang proved robustness of this naming, so it shouldn't be a concern either.

No other proposals/experiments/etc. are affected.

## Feedback

### Call for testing

Call for testing **wasn't** done - it was slightly discussed [#t-compiler > Stabilizing Sample PGO (SPGO): `-Zprofile-sample-use` @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Stabilizing.20Sample.20PGO.20.28SPGO.29.3A.20.60-Zprofile-sample-use.60/near/590581795). However, no negative feedback was received for stabilization of this feature.

Right now this feature is already tested personally by me (local experiments with assembly changes verification before/after applying SPGO on an Intel-based (with LBR) Linux machine in some sample apps with `llvm-profgen` tool and by Rust-for-Linux project in this [patch](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/). Additionally, this feature was in unstable state for 5 years (since 2021) with no concerns (due to no bugs or no users - who knows. At least it was implemented for a reason 5 years ).

I think that's enough verification for such kind of feature.

### Nightly use

The only publicly-known user of this feature is Rust-for-Linux project (see [this](https://lore.kernel.org/rust-for-linux/20260331-autofdo-v2-1-eb5c5964820d@google.com/) commit). Besides that, no other users were found on GitHub via GitHub search for `"-Zprofile-sample-use"` query: almost all found entries are various copies of the Unstable book with the documentation for the option, and other places are related to the Linux kernel. Two found issues are related to the tracking [issue](#155668) of these two flags, and corresponding tracking [issue](Rust-for-Linux/linux#2) in Rust-for-Linux.

I am not personally aware of any closed-source users of this feature. Probably Google (Sampled-based PGO biggest user at least for C++) and other big techs use it somewhere internally too but it's just a guess.

## Implementation

### Major parts

- #87918 - unstable original implementation
- #155942 - this PR, stabilization with some minor changes

No significant developments on the Rustc side - just propagating in a proper way SPGO profile to the LLVM part of the compiler.

### Coverage

* For `-Cprofile-sample-use` we have only UI tests. We haven't implemented e2e tests since it's will be hard to add them to the current test suite (see the [comment](#155942 (comment)))

### Breaking changes

No breaking changes are expected from this stabilization.

## History

- #87918 - initial implementation
- #156887 - renaming `-Zdebug_info_for_profiling` into `-Zdebuginfo_for_profiling` + adding more tests for the feature (left for the history)
- #155668 - tracking issue

## Acknowledgments

* [Michael Benfield](https://github.com/mikebenfield) - author of the original PR for Unstable
* [Jakub Beránek](https://github.com/Kobzol/) - the "PGO guy" in Rustc and `cargo-pgo` author
* [Miguel Ojeda](https://github.com/ojeda) - Rust-for-Linux maintainer (they already use Sample-based PGO in Rust-for-Linux)
* [Alexander Zaitsev](https://github.com/zamazan4ik) - me

I am not aware of any person, who is against stabilization of these two flags.

## Open items

I am not aware of any open issue, that is a blocker for stabilization of this feature.

List of SPGO-related things, which are **not** stabilization blockers in my opinion:

* #155525 - this could improve SPGO UX with Rustc, but it's not a strict requirement - an externally-installed `llvm-profgen` can be used instead (I've tested it locally by using `llvm-profgen-21` for SPGO with Rustc 1.95, which is LLVM 22-based
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants