Simplify the Objective-C exception handling.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64031 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index ff23b83..6c6419e 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1766,7 +1766,8 @@
 {
   objc_exception_data d;
   id _rethrow = null;
-
+  bool _call_try_exit = true;
+ 
   objc_exception_try_enter(&d);
   if (!setjmp(d.jmp_buf)) {
     ... try body ... 
@@ -1784,16 +1785,16 @@
     } else {
       // exception in catch block
       _rethrow = objc_exception_extract(&d);
-      ... jump-through-finally_no_exit to finally_rethrow ...
+      _call_try_exit = false;
+      ... jump-through-finally to finally_rethrow ...
     }
   }
   ... jump-through-finally to finally_end ...
 
 finally:
-  // match either the initial try_enter or the catch try_enter,
-  // depending on the path followed.
-  objc_exception_try_exit(&d);
-finally_no_exit:
+  if (_call_try_exit)
+    objc_exception_try_exit(&d);
+
   ... finally block ....
   ... dispatch to finally destination ...
 
@@ -1849,6 +1850,7 @@
   bool isTry = isa<ObjCAtTryStmt>(S);
   // Create various blocks we refer to for handling @finally.
   llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
+  llvm::BasicBlock *FinallyExit = CGF.createBasicBlock("finally.exit");
   llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit");
   llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
   llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
@@ -1864,8 +1866,7 @@
 
   // Push an EH context entry, used for handling rethrows and jumps
   // through finally.
-  CodeGenFunction::ObjCEHEntry EHEntry(FinallyBlock, FinallyNoExit,
-                                       FinallySwitch, DestCode);
+  CodeGenFunction::ObjCEHEntry EHEntry(FinallyBlock, FinallySwitch, DestCode);
   CGF.ObjCEHStack.push_back(&EHEntry);
 
   // Allocate memory for the exception data and rethrow pointer.
@@ -1873,6 +1874,10 @@
                                                     "exceptiondata.ptr");
   llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, 
                                                  "_rethrow");
+  llvm::Value *CallTryExitPtr = CGF.CreateTempAlloca(llvm::Type::Int1Ty,
+                                                     "_call_try_exit");
+  CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(), CallTryExitPtr);
+  
   if (!isTry) {
     // For @synchronized, call objc_sync_enter(sync.expr)
     llvm::Value *Arg = CGF.EmitScalarExpr(
@@ -1912,6 +1917,7 @@
   if (!isTry)
   {
     CGF.Builder.CreateStore(Caught, RethrowPtr);
+    CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(), CallTryExitPtr);
     CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);    
   }
   else if (const ObjCAtCatchStmt* CatchStmt = 
@@ -2014,9 +2020,11 @@
     CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
                                                    ExceptionData), 
                             RethrowPtr);
+    CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(), CallTryExitPtr);
     CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);
   } else {
     CGF.Builder.CreateStore(Caught, RethrowPtr);
+    CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(), CallTryExitPtr);
     CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);    
   }
   
@@ -2027,6 +2035,11 @@
 
   // Emit the @finally block.
   CGF.EmitBlock(FinallyBlock);
+  llvm::Value* CallTryExit = CGF.Builder.CreateLoad(CallTryExitPtr, "tmp");
+  
+  CGF.Builder.CreateCondBr(CallTryExit, FinallyExit, FinallyNoExit);
+  
+  CGF.EmitBlock(FinallyExit);
   CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
 
   CGF.EmitBlock(FinallyNoExit);
@@ -2099,7 +2112,7 @@
 
   // Set the destination code and branch.
   Builder.CreateStore(ID, E->DestCode);
-  EmitBranch(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit);
+  EmitBranch(E->FinallyBlock);
 }
 
 /// EmitObjCWeakRead - Code gen for loading value of a __weak