From d7755701ad62f2b0764f9c86b77d65e59b7c5e6f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Nov 2016 14:22:57 +1100 Subject: [PATCH] Remove `scope_auxiliary`. This reduces the peak RSS for a cut-down version of the program in #36799 by 10%, from 951MB to 856MB. --- src/librustc_mir/build/block.rs | 2 +- src/librustc_mir/build/cfg.rs | 5 --- src/librustc_mir/build/mod.rs | 60 ++++++-------------------- src/librustc_mir/build/scope.rs | 25 ++--------- src/librustc_mir/mir_map.rs | 6 +-- src/librustc_mir/pretty.rs | 58 +++---------------------- src/librustc_mir/transform/dump_mir.rs | 3 +- 7 files changed, 30 insertions(+), 129 deletions(-) diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index b53f8c4da86..2c7b47c7669 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -54,7 +54,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let tcx = this.hir.tcx(); // Enter the remainder scope, i.e. the bindings' destruction scope. - this.push_scope(remainder_scope, block); + this.push_scope(remainder_scope); let_extent_stack.push(remainder_scope); // Declare the bindings, which may create a visibility scope. diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index 9f612175e5d..71e97e4bfe0 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -40,11 +40,6 @@ impl<'tcx> CFG<'tcx> { self.block_data_mut(block).statements.push(statement); } - pub fn current_location(&mut self, block: BasicBlock) -> Location { - let index = self.block_data(block).statements.len(); - Location { block: block, statement_index: index } - } - pub fn push_assign(&mut self, block: BasicBlock, source_info: SourceInfo, diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f43181d8a61..458a952543e 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -36,13 +36,6 @@ pub struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// see the `scope` module for more details scopes: Vec>, - /// for each scope, a span of blocks that defines it; - /// we track these for use in region and borrow checking, - /// but these are liable to get out of date once optimization - /// begins. They are also hopefully temporary, and will be - /// no longer needed when we adopt graph-based regions. - scope_auxiliary: IndexVec, - /// the current set of loops; see the `scope` module for more /// details loop_scopes: Vec, @@ -82,30 +75,6 @@ impl Idx for ScopeId { } } -/// For each scope, we track the extent (from the HIR) and a -/// single-entry-multiple-exit subgraph that contains all the -/// statements/terminators within it. -/// -/// This information is separated out from the main `ScopeData` -/// because it is short-lived. First, the extent contains node-ids, -/// so it cannot be saved and re-loaded. Second, any optimization will mess up -/// the dominator/postdominator information. -/// -/// The intention is basically to use this information to do -/// regionck/borrowck and then throw it away once we are done. -pub struct ScopeAuxiliary { - /// extent of this scope from the MIR. - pub extent: CodeExtent, - - /// "entry point": dominator of all nodes in the scope - pub dom: Location, - - /// "exit points": mutual postdominators of all nodes in the scope - pub postdoms: Vec, -} - -pub type ScopeAuxiliaryVec = IndexVec; - /////////////////////////////////////////////////////////////////////////// /// The `BlockAnd` "monad" packages up the new basic block along with a /// produced value (sometimes just unit, of course). The `unpack!` @@ -158,7 +127,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, abi: Abi, return_ty: Ty<'gcx>, ast_body: &'gcx hir::Expr) - -> (Mir<'tcx>, ScopeAuxiliaryVec) + -> Mir<'tcx> where A: Iterator, Option<&'gcx hir::Pat>)> { let arguments: Vec<_> = arguments.collect(); @@ -221,15 +190,15 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, }).collect() }); - let (mut mir, aux) = builder.finish(upvar_decls, return_ty); + let mut mir = builder.finish(upvar_decls, return_ty); mir.spread_arg = spread_arg; - (mir, aux) + mir } pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, item_id: ast::NodeId, ast_expr: &'tcx hir::Expr) - -> (Mir<'tcx>, ScopeAuxiliaryVec) { + -> Mir<'tcx> { let tcx = hir.tcx(); let ty = tcx.tables().expr_ty_adjusted(ast_expr); let span = tcx.map.span(item_id); @@ -269,7 +238,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { scopes: vec![], visibility_scopes: IndexVec::new(), visibility_scope: ARGUMENT_VISIBILITY_SCOPE, - scope_auxiliary: IndexVec::new(), loop_scopes: vec![], local_decls: IndexVec::from_elem_n(LocalDecl::new_return_pointer(return_ty), 1), var_indices: NodeMap(), @@ -288,22 +256,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { fn finish(self, upvar_decls: Vec, return_ty: Ty<'tcx>) - -> (Mir<'tcx>, ScopeAuxiliaryVec) { + -> Mir<'tcx> { for (index, block) in self.cfg.basic_blocks.iter().enumerate() { if block.terminator.is_none() { span_bug!(self.fn_span, "no terminator on block {:?}", index); } } - (Mir::new(self.cfg.basic_blocks, - self.visibility_scopes, - IndexVec::new(), - return_ty, - self.local_decls, - self.arg_count, - upvar_decls, - self.fn_span - ), self.scope_auxiliary) + Mir::new(self.cfg.basic_blocks, + self.visibility_scopes, + IndexVec::new(), + return_ty, + self.local_decls, + self.arg_count, + upvar_decls, + self.fn_span + ) } fn args_and_body(&mut self, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 4af87381c70..4d9b6c0e05a 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -86,7 +86,7 @@ should go to. */ -use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary, ScopeId}; +use build::{BlockAnd, BlockAndExtension, Builder, CFG}; use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::middle::lang_items; use rustc::ty::subst::{Kind, Subst}; @@ -97,14 +97,10 @@ use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::fx::FxHashMap; pub struct Scope<'tcx> { - /// the scope-id within the scope_auxiliary - id: ScopeId, - /// The visibility scope this scope was created in. visibility_scope: VisibilityScope, - /// the extent of this scope within source code; also stored in - /// `ScopeAuxiliary`, but kept here for convenience + /// the extent of this scope within source code. extent: CodeExtent, /// Whether there's anything to do for the cleanup path, that is, @@ -276,7 +272,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd { debug!("in_scope(extent={:?}, block={:?})", extent, block); - self.push_scope(extent, block); + self.push_scope(extent); let rv = unpack!(block = f(self)); unpack!(block = self.pop_scope(extent, block)); debug!("in_scope: exiting extent={:?} block={:?}", extent, block); @@ -287,12 +283,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// scope and call `pop_scope` afterwards. Note that these two /// calls must be paired; using `in_scope` as a convenience /// wrapper maybe preferable. - pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) { + pub fn push_scope(&mut self, extent: CodeExtent) { debug!("push_scope({:?})", extent); - let id = ScopeId::new(self.scope_auxiliary.len()); let vis_scope = self.visibility_scope; self.scopes.push(Scope { - id: id, visibility_scope: vis_scope, extent: extent, needs_cleanup: false, @@ -300,11 +294,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { free: None, cached_exits: FxHashMap() }); - self.scope_auxiliary.push(ScopeAuxiliary { - extent: extent, - dom: self.cfg.current_location(entry), - postdoms: vec![] - }); } /// Pops a scope, which should have extent `extent`, adding any @@ -325,9 +314,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { &self.scopes, block, self.arg_count)); - self.scope_auxiliary[scope.id] - .postdoms - .push(self.cfg.current_location(block)); block.unit() } @@ -375,9 +361,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.cfg.terminate(block, scope.source_info(span), free); block = next; } - self.scope_auxiliary[scope.id] - .postdoms - .push(self.cfg.current_location(block)); } } let scope = &self.scopes[len - scope_count]; diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index f22a2a7ac9c..4a50585efe3 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -103,11 +103,11 @@ impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> { impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> { fn build(&'tcx mut self, f: F) - where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> (Mir<'tcx>, build::ScopeAuxiliaryVec) + where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> Mir<'tcx> { let (src, def_id) = (self.src, self.def_id); self.infcx.enter(|infcx| { - let (mut mir, scope_auxiliary) = f(Cx::new(&infcx, src)); + let mut mir = f(Cx::new(&infcx, src)); // Convert the Mir to global types. let tcx = infcx.tcx.global_tcx(); @@ -120,7 +120,7 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> { mem::transmute::>(mir) }; - pretty::dump_mir(tcx, "mir_map", &0, src, &mir, Some(&scope_auxiliary)); + pretty::dump_mir(tcx, "mir_map", &0, src, &mir); let mir = tcx.alloc_mir(mir); assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none()); diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index d6f514cfb91..e7188d53698 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use build::{ScopeAuxiliaryVec, ScopeId}; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::mir::*; @@ -43,8 +42,7 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pass_name: &str, disambiguator: &Display, src: MirSource, - mir: &Mir<'tcx>, - auxiliary: Option<&ScopeAuxiliaryVec>) { + mir: &Mir<'tcx>) { let filters = match tcx.sess.opts.debugging_opts.dump_mir { None => return, Some(ref filters) => filters, @@ -81,7 +79,7 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, writeln!(file, "// pass_name = {}", pass_name)?; writeln!(file, "// disambiguator = {}", disambiguator)?; writeln!(file, "")?; - write_mir_fn(tcx, src, mir, &mut file, auxiliary)?; + write_mir_fn(tcx, src, mir, &mut file)?; Ok(()) }); } @@ -106,52 +104,24 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, let id = tcx.map.as_local_node_id(def_id).unwrap(); let src = MirSource::from_node(tcx, id); - write_mir_fn(tcx, src, mir, w, None)?; + write_mir_fn(tcx, src, mir, w)?; for (i, mir) in mir.promoted.iter_enumerated() { writeln!(w, "")?; - write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?; + write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w)?; } } Ok(()) } -enum Annotation { - EnterScope(ScopeId), - ExitScope(ScopeId), -} - -fn scope_entry_exit_annotations(auxiliary: Option<&ScopeAuxiliaryVec>) - -> FxHashMap> -{ - // compute scope/entry exit annotations - let mut annotations = FxHashMap(); - if let Some(auxiliary) = auxiliary { - for (scope_id, auxiliary) in auxiliary.iter_enumerated() { - annotations.entry(auxiliary.dom) - .or_insert(vec![]) - .push(Annotation::EnterScope(scope_id)); - - for &loc in &auxiliary.postdoms { - annotations.entry(loc) - .or_insert(vec![]) - .push(Annotation::ExitScope(scope_id)); - } - } - } - return annotations; -} - pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &Mir<'tcx>, - w: &mut Write, - auxiliary: Option<&ScopeAuxiliaryVec>) + w: &mut Write) -> io::Result<()> { - let annotations = scope_entry_exit_annotations(auxiliary); write_mir_intro(tcx, src, mir, w)?; for block in mir.basic_blocks().indices() { - write_basic_block(tcx, block, mir, w, &annotations)?; + write_basic_block(tcx, block, mir, w)?; if block.index() + 1 != mir.basic_blocks().len() { writeln!(w, "")?; } @@ -165,8 +135,7 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn write_basic_block(tcx: TyCtxt, block: BasicBlock, mir: &Mir, - w: &mut Write, - annotations: &FxHashMap>) + w: &mut Write) -> io::Result<()> { let data = &mir[block]; @@ -176,19 +145,6 @@ fn write_basic_block(tcx: TyCtxt, // List of statements in the middle. let mut current_location = Location { block: block, statement_index: 0 }; for statement in &data.statements { - if let Some(ref annotations) = annotations.get(¤t_location) { - for annotation in annotations.iter() { - match *annotation { - Annotation::EnterScope(id) => - writeln!(w, "{0}{0}// Enter Scope({1})", - INDENT, id.index())?, - Annotation::ExitScope(id) => - writeln!(w, "{0}{0}// Exit Scope({1})", - INDENT, id.index())?, - } - } - } - let indented_mir = format!("{0}{0}{1:?};", INDENT, statement); writeln!(w, "{0:1$} // {2}", indented_mir, diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index b8fd9fb12ab..035f33de91a 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -64,8 +64,7 @@ impl<'tcx> MirPassHook<'tcx> for DumpMir { is_after: is_after }, src, - mir, - None + mir ); } }