]> granicus.if.org Git - clang/commitdiff
Generate atomic api for atomic properties (x86 and x86_64
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 5 Apr 2011 21:41:23 +0000 (21:41 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 5 Apr 2011 21:41:23 +0000 (21:41 +0000)
targets) when load/store results in multiple instructions.
// rdar://8808439

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128937 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjC.cpp
test/CodeGenObjC/misc-atomic-property.m [new file with mode: 0644]

index ac4e763f89f9f02a1e7bd4c444529625910195d8..78305c6ddc69dc93983c8510a2366d27b4ee6903 100644 (file)
@@ -262,6 +262,22 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
         CGM.getObjCRuntime().GetGetStructFunction()) {
       GenerateObjCGetterBody(Ivar, true, false);
     }
+    else if (IsAtomic &&
+             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
+             Triple.getArch() == llvm::Triple::x86 &&
+             (getContext().getTypeSizeInChars(IVART) 
+              > CharUnits::fromQuantity(4)) &&
+             CGM.getObjCRuntime().GetGetStructFunction()) {
+      GenerateObjCGetterBody(Ivar, true, false);
+    }
+    else if (IsAtomic &&
+             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
+             Triple.getArch() == llvm::Triple::x86_64 &&
+             (getContext().getTypeSizeInChars(IVART) 
+              > CharUnits::fromQuantity(8)) &&
+             CGM.getObjCRuntime().GetGetStructFunction()) {
+      GenerateObjCGetterBody(Ivar, true, false);
+    }
     else if (IVART->isAnyComplexType()) {
       LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
                                     Ivar, 0);
@@ -283,6 +299,21 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
                                           PID->getGetterCXXConstructor(),
                                           0);
           EmitReturnStmt(*Stmt);
+        } else if (IsAtomic &&
+                   !IVART->isAnyComplexType() &&
+                   Triple.getArch() == llvm::Triple::x86 &&
+                   (getContext().getTypeSizeInChars(IVART) 
+                    > CharUnits::fromQuantity(4)) &&
+                   CGM.getObjCRuntime().GetGetStructFunction()) {
+          GenerateObjCGetterBody(Ivar, true, false);
+        }
+        else if (IsAtomic &&
+                 !IVART->isAnyComplexType() &&
+                 Triple.getArch() == llvm::Triple::x86_64 &&
+                 (getContext().getTypeSizeInChars(IVART) 
+                  > CharUnits::fromQuantity(8)) &&
+                 CGM.getObjCRuntime().GetGetStructFunction()) {
+          GenerateObjCGetterBody(Ivar, true, false);
         }
         else {
           LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
@@ -358,7 +389,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
   assert(OMD && "Invalid call to generate setter (empty method)");
   StartObjCMethod(OMD, IMP->getClassInterface());
-
+  const llvm::Triple &Triple = getContext().Target.getTriple();
+  QualType IVART = Ivar->getType();
   bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
   bool IsAtomic =
     !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
@@ -414,18 +446,21 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
                                    FunctionType::ExtInfo()),
              SetPropertyFn,
              ReturnValueSlot(), Args);
-  } else if (IsAtomic && hasAggregateLLVMType(Ivar->getType()) &&
-             !Ivar->getType()->isAnyComplexType() &&
-             IndirectObjCSetterArg(*CurFnInfo)
+  } else if (IsAtomic && hasAggregateLLVMType(IVART) &&
+             !IVART->isAnyComplexType() &&
+             ((Triple.getArch() == llvm::Triple::x86 &&
+              (getContext().getTypeSizeInChars(IVART)
+               > CharUnits::fromQuantity(4))) ||
+              (Triple.getArch() == llvm::Triple::x86_64 &&
+              (getContext().getTypeSizeInChars(IVART)
+               > CharUnits::fromQuantity(8))))
              && CGM.getObjCRuntime().GetSetStructFunction()) {
-    // objc_copyStruct (&structIvar, &Arg, 
-    //                  sizeof (struct something), true, false);
+          // objc_copyStruct (&structIvar, &Arg, 
+          //                  sizeof (struct something), true, false);
     GenerateObjCAtomicSetterBody(OMD, Ivar);
   } else if (PID->getSetterCXXAssignment()) {
     EmitIgnoredExpr(PID->getSetterCXXAssignment());
   } else {
-    const llvm::Triple &Triple = getContext().Target.getTriple();
-    QualType IVART = Ivar->getType();
     if (IsAtomic &&
         IVART->isScalarType() &&
         (Triple.getArch() == llvm::Triple::arm ||
@@ -435,6 +470,22 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
         CGM.getObjCRuntime().GetGetStructFunction()) {
       GenerateObjCAtomicSetterBody(OMD, Ivar);
     }
+    else if (IsAtomic &&
+             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
+             Triple.getArch() == llvm::Triple::x86 &&
+             (getContext().getTypeSizeInChars(IVART)
+              > CharUnits::fromQuantity(4)) &&
+             CGM.getObjCRuntime().GetGetStructFunction()) {
+      GenerateObjCAtomicSetterBody(OMD, Ivar);
+    }
+    else if (IsAtomic &&
+             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
+             Triple.getArch() == llvm::Triple::x86_64 &&
+             (getContext().getTypeSizeInChars(IVART)
+              > CharUnits::fromQuantity(8)) &&
+             CGM.getObjCRuntime().GetGetStructFunction()) {
+      GenerateObjCAtomicSetterBody(OMD, Ivar);
+    }
     else {
       // FIXME: Find a clean way to avoid AST node creation.
       SourceLocation Loc = PD->getLocation();
diff --git a/test/CodeGenObjC/misc-atomic-property.m b/test/CodeGenObjC/misc-atomic-property.m
new file mode 100644 (file)
index 0000000..26402d3
--- /dev/null
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9  -emit-llvm -o - %s | FileCheck %s
+// rdar: //8808439
+
+typedef struct {
+#ifdef __LP64__
+       unsigned char b[15];
+#else
+       unsigned char b[7];
+#endif
+} bools_minus_one;
+
+typedef struct {
+#ifdef __LP64__
+       unsigned char b[16];
+#else
+       unsigned char b[8];
+#endif
+} bools;
+
+
+@interface Foo
+{
+#ifndef __LP64__
+       bools x;
+       bools_minus_one y;
+#endif
+}
+@property(assign) bools bools_p;
+@property(assign) bools_minus_one bools_minus_one_p;
+@end
+
+@implementation Foo
+@synthesize bools_p=x;
+@synthesize bools_minus_one_p=y;
+@end
+
+#ifdef __LP64__
+typedef __int128_t dword;
+#else
+typedef long long int dword;
+#endif
+
+@interface Test_dwords
+{
+#ifndef __LP64__
+       dword dw;
+#endif
+}
+@property(assign) dword dword_p;
+@end
+
+@implementation Test_dwords
+@synthesize dword_p=dw;
+@end
+
+
+@interface Test_floats
+{
+  float fl;
+  double d;
+  long double ld;
+}
+@property(assign) float fl_p;
+@property(assign) double  d_p;
+@property(assign) long double ld_p;
+@end
+
+@implementation Test_floats
+@synthesize fl_p = fl;
+@synthesize d_p = d;
+@synthesize ld_p = ld;
+@end
+
+// CHECK: call void @objc_copyStruct
+// CHECK: call void @objc_copyStruct
+// CHECK: call void @objc_copyStruct
+// CHECK: call void @objc_copyStruct
+// CHECK: call void @objc_copyStruct
+// CHECK: call void @objc_copyStruct