Skip to content

Commit 6e03608

Browse files
committed
Auto merge of #33030 - nagisa:mir-unrequire-end-block, r=nikomatsakis
MIR: Do not require END_BLOCK to always exist Basically, all this does, is removing restriction for END_BLOCK to exist past the first invocation of RemoveDeadBlocks pass. This way for functions whose CFG does not reach the `END_BLOCK` end up not containing the block. As far as the implementation goes, I’m not entirely satisfied with the `BasicBlock::end_block`. I had hoped to make `new` a `const fn` and then just have a `const END_BLOCK` private to mir::build, but it turns out that constant functions don’t yet support conditionals nor a way to assert.
2 parents 95545e7 + d1180af commit 6e03608

File tree

5 files changed

+35
-29
lines changed

5 files changed

+35
-29
lines changed

src/librustc/mir/repr.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ pub struct Mir<'tcx> {
6363
/// where execution begins
6464
pub const START_BLOCK: BasicBlock = BasicBlock(0);
6565

66-
/// where execution ends, on normal return
67-
pub const END_BLOCK: BasicBlock = BasicBlock(1);
68-
6966
impl<'tcx> Mir<'tcx> {
7067
pub fn all_basic_blocks(&self) -> Vec<BasicBlock> {
7168
(0..self.basic_blocks.len())
@@ -322,8 +319,7 @@ pub enum TerminatorKind<'tcx> {
322319
Resume,
323320

324321
/// Indicates a normal return. The ReturnPointer lvalue should
325-
/// have been filled in by now. This should only occur in the
326-
/// `END_BLOCK`.
322+
/// have been filled in by now. This should occur at most once.
327323
Return,
328324

329325
/// Drop the Lvalue

src/librustc_mir/build/expr/into.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
262262
}
263263
};
264264
let extent = this.extent_of_return_scope();
265-
this.exit_scope(expr_span, extent, block, END_BLOCK);
265+
let return_block = this.return_block();
266+
this.exit_scope(expr_span, extent, block, return_block);
266267
this.cfg.start_new_block().unit()
267268
}
268269
ExprKind::Call { ty, fun, args } => {

src/librustc_mir/build/mod.rs

+31-19
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,35 @@ pub struct Builder<'a, 'tcx: 'a> {
2626

2727
fn_span: Span,
2828

29-
// the current set of scopes, updated as we traverse;
30-
// see the `scope` module for more details
29+
/// the current set of scopes, updated as we traverse;
30+
/// see the `scope` module for more details
3131
scopes: Vec<scope::Scope<'tcx>>,
3232

33-
// for each scope, a span of blocks that defines it;
34-
// we track these for use in region and borrow checking,
35-
// but these are liable to get out of date once optimization
36-
// begins. They are also hopefully temporary, and will be
37-
// no longer needed when we adopt graph-based regions.
33+
/// for each scope, a span of blocks that defines it;
34+
/// we track these for use in region and borrow checking,
35+
/// but these are liable to get out of date once optimization
36+
/// begins. They are also hopefully temporary, and will be
37+
/// no longer needed when we adopt graph-based regions.
3838
scope_auxiliary: ScopeAuxiliaryVec,
3939

40-
// the current set of loops; see the `scope` module for more
41-
// details
40+
/// the current set of loops; see the `scope` module for more
41+
/// details
4242
loop_scopes: Vec<scope::LoopScope>,
4343

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

4848
var_decls: Vec<VarDecl<'tcx>>,
4949
var_indices: FnvHashMap<ast::NodeId, u32>,
5050
temp_decls: Vec<TempDecl<'tcx>>,
5151
unit_temp: Option<Lvalue<'tcx>>,
5252

53-
// cached block with a RESUME terminator; we create this at the
54-
// first panic
53+
/// cached block with the RESUME terminator; this is created
54+
/// when first set of cleanups are built.
5555
cached_resume_block: Option<BasicBlock>,
56+
/// cached block with the RETURN terminator
57+
cached_return_block: Option<BasicBlock>,
5658
}
5759

5860
struct CFG<'tcx> {
@@ -182,11 +184,10 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
182184
var_indices: FnvHashMap(),
183185
unit_temp: None,
184186
cached_resume_block: None,
187+
cached_return_block: None
185188
};
186189

187190
assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
188-
assert_eq!(builder.cfg.start_new_block(), END_BLOCK);
189-
190191

191192
let mut arg_decls = None; // assigned to `Some` in closures below
192193
let call_site_extent =
@@ -206,12 +207,12 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
206207
block.unit()
207208
}));
208209

210+
let return_block = builder.return_block();
209211
builder.cfg.terminate(block, call_site_scope_id, span,
210-
TerminatorKind::Goto { target: END_BLOCK });
211-
builder.cfg.terminate(END_BLOCK, call_site_scope_id, span,
212+
TerminatorKind::Goto { target: return_block });
213+
builder.cfg.terminate(return_block, call_site_scope_id, span,
212214
TerminatorKind::Return);
213-
214-
END_BLOCK.unit()
215+
return_block.unit()
215216
});
216217

217218
assert!(
@@ -329,6 +330,17 @@ impl<'a,'tcx> Builder<'a,'tcx> {
329330
}
330331
}
331332
}
333+
334+
fn return_block(&mut self) -> BasicBlock {
335+
match self.cached_return_block {
336+
Some(rb) => rb,
337+
None => {
338+
let rb = self.cfg.start_new_block();
339+
self.cached_return_block = Some(rb);
340+
rb
341+
}
342+
}
343+
}
332344
}
333345

334346
///////////////////////////////////////////////////////////////////////////

src/librustc_mir/transform/remove_dead_blocks.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ pub struct RemoveDeadBlocks;
4343
impl<'tcx> MirPass<'tcx> for RemoveDeadBlocks {
4444
fn run_pass(&mut self, _: &TyCtxt<'tcx>, _: NodeId, mir: &mut Mir<'tcx>) {
4545
let mut seen = BitVector::new(mir.basic_blocks.len());
46-
// These blocks are always required.
46+
// This block is always required.
4747
seen.insert(START_BLOCK.index());
48-
seen.insert(END_BLOCK.index());
4948

5049
let mut worklist = Vec::with_capacity(4);
5150
worklist.push(START_BLOCK);

src/librustc_trans/mir/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,6 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
164164
.map(|&bb|{
165165
if bb == mir::START_BLOCK {
166166
fcx.new_block("start", None)
167-
} else if bb == mir::END_BLOCK {
168-
fcx.new_block("end", None)
169167
} else {
170168
fcx.new_block(&format!("{:?}", bb), None)
171169
}

0 commit comments

Comments
 (0)