Add objc.* ARC intrinsics and codegen them to their runtime methods.
authorPete Cooper <peter_cooper@apple.com>
Thu, 6 Dec 2018 00:52:54 +0000 (00:52 +0000)
committerPete Cooper <peter_cooper@apple.com>
Thu, 6 Dec 2018 00:52:54 +0000 (00:52 +0000)
Reviewers: erik.pilkington, ahatanak

Differential Revision: https://reviews.llvm.org/D55233

llvm-svn: 348441

llvm/include/llvm/IR/Intrinsics.td
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/test/CodeGen/X86/objc-arc.ll [new file with mode: 0644]

index 4213d75..460f4e4 100644 (file)
@@ -319,6 +319,50 @@ def int_gcwrite : Intrinsic<[],
                             [llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
                             [IntrArgMemOnly, NoCapture<1>, NoCapture<2>]>;
 
+//===------------------- ObjC ARC runtime Intrinsics --------------------===//
+//
+// Note these are to support the Objective-C ARC optimizer which wants to
+// eliminate retain and releases where possible.
+
+def int_objc_autorelease                    : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_autoreleasePoolPop             : Intrinsic<[], [llvm_ptr_ty]>;
+def int_objc_autoreleasePoolPush            : Intrinsic<[llvm_ptr_ty], []>;
+def int_objc_autoreleaseReturnValue         : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_copyWeak                       : Intrinsic<[],
+                                                        [llvm_ptrptr_ty,
+                                                         llvm_ptrptr_ty]>;
+def int_objc_destroyWeak                    : Intrinsic<[], [llvm_ptrptr_ty]>;
+def int_objc_initWeak                       : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptrptr_ty,
+                                                         llvm_ptr_ty]>;
+def int_objc_loadWeak                       : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptrptr_ty]>;
+def int_objc_loadWeakRetained               : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptrptr_ty]>;
+def int_objc_moveWeak                       : Intrinsic<[],
+                                                        [llvm_ptrptr_ty,
+                                                         llvm_ptrptr_ty]>;
+def int_objc_release                        : Intrinsic<[], [llvm_ptr_ty]>;
+def int_objc_retain                         : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_retainAutorelease              : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_retainAutoreleaseReturnValue   : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_retainAutoreleasedReturnValue  : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_retainBlock                    : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptr_ty]>;
+def int_objc_storeStrong                    : Intrinsic<[],
+                                                        [llvm_ptrptr_ty,
+                                                         llvm_ptr_ty]>;
+def int_objc_storeWeak                      : Intrinsic<[llvm_ptr_ty],
+                                                        [llvm_ptrptr_ty,
+                                                         llvm_ptr_ty]>;
+
+
 //===--------------------- Code Generator Intrinsics ----------------------===//
 //
 def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
index d0d748f..eb36bae 100644 (file)
@@ -6354,6 +6354,42 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
     // MachineFunction in SelectionDAGISel::PrepareEHLandingPad. We can safely
     // delete it now.
     return nullptr;
+  case Intrinsic::objc_autorelease:
+    return "objc_autorelease";
+  case Intrinsic::objc_autoreleasePoolPop:
+    return "objc_autoreleasePoolPop";
+  case Intrinsic::objc_autoreleasePoolPush:
+    return "objc_autoreleasePoolPush";
+  case Intrinsic::objc_autoreleaseReturnValue:
+    return "objc_autoreleaseReturnValue";
+  case Intrinsic::objc_copyWeak:
+    return "objc_copyWeak";
+  case Intrinsic::objc_destroyWeak:
+    return "objc_destroyWeak";
+  case Intrinsic::objc_initWeak:
+    return "objc_initWeak";
+  case Intrinsic::objc_loadWeak:
+    return "objc_loadWeak";
+  case Intrinsic::objc_loadWeakRetained:
+    return "objc_loadWeakRetained";
+  case Intrinsic::objc_moveWeak:
+    return "objc_moveWeak";
+  case Intrinsic::objc_release:
+    return "objc_release";
+  case Intrinsic::objc_retain:
+    return "objc_retain";
+  case Intrinsic::objc_retainAutorelease:
+    return "objc_retainAutorelease";
+  case Intrinsic::objc_retainAutoreleaseReturnValue:
+    return "objc_retainAutoreleaseReturnValue";
+  case Intrinsic::objc_retainAutoreleasedReturnValue:
+    return "objc_retainAutoreleasedReturnValue";
+  case Intrinsic::objc_retainBlock:
+    return "objc_retainBlock";
+  case Intrinsic::objc_storeStrong:
+    return "objc_storeStrong";
+  case Intrinsic::objc_storeWeak:
+    return "objc_storeWeak";
   }
 }
 
