objC block layout: Patch reorders block layout to

produce more inline layout metadata. // rdar://12752901

llvm-svn: 172683
This commit is contained in:
Fariborz Jahanian 2013-01-17 00:25:06 +00:00
parent e9fe5308ca
commit c889205567
8 changed files with 169 additions and 178 deletions

View File

@ -182,13 +182,16 @@ namespace {
struct BlockLayoutChunk {
CharUnits Alignment;
CharUnits Size;
Qualifiers::ObjCLifetime Lifetime;
const BlockDecl::Capture *Capture; // null for 'this'
llvm::Type *Type;
BlockLayoutChunk(CharUnits align, CharUnits size,
Qualifiers::ObjCLifetime lifetime,
const BlockDecl::Capture *capture,
llvm::Type *type)
: Alignment(align), Size(size), Capture(capture), Type(type) {}
: Alignment(align), Size(size), Lifetime(lifetime),
Capture(capture), Type(type) {}
/// Tell the block info that this chunk has the given field index.
void setIndex(CGBlockInfo &info, unsigned index) {
@ -200,9 +203,35 @@ namespace {
}
};
/// Order by descending alignment.
/// Order by 1) all __strong together 2) next, all byfref together 3) next,
/// all __weak together. Preserve descending alignment in all situations.
bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) {
return left.Alignment > right.Alignment;
CharUnits LeftValue, RightValue;
bool LeftByref = left.Capture ? left.Capture->isByRef() : false;
bool RightByref = right.Capture ? right.Capture->isByRef() : false;
if (left.Lifetime == Qualifiers::OCL_Strong &&
left.Alignment >= right.Alignment)
LeftValue = CharUnits::fromQuantity(64);
else if (LeftByref && left.Alignment >= right.Alignment)
LeftValue = CharUnits::fromQuantity(32);
else if (left.Lifetime == Qualifiers::OCL_Weak &&
left.Alignment >= right.Alignment)
LeftValue = CharUnits::fromQuantity(16);
else
LeftValue = left.Alignment;
if (right.Lifetime == Qualifiers::OCL_Strong &&
right.Alignment >= left.Alignment)
RightValue = CharUnits::fromQuantity(64);
else if (RightByref && right.Alignment >= left.Alignment)
RightValue = CharUnits::fromQuantity(32);
else if (right.Lifetime == Qualifiers::OCL_Weak &&
right.Alignment >= left.Alignment)
RightValue = CharUnits::fromQuantity(16);
else
RightValue = right.Alignment;
return LeftValue > RightValue;
}
}
@ -337,7 +366,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
= CGM.getContext().getTypeInfoInChars(thisType);
maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 0, llvmType));
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
Qualifiers::OCL_None,
0, llvmType));
}
// Next, all the block captures.
@ -358,6 +389,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
Qualifiers::OCL_None,
&*ci, llvmType));
continue;
}
@ -371,8 +403,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
// If we have a lifetime qualifier, honor it for capture purposes.
// That includes *not* copying it if it's __unsafe_unretained.
if (Qualifiers::ObjCLifetime lifetime
= variable->getType().getObjCLifetime()) {
Qualifiers::ObjCLifetime lifetime =
variable->getType().getObjCLifetime();
if (lifetime) {
switch (lifetime) {
case Qualifiers::OCL_None: llvm_unreachable("impossible");
case Qualifiers::OCL_ExplicitNone:
@ -387,6 +420,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
// Block pointers require copy/dispose. So do Objective-C pointers.
} else if (variable->getType()->isObjCRetainableType()) {
info.NeedsCopyDispose = true;
// used for mrr below.
lifetime = Qualifiers::OCL_Strong;
// So do types that require non-trivial copy construction.
} else if (ci->hasCopyExpr()) {
@ -413,7 +448,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
llvm::Type *llvmType =
CGM.getTypes().ConvertTypeForMem(VT);
layout.push_back(BlockLayoutChunk(align, size, &*ci, llvmType));
layout.push_back(BlockLayoutChunk(align, size, lifetime, &*ci, llvmType));
}
// If that was everything, we're done here.

View File

@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o %t-64.s
// RUN: FileCheck --input-file=%t-64.s %s
// rdar://12773256
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
// RUN: FileCheck --input-file=%t-32.layout %s
// rdar://12184410
// rdar://12752901
@class NSString;
extern void NSLog(NSString *format, ...);
@ -10,43 +11,32 @@ int main() {
NSString *strong;
unsigned long long eightByte = 0x8001800181818181ull;
// Test1
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\220\00"
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
void (^block1)() = ^{ printf("%#llx", eightByte); NSLog(@"%@", strong); };
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i64, %0* }>, align 8
// block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
// Test2
int i = 1;
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"#0\00"
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
void (^block2)() = ^{ printf("%#llx, %d", eightByte, i); NSLog(@"%@", strong); };
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32, i64, i32, %0* }>, align 8
// block variable layout: BL_NON_OBJECT_WORD:4, BL_STRONG:1, BL_OPERATOR:0
// Test3
char ch = 'a';
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\220\00"
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
void (^block3)() = ^{ printf("%c %#llx", ch, eightByte); NSLog(@"%@", strong); };
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i64, %0*, i8 }>, align 8
// block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
// Test4
unsigned long fourByte = 0x8001ul;
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" 0\00"
void (^block4)() = ^{ printf("%c %#lx", ch, fourByte); NSLog(@"%@", strong); };
// block variable layout: BL_NON_OBJECT_WORD:1, BL_STRONG:1, BL_OPERATOR:0
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32, %0*, i8 }>, align 4
// CHECK: Inline instruction for block variable layout: 0x0100
void (^block4)() = ^{ printf("%c %#lx", ch, fourByte); NSLog(@"%@", strong); };
// Test5
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\220\00"
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
void (^block5)() = ^{ NSLog(@"%@", strong); printf("%c %#llx", ch, eightByte); };
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i64, %0*, i8 }>, align 8
// block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
// Test6
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
void (^block6)() = ^{ printf("%#llx", eightByte); };
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [4 x i8], i64 }>, align 8
// block variable layout: BL_OPERATOR:0
}
/**

View File

@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o %t-64.s
// RUN: FileCheck --input-file=%t-64.s %s
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
// RUN: FileCheck --input-file=%t-32.layout %s
// rdar://12184410
// rdar://12752901
void x(id y) {}
void y(int a) {}
@ -32,8 +33,7 @@ void f() {
// and a descriptor pointer).
// Test 1
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
// CHECK: Inline instruction for block variable layout: 0x0320
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -44,8 +44,7 @@ void f() {
b();
// Test 2
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
// CHECK: Inline instruction for block variable layout: 0x0331
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -66,8 +65,7 @@ void g() {
unsigned int i;
NSString *y;
NSString *z;
// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"!1P1\00"
// CHECK: Inline instruction for block variable layout: 0x0401
void (^c)() = ^{
int j = i + bletch;
x(foo);
@ -112,7 +110,7 @@ void h() {
block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
*/
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
// CHECK: block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@ -127,8 +125,7 @@ void arr1() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
// CHECK: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@ -143,8 +140,7 @@ void arr2() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
// CHECK: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@ -159,8 +155,7 @@ void arr3() {
__unsafe_unretained id unsafe_unretained_var[0];
} imported_s;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
void (^c)() = ^{
int i = imported_s.a;
};
@ -186,15 +181,7 @@ void arr4() {
} f4[2][2];
} captured_s;
/**
block variable layout: BL_UNRETAINE:3,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_OPERATOR:0
*/
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
// CHECK: block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
id i = captured_s.f0.s_f1;
};
@ -212,8 +199,7 @@ void bf1() {
int flag4: 24;
} s;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@ -226,8 +212,7 @@ void bf2() {
int flag : 1;
} s;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@ -258,8 +243,7 @@ void bf3() {
unsigned int _filler : 32;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@ -294,8 +278,7 @@ void bf4() {
unsigned int _filler : 32;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@ -313,8 +296,7 @@ void bf5() {
unsigned char flag1 : 1;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@ -331,8 +313,7 @@ void bf6() {
unsigned char flag1 : 1;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@ -348,8 +329,7 @@ void Test7() {
__weak id wid9, wid10, wid11, wid12;
__weak id wid13, wid14, wid15, wid16;
const id bar = (id) opaque_id();
//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
// CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);
@ -384,8 +364,7 @@ __weak id wid;
__weak id w9, w10, w11, w12;
__weak id w13, w14, w15, w16;
const id bar = (id) opaque_id();
// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
// CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);

View File

@ -1,5 +1,7 @@
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-i386 %s
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
// RUN: FileCheck --input-file=%t-64.layout %s
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
// RUN: FileCheck -check-prefix=CHECK-i386 --input-file=%t-32.layout %s
// rdar://12184410
void x(id y) {}
@ -15,25 +17,22 @@ void f() {
__block id byref_bab = (id)0;
__block id bl_var1;
// Inline instruction for block variable layout: 0x0100
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 256 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 256 }
// CHECK: Inline instruction for block variable layout: 0x0100
// CHECK-i386: Inline instruction for block variable layout: 0x0100
void (^b)() = ^{
x(bar);
};
// Inline instruction for block variable layout: 0x0210
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 528 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 528 }
// CHECK: Inline instruction for block variable layout: 0x0210
// CHECK-i386: Inline instruction for block variable layout: 0x0210
void (^c)() = ^{
x(bar);
x(baz);
byref_int = 1;
};
// Inline instruction for block variable layout: 0x0230
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 560 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 560 }
// CHECK: Inline instruction for block variable layout: 0x0230
// CHECK-i386: Inline instruction for block variable layout: 0x0230
void (^d)() = ^{
x(bar);
x(baz);
@ -42,9 +41,8 @@ void f() {
byref_bab = 0;
};
// Inline instruction for block variable layout: 0x0231
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 561 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 561 }
// CHECK: Inline instruction for block variable layout: 0x0231
// CHECK-i386: Inline instruction for block variable layout: 0x0231
__weak id wid;
id (^e)() = ^{
x(bar);
@ -55,9 +53,8 @@ void f() {
return wid;
};
// Inline instruction for block variable layout: 0x0235
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 565 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 565 }
// CHECK: Inline instruction for block variable layout: 0x0235
// CHECK-i386: Inline instruction for block variable layout: 0x0235
__weak id wid1, wid2, wid3, wid4;
id (^f)() = ^{
x(bar);
@ -72,9 +69,8 @@ void f() {
return wid;
};
// Inline instruction for block variable layout: 0x035
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 53 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 53 }
// CHECK: Inline instruction for block variable layout: 0x035
// CHECK-i386: Inline instruction for block variable layout: 0x035
id (^g)() = ^{
byref_int = 1;
bl_var1 = 0;
@ -86,27 +82,41 @@ void f() {
return wid;
};
// Inline instruction for block variable layout: 0x01
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 1 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 1 }
// CHECK: Inline instruction for block variable layout: 0x01
// CHECK-i386: Inline instruction for block variable layout: 0x01
id (^h)() = ^{
return wid;
};
// Inline instruction for block variable layout: 0x020
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 32 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 32 }
// CHECK: Inline instruction for block variable layout: 0x020
// CHECK-i386: Inline instruction for block variable layout: 0x020
void (^ii)() = ^{
byref_int = 1;
byref_bab = 0;
};
// Inline instruction for block variable layout: 0x0102
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 258 }
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 258 }
// CHECK: Inline instruction for block variable layout: 0x0102
// CHECK-i386: Inline instruction for block variable layout: 0x0102
void (^jj)() = ^{
x(bar);
x(wid1);
x(wid2);
};
}
// rdar://12752901
@class NSString;
extern void NSLog(NSString *format, ...);
typedef void (^dispatch_block_t)(void);
int main() {
__strong NSString *s1 = 0;
__strong NSString *s2 = 0;
__weak NSString *w1 = 0;
// CHECK: Inline instruction for block variable layout: 0x0201
// CHECK-i386: Inline instruction for block variable layout: 0x0201
dispatch_block_t block2 = ^{
NSLog(@"%@, %@, %@", s1, w1, s2);
};
}

