зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
b88fb027bf
Коммит
1d3a61a5ab
|
@ -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
|
Загрузка…
Ссылка в новой задаче