[cfe-commits] r59767 - in /cfe/trunk/lib/CodeGen: CGObjC.cpp CGObjCGNU.cpp CGObjCMac.cpp CGObjCRuntime.h

Fariborz Jahanian fjahanian at apple.com
Thu Nov 20 16:49:25 PST 2008


Author: fjahanian
Date: Thu Nov 20 18:49:24 2008
New Revision: 59767

URL: http://llvm.org/viewvc/llvm-project?rev=59767&view=rev
Log:
Consolidated @try and @synchronize into a single
code gen. method.

Modified:
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.h

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=59767&r1=59766&r2=59767&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Thu Nov 20 18:49:24 2008
@@ -524,7 +524,7 @@
 
 void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
 {
-  CGM.getObjCRuntime().EmitTryStmt(*this, S);
+  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
 }
 
 void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
@@ -535,7 +535,7 @@
 void CodeGenFunction::EmitObjCAtSynchronizedStmt(
                                               const ObjCAtSynchronizedStmt &S)
 {
-  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
+  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
 }
 
 CGObjCRuntime::~CGObjCRuntime() {}

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=59767&r1=59766&r2=59767&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Thu Nov 20 18:49:24 2008
@@ -124,12 +124,10 @@
   virtual llvm::Function *GetPropertySetFunction();
   virtual llvm::Function *EnumerationMutationFunction();
   
-  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                           const ObjCAtTryStmt &S);
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S);
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S);
-  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                    const ObjCAtSynchronizedStmt &S);
   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *AddrWeakObj);
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
@@ -963,9 +961,9 @@
   return 0;
 }
 
-void CGObjCGNU::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                            const ObjCAtTryStmt &S) {
-  CGF.ErrorUnsupported(&S, "@try statement");
+void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                          const Stmt &S) {
+  CGF.ErrorUnsupported(&S, "@try/@synchronized statement");
 }
 
 void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
@@ -973,11 +971,6 @@
   CGF.ErrorUnsupported(&S, "@throw statement");
 }
 
-void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                     const ObjCAtSynchronizedStmt &S) {
-  CGF.ErrorUnsupported(&S, "@synchronized statement");
-}
-
 llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
                                           llvm::Value *AddrWeakObj)
 {

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=59767&r1=59766&r2=59767&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Nov 20 18:49:24 2008
@@ -451,12 +451,10 @@
   virtual llvm::Function *GetPropertySetFunction();
   virtual llvm::Function *EnumerationMutationFunction();
   
-  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                           const ObjCAtTryStmt &S);
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S);
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S);
-  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                    const ObjCAtSynchronizedStmt &S);
   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *AddrWeakObj); 
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
@@ -1553,11 +1551,16 @@
 destination in a variable prior to entering the finally block. At the
 end of the finally block we simply create a switch to the proper
 destination.
-
+ 
+Code gen for @synchronized(expr) stmt;
+Effectively generating code for:
+objc_sync_enter(expr);
+ at try stmt @finally { objc_sync_exit(expr); }
 */
 
-void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                            const ObjCAtTryStmt &S) {
+void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                          const Stmt &S) {
+  bool isTry = isa<ObjCAtTryStmt>(S);
   // Create various blocks we refer to for handling @finally.
   llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
   llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit");
@@ -1584,6 +1587,12 @@
                                                     "exceptiondata.ptr");
   llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, 
                                                  "_rethrow");
+  if (!isTry) {
+    // For @synchronized, call objc_sync_enter(sync.expr)
+    CGF.Builder.CreateCall(ObjCTypes.SyncEnterFn,
+                           CGF.EmitScalarExpr(
+                              cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()));
+  }
   
   // Enter a new try block and call setjmp.
   CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
@@ -1600,7 +1609,8 @@
 
   // Emit the @try block.
   CGF.EmitBlock(TryBlock);
-  CGF.EmitStmt(S.getTryBody());
+  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 
+                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
   CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
   
   // Emit the "exception in @try" block.
@@ -1612,7 +1622,14 @@
                                                ExceptionData,
                                                "caught");
   EHEntry.Exception = Caught;
-  if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) {    
+  if (!isTry)
+  {
+    CGF.Builder.CreateStore(Caught, RethrowPtr);
+    CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);    
+  }
+  else if (const ObjCAtCatchStmt* CatchStmt = 
+           cast<ObjCAtTryStmt>(S).getCatchStmts()) 
+  {    
     // Enter a new exception try block (in case a @catch block throws
     // an exception).
     CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
@@ -1726,8 +1743,16 @@
   CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
 
   CGF.EmitBlock(FinallyNoExit);
-  if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt())
-    CGF.EmitStmt(FinallyStmt->getFinallyBody());
+  if (isTry) {
+    if (const ObjCAtFinallyStmt* FinallyStmt = 
+          cast<ObjCAtTryStmt>(S).getFinallyStmt())
+      CGF.EmitStmt(FinallyStmt->getFinallyBody());
+  }
+  else
+    // For @synchronized objc_sync_exit(expr); As finally's sole statement.
+    CGF.Builder.CreateCall(ObjCTypes.SyncExitFn,
+                           CGF.EmitScalarExpr(
+                             cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()));
 
   CGF.EmitBlock(FinallyJump);
  
