Skip to content

Add -Z hint-mostly-unused to tell rustc that most of a crate will go unused #135656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(force_unstable_if_unmarked, true);
tracked!(function_return, FunctionReturn::ThunkExtern);
tracked!(function_sections, Some(false));
tracked!(hint_mostly_unused, true);
tracked!(human_readable_cgu_names, true);
tracked!(incremental_ignore_spans, true);
tracked!(inline_mir, Some(true));
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_mir_transform/src/cross_crate_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
_ => {}
}

// If the crate is likely to be mostly unused, use cross-crate inlining to defer codegen until
// the function is referenced, in order to skip codegen for unused functions. This is
// intentionally after the check for `inline(never)`, so that `inline(never)` wins.
if tcx.sess.opts.unstable_opts.hint_mostly_unused {
return true;
}

let sig = tcx.fn_sig(def_id).instantiate_identity();
for ty in sig.inputs().skip_binder().iter().chain(std::iter::once(&sig.output().skip_binder()))
{
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2233,6 +2233,8 @@ options! {
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
"explicitly enable the `cfg(target_thread_local)` directive"),
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],
"hint that most of this crate will go unused, to minimize work for uncalled functions"),
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
"generate human-readable, predictable names for codegen units (default: no)"),
identify_regions: bool = (false, parse_bool, [UNTRACKED],
Expand Down
33 changes: 33 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/hint-mostly-unused.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# `hint-mostly-unused`

This flag hints to the compiler that most of the crate will probably go unused.
The compiler can optimize its operation based on this assumption, in order to
compile faster. This is a hint, and does not guarantee any particular behavior.

This option can substantially speed up compilation if applied to a large
dependency where the majority of the dependency does not get used. This flag
may slow down compilation in other cases.

Currently, this option makes the compiler defer as much code generation as
possible from functions in the crate, until later crates invoke those
functions. Functions that never get invoked will never have code generated for
them. For instance, if a crate provides thousands of functions, but only a few
of them will get called, this flag will result in the compiler only doing code
generation for the called functions. (This uses the same mechanisms as
cross-crate inlining of functions.) This does not affect `extern` functions, or
functions marked as `#[inline(never)]`.

To try applying this flag to one dependency out of a dependency tree, use the
[`profile-rustflags`](https://doc.rust-lang.org/cargo/reference/unstable.html#profile-rustflags-option)
feature of nightly cargo:

```toml
cargo-features = ["profile-rustflags"]

# ...
[dependencies]
mostly-unused-dependency = "1.2.3"

[profile.release.package.mostly-unused-dependency]
rustflags = ["-Zhint-mostly-unused"]
```
Loading