Skip to content

Commit 9326ef4

Browse files
gottesmmbob-wilson
authored andcommitted
[upstream-update] Update LLVMPasses for new objc arc intrinsics.
We used to represent these just as normal LLVM functions, e.x.: declare objc_object* @objc_retain(objc_object*) declare void @objc_release(objc_object*) Recently, special objc intrinsics were added to LLVM. This pass updates these small (old) passes to use the new intrinsics. This turned out to not be too difficult since we never create these instructions. We only analyze them, move them, and delete them. rdar://47852297
1 parent b1be41a commit 9326ef4

File tree

7 files changed

+60
-42
lines changed

7 files changed

+60
-42
lines changed

lib/LLVMPasses/ARCEntryPointBuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ class ARCEntryPointBuilder {
194194
}
195195

196196
bool isNonAtomic(CallInst *I) {
197+
// If we have an intrinsic, we know it must be an objc intrinsic. All objc
198+
// intrinsics are atomic today.
199+
if (I->getIntrinsicID() != llvm::Intrinsic::not_intrinsic)
200+
return false;
197201
return (I->getCalledFunction()->getName().find("nonatomic") !=
198202
llvm::StringRef::npos);
199203
}

lib/LLVMPasses/LLVMARCOpts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ static bool performLocalRetainMotion(CallInst &Retain, BasicBlock &BB,
413413
BasicBlock::iterator BBI = Retain.getIterator(),
414414
BBE = BB.getTerminator()->getIterator();
415415

416-
bool isObjCRetain = Retain.getCalledFunction()->getName() == "objc_retain";
416+
bool isObjCRetain = Retain.getIntrinsicID() == llvm::Intrinsic::objc_retain;
417417

418418
bool MadeProgress = false;
419419

lib/LLVMPasses/LLVMARCOpts.h

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414

1515
#include "swift/Basic/LLVM.h"
1616
#include "swift/Runtime/Config.h"
17-
#include "llvm/IR/Instructions.h"
18-
#include "llvm/IR/Function.h"
1917
#include "llvm/ADT/StringSwitch.h"
18+
#include "llvm/IR/Function.h"
19+
#include "llvm/IR/Instructions.h"
20+
#include "llvm/IR/Intrinsics.h"
2021

2122
namespace swift {
2223

@@ -25,23 +26,40 @@ enum RT_Kind {
2526
#include "LLVMSwift.def"
2627
};
2728

28-
/// classifyInstruction - Take a look at the specified instruction and classify
29-
/// it into what kind of runtime entrypoint it is, if any.
29+
/// Take a look at the specified instruction and classify it into what kind of
30+
/// runtime entrypoint it is, if any.
3031
inline RT_Kind classifyInstruction(const llvm::Instruction &I) {
3132
if (!I.mayReadOrWriteMemory())
3233
return RT_NoMemoryAccessed;
3334

3435
// Non-calls or calls to indirect functions are unknown.
3536
auto *CI = dyn_cast<llvm::CallInst>(&I);
3637
if (CI == 0) return RT_Unknown;
38+
39+
// First check if we have an objc intrinsic.
40+
auto intrinsic = CI->getIntrinsicID();
41+
switch (intrinsic) {
42+
// This is an intrinsic that we do not understand. It can not be one of our
43+
// "special" runtime functions as well... so return RT_Unknown early.
44+
default:
45+
return RT_Unknown;
46+
case llvm::Intrinsic::not_intrinsic:
47+
// If we do not have an intrinsic, break and move onto runtime functions
48+
// that we identify by name.
49+
break;
50+
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
51+
case llvm::Intrinsic::objc_##TextualName: \
52+
return RT_##Name;
53+
#include "LLVMSwift.def"
54+
}
55+
3756
llvm::Function *F = CI->getCalledFunction();
38-
if (F == 0) return RT_Unknown;
57+
if (F == nullptr)
58+
return RT_Unknown;
3959

4060
return llvm::StringSwitch<RT_Kind>(F->getName())
4161
#define SWIFT_FUNC(Name, MemBehavior, TextualName) \
4262
.Case("swift_" #TextualName, RT_ ## Name)
43-
#define OBJC_FUNC(Name, MemBehavior, TextualName) \
44-
.Case("objc_" #TextualName, RT_ ## Name)
4563
#define SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(Name, MemBehavior, TextualName) \
4664
.Case("__swift_" #TextualName, RT_ ## Name)
4765
#include "LLVMSwift.def"

lib/LLVMPasses/LLVMSwift.def

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- LLVMSwift.def ----------------------------------------------------===//
1+
//===--- LLVMSwift.def ----------------------------------*- C++ -*---------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -142,7 +142,6 @@ SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC(EndBorrow, ModRef, endBorrow)
142142
/// or is a call to something we don't care about.
143143
KIND(Unknown, ModRef)
144144

145-
#undef OBJC_NEVER_NONATOMIC_FUNC
146145
#undef SWIFT_INTERNAL_FUNC_NEVER_NONATOMIC
147146
#undef SWIFT_NEVER_NONATOMIC_FUNC
148147
#undef OBJC_FUNC

test/LLVMPasses/allocation-deletion.ll

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ target triple = "x86_64-apple-macosx10.9"
55

66
%swift.refcounted = type { %swift.heapmetadata*, i64 }
77
%swift.heapmetadata = type { i64 (%swift.refcounted*)*, i64 (%swift.refcounted*)* }
8-
%objc_object = type opaque
98

10-
declare %objc_object* @objc_retain(%objc_object*)
11-
declare void @objc_release(%objc_object*)
129
declare %swift.refcounted* @swift_allocObject(%swift.heapmetadata* , i64, i64) nounwind
1310
declare void @swift_release(%swift.refcounted* nocapture)
1411
declare void @swift_retain(%swift.refcounted* ) nounwind

test/LLVMPasses/basic.ll

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ target triple = "x86_64-apple-macosx10.9"
1010

1111
declare %swift.refcounted* @swift_unknownObjectRetain(%swift.refcounted* returned)
1212
declare void @swift_unknownObjectRelease(%swift.refcounted*)
13-
declare %objc_object* @objc_retain(%objc_object*)
14-
declare void @objc_release(%objc_object*)
13+
declare i8* @llvm.objc.retain(i8*)
14+
declare void @llvm.objc.release(i8*)
1515
declare %swift.refcounted* @swift_allocObject(%swift.heapmetadata* , i64, i64) nounwind
1616
declare void @swift_release(%swift.refcounted* nocapture)
1717
declare %swift.refcounted* @swift_retain(%swift.refcounted* returned) nounwind
@@ -20,7 +20,7 @@ declare void @swift_bridgeObjectRelease(%swift.bridge*)
2020
declare %swift.refcounted* @swift_retainUnowned(%swift.refcounted* returned)
2121

2222
declare void @user(%swift.refcounted *) nounwind
23-
declare void @user_objc(%objc_object*) nounwind
23+
declare void @user_objc(i8*) nounwind
2424
declare void @unknown_func()
2525

2626
define private void @__swift_fixLifetime(%swift.refcounted*) noinline nounwind {
@@ -30,16 +30,16 @@ entry:
3030

3131
; CHECK-LABEL: @trivial_objc_canonicalization(
3232
; CHECK-NEXT: entry:
33-
; CHECK-NEXT: [[RET0:%.+]] = bitcast i8* %O to %objc_object*
34-
; CHECK-NEXT: [[RET1:%.+]] = tail call %objc_object* @objc_retain(%objc_object* [[RET0:%.+]])
35-
; CHECK-NEXT: call void @user_objc(%objc_object* [[RET0:%.+]])
33+
; CHECK-NEXT: [[RET0:%.+]] = bitcast i8* %O to i8*
34+
; CHECK-NEXT: [[RET1:%.+]] = tail call i8* @llvm.objc.retain(i8* [[RET0:%.+]])
35+
; CHECK-NEXT: call void @user_objc(i8* [[RET0:%.+]])
3636
; CHECK-NEXT: ret void
3737

3838
define void @trivial_objc_canonicalization(i8* %O) {
3939
entry:
40-
%0 = bitcast i8* %O to %objc_object*
41-
%1 = tail call %objc_object* @objc_retain(%objc_object* %0)
42-
call void @user_objc(%objc_object* %1) nounwind
40+
%0 = bitcast i8* %O to i8*
41+
%1 = tail call i8* @llvm.objc.retain(i8* %0)
42+
call void @user_objc(i8* %1) nounwind
4343
ret void
4444
}
4545

@@ -48,14 +48,14 @@ entry:
4848
; CHECK-NEXT: call void @user
4949
; CHECK-NEXT: ret void
5050

51-
define void @trivial_retain_release(%swift.refcounted* %P, %objc_object* %O, %swift.bridge * %B) {
51+
define void @trivial_retain_release(%swift.refcounted* %P, i8* %O, %swift.bridge * %B) {
5252
entry:
5353
tail call %swift.refcounted* @swift_retain(%swift.refcounted* %P)
5454
tail call void @swift_release(%swift.refcounted* %P) nounwind
5555
tail call %swift.refcounted* @swift_unknownObjectRetain(%swift.refcounted* %P)
5656
tail call void @swift_unknownObjectRelease(%swift.refcounted* %P)
57-
tail call %objc_object* @objc_retain(%objc_object* %O)
58-
tail call void @objc_release(%objc_object* %O)
57+
tail call i8* @llvm.objc.retain(i8* %O)
58+
tail call void @llvm.objc.release(i8* %O)
5959
%v = tail call %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge* %B)
6060
tail call void @swift_bridgeObjectRelease(%swift.bridge* %v)
6161
call void @user(%swift.refcounted* %P) nounwind
@@ -66,21 +66,21 @@ entry:
6666
; CHECK-NEXT: entry:
6767
; CHECK-NEXT: [[RET0:%.+]] = bitcast %swift.refcounted* %P to %swift.refcounted*
6868
; CHECK-NEXT: [[RET1:%.+]] = bitcast %swift.refcounted* %P to %swift.refcounted*
69-
; CHECK-NEXT: [[RET2:%.+]] = bitcast %objc_object* %O to %objc_object*
69+
; CHECK-NEXT: [[RET2:%.+]] = bitcast i8* %O to i8*
7070
; CHECK-NEXT: call void @user
7171
; CHECK-NEXT: ret void
7272

73-
define void @trivial_retain_release_with_rcidentity(%swift.refcounted* %P, %objc_object* %O, %swift.bridge * %B) {
73+
define void @trivial_retain_release_with_rcidentity(%swift.refcounted* %P, i8* %O, %swift.bridge * %B) {
7474
entry:
7575
tail call %swift.refcounted* @swift_retain(%swift.refcounted* %P)
7676
%1 = bitcast %swift.refcounted* %P to %swift.refcounted*
7777
tail call void @swift_release(%swift.refcounted* %1) nounwind
7878
tail call %swift.refcounted* @swift_unknownObjectRetain(%swift.refcounted* %P)
7979
%3 = bitcast %swift.refcounted* %P to %swift.refcounted*
8080
tail call void @swift_unknownObjectRelease(%swift.refcounted* %3)
81-
tail call %objc_object* @objc_retain(%objc_object* %O)
82-
%5 = bitcast %objc_object* %O to %objc_object*
83-
tail call void @objc_release(%objc_object* %5)
81+
tail call i8* @llvm.objc.retain(i8* %O)
82+
%5 = bitcast i8* %O to i8*
83+
tail call void @llvm.objc.release(i8* %5)
8484
call void @user(%swift.refcounted* %P) nounwind
8585
ret void
8686
}
@@ -110,8 +110,8 @@ define void @retain_motion1(%swift.refcounted* %A) {
110110

111111
define void @objc_retain_release_null() {
112112
entry:
113-
tail call void @objc_release(%objc_object* null) nounwind
114-
tail call %objc_object* @objc_retain(%objc_object* null)
113+
tail call void @llvm.objc.release(i8* null) nounwind
114+
tail call i8* @llvm.objc.retain(i8* null)
115115
ret void
116116
}
117117

@@ -132,10 +132,10 @@ entry:
132132
; CHECK-NEXT: store i32 42
133133
; CHECK-NEXT: ret void
134134

135-
define void @objc_retain_release_opt(%objc_object* %P, i32* %IP) {
136-
tail call %objc_object* @objc_retain(%objc_object* %P) nounwind
135+
define void @objc_retain_release_opt(i8* %P, i32* %IP) {
136+
tail call i8* @llvm.objc.retain(i8* %P) nounwind
137137
store i32 42, i32* %IP
138-
tail call void @objc_release(%objc_object* %P) nounwind
138+
tail call void @llvm.objc.release(i8* %P) nounwind
139139
ret void
140140
}
141141

@@ -165,12 +165,12 @@ define void @move_retain_across_unknown_retain(%swift.refcounted* %A, %swift.ref
165165

166166
; CHECK-LABEL: @move_retain_across_objc_retain
167167
; CHECK-NOT: swift_retain
168-
; CHECK: objc_retain
168+
; CHECK: llvm.objc.retain
169169
; CHECK-NOT: swift_release
170170
; CHECK: ret
171-
define void @move_retain_across_objc_retain(%swift.refcounted* %A, %objc_object* %B) {
171+
define void @move_retain_across_objc_retain(%swift.refcounted* %A, i8* %B) {
172172
tail call %swift.refcounted* @swift_retain(%swift.refcounted* %A)
173-
tail call %objc_object* @objc_retain(%objc_object* %B)
173+
tail call i8* @llvm.objc.retain(i8* %B)
174174
tail call void @swift_release(%swift.refcounted* %A) nounwind
175175
ret void
176176
}

test/LLVMPasses/disable_llvm_optzns.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ target triple = "x86_64-apple-macosx10.9"
1313

1414
declare %swift.refcounted* @swift_unknownObjectRetain(%swift.refcounted* returned)
1515
declare void @swift_unknownObjectRelease(%swift.refcounted*)
16-
declare %objc_object* @objc_retain(%objc_object*)
17-
declare void @objc_release(%objc_object*)
16+
declare i8* @llvm.objc.retain(i8*)
17+
declare void @llvm.objc.release(i8*)
1818
declare %swift.refcounted* @swift_allocObject(%swift.heapmetadata* , i64, i64) nounwind
1919
declare void @swift_release(%swift.refcounted* nocapture)
2020
declare %swift.refcounted* @swift_retain(%swift.refcounted* returned) nounwind
@@ -23,7 +23,7 @@ declare void @swift_bridgeObjectRelease(%swift.bridge*)
2323
declare %swift.refcounted* @swift_retainUnowned(%swift.refcounted* returned)
2424

2525
declare void @user(%swift.refcounted *) nounwind
26-
declare void @user_objc(%objc_object*) nounwind
26+
declare void @user_objc(i8*) nounwind
2727
declare void @unknown_func()
2828

2929
; CHECK-LABEL: @trivial_retain_release(
@@ -37,7 +37,7 @@ declare void @unknown_func()
3737
; NEGATIVE-NEXT: entry:
3838
; NEGATIVE-NEXT: call void @user(
3939
; NEGATIVE-NEXT: ret void
40-
define void @trivial_retain_release(%swift.refcounted* %P, %objc_object* %O, %swift.bridge * %B) {
40+
define void @trivial_retain_release(%swift.refcounted* %P, i8* %O, %swift.bridge * %B) {
4141
entry:
4242
call %swift.refcounted* @swift_retain(%swift.refcounted* %P)
4343
call void @swift_release(%swift.refcounted* %P) nounwind

0 commit comments

Comments
 (0)