diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2017-04-20 01:20:50 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-04-22 21:00:50 +0300 |
| commit | 3bf00450cb9413b3c8e1e52fb7dfeaf31eb93b83 (patch) | |
| tree | 9daf2ace5d0f2e5a9e4c6c6141acbfda33d1693e | |
| parent | 9cc77d7690fc723b264962a4d01a6221be87d80e (diff) | |
| download | rust-3bf00450cb9413b3c8e1e52fb7dfeaf31eb93b83.tar.gz rust-3bf00450cb9413b3c8e1e52fb7dfeaf31eb93b83.zip | |
remove cleanup branches to the resume block
This improves LLVM performance by 10% lost during the shimmir transition.
| -rw-r--r-- | src/librustc_mir/transform/simplify.rs | 34 | ||||
| -rw-r--r-- | src/test/codegen/drop.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen/personality_lifetimes.rs | 1 |
3 files changed, 36 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 0a8f147b214..ef7990653ba 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -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 { diff --git a/src/test/codegen/drop.rs b/src/test/codegen/drop.rs index a4bd5cf2c15..d7e2cb6d9a5 100644 --- a/src/test/codegen/drop.rs +++ b/src/test/codegen/drop.rs @@ -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: {{^[}]}} diff --git a/src/test/codegen/personality_lifetimes.rs b/src/test/codegen/personality_lifetimes.rs index e0de64b26df..9fd600b32e6 100644 --- a/src/test/codegen/personality_lifetimes.rs +++ b/src/test/codegen/personality_lifetimes.rs @@ -37,5 +37,6 @@ pub fn test() { // CHECK: bitcast{{.*}}personalityslot // CHECK-NEXT: call void @llvm.lifetime.start might_unwind(); + let _t = S; might_unwind(); } |
