Skip to content

Commit 59cc39a

Browse files
committed
[ObjC][ARC] Use the addresses of the ARC runtime functions instead of
integer 0/1 for the operand of bundle "clang.arc.attachedcall" This should make it easier to understand what the IR is doing and also simplify some of the passes as they no longer have to translate the integer values to the runtime functions. Differential Revision: https://reviews.llvm.org/D102996
1 parent ff77c4e commit 59cc39a

File tree

3 files changed

+45
-57
lines changed

3 files changed

+45
-57
lines changed

clang/lib/CodeGen/CGObjC.cpp

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,13 @@ static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM,
21082108
setARCRuntimeFunctionLinkage(CGM, RTF.getCallee());
21092109
}
21102110

2111+
static llvm::Function *getARCIntrinsic(llvm::Intrinsic::ID IntID,
2112+
CodeGenModule &CGM) {
2113+
llvm::Function *fn = CGM.getIntrinsic(IntID);
2114+
setARCRuntimeFunctionLinkage(CGM, fn);
2115+
return fn;
2116+
}
2117+
21112118
/// Perform an operation having the signature
21122119
/// i8* (i8*)
21132120
/// where a null input causes a no-op and returns null.
@@ -2118,10 +2125,8 @@ static llvm::Value *emitARCValueOperation(
21182125
if (isa<llvm::ConstantPointerNull>(value))
21192126
return value;
21202127

2121-
if (!fn) {
2122-
fn = CGF.CGM.getIntrinsic(IntID);
2123-
setARCRuntimeFunctionLinkage(CGF.CGM, fn);
2124-
}
2128+
if (!fn)
2129+
fn = getARCIntrinsic(IntID, CGF.CGM);
21252130

21262131
// Cast the argument to 'id'.
21272132
llvm::Type *origType = returnType ? returnType : value->getType();
@@ -2140,10 +2145,8 @@ static llvm::Value *emitARCValueOperation(
21402145
static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr,
21412146
llvm::Function *&fn,
21422147
llvm::Intrinsic::ID IntID) {
2143-
if (!fn) {
2144-
fn = CGF.CGM.getIntrinsic(IntID);
2145-
setARCRuntimeFunctionLinkage(CGF.CGM, fn);
2146-
}
2148+
if (!fn)
2149+
fn = getARCIntrinsic(IntID, CGF.CGM);
21472150

21482151
// Cast the argument to 'id*'.
21492152
llvm::Type *origType = addr.getElementType();
@@ -2168,10 +2171,8 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr,
21682171
bool ignored) {
21692172
assert(addr.getElementType() == value->getType());
21702173

2171-
if (!fn) {
2172-
fn = CGF.CGM.getIntrinsic(IntID);
2173-
setARCRuntimeFunctionLinkage(CGF.CGM, fn);
2174-
}
2174+
if (!fn)
2175+
fn = getARCIntrinsic(IntID, CGF.CGM);
21752176

21762177
llvm::Type *origType = value->getType();
21772178

@@ -2193,10 +2194,8 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src,
21932194
llvm::Intrinsic::ID IntID) {
21942195
assert(dst.getType() == src.getType());
21952196

2196-
if (!fn) {
2197-
fn = CGF.CGM.getIntrinsic(IntID);
2198-
setARCRuntimeFunctionLinkage(CGF.CGM, fn);
2199-
}
2197+
if (!fn)
2198+
fn = getARCIntrinsic(IntID, CGF.CGM);
22002199

22012200
llvm::Value *args[] = {
22022201
CGF.Builder.CreateBitCast(dst.getPointer(), CGF.Int8PtrPtrTy),
@@ -2340,13 +2339,19 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
23402339
// retainRV or claimRV calls in the IR. We currently do this only when the
23412340
// optimization level isn't -O0 since global-isel, which is currently run at
23422341
// -O0, doesn't know about the operand bundle.
2342+
ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints();
2343+
llvm::Function *&EP = IsRetainRV
2344+
? EPs.objc_retainAutoreleasedReturnValue
2345+
: EPs.objc_unsafeClaimAutoreleasedReturnValue;
2346+
llvm::Intrinsic::ID IID =
2347+
IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2348+
: llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
2349+
EP = getARCIntrinsic(IID, CGF.CGM);
23432350

23442351
// FIXME: Do this when the target isn't aarch64.
23452352
if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 &&
23462353
CGF.CGM.getTarget().getTriple().isAArch64()) {
2347-
llvm::Value *bundleArgs[] = {llvm::ConstantInt::get(
2348-
CGF.Int64Ty,
2349-
llvm::objcarc::getAttachedCallOperandBundleEnum(IsRetainRV))};
2354+
llvm::Value *bundleArgs[] = {EP};
23502355
llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);
23512356
auto *oldCall = cast<llvm::CallBase>(value);
23522357
llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
@@ -2362,13 +2367,6 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
23622367
CGF.CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail();
23632368
llvm::CallInst::TailCallKind tailKind =
23642369
isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
2365-
ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints();
2366-
llvm::Function *&EP = IsRetainRV
2367-
? EPs.objc_retainAutoreleasedReturnValue
2368-
: EPs.objc_unsafeClaimAutoreleasedReturnValue;
2369-
llvm::Intrinsic::ID IID =
2370-
IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2371-
: llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
23722370
return emitARCValueOperation(CGF, value, nullptr, EP, IID, tailKind);
23732371
}
23742372

@@ -2401,10 +2399,8 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value,
24012399
if (isa<llvm::ConstantPointerNull>(value)) return;
24022400

24032401
llvm::Function *&fn = CGM.getObjCEntrypoints().objc_release;
2404-
if (!fn) {
2405-
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_release);
2406-
setARCRuntimeFunctionLinkage(CGM, fn);
2407-
}
2402+
if (!fn)
2403+
fn = getARCIntrinsic(llvm::Intrinsic::objc_release, CGM);
24082404

