Skip to content

Commit e96e15f

Browse files
committed
Add -C hint-mostly-unused to tell rustc that most of a crate will go unused
This hint allows the compiler to 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)]`. Some performance numbers, based on a crate with many dependencies having just *one* large dependency set to `-C hint-mostly-unused` (using Cargo's `profile-rustflags` option): A release build went from 4m32s to 2m06s. A non-release build went from 2m13s to 1m24s.
1 parent 73c0ae6 commit e96e15f

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ fn test_codegen_options_tracking_hash() {
615615
tracked!(embed_bitcode, false);
616616
tracked!(force_frame_pointers, FramePointer::Always);
617617
tracked!(force_unwind_tables, Some(true));
618+
tracked!(hint_mostly_unused, true);
618619
tracked!(instrument_coverage, InstrumentCoverage::Yes);
619620
tracked!(link_dead_code, Some(true));
620621
tracked!(linker_plugin_lto, LinkerPluginLto::LinkerPluginAuto);

compiler/rustc_mir_transform/src/cross_crate_inline.rs

+6
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
5050
_ => {}
5151
}
5252

53+
// If the crate is likely to be mostly unused, use cross-crate inlining to defer codegen until
54+
// the function is referenced, in order to skip codegen for unused functions.
55+
if tcx.sess.opts.cg.hint_mostly_unused {
56+
return true;
57+
}
58+
5359
let sig = tcx.fn_sig(def_id).instantiate_identity();
5460
for ty in sig.inputs().skip_binder().iter().chain(std::iter::once(&sig.output().skip_binder()))
5561
{

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,8 @@ options! {
16201620
#[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
16211621
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
16221622
"force use of unwind tables"),
1623+
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],
1624+
"hint that most of this crate will go unused, to minimize work for uncalled functions"),
16231625
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
16241626
"enable incremental compilation"),
16251627
#[rustc_lint_opt_deny_field_access("documented to do nothing")]

src/doc/rustc/src/codegen-options/index.md

+19
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,25 @@ values:
172172

173173
The default if not specified depends on the target.
174174

175+
## hint-mostly-unused
176+
177+
This flag hints to the compiler that most of the crate will probably go unused.
178+
The compiler can optimize its operation based on this assumption, in order to
179+
compile faster. This is a hint, and does not guarantee any particular behavior.
180+
181+
This option can substantially speed up compilation if applied to a large
182+
dependency where the majority of the dependency does not get used. This flag
183+
may slow down compilation in other cases.
184+
185+
Currently, this option makes the compiler defer as much code generation as
186+
possible from functions in the crate, until later crates invoke those
187+
functions. Functions that never get invoked will never have code generated for
188+
them. For instance, if a crate provides thousands of functions, but only a few
189+
of them will get called, this flag will result in the compiler only doing code
190+
generation for the called functions. (This uses the same mechanisms as
191+
cross-crate inlining of functions.) This does not affect `extern` functions, or
192+
functions marked as `#[inline(never)]`.
193+
175194
## incremental
176195

177196
This flag allows you to enable incremental compilation, which allows `rustc`

0 commit comments

Comments
 (0)