@@ -1851,96 +1876,6 @@
   return;
 }
 
-/// EmitSynchronizedStmt - Code gen for @synchronized(expr) stmt;
-/// Effectively generating code for:
-/// objc_sync_enter(expr);
-/// @try stmt @finally { objc_sync_exit(expr); }
-void CGObjCMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                     const ObjCAtSynchronizedStmt &S) {
-  // Create various blocks we refer to for handling @finally.
-  llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally");
-  llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit");
-  llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw");
-  llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end");
-  llvm::Value *DestCode = 
-  CGF.CreateTempAlloca(llvm::Type::Int32Ty, "finally.dst");
-  
-  // Generate jump code. Done here so we can directly add things to
-  // the switch instruction.
-  llvm::BasicBlock *FinallyJump = CGF.createBasicBlock("finally.jump");
-  llvm::SwitchInst *FinallySwitch = 
-  llvm::SwitchInst::Create(new llvm::LoadInst(DestCode, "", FinallyJump), 
-                           FinallyEnd, 10, FinallyJump);
-  
-  // Push an EH context entry, used for handling rethrows and jumps
-  // through finally.
-  CodeGenFunction::ObjCEHEntry EHEntry(FinallyBlock, FinallyNoExit,
-                                       FinallySwitch, DestCode);
-  CGF.ObjCEHStack.push_back(&EHEntry);
-  
-  // Allocate memory for the exception data and rethrow pointer.
-  llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
-                                                    "exceptiondata.ptr");
-  llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, 
-                                                 "_rethrow");
-  // Call objc_sync_enter(sync.expr)
-  CGF.Builder.CreateCall(ObjCTypes.SyncEnterFn,
-                         CGF.EmitScalarExpr(S.getSynchExpr()));
-  
-  // Enter a new try block and call setjmp.
-  CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
-  llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0, 
-                                                       "jmpbufarray");
-  JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
-  llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
-                                                     JmpBufPtr, "result");
-  
-  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
-  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
-  CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"), 
-                           TryHandler, TryBlock);
-  
-  // Emit the @try block.
-  CGF.EmitBlock(TryBlock);
-  CGF.EmitStmt(S.getSynchBody());
-  CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
-  
-  // Emit the "exception in @try" block.
-  CGF.EmitBlock(TryHandler);
-  
-  // Retrieve the exception object.  We may emit multiple blocks but
-  // nothing can cross this so the value is already in SSA form.
-  llvm::Value *Caught = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
-                                               ExceptionData,
-                                               "caught");
-  EHEntry.Exception = Caught;
-  CGF.Builder.CreateStore(Caught, RethrowPtr);
-  CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);    
-  
-  // Pop the exception-handling stack entry. It is important to do
-  // this now, because the code in the @finally block is not in this
-  // context.
-  CGF.ObjCEHStack.pop_back();
-  
-  // Emit the @finally block.
-  CGF.EmitBlock(FinallyBlock);
-  CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
-  
-  CGF.EmitBlock(FinallyNoExit);
-  // objc_sync_exit(expr); As finally's sole statement.
-  CGF.Builder.CreateCall(ObjCTypes.SyncExitFn,
-                         CGF.EmitScalarExpr(S.getSynchExpr()));
-  
-  CGF.EmitBlock(FinallyJump);
-  
-  CGF.EmitBlock(FinallyRethrow);
-  CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, 
-                         CGF.Builder.CreateLoad(RethrowPtr));
-  CGF.Builder.CreateUnreachable();
-  
-  CGF.EmitBlock(FinallyEnd);  
-}
-
 /* *** Private Interface *** */
 
 /// EmitImageInfo - Emit the image info marker used to encode some module

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=59767&r1=59766&r2=59767&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Thu Nov 20 18:49:24 2008
@@ -139,12 +139,10 @@
   /// runtime and a warning should be generated.
   virtual bool LateBoundIVars() const { return false; }
 
-  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                           const ObjCAtTryStmt &S) = 0;
+  virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                                         const Stmt &S) = 0;
   virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
                              const ObjCAtThrowStmt &S) = 0;
-  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                    const ObjCAtSynchronizedStmt &S) = 0;
   virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
 					 llvm::Value *AddrWeakObj) = 0;
   virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,





More information about the cfe-commits mailing list