Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIR: Do not require END_BLOCK to always exist #33030

Merged
merged 2 commits into from
Apr 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/librustc/mir/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ pub struct Mir<'tcx> {
/// where execution begins
pub const START_BLOCK: BasicBlock = BasicBlock(0);

/// where execution ends, on normal return
pub const END_BLOCK: BasicBlock = BasicBlock(1);

impl<'tcx> Mir<'tcx> {
pub fn all_basic_blocks(&self) -> Vec<BasicBlock> {
(0..self.basic_blocks.len())
Expand Down Expand Up @@ -305,8 +302,7 @@ pub enum TerminatorKind<'tcx> {
Resume,

/// Indicates a normal return. The ReturnPointer lvalue should
/// have been filled in by now. This should only occur in the
/// `END_BLOCK`.
/// have been filled in by now. This should occur at most once.
Return,

/// Drop the Lvalue
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
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, 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
Original file line number Diff line number Diff line change
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,11 +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);
assert_eq!(builder.cfg.start_new_block(), END_BLOCK);


let mut arg_decls = None; // assigned to `Some` in closures below
let call_site_extent =
Expand All @@ -204,12 +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
3 changes: 1 addition & 2 deletions src/librustc_mir/transform/remove_dead_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ pub struct RemoveDeadBlocks;
impl<'tcx> MirPass<'tcx> for RemoveDeadBlocks {
fn run_pass(&mut self, _: &TyCtxt<'tcx>, _: NodeId, mir: &mut Mir<'tcx>) {
let mut seen = BitVector::new(mir.basic_blocks.len());
// These blocks are always required.
// This block is always required.
seen.insert(START_BLOCK.index());
seen.insert(END_BLOCK.index());

let mut worklist = Vec::with_capacity(4);
worklist.push(START_BLOCK);
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_trans/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,6 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
.map(|&bb|{
if bb == mir::START_BLOCK {
fcx.new_block("start", None)
} else if bb == mir::END_BLOCK {
fcx.new_block("end", None)
} else {
fcx.new_block(&format!("{:?}", bb), None)
}
Expand Down