From f1c721caa723fd2a685db673003dc31b8e606e26 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 31 Aug 2017 12:04:19 +0200 Subject: [PATCH] Skip EndRegion emission by default. Use `-Z emit-end-regions` to reenable it. The main intent is to fix cases where EndRegion emission is believed to be causing excess peak memory pressure. It may also be a welcome change to people inspecting the MIR output who find the EndRegions to be a distraction. --- src/librustc/session/config.rs | 2 ++ src/librustc_mir/build/cfg.rs | 20 +++++++++++-------- src/librustc_mir/build/scope.rs | 15 +++++++------- .../transform/clean_end_regions.rs | 4 +++- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b538c6a6eca7..577c905a1d5a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -919,6 +919,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)"), + emit_end_regions: bool = (false, parse_bool, [UNTRACKED], + "emit EndRegion as part of MIR; enable 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 d77fe5170e04..859a1000ebe1 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; 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, - region_scope: region::Scope) { - self.push(block, Statement { - source_info, - kind: StatementKind::EndRegion(region_scope), - }); + pub fn push_end_region<'a, 'gcx:'a+'tcx>(&mut self, + tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, + block: BasicBlock, + source_info: SourceInfo, + region_scope: region::Scope) { + if tcx.sess.opts.debugging_opts.emit_end_regions { + self.push(block, Statement { + source_info, + kind: StatementKind::EndRegion(region_scope), + }); + } } pub fn push_assign(&mut self, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index ed598c876f3e..c08620c1e410 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; -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, region_scope.1, scope.region_scope); + self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope); block.unit() } @@ -414,7 +414,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, region_scope.1, scope.region_scope); + self.cfg.push_end_region(self.hir.tcx(), block, region_scope.1, scope.region_scope); } } let scope = &self.scopes[len - scope_count]; @@ -463,7 +463,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.region_scope); + self.cfg.push_end_region(self.hir.tcx(), block, src_info, scope.region_scope); } self.cfg.terminate(block, src_info, TerminatorKind::GeneratorDrop); @@ -694,7 +694,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; for scope in scopes.iter_mut() { - target = build_diverge_scope(cfg, scope.region_scope_span, + target = build_diverge_scope(self.hir.tcx(), cfg, scope.region_scope_span, scope, target, generator_drop); } Some(target) @@ -831,7 +831,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, @@ -893,7 +894,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.region_scope); + cfg.push_end_region(tcx, block, source_info(span), scope.region_scope); 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 55a16b2f3916..4e4698457c37 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.emit_end_regions { return; } + let mut gather = GatherBorrowedRegions { seen_regions: FxHashSet() };