aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCGNU.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-07-21 00:41:47 +0000
committerJohn McCall <rjmccall@apple.com>2010-07-21 00:41:47 +0000
commit740e807eee153348f50a86f4a6eac49f324467ab (patch)
tree67a8c7e574ff5e7eb32369481f8da9a496d252e7 /lib/CodeGen/CGObjCGNU.cpp
parent1bda662cb37d9fe24be4b3cf8ea0f4e550e1f889 (diff)
Convert the ObjC @synchronized cleanups to laziness. This is not actually
a big deal, except that I want to eliminate the shared-code EH cleanups in preparation for a significant algorithmic fix. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108973 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 1b8705055e..567b8c3d7d 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -1855,6 +1855,19 @@ llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
}
+namespace {
+ struct CallSyncExit : EHScopeStack::LazyCleanup {
+ llvm::Value *SyncExitFn;
+ llvm::Value *SyncArg;
+ CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
+ : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
+
+ void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
+ CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
+ }
+ };
+}
+
void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) {
std::vector<const llvm::Type*> Args(1, IdTy);
@@ -1871,13 +1884,9 @@ void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
CGF.Builder.CreateCall(SyncEnter, SyncArg);
// Register an all-paths cleanup to release the lock.
- {
- CodeGenFunction::CleanupBlock ReleaseScope(CGF, NormalAndEHCleanup);
-
- llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
- SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
- CGF.Builder.CreateCall(SyncExit, SyncArg);
- }
+ llvm::Value *SyncExit = CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
+ CGF.EHStack.pushLazyCleanup<CallSyncExit>(NormalAndEHCleanup,
+ SyncExit, SyncArg);
// Emit the body of the statement.
CGF.EmitStmt(S.getSynchBody());