From: Pete Cooper Date: Thu, 6 Dec 2018 00:52:54 +0000 (+0000) Subject: Add objc.* ARC intrinsics and codegen them to their runtime methods. X-Git-Tag: llvmorg-8.0.0-rc1~2762 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e13d0992dcd0649bee760d3d606b9353edfd1ebc;p=platform%2Fupstream%2Fllvm.git Add objc.* ARC intrinsics and codegen them to their runtime methods. Reviewers: erik.pilkington, ahatanak Differential Revision: https://reviews.llvm.org/D55233 llvm-svn: 348441 --- diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 4213d75..460f4e4 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -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]>; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index d0d748f..eb36bae 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -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 index 0000000..7230469 --- /dev/null +++ b/llvm/test/CodeGen/X86/objc-arc.ll @@ -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*)