Generate atomic api for atomic properties (x86 and x86_64

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
This commit is contained in:
Fariborz Jahanian 2011-04-05 21:41:23 +00:00
Родитель b88fb027bf
Коммит 1d3a61a5ab
2 изменённых файлов: 139 добавлений и 8 удалений

Просмотреть файл

@ -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();

Просмотреть файл

@ -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