Optionally don't steal the THIR
This commit is contained in:
@@ -715,6 +715,7 @@ fn test_unstable_options_tracking_hash() {
|
|||||||
untracked!(no_analysis, true);
|
untracked!(no_analysis, true);
|
||||||
untracked!(no_leak_check, true);
|
untracked!(no_leak_check, true);
|
||||||
untracked!(no_parallel_backend, true);
|
untracked!(no_parallel_backend, true);
|
||||||
|
untracked!(no_steal_thir, true);
|
||||||
untracked!(parse_crate_root_only, true);
|
untracked!(parse_crate_root_only, true);
|
||||||
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
|
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
|
||||||
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
|
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
|
||||||
|
|||||||
@@ -535,7 +535,8 @@ rustc_queries! {
|
|||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the THIR for a given body.
|
/// Fetch the THIR for a given body. The THIR body gets stolen by unsafety checking unless
|
||||||
|
/// `-Zno-steal-thir` is on.
|
||||||
query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
|
query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
|
||||||
// Perf tests revealed that hashing THIR is inefficient (see #85729).
|
// Perf tests revealed that hashing THIR is inefficient (see #85729).
|
||||||
no_hash
|
no_hash
|
||||||
|
|||||||
@@ -201,9 +201,14 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
|||||||
/// Handle closures/coroutines/inline-consts, which is unsafecked with their parent body.
|
/// Handle closures/coroutines/inline-consts, which is unsafecked with their parent body.
|
||||||
fn visit_inner_body(&mut self, def: LocalDefId) {
|
fn visit_inner_body(&mut self, def: LocalDefId) {
|
||||||
if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
|
if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
|
||||||
// Runs all other queries that depend on THIR.
|
// Run all other queries that depend on THIR.
|
||||||
self.tcx.ensure_done().mir_built(def);
|
self.tcx.ensure_done().mir_built(def);
|
||||||
let inner_thir = &inner_thir.steal();
|
let inner_thir = if self.tcx.sess.opts.unstable_opts.no_steal_thir {
|
||||||
|
&inner_thir.borrow()
|
||||||
|
} else {
|
||||||
|
// We don't have other use for the THIR. Steal it to reduce memory usage.
|
||||||
|
&inner_thir.steal()
|
||||||
|
};
|
||||||
let hir_context = self.tcx.local_def_id_to_hir_id(def);
|
let hir_context = self.tcx.local_def_id_to_hir_id(def);
|
||||||
let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe);
|
let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe);
|
||||||
let mut inner_visitor = UnsafetyVisitor {
|
let mut inner_visitor = UnsafetyVisitor {
|
||||||
@@ -1157,7 +1162,12 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
|
|||||||
let Ok((thir, expr)) = tcx.thir_body(def) else { return };
|
let Ok((thir, expr)) = tcx.thir_body(def) else { return };
|
||||||
// Runs all other queries that depend on THIR.
|
// Runs all other queries that depend on THIR.
|
||||||
tcx.ensure_done().mir_built(def);
|
tcx.ensure_done().mir_built(def);
|
||||||
let thir = &thir.steal();
|
let thir = if tcx.sess.opts.unstable_opts.no_steal_thir {
|
||||||
|
&thir.borrow()
|
||||||
|
} else {
|
||||||
|
// We don't have other use for the THIR. Steal it to reduce memory usage.
|
||||||
|
&thir.steal()
|
||||||
|
};
|
||||||
|
|
||||||
let hir_id = tcx.local_def_id_to_hir_id(def);
|
let hir_id = tcx.local_def_id_to_hir_id(def);
|
||||||
let safety_context = tcx.hir_fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
|
let safety_context = tcx.hir_fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
|
||||||
|
|||||||
@@ -2366,6 +2366,8 @@ options! {
|
|||||||
"run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
|
"run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
|
||||||
no_profiler_runtime: bool = (false, parse_no_value, [TRACKED],
|
no_profiler_runtime: bool = (false, parse_no_value, [TRACKED],
|
||||||
"prevent automatic injection of the profiler_builtins crate"),
|
"prevent automatic injection of the profiler_builtins crate"),
|
||||||
|
no_steal_thir: bool = (false, parse_bool, [UNTRACKED],
|
||||||
|
"don't steal the THIR when we're done with it; useful for rustc drivers (default: no)"),
|
||||||
no_trait_vptr: bool = (false, parse_no_value, [TRACKED],
|
no_trait_vptr: bool = (false, parse_no_value, [TRACKED],
|
||||||
"disable generation of trait vptr in vtable for upcasting"),
|
"disable generation of trait vptr in vtable for upcasting"),
|
||||||
no_unique_section_names: bool = (false, parse_bool, [TRACKED],
|
no_unique_section_names: bool = (false, parse_bool, [TRACKED],
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# `no-steal-thir`
|
||||||
|
|
||||||
|
By default, to save on memory, the THIR body (obtained from the `tcx.thir_body` query) is stolen
|
||||||
|
once no longer used. This is inconvenient for authors of rustc drivers who want to access the THIR.
|
||||||
|
|
||||||
|
This option disables the stealing. This has no observable effect on compiler behavior, only on
|
||||||
|
memory usage.
|
||||||
Reference in New Issue
Block a user