[cfe-commits] r147691 - in /cfe/trunk: lib/CodeGen/CGObjC.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.h test/CodeGenObjCXX/property-reference.mm

Fariborz Jahanian fjahanian at apple.com
Fri Jan 6 14:33:54 PST 2012


Author: fjahanian
Date: Fri Jan  6 16:33:54 2012
New Revision: 147691

URL: http://llvm.org/viewvc/llvm-project?rev=147691&view=rev
Log:
objc++: more code gen stuff for atomic property api,
currently turned off. // rdar://6137845
Also, fixes a test case which should be nonatomic under
new API.

Modified:
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/test/CodeGenObjCXX/property-reference.mm

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Fri Jan  6 16:33:54 2012
@@ -776,6 +776,44 @@
                copyStructFn, ReturnValueSlot(), args);
 }
 
+/// emitCPPObjectAtomicSetterCall - Call the runtime function to store 
+/// the value from the first formal parameter into the given ivar, using 
+/// the Cpp API for atomic Cpp objects with non-trivial copy assignment.
+static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, 
+                                          ObjCMethodDecl *OMD,
+                                          ObjCIvarDecl *ivar,
+                                          llvm::Constant *AtomicHelperFn) {
+  // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg, 
+  //                           AtomicHelperFn);
+  CallArgList args;
+  
+  // The first argument is the address of the ivar.
+  llvm::Value *ivarAddr = 
+    CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), 
+                          CGF.LoadObjCSelf(), ivar, 0).getAddress();
+  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
+  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
+  
+  // The second argument is the address of the parameter variable.
+  ParmVarDecl *argVar = *OMD->param_begin();
+  DeclRefExpr argRef(argVar, argVar->getType().getNonReferenceType(), 
+                     VK_LValue, SourceLocation());
+  llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
+  argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
+  args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
+  
+  // Third argument is the helper function.
+  args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
+  
+  llvm::Value *copyCppAtomicObjectFn = 
+    CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
+  CGF.EmitCall(CGF.getTypes().getFunctionInfo(CGF.getContext().VoidTy, args,
+                                              FunctionType::ExtInfo()),
+               copyCppAtomicObjectFn, ReturnValueSlot(), args);
+  
+
+}
+
 static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) {
   Expr *setter = PID->getSetterCXXAssignment();
   if (!setter) return true;
@@ -802,17 +840,24 @@
 
 void
 CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
-                                        const ObjCPropertyImplDecl *propImpl) {
+                                        const ObjCPropertyImplDecl *propImpl,
+                                        llvm::Constant *AtomicHelperFn) {
+  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
+  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
+  ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
+  
   // Just use the setter expression if Sema gave us one and it's
-  // non-trivial.  There's no way to do this atomically.
+  // non-trivial.
   if (!hasTrivialSetExpr(propImpl)) {
-    EmitStmt(propImpl->getSetterCXXAssignment());
+    if (!AtomicHelperFn)
+      // If non-atomic, assignment is called directly.
+      EmitStmt(propImpl->getSetterCXXAssignment());
+    else
+      // If atomic, assignment is called via a locking api.
+      emitCPPObjectAtomicSetterCall(*this, setterMethod, ivar,
+                                    AtomicHelperFn);
     return;
   }
-  
-  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
-  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
-  ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
 
   PropertyImplStrategy strategy(CGM, propImpl);
   switch (strategy.getKind()) {
@@ -944,13 +989,13 @@
 /// is illegal within a category.
 void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
                                          const ObjCPropertyImplDecl *PID) {
-  GenerateObjCAtomicCopyHelperFunction(PID);
+  llvm::Constant *AtomicHelperFn = GenerateObjCAtomicCopyHelperFunction(PID);
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
   assert(OMD && "Invalid call to generate setter (empty method)");
   StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
 
-  generateObjCSetterBody(IMP, PID);
+  generateObjCSetterBody(IMP, PID, AtomicHelperFn);
 
   FinishFunction();
 }
@@ -2489,15 +2534,21 @@
 llvm::Constant *
 CodeGenFunction::GenerateObjCAtomicCopyHelperFunction(
                                         const ObjCPropertyImplDecl *PID) {
-  if (!getLangOptions().CPlusPlus)
+  // FIXME. This api is for NeXt runtime only for now.
+  if (!getLangOptions().CPlusPlus || !getLangOptions().NeXTRuntime)
     return 0;
   QualType Ty = PID->getPropertyIvarDecl()->getType();
   if (!Ty->isRecordType())
     return 0;
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   if (!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic) ||
-      hasTrivialSetExpr(PID))
+      hasTrivialSetExpr(PID) || /* temporary */ true)
     return 0;
+  
+  llvm::Constant * HelperFn = CGM.getAtomicHelperFnMap(Ty);
+  if (HelperFn)
+    return HelperFn;
+    
   assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null");
   
   ASTContext &C = getContext();
@@ -2562,8 +2613,9 @@
   EmitStmt(TheCall);
 
   FinishFunction();
-  
-  return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
+  HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
+  CGM.setAtomicHelperFnMap(Ty, HelperFn);
+  return HelperFn;
   
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Jan  6 16:33:54 2012
@@ -1310,7 +1310,8 @@
   void GenerateObjCSetter(ObjCImplementationDecl *IMP,
                           const ObjCPropertyImplDecl *PID);
   void generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
-                              const ObjCPropertyImplDecl *propImpl);
+                              const ObjCPropertyImplDecl *propImpl,
+                              llvm::Constant *AtomicHelperFn);
   bool IndirectObjCSetterArg(const CGFunctionInfo &FI);
   bool IvarTypeWithAggrGCObjects(QualType Ty);
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Jan  6 16:33:54 2012
@@ -276,6 +276,8 @@
   llvm::StringMap<llvm::Constant*> CFConstantStringMap;
   llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
   llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
+  
+  llvm::DenseMap<QualType, llvm::Constant *> AtomicHelperFnMap;
 
   /// CXXGlobalInits - Global variables with initializers that need to run
   /// before main.
@@ -398,6 +400,14 @@
     StaticLocalDeclMap[D] = GV;
   }
 
+  llvm::Constant *getAtomicHelperFnMap(QualType Ty) {
+    return AtomicHelperFnMap[Ty];
+  }
+  void setAtomicHelperFnMap(QualType Ty,
+                            llvm::Constant *Fn) {
+    AtomicHelperFnMap[Ty] = Fn;
+  }
+
   CGDebugInfo *getModuleDebugInfo() { return DebugInfo; }
 
   ASTContext &getContext() const { return Context; }

Modified: cfe/trunk/test/CodeGenObjCXX/property-reference.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-reference.mm?rev=147691&r1=147690&r2=147691&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/property-reference.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/property-reference.mm Fri Jan  6 16:33:54 2012
@@ -35,7 +35,7 @@
 @interface Test1 {
   test1::A ivar;
 }
- at property const test1::A &prop1;
+ at property (nonatomic) const test1::A &prop1;
 @end
 @implementation Test1
 @synthesize prop1 = ivar;





More information about the cfe-commits mailing list