View File

@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.layout %s
// rdar://12184410
// rdar://12752901
void x(id y) {}
void y(int a) {}
@ -32,8 +33,8 @@ void f() {
// and a descriptor pointer).
// Test 1
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
// Inline instruction for block variable layout: 0x0320 (3 strong 2 byref)
// CHECK-LP64: Inline instruction for block variable layout: 0x0320
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -44,8 +45,8 @@ void f() {
b();
// Test 2
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
// Inline instruction for block variable layout: 0x0331 (3 strong 3 byref 1 weak)
// CHECK-LP64: Inline instruction for block variable layout: 0x0331
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -66,8 +67,8 @@ void g() {
unsigned int i;
NSString *y;
NSString *z;
// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"1P1\00"
// Inline instruction for block variable layout: 0x0401 (4 strong 0 byref 1 weak)
// CHECK-LP64: Inline instruction for block variable layout: 0x0401
void (^c)() = ^{
int j = i + bletch;
x(foo);
@ -108,11 +109,7 @@ void h() {
union U u2;
__block id block_id;
/**
block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
*/
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
// CHECK-LP64: block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@ -127,8 +124,7 @@ void arr1() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
// CHECK-LP64: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@ -143,8 +139,7 @@ void arr2() {
__unsafe_unretained id unsafe_unretained_var[4];
} imported_s;
// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
// CHECK-LP64: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
void (^c)() = ^{
x(imported_s.unsafe_unretained_var[2]);
};
@ -159,8 +154,7 @@ void arr3() {
__unsafe_unretained id unsafe_unretained_var[0];
} imported_s;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
void (^c)() = ^{
int i = imported_s.a;
};
@ -186,15 +180,7 @@ void arr4() {
} f4[2][2];
} captured_s;
/**
block variable layout: BL_UNRETAINE:3,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
BL_OPERATOR:0
*/
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
// CHECK-LP64: block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
void (^c)() = ^{
id i = captured_s.f0.s_f1;
};
@ -212,8 +198,7 @@ void bf1() {
int flag4: 24;
} s;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@ -226,8 +211,7 @@ void bf2() {
int flag : 1;
} s;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
int (^c)() = ^{
return s.flag;
};
@ -258,8 +242,7 @@ void bf3() {
unsigned int _filler : 32;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@ -294,8 +277,7 @@ void bf4() {
unsigned int _filler : 32;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags._draggedNodesAreDeletable;
};
@ -313,8 +295,7 @@ void bf5() {
unsigned char flag1 : 1;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@ -331,8 +312,7 @@ void bf6() {
unsigned char flag1 : 1;
} _flags;
// block variable layout: BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
// CHECK-LP64: block variable layout: BL_OPERATOR:0
unsigned char (^c)() = ^{
return _flags.flag;
};
@ -348,8 +328,7 @@ void Test7() {
__weak id wid9, wid10, wid11, wid12;
__weak id wid13, wid14, wid15, wid16;
const id bar = (id) opaque_id();
//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);
@ -384,8 +363,7 @@ __weak id wid;
__weak id w9, w10, w11, w12;
__weak id w13, w14, w15, w16;
const id bar = (id) opaque_id();
// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
void (^b)() = ^{
x(bar);
x(wid1);

View File

@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -emit-llvm %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.layout %s
// rdar://12752901
struct S {
int i1;
@ -46,8 +47,7 @@ void f() {
// Test 1
// byref int, short, char, char, char, id, id, strong void*, byref id
// 01 35 10 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x10, 0x00
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -60,7 +60,7 @@ void f() {
// Test 2
// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
// 01 36 10 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
// CHECK-LP64: block variable layout for block: 0x01, 0x36, 0x10, 0x00
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -76,7 +76,7 @@ void f() {
// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
// 01 34 11 30 00
// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x30, 0x00
void (^d)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -91,7 +91,7 @@ void f() {
// Test 4
// struct S (int, id, int, id, int, id)
// 01 41 11 11 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
struct S s2;
void (^e)() = ^{
x(s2.o1);
@ -129,7 +129,7 @@ void Test5() {
// struct s2 (int, id, int, id, int, id?), union u2 (id?)
// 01 41 11 12 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\12\00"
// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@ -146,7 +146,7 @@ void notifyBlock(id dependentBlock) {
// id, id, void(^)()
// 01 33 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
// CHECK-LP64: block variable layout for block: 0x01, 0x33, 0x00
void (^wrapperBlock)() = ^() {
CFRelease(singleObservationToken);
CFRelease(singleObservationToken);
@ -159,7 +159,7 @@ void notifyBlock(id dependentBlock) {
void test_empty_block() {
// 01 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
// CHECK-LP64: block variable layout for block: 0x01, 0x00
void (^wrapperBlock)() = ^() {
};
wrapperBlock();

View File

@ -1,5 +1,8 @@
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin -O0 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-i386 %s
// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
// RUN: FileCheck --input-file=%t-64.layout %s
// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
// RUN: FileCheck -check-prefix=CHECK-i386 --input-file=%t-32.layout %s
// rdar://12184410
// rdar://12184410
void x(id y) {}
@ -17,17 +20,15 @@ void f() {
__block id bl_var1;
// block variable layout: BL_STRONG:1, BL_OPERATOR:0
// Inline instruction for block variable layout: 0x0100
// CHECK: internal constant{{.*}}i64 256
// CHECK-i386: internal constant{{.*}}i32 256
// CHECK: Inline instruction for block variable layout: 0x0100
// CHECK-i386: Inline instruction for block variable layout: 0x0100
void (^b)() = ^{
x(bar);
};
// block variable layout: BL_STRONG:2, BL_BYREF:1, BL_OPERATOR:0
// Inline instruction for block variable layout: 0x0210
// CHECK: internal constant{{.*}}i64 528
// CHECK-i386: internal constant{{.*}}i32 528
// CHECK: Inline instruction for block variable layout: 0x0210
// CHECK-i386: Inline instruction for block variable layout: 0x0210
void (^c)() = ^{
x(bar);
x(baz);
@ -35,9 +36,8 @@ void f() {
};
// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
// Inline instruction for block variable layout: 0x0230
// CHECK: internal constant{{.*}}i64 560
// CHECK-i386: internal constant{{.*}}i32 560
// CHECK: Inline instruction for block variable layout: 0x0230
// CHECK-i386: Inline instruction for block variable layout: 0x0230
void (^d)() = ^{
x(bar);
x(baz);
@ -47,9 +47,8 @@ void f() {
};
// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
// Inline instruction for block variable layout: 0x0230
// CHECK: internal constant{{.*}}i64 560
// CHECK-i386: internal constant{{.*}}i32 560
// CHECK: Inline instruction for block variable layout: 0x0230
// CHECK-i386: Inline instruction for block variable layout: 0x0230
id (^e)() = ^{
x(bar);
x(baz);
@ -59,9 +58,8 @@ void f() {
return wid;
};
// Inline instruction for block variable layout: 0x020
// CHECK: internal constant{{.*}}i64 32
// CHECK-i386: internal constant{{.*}}i32 32
// CHECK: Inline instruction for block variable layout: 0x020
// CHECK-i386: Inline instruction for block variable layout: 0x020
void (^ii)() = ^{
byref_int = 1;
byref_bab = 0;

View File

@ -1,5 +1,7 @@
// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o %t-64.ll
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.ll %s
// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
// RUN: FileCheck --input-file=%t-64.layout %s
// rdar://12184410
// rdar://12752901
// See commentary in test/CodeGenObjC/block-var-layout.m, from which
// this is largely cloned.
@ -37,7 +39,7 @@ void f() {
// Test 1
// byref int, short, char, char, char, id, id, strong void*, byref id
// 01 35 10 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
// CHECK: block variable layout for block: 0x01, 0x35, 0x10, 0x00
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -50,7 +52,7 @@ void f() {
// Test 2
// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
// 01 36 10 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
// CHECK: 0x01, 0x36, 0x10, 0x00
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -65,8 +67,7 @@ void f() {
// Test 3
// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
// 01 34 11 30 00
// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
// CHECK: block variable layout for block: 0x01, 0x35, 0x30, 0x00
void (^d)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@ -81,7 +82,7 @@ void (^d)() = ^{
// Test4
// struct S (int, id, int, id, int, id)
// 01 41 11 11 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
struct S s2;
void (^e)() = ^{
x(s2.o1);
@ -119,7 +120,7 @@ void Test5() {
// struct s2 (int, id, int, id, int, id?), union u2 (id?)
// 01 41 11 12 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\12\00"
// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@ -137,7 +138,7 @@ void notifyBlock(id dependentBlock) {
// id, id, void(^)()
// 01 33 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
// CHECK: block variable layout for block: 0x01, 0x33, 0x00
void (^wrapperBlock)() = ^() {
CFRelease(singleObservationToken);
CFRelease(singleObservationToken);
@ -150,7 +151,7 @@ void notifyBlock(id dependentBlock) {
void test_empty_block() {
// 01 00
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
// CHECK: block variable layout for block: 0x01, 0x00
void (^wrapperBlock)() = ^() {
};
wrapperBlock();