Skip to content

Commit

Permalink
Generate block containing return lazily instead
Browse files Browse the repository at this point in the history
  • Loading branch information
nagisa committed Apr 19, 2016
1 parent 1356572 commit d1180af
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
7 changes: 0 additions & 7 deletions src/librustc/mir/repr.rs
Expand Up @@ -213,13 +213,6 @@ impl BasicBlock {
BasicBlock(index as u32)
}

/// Returns a BasicBlock with index 1. This is actual end block (containing
/// the Return terminator) only during the building of MIR and should not be
/// used outside that.
pub const fn end_block() -> BasicBlock {
BasicBlock(1)
}

/// Extract the index.
pub fn index(self) -> usize {
self.0 as usize
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/build/expr/into.rs
Expand Up @@ -262,7 +262,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
};
let extent = this.extent_of_return_scope();
this.exit_scope(expr_span, extent, block, BasicBlock::end_block());
let return_block = this.return_block();
this.exit_scope(expr_span, extent, block, return_block);
this.cfg.start_new_block().unit()
}
ExprKind::Call { ty, fun, args } => {
Expand Down
50 changes: 31 additions & 19 deletions src/librustc_mir/build/mod.rs
Expand Up @@ -24,33 +24,35 @@ pub struct Builder<'a, 'tcx: 'a> {

fn_span: Span,

// the current set of scopes, updated as we traverse;
// see the `scope` module for more details
/// the current set of scopes, updated as we traverse;
/// 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.
/// 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: ScopeAuxiliaryVec,

// the current set of loops; see the `scope` module for more
// details
/// the current set of loops; see the `scope` module for more
/// details
loop_scopes: Vec<scope::LoopScope>,

// the vector of all scopes that we have created thus far;
// we track this for debuginfo later
/// the vector of all scopes that we have created thus far;
/// we track this for debuginfo later
scope_datas: Vec<ScopeData>,

var_decls: Vec<VarDecl<'tcx>>,
var_indices: FnvHashMap<ast::NodeId, u32>,
temp_decls: Vec<TempDecl<'tcx>>,
unit_temp: Option<Lvalue<'tcx>>,

// cached block with a RESUME terminator; we create this at the
// first panic
/// cached block with the RESUME terminator; this is created
/// when first set of cleanups are built.
cached_resume_block: Option<BasicBlock>,
/// cached block with the RETURN terminator
cached_return_block: Option<BasicBlock>,
}

struct CFG<'tcx> {
Expand Down Expand Up @@ -180,12 +182,10 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
var_indices: FnvHashMap(),
unit_temp: None,
cached_resume_block: None,
cached_return_block: None
};

assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
let end_block = builder.cfg.start_new_block();
assert_eq!(end_block, BasicBlock::end_block());


let mut arg_decls = None; // assigned to `Some` in closures below
let call_site_extent =
Expand All @@ -205,11 +205,12 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
block.unit()
}));

let return_block = builder.return_block();
builder.cfg.terminate(block, call_site_scope_id, span,
TerminatorKind::Goto { target: end_block });
builder.cfg.terminate(end_block, call_site_scope_id, span,
TerminatorKind::Goto { target: return_block });
builder.cfg.terminate(return_block, call_site_scope_id, span,
TerminatorKind::Return);
end_block.unit()
return_block.unit()
});

assert!(
Expand Down Expand Up @@ -290,6 +291,17 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
}
}

fn return_block(&mut self) -> BasicBlock {
match self.cached_return_block {
Some(rb) => rb,
None => {
let rb = self.cfg.start_new_block();
self.cached_return_block = Some(rb);
rb
}
}
}
}

///////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 0 additions & 1 deletion src/librustc_mir/lib.rs
Expand Up @@ -21,7 +21,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![unstable(feature = "rustc_private", issue = "27812")]

#![feature(box_patterns)]
#![feature(const_fn)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]
Expand Down

0 comments on commit d1180af

Please sign in to comment.