diff --git a/llvm/test/CodeGen/X86/objc-arc.ll b/llvm/test/CodeGen/X86/objc-arc.ll
new file mode 100644 (file)
index 0000000..7230469
--- /dev/null
@@ -0,0 +1,167 @@
+; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
+
+; Make sure calls to the objc intrinsics are translated to calls in to the
+; runtime
+
+define i8* @test_objc_autorelease(i8* %arg0) {
+; CHECK-LABEL: test_objc_autorelease
+; CHECK: callq _objc_autorelease
+entry:
+    %0 = call i8* @llvm.objc.autorelease(i8* %arg0)
+       ret i8* %0
+}
+
+define void @test_objc_autoreleasePoolPop(i8* %arg0) {
+; CHECK-LABEL: test_objc_autoreleasePoolPop
+; CHECK: callq _objc_autoreleasePoolPop
+entry:
+    call void @llvm.objc.autoreleasePoolPop(i8* %arg0)
+    ret void
+}
+
+define i8* @test_objc_autoreleasePoolPush() {
+; CHECK-LABEL: test_objc_autoreleasePoolPush
+; CHECK: callq _objc_autoreleasePoolPush
+entry:
+    %0 = call i8* @llvm.objc.autoreleasePoolPush()
+       ret i8* %0
+}
+
+define i8* @test_objc_autoreleaseReturnValue(i8* %arg0) {
+; CHECK-LABEL: test_objc_autoreleaseReturnValue
+; CHECK: callq _objc_autoreleaseReturnValue
+entry:
+    %0 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %arg0)
+       ret i8* %0
+}
+
+define void @test_objc_copyWeak(i8** %arg0, i8** %arg1) {
+; CHECK-LABEL: test_objc_copyWeak
+; CHECK: callq _objc_copyWeak
+entry:
+    call void @llvm.objc.copyWeak(i8** %arg0, i8** %arg1)
+    ret void
+}
+
+define void @test_objc_destroyWeak(i8** %arg0) {
+; CHECK-LABEL: test_objc_destroyWeak
+; CHECK: callq _objc_destroyWeak
+entry:
+    call void @llvm.objc.destroyWeak(i8** %arg0)
+    ret void
+}
+
+define i8* @test_objc_initWeak(i8** %arg0, i8* %arg1) {
+; CHECK-LABEL: test_objc_initWeak
+; CHECK: callq _objc_initWeak
+entry:
+    %0 = call i8* @llvm.objc.initWeak(i8** %arg0, i8* %arg1)
+       ret i8* %0
+}
+
+define i8* @test_objc_loadWeak(i8** %arg0) {
+; CHECK-LABEL: test_objc_loadWeak
+; CHECK: callq _objc_loadWeak
+entry:
+    %0 = call i8* @llvm.objc.loadWeak(i8** %arg0)
+       ret i8* %0
+}
+
+define i8* @test_objc_loadWeakRetained(i8** %arg0) {
+; CHECK-LABEL: test_objc_loadWeakRetained
+; CHECK: callq _objc_loadWeakRetained
+entry:
+    %0 = call i8* @llvm.objc.loadWeakRetained(i8** %arg0)
+       ret i8* %0
+}
+
+define void @test_objc_moveWeak(i8** %arg0, i8** %arg1) {
+; CHECK-LABEL: test_objc_moveWeak
+; CHECK: callq _objc_moveWeak
+entry:
+    call void @llvm.objc.moveWeak(i8** %arg0, i8** %arg1)
+    ret void
+}
+
+define void @test_objc_release(i8* %arg0) {
+; CHECK-LABEL: test_objc_release
+; CHECK: callq _objc_release
+entry:
+    call void @llvm.objc.release(i8* %arg0)
+    ret void
+}
+
+define i8* @test_objc_retain(i8* %arg0) {
+; CHECK-LABEL: test_objc_retain
+; CHECK: callq _objc_retain
+entry:
+    %0 = call i8* @llvm.objc.retain(i8* %arg0)
+       ret i8* %0
+}
+
+define i8* @test_objc_retainAutorelease(i8* %arg0) {
+; CHECK-LABEL: test_objc_retainAutorelease
+; CHECK: callq _objc_retainAutorelease
+entry:
+    %0 = call i8* @llvm.objc.retainAutorelease(i8* %arg0)
+       ret i8* %0
+}
+
+define i8* @test_objc_retainAutoreleaseReturnValue(i8* %arg0) {
+; CHECK-LABEL: test_objc_retainAutoreleaseReturnValue
+; CHECK: callq _objc_retainAutoreleaseReturnValue
+entry:
+    %0 = call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* %arg0)
+       ret i8* %0
+}
+
+define i8* @test_objc_retainAutoreleasedReturnValue(i8* %arg0) {
+; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue
+; CHECK: callq _objc_retainAutoreleasedReturnValue
+entry:
+    %0 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %arg0)
+       ret i8* %0
+}
+
+define i8* @test_objc_retainBlock(i8* %arg0) {
+; CHECK-LABEL: test_objc_retainBlock
+; CHECK: callq _objc_retainBlock
+entry:
+    %0 = call i8* @llvm.objc.retainBlock(i8* %arg0)
+       ret i8* %0
+}
+
+define void @test_objc_storeStrong(i8** %arg0, i8* %arg1) {
+; CHECK-LABEL: test_objc_storeStrong
+; CHECK: callq _objc_storeStrong
+entry:
+    call void @llvm.objc.storeStrong(i8** %arg0, i8* %arg1)
+       ret void
+}
+
+define i8* @test_objc_storeWeak(i8** %arg0, i8* %arg1) {
+; CHECK-LABEL: test_objc_storeWeak
+; CHECK: callq _objc_storeWeak
+entry:
+    %0 = call i8* @llvm.objc.storeWeak(i8** %arg0, i8* %arg1)
+       ret i8* %0
+}
+
+declare i8* @llvm.objc.autorelease(i8*)
+declare void @llvm.objc.autoreleasePoolPop(i8*)
+declare i8* @llvm.objc.autoreleasePoolPush()
+declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
+declare void @llvm.objc.copyWeak(i8**, i8**)
+declare void @llvm.objc.destroyWeak(i8**)
+declare i8* @llvm.objc.initWeak(i8**, i8*)
+declare i8* @llvm.objc.loadWeak(i8**)
+declare i8* @llvm.objc.loadWeakRetained(i8**)
+declare void @llvm.objc.moveWeak(i8**, i8**)
+declare void @llvm.objc.release(i8*)
+declare i8* @llvm.objc.retain(i8*)
+declare i8* @llvm.objc.retainAutorelease(i8*)
+declare i8* @llvm.objc.retainAutoreleaseReturnValue(i8*)
+declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
+declare i8* @llvm.objc.retainBlock(i8*)
+declare void @llvm.objc.storeStrong(i8**, i8*)
+declare i8* @llvm.objc.storeWeak(i8**, i8*)