From 051601e0f975ad6025b48775c713a37adf9911cc Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 31 Aug 2017 12:04:19 +0200 Subject: [PATCH] Add `-Z skip-end-regions` as way to side-step EndRegion emission. The main intent is to investigate cases where EndRegion emission is believed to be causing excess peak memory pressure. It may also be of use to people inspecting the MIR output who find the EndRegions to be a distraction. ---- (commit is now updated to thread the tcx down instead of consulting thread-local storage for it.) --- src/librustc/session/config.rs | 2 ++ src/librustc_mir/build/cfg.rs | 20 +++++++++++-------- src/librustc_mir/build/scope.rs | 16 ++++++++------- .../transform/clean_end_regions.rs | 4 +++- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 99fe8e60ae52b..4086e3cf071d4 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -918,6 +918,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "when debug-printing compiler state, do not include spans"), // o/w tests have closure@path identify_regions: bool = (false, parse_bool, [UNTRACKED], "make unnamed regions display as '# (where # is some non-ident unique id)"), + skip_end_regions: bool = (false, parse_bool, [UNTRACKED], + "skip EndRegion emission in MIR, skip transforms that solely process EndRegion"), borrowck_mir: bool = (false, parse_bool, [UNTRACKED], "implicitly treat functions as if they have `#[rustc_mir_borrowck]` attribute"), time_passes: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index b390e2888f26c..e92d8507f7613 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -16,6 +16,7 @@ use build::CFG; use rustc::middle::region::CodeExtent; use rustc::mir::*; +use rustc::ty; impl<'tcx> CFG<'tcx> { pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { @@ -44,14 +45,17 @@ impl<'tcx> CFG<'tcx> { self.block_data_mut(block).statements.push(statement); } - pub fn push_end_region(&mut self, - block: BasicBlock, - source_info: SourceInfo, - extent: CodeExtent) { - self.push(block, Statement { - source_info, - kind: StatementKind::EndRegion(extent), - }); + pub fn push_end_region<'a, 'gcx:'a+'tcx>(&mut self, + tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, + block: BasicBlock, + source_info: SourceInfo, + extent: CodeExtent) { + if !tcx.sess.opts.debugging_opts.skip_end_regions { + self.push(block, Statement { + source_info, + kind: StatementKind::EndRegion(extent), + }); + } } pub fn push_assign(&mut self, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 90f9c1c0d5f56..4b77cab443a38 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -89,7 +89,7 @@ should go to. use build::{BlockAnd, BlockAndExtension, Builder, CFG}; use rustc::middle::region::CodeExtent; -use rustc::ty::Ty; +use rustc::ty::{Ty, TyCtxt}; use rustc::mir::*; use rustc::mir::transform::MirSource; use syntax_pos::{Span}; @@ -359,7 +359,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.arg_count, false)); - self.cfg.push_end_region(block, extent.1, scope.extent); + self.cfg.push_end_region(self.hir.tcx(), block, extent.1, scope.extent); block.unit() } @@ -412,7 +412,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { false)); // End all regions for scopes out of which we are breaking. - self.cfg.push_end_region(block, extent.1, scope.extent); + self.cfg.push_end_region(self.hir.tcx(), block, extent.1, scope.extent); } } let scope = &self.scopes[len - scope_count]; @@ -461,7 +461,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { true)); // End all regions for scopes out of which we are breaking. - self.cfg.push_end_region(block, src_info, scope.extent); + self.cfg.push_end_region(self.hir.tcx(), block, src_info, scope.extent); } self.cfg.terminate(block, src_info, TerminatorKind::GeneratorDrop); @@ -692,7 +692,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; for scope in scopes.iter_mut() { - target = build_diverge_scope(cfg, scope.extent_span, scope, target, generator_drop); + target = build_diverge_scope( + self.hir.tcx(), cfg, scope.extent_span, scope, target, generator_drop); } Some(target) } @@ -828,7 +829,8 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>, block.unit() } -fn build_diverge_scope<'a, 'gcx, 'tcx>(cfg: &mut CFG<'tcx>, +fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + cfg: &mut CFG<'tcx>, span: Span, scope: &mut Scope<'tcx>, mut target: BasicBlock, @@ -890,7 +892,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(cfg: &mut CFG<'tcx>, // becomes trivial goto after pass that removes all EndRegions.) { let block = cfg.start_new_cleanup_block(); - cfg.push_end_region(block, source_info(span), scope.extent); + cfg.push_end_region(tcx, block, source_info(span), scope.extent); cfg.terminate(block, source_info(span), TerminatorKind::Goto { target: target }); target = block } diff --git a/src/librustc_mir/transform/clean_end_regions.rs b/src/librustc_mir/transform/clean_end_regions.rs index f06b88551d11d..a50acd84876ff 100644 --- a/src/librustc_mir/transform/clean_end_regions.rs +++ b/src/librustc_mir/transform/clean_end_regions.rs @@ -39,9 +39,11 @@ struct DeleteTrivialEndRegions<'a> { impl MirPass for CleanEndRegions { fn run_pass<'a, 'tcx>(&self, - _tcx: TyCtxt<'a, 'tcx, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, _source: MirSource, mir: &mut Mir<'tcx>) { + if tcx.sess.opts.debugging_opts.skip_end_regions { return; } + let mut gather = GatherBorrowedRegions { seen_regions: FxHashSet() };