remove cleanup branches to the resume block
This improves LLVM performance by 10% lost during the shimmir transition.
This commit is contained in:
parent
9cc77d7690
commit
3bf00450cb
@ -124,6 +124,8 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
|
||||
self.collapse_goto_chain(successor, &mut changed);
|
||||
}
|
||||
|
||||
changed |= self.simplify_unwind(&mut terminator);
|
||||
|
||||
let mut new_stmts = vec![];
|
||||
let mut inner_changed = true;
|
||||
while inner_changed {
|
||||
@ -238,6 +240,38 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
|
||||
true
|
||||
}
|
||||
|
||||
// turn an unwind branch to a resume block into a None
|
||||
fn simplify_unwind(&mut self, terminator: &mut Terminator<'tcx>) -> bool {
|
||||
let unwind = match terminator.kind {
|
||||
TerminatorKind::Drop { ref mut unwind, .. } |
|
||||
TerminatorKind::DropAndReplace { ref mut unwind, .. } |
|
||||
TerminatorKind::Call { cleanup: ref mut unwind, .. } |
|
||||
TerminatorKind::Assert { cleanup: ref mut unwind, .. } =>
|
||||
unwind,
|
||||
_ => return false
|
||||
};
|
||||
|
||||
if let &mut Some(unwind_block) = unwind {
|
||||
let is_resume_block = match self.basic_blocks[unwind_block] {
|
||||
BasicBlockData {
|
||||
ref statements,
|
||||
terminator: Some(Terminator {
|
||||
kind: TerminatorKind::Resume, ..
|
||||
}), ..
|
||||
} if statements.is_empty() => true,
|
||||
_ => false
|
||||
};
|
||||
if is_resume_block {
|
||||
debug!("simplifying unwind to {:?} from {:?}",
|
||||
unwind_block, terminator.source_info);
|
||||
*unwind = None;
|
||||
}
|
||||
return is_resume_block;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn strip_nops(&mut self) {
|
||||
for blk in self.basic_blocks.iter_mut() {
|
||||
blk.statements.retain(|stmt| if let StatementKind::Nop = stmt.kind {
|
||||
|
@ -36,7 +36,7 @@ pub fn droppy() {
|
||||
// CHECK-NOT: call{{.*}}drop{{.*}}SomeUniqueName
|
||||
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
|
||||
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
|
||||
// CHECK: invoke{{.*}}drop{{.*}}SomeUniqueName
|
||||
// CHECK: call{{.*}}drop{{.*}}SomeUniqueName
|
||||
// CHECK-NOT: {{(call|invoke).*}}drop{{.*}}SomeUniqueName
|
||||
// The next line checks for the } that ends the function definition
|
||||
// CHECK-LABEL: {{^[}]}}
|
||||
|
@ -37,5 +37,6 @@ pub fn test() {
|
||||
// CHECK: bitcast{{.*}}personalityslot
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start
|
||||
might_unwind();
|
||||
let _t = S;
|
||||
might_unwind();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user