mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #37764 - nnethercote:shrink-scope_auxiliary, r=nikomatsakis
Remove `scope_auxiliary`. `scope_auxiliary` is a big part of the high memory usage in #36799. It's only used for MIR dumping. I have taken a hubristic approach: I have assumed that particular use is unimportant and removed `scope_auxiliary` and related things. This reduces peak RSS by ~10% for a cut-down version of the program in #36799. If that assumption is wrong perhaps we can avoid building `scope_auxiliary` unless MIR dumping is enabled.
This commit is contained in:
commit
c19cb9c12d
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -36,13 +36,6 @@ pub struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
/// see the `scope` module for more details
|
||||
scopes: Vec<scope::Scope<'tcx>>,
|
||||
|
||||
/// 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<ScopeId, ScopeAuxiliary>,
|
||||
|
||||
/// the current set of loops; see the `scope` module for more
|
||||
/// details
|
||||
loop_scopes: Vec<scope::LoopScope>,
|
||||
@ -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<Location>,
|
||||
}
|
||||
|
||||
pub type ScopeAuxiliaryVec = IndexVec<ScopeId, ScopeAuxiliary>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// 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<Item=(Ty<'gcx>, 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<UpvarDecl>,
|
||||
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,
|
||||
|
@ -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<R>
|
||||
{
|
||||
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];
|
||||
|
@ -103,11 +103,11 @@ impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
|
||||
|
||||
impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
|
||||
fn build<F>(&'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, Mir<'gcx>>(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());
|
||||
|
@ -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<Location, Vec<Annotation>>
|
||||
{
|
||||
// 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<Location, Vec<Annotation>>)
|
||||
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,
|
||||
|
@ -64,8 +64,7 @@ impl<'tcx> MirPassHook<'tcx> for DumpMir {
|
||||
is_after: is_after
|
||||
},
|
||||
src,
|
||||
mir,
|
||||
None
|
||||
mir
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user