24092405
// Cast the argument to 'id'.
24102406
value = Builder.CreateBitCast(value, Int8PtrTy);
@@ -2447,10 +2443,8 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr,
24472443
assert(addr.getElementType() == value->getType());
24482444

24492445
llvm::Function *&fn = CGM.getObjCEntrypoints().objc_storeStrong;
2450-
if (!fn) {
2451-
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_storeStrong);
2452-
setARCRuntimeFunctionLinkage(CGM, fn);
2453-
}
2446+
if (!fn)
2447+
fn = getARCIntrinsic(llvm::Intrinsic::objc_storeStrong, CGM);
24542448

24552449
llvm::Value *args[] = {
24562450
Builder.CreateBitCast(addr.getPointer(), Int8PtrPtrTy),
@@ -2603,10 +2597,8 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) {
26032597
/// Essentially objc_storeWeak(addr, nil).
26042598
void CodeGenFunction::EmitARCDestroyWeak(Address addr) {
26052599
llvm::Function *&fn = CGM.getObjCEntrypoints().objc_destroyWeak;
2606-
if (!fn) {
2607-
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_destroyWeak);
2608-
setARCRuntimeFunctionLinkage(CGM, fn);
2609-
}
2600+
if (!fn)
2601+
fn = getARCIntrinsic(llvm::Intrinsic::objc_destroyWeak, CGM);
26102602

26112603
// Cast the argument to 'id*'.
26122604
addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
@@ -2651,10 +2643,8 @@ void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr,
26512643
/// call i8* \@objc_autoreleasePoolPush(void)
26522644
llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
26532645
llvm::Function *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush;
2654-
if (!fn) {
2655-
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush);
2656-
setARCRuntimeFunctionLinkage(CGM, fn);
2657-
}
2646+
if (!fn)
2647+
fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush, CGM);
26582648

26592649
return EmitNounwindRuntimeCall(fn);
26602650
}
@@ -2679,10 +2669,8 @@ void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
26792669
EmitRuntimeCallOrInvoke(fn, value);
26802670
} else {
26812671
llvm::FunctionCallee &fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop;
2682-
if (!fn) {
2683-
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop);
2684-
setARCRuntimeFunctionLinkage(CGM, fn);
2685-
}
2672+
if (!fn)
2673+
fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop, CGM);
26862674

