forked from OSchip/llvm-project
objective-C arc IR-gen. Retaining of strong
arguments in function prologue is done with objc_StoreStrong to pair it with similar objc_StoreStrong for release in function epilogue. This is done with -O0 only. // rdar://13145317 llvm-svn: 175698
This commit is contained in:
parent
f5b474c6c6
commit
134cec62ab
|
@ -1526,13 +1526,14 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
|
|||
// Otherwise, create a temporary to hold the value.
|
||||
llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty),
|
||||
D.getName() + ".addr");
|
||||
Alloc->setAlignment(getContext().getDeclAlign(&D).getQuantity());
|
||||
CharUnits Align = getContext().getDeclAlign(&D);
|
||||
Alloc->setAlignment(Align.getQuantity());
|
||||
DeclPtr = Alloc;
|
||||
|
||||
bool doStore = true;
|
||||
|
||||
Qualifiers qs = Ty.getQualifiers();
|
||||
|
||||
LValue lv = MakeAddrLValue(DeclPtr, Ty, Align);
|
||||
if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) {
|
||||
// We honor __attribute__((ns_consumed)) for types with lifetime.
|
||||
// For __strong, it's handled by just skipping the initial retain;
|
||||
|
@ -1553,11 +1554,22 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
|
|||
}
|
||||
|
||||
if (lt == Qualifiers::OCL_Strong) {
|
||||
if (!isConsumed)
|
||||
if (!isConsumed) {
|
||||
if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
|
||||
// use objc_storeStrong(&dest, value) for retaining the
|
||||
// object. But first, store a null into 'dest' because
|
||||
// objc_storeStrong attempts to release its old value.
|
||||
llvm::Value * Null = CGM.EmitNullConstant(D.getType());
|
||||
EmitStoreOfScalar(Null, lv, /* isInitialization */ true);
|
||||
EmitARCStoreStrongCall(lv.getAddress(), Arg, true);
|
||||
doStore = false;
|
||||
}
|
||||
else
|
||||
// Don't use objc_retainBlock for block pointers, because we
|
||||
// don't want to Block_copy something just because we got it
|
||||
// as a parameter.
|
||||
Arg = EmitARCRetainNonBlock(Arg);
|
||||
Arg = EmitARCRetainNonBlock(Arg);
|
||||
}
|
||||
} else {
|
||||
// Push the cleanup for a consumed parameter.
|
||||
if (isConsumed)
|
||||
|
@ -1574,11 +1586,8 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
|
|||
}
|
||||
|
||||
// Store the initial value into the alloca.
|
||||
if (doStore) {
|
||||
LValue lv = MakeAddrLValue(DeclPtr, Ty,
|
||||
getContext().getDeclAlign(&D));
|
||||
if (doStore)
|
||||
EmitStoreOfScalar(Arg, lv, /* isInitialization */ true);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *&DMEntry = LocalDeclMap[&D];
|
||||
|
|
|
@ -614,8 +614,8 @@ void test18(id x) {
|
|||
// CHECK-UNOPT: define void @test18(
|
||||
// CHECK-UNOPT: [[X:%.*]] = alloca i8*,
|
||||
// CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
|
||||
// CHECK-UNOPT-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}})
|
||||
// CHECK-UNOPT-NEXT: store i8* [[PARM]], i8** [[X]]
|
||||
// CHECK-UNOPT-NEXT: store i8* null, i8** [[X]]
|
||||
// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]],
|
||||
// CHECK-UNOPT-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
|
||||
// CHECK-UNOPT: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
|
||||
// CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8** [[X]],
|
||||
|
|
|
@ -30,10 +30,10 @@ void test0(NSArray *array) {
|
|||
// CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
|
||||
|
||||
// Initialize 'array'.
|
||||
// CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[ARRAY_T:%.*]]* {{%.*}} to i8*
|
||||
// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
|
||||
// CHECK-LP64-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[ARRAY_T]]*
|
||||
// CHECK-LP64-NEXT: store [[ARRAY_T]]* [[T2]], [[ARRAY_T]]** [[ARRAY]], align 8
|
||||
// CHECK-LP64-NEXT: store [[ARRAY_T]]* null, [[ARRAY_T]]** [[ARRAY]]
|
||||
// CHECK-LP64-NEXT: [[ZERO:%.*]] = bitcast [[ARRAY_T]]** [[ARRAY]] to i8**
|
||||
// CHECK-LP64-NEXT: [[ONE:%.*]] = bitcast [[ARRAY_T]]* {{%.*}} to i8*
|
||||
// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[ZERO]], i8* [[ONE]]) nounwind
|
||||
|
||||
// Initialize the fast enumaration state.
|
||||
// CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[STATE_T]]* [[STATE]] to i8*
|
||||
|
|
|
@ -8,8 +8,8 @@ void test0(Test0 *t0, id value) {
|
|||
t0.value = value;
|
||||
}
|
||||
// CHECK: define void @test0(
|
||||
// CHECK: call i8* @objc_retain(
|
||||
// CHECK: call i8* @objc_retain(
|
||||
// CHECK: call void @objc_storeStrong
|
||||
// CHECK: call void @objc_storeStrong
|
||||
// CHECK: @objc_msgSend
|
||||
// CHECK: call void @objc_storeStrong(
|
||||
// CHECK: call void @objc_storeStrong(
|
||||
|
|
|
@ -9,10 +9,10 @@ void test0(Test0 *val) {
|
|||
// CHECK: define void @test0(
|
||||
// CHECK: [[VAL:%.*]] = alloca [[TEST0:%.*]]*
|
||||
// CHECK-NEXT: [[X:%.*]] = alloca [[TEST0]]*
|
||||
// CHECK-NEXT: store [[TEST0]]* null
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: call i8* @objc_retain(
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: store
|
||||
// CHECK-NEXT: call void @objc_storeStrong(
|
||||
// CHECK-NEXT: load [[TEST0]]** [[VAL]],
|
||||
// CHECK-NEXT: load
|
||||
// CHECK-NEXT: bitcast
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
// RUN: %clang_cc1 -fobjc-runtime=macosx-10.6.0 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-ALIEN %s
|
||||
// RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
|
||||
|
||||
// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8*)
|
||||
// ARC-ALIEN: declare extern_weak void @objc_storeStrong(i8**, i8*)
|
||||
// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8*)
|
||||
// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8*)
|
||||
// ARC-ALIEN: declare i8* @objc_msgSend(i8*, i8*, ...) #1
|
||||
// ARC-ALIEN: declare extern_weak void @objc_release(i8*)
|
||||
|
@ -19,8 +19,8 @@
|
|||
// ARC-ALIEN: declare extern_weak i8* @objc_autorelease(i8*)
|
||||
// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8*)
|
||||
|
||||
// ARC-NATIVE: declare i8* @objc_retain(i8*) #1
|
||||
// ARC-NATIVE: declare void @objc_storeStrong(i8**, i8*)
|
||||
// ARC-NATIVE: declare i8* @objc_retain(i8*) #1
|
||||
// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8*)
|
||||
// ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) #1
|
||||
// ARC-NATIVE: declare void @objc_release(i8*) #1
|
||||
|
|
|
@ -62,12 +62,14 @@ typedef enum : NSUInteger {
|
|||
TMap *map = [TMap mapForID:mapID];
|
||||
// Make sure we do not map code generated for the block to the above line.
|
||||
// CHECK: define internal void @"__39-[TServer serverConnection:getCommand:]_block_invoke"
|
||||
// CHECK: call void @objc_storeStrong(i8** [[ZERO:%.*]], i8* [[ONE:%.*]]) nounwind
|
||||
// CHECK: call void @objc_storeStrong(i8** [[TWO:%.*]], i8* [[THREE:%.*]]) nounwind
|
||||
// CHECK: bitcast %5** [[TMP:%.*]] to i8**
|
||||
// CHECK: call void @objc_storeStrong(i8** [[VAL1:%.*]], i8* null) nounwind, !dbg ![[MD1:.*]]
|
||||
// CHECK: bitcast %4** [[TMP:%.*]] to i8**
|
||||
// CHECK: call void @objc_storeStrong(i8** [[VAL2:%.*]], i8* null) nounwind, !dbg ![[MD1]]
|
||||
// CHECK-NEXT: ret
|
||||
// CHECK: ![[MD1]] = metadata !{i32 84
|
||||
// CHECK: ![[MD1]] = metadata !{i32 86
|
||||
[map dataWithCompletionBlock:^(NSData *data, NSError *error) {
|
||||
if (data) {
|
||||
NSString *encoded = [[data compressedData] encodedString:18];
|
||||
|
|
|
@ -5,8 +5,9 @@ typedef __weak id weak_id;
|
|||
|
||||
// CHECK: define void @_Z8test_newP11objc_object
|
||||
void test_new(id invalue) {
|
||||
// CHECK: alloca i8*
|
||||
// CHECK-NEXT: call i8* @objc_retain
|
||||
// CHECK: [[INVALUEADDR:%.*]] = alloca i8*
|
||||
// CHECK-NEXT: store i8* null, i8** [[INVALUEADDR]]
|
||||
// CHECK-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]])
|
||||
|
||||
// CHECK: call noalias i8* @_Znwm
|
||||
// CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
|
||||
|
|
Loading…
Reference in New Issue