[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