26872675
EmitRuntimeCall(fn, value);
26882676
}

clang/test/CodeGenObjC/arc-rv-attr.m

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void test_assign() {
1010
}
1111
// CHECK-LABEL: define{{.*}} void @test_assign()
1212
// CHECK: [[X:%.*]] = alloca i8*
13-
// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ]
13+
// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
1414
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
1515
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
1616
// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
@@ -25,7 +25,7 @@ void test_assign_assign() {
2525
// CHECK-LABEL: define{{.*}} void @test_assign_assign()
2626
// CHECK: [[X:%.*]] = alloca i8*
2727
// CHECK: [[Y:%.*]] = alloca i8*
28-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ]
28+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
2929
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
3030
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
3131
// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
@@ -44,7 +44,7 @@ void test_strong_assign_assign() {
4444
// CHECK-LABEL: define{{.*}} void @test_strong_assign_assign()
4545
// CHECK: [[X:%.*]] = alloca i8*
4646
// CHECK: [[Y:%.*]] = alloca i8*
47-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ]
47+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
4848
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
4949
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
5050
// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
@@ -67,7 +67,7 @@ void test_assign_strong_assign() {
6767
// CHECK-LABEL: define{{.*}} void @test_assign_strong_assign()
6868
// CHECK: [[X:%.*]] = alloca i8*
6969
// CHECK: [[Y:%.*]] = alloca i8*
70-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ]
70+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
7171
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
7272
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
7373
// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]]
@@ -87,7 +87,7 @@ void test_init() {
8787
}
8888
// CHECK-LABEL: define{{.*}} void @test_init()
8989
// CHECK: [[X:%.*]] = alloca i8*
90-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ]
90+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
9191
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
9292
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
9393
// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
@@ -102,7 +102,7 @@ void test_init_assignment() {
102102
// CHECK-LABEL: define{{.*}} void @test_init_assignment()
103103
// CHECK: [[X:%.*]] = alloca i8*
104104
// CHECK: [[Y:%.*]] = alloca i8*
105-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ]
105+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
106106
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
107107
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
108108
// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
@@ -120,7 +120,7 @@ void test_strong_init_assignment() {
120120
// CHECK-LABEL: define{{.*}} void @test_strong_init_assignment()
121121
// CHECK: [[X:%.*]] = alloca i8*
122122
// CHECK: [[Y:%.*]] = alloca i8*
123-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ]
123+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
124124
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
125125
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
126126
// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
@@ -140,7 +140,7 @@ void test_init_strong_assignment() {
140140
// CHECK-LABEL: define{{.*}} void @test_init_strong_assignment()
141141
// CHECK: [[X:%.*]] = alloca i8*
142142
// CHECK: [[Y:%.*]] = alloca i8*
143-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ]
143+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
144144
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
145145
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
146146
// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]]
@@ -159,15 +159,15 @@ void test_ignored() {
159159
makeA();
160160
}
161161
// CHECK-LABEL: define{{.*}} void @test_ignored()
162-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ]
162+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
163163
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
164164
// CHECK-NEXT: ret void
165165

166166
void test_cast_to_void() {
167167
(void) makeA();
168168
}
169169
// CHECK-LABEL: define{{.*}} void @test_cast_to_void()
170-
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ]
170+
// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
171171
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
172172
// CHECK-NEXT: ret void
173173

clang/test/CodeGenObjCXX/arc-rv-attr.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
id foo(void);
44

55
// CHECK-LABEL: define{{.*}} void @_Z14test_list_initv(
6-
// CHECK: %[[CALL1:.*]] = call i8* @_Z3foov() [ "clang.arc.attachedcall"(i64 0) ]
6+
// CHECK: %[[CALL1:.*]] = call i8* @_Z3foov() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
77
// CHECK: call i8* @llvm.objc.retain(i8* %[[CALL1]])
88

99
void test_list_init() {

0 commit comments

Comments
 (0)