use lazy cached unreachable block - assign it to the function's closing brace

This commit is contained in:
Djzin 2017-11-13 23:08:12 +00:00
parent 829b70330e
commit aed0c9c9c0
2 changed files with 21 additions and 2 deletions

View File

@ -205,7 +205,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
if let Some(otherwise_block) = otherwise_block { if let Some(otherwise_block) = otherwise_block {
targets.push(otherwise_block); targets.push(otherwise_block);
} else { } else {
let unreachable_block = self.cfg.start_new_block(); let unreachable_block = self.unreachable_block();
targets.push(unreachable_block); targets.push(unreachable_block);
target_blocks.push(unreachable_block); target_blocks.push(unreachable_block);
} }

View File

@ -306,6 +306,8 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
cached_resume_block: Option<BasicBlock>, cached_resume_block: Option<BasicBlock>,
/// cached block with the RETURN terminator /// cached block with the RETURN terminator
cached_return_block: Option<BasicBlock>, cached_return_block: Option<BasicBlock>,
/// cached block with the UNREACHABLE terminator
cached_unreachable_block: Option<BasicBlock>,
} }
struct CFG<'tcx> { struct CFG<'tcx> {
@ -399,6 +401,11 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
TerminatorKind::Goto { target: return_block }); TerminatorKind::Goto { target: return_block });
builder.cfg.terminate(return_block, source_info, builder.cfg.terminate(return_block, source_info,
TerminatorKind::Return); TerminatorKind::Return);
// Attribute any unreachable codepaths to the function's closing brace
if let Some(unreachable_block) = builder.cached_unreachable_block {
builder.cfg.terminate(unreachable_block, source_info,
TerminatorKind::Unreachable);
}
return_block.unit() return_block.unit()
})); }));
assert_eq!(block, builder.return_block()); assert_eq!(block, builder.return_block());
@ -501,7 +508,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
var_indices: NodeMap(), var_indices: NodeMap(),
unit_temp: None, unit_temp: None,
cached_resume_block: None, cached_resume_block: None,
cached_return_block: None cached_return_block: None,
cached_unreachable_block: None,
}; };
assert_eq!(builder.cfg.start_new_block(), START_BLOCK); assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
@ -630,6 +638,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} }
} }
} }
fn unreachable_block(&mut self) -> BasicBlock {
match self.cached_unreachable_block {
Some(ub) => ub,
None => {
let ub = self.cfg.start_new_block();
self.cached_unreachable_block = Some(ub);
ub
}
}
}
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////