[cfe-commits] r108997 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp

John McCall rjmccall at apple.com
Tue Jul 20 23:59:37 PDT 2010


Author: rjmccall
Date: Wed Jul 21 01:59:36 2010
New Revision: 108997

URL: http://llvm.org/viewvc/llvm-project?rev=108997&view=rev
Log:
Switch the fragile-ABI @finally/@synchronized cleanup over to using a lazy
cleanup.


Modified:
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=108997&r1=108996&r2=108997&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Jul 21 01:59:36 2010
@@ -2541,6 +2541,54 @@
   return EmitTryOrSynchronizedStmt(CGF, S);
 }
 
+namespace {
+  struct PerformFragileFinally : EHScopeStack::LazyCleanup {
+    const Stmt &S;
+    llvm::Value *SyncArg;
+    llvm::Value *CallTryExitVar;
+    llvm::Value *ExceptionData;
+    ObjCTypesHelper &ObjCTypes;
+    PerformFragileFinally(const Stmt *S,
+                          llvm::Value *SyncArg,
+                          llvm::Value *CallTryExitVar,
+                          llvm::Value *ExceptionData,
+                          ObjCTypesHelper *ObjCTypes)
+      : S(*S), SyncArg(SyncArg), CallTryExitVar(CallTryExitVar),
+        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // Check whether we need to call objc_exception_try_exit.
+      // In optimized code, this branch will always be folded.
+      llvm::BasicBlock *FinallyCallExit =
+        CGF.createBasicBlock("finally.call_exit");
+      llvm::BasicBlock *FinallyNoCallExit =
+        CGF.createBasicBlock("finally.no_call_exit");
+      CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
+                               FinallyCallExit, FinallyNoCallExit);
+
+      CGF.EmitBlock(FinallyCallExit);
+      CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
+        ->setDoesNotThrow();
+
+      CGF.EmitBlock(FinallyNoCallExit);
+
+      if (isa<ObjCAtTryStmt>(S)) {
+        if (const ObjCAtFinallyStmt* FinallyStmt =
+            cast<ObjCAtTryStmt>(S).getFinallyStmt())
+          CGF.EmitStmt(FinallyStmt->getFinallyBody());
+
+        // Currently, the end of the cleanup must always exist.
+        CGF.EnsureInsertPoint();
+      } else {
+        // Emit objc_sync_exit(expr); as finally's sole statement for
+        // @synchronized.
+        CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
+          ->setDoesNotThrow();
+      }
+    }
+  };
+}
+
 /*
 
   Objective-C setjmp-longjmp (sjlj) Exception Handling
@@ -2697,38 +2745,11 @@
                           CallTryExitVar);
 
   // Push a normal cleanup to leave the try scope.
-  {
-    CodeGenFunction::CleanupBlock FinallyScope(CGF, NormalCleanup);
-
-    // Check whether we need to call objc_exception_try_exit.
-    // In optimized code, this branch will always be folded.
-    llvm::BasicBlock *FinallyCallExit =
-      CGF.createBasicBlock("finally.call_exit");
-    llvm::BasicBlock *FinallyNoCallExit =
-      CGF.createBasicBlock("finally.no_call_exit");
-    CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
-                             FinallyCallExit, FinallyNoCallExit);
-
-    CGF.EmitBlock(FinallyCallExit);
-    CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
-      ->setDoesNotThrow();
-
-    CGF.EmitBlock(FinallyNoCallExit);
-
-    if (isTry) {
-      if (const ObjCAtFinallyStmt* FinallyStmt =
-          cast<ObjCAtTryStmt>(S).getFinallyStmt())
-        CGF.EmitStmt(FinallyStmt->getFinallyBody());
-
-      // ~CleanupBlock requires there to be an exit block.
-      CGF.EnsureInsertPoint();
-    } else {
-      // Emit objc_sync_exit(expr); as finally's sole statement for
-      // @synchronized.
-      CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
-        ->setDoesNotThrow();
-    }
-  }
+  CGF.EHStack.pushLazyCleanup<PerformFragileFinally>(NormalCleanup, &S,
+                                                     SyncArg,
+                                                     CallTryExitVar,
+                                                     ExceptionData,
+                                                     &ObjCTypes);
 
   // Enter a try block:
   //  - Call objc_exception_try_enter to push ExceptionData on top of





More information about the cfe-commits mailing list