[llvm] 8f8d9f7 - [ObjC][ARC] Handle operand bundle "clang.arc.attachedcall" on targets
Akira Hatanaka via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 8 18:40:19 PST 2021
Author: Akira Hatanaka
Date: 2021-11-08T18:38:39-08:00
New Revision: 8f8d9f743d317ca05ed2fac241fd9abc806d4c26
URL: https://github.com/llvm/llvm-project/commit/8f8d9f743d317ca05ed2fac241fd9abc806d4c26
DIFF: https://github.com/llvm/llvm-project/commit/8f8d9f743d317ca05ed2fac241fd9abc806d4c26.diff
LOG: [ObjC][ARC] Handle operand bundle "clang.arc.attachedcall" on targets
that don't use the inline asm marker
This patch makes the changes to the ARC middle-end passes that are
needed to handle operand bundle "clang.arc.attachedcall" on targets that
don't use the inline asm marker for the retainRV/autoreleaseRV
handshake (e.g., x86-64).
Note that anyone who wants to use the operand bundle on their target has
to teach their backend to handle the operand bundle. The x86-64 backend
already knows about the operand bundle (see
https://reviews.llvm.org/D94597).
Differential Revision: https://reviews.llvm.org/D111334
Added:
llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll
Modified:
llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
llvm/lib/Transforms/ObjCARC/ObjCARC.h
llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
index a0c9caa6d26cc..1ca6ddabac5bc 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
@@ -124,14 +124,19 @@ BundledRetainClaimRVs::~BundledRetainClaimRVs() {
if (auto *CI = dyn_cast<CallInst>(CB))
CI->setTailCallKind(CallInst::TCK_NoTail);
- // Remove the ARC intrinsic function operand from the operand bundle.
- OperandBundleDef OB("clang.arc.attachedcall", None);
- auto *NewCB = CallBase::Create(CB, OB, CB);
- CB->replaceAllUsesWith(NewCB);
- CB->eraseFromParent();
- } else {
- EraseInstruction(P.first);
+ if (UseMarker) {
+ // Remove the retainRV/claimRV function operand from the operand bundle
+ // to reflect the fact that the backend is responsible for emitting only
+ // the marker instruction, but not the retainRV/claimRV call.
+ OperandBundleDef OB("clang.arc.attachedcall", None);
+ auto *NewCB = CallBase::Create(CB, OB, CB);
+ CB->replaceAllUsesWith(NewCB);
+ CB->eraseFromParent();
+ }
}
+
+ if (!ContractPass || !UseMarker)
+ EraseInstruction(P.first);
}
RVCalls.clear();
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.h b/llvm/lib/Transforms/ObjCARC/ObjCARC.h
index 62f88a8cc02ba..2b47bec7ffe82 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARC.h
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.h
@@ -105,7 +105,8 @@ CallInst *createCallInstWithColors(
class BundledRetainClaimRVs {
public:
- BundledRetainClaimRVs(bool ContractPass) : ContractPass(ContractPass) {}
+ BundledRetainClaimRVs(bool ContractPass, bool UseMarker)
+ : ContractPass(ContractPass), UseMarker(UseMarker) {}
~BundledRetainClaimRVs();
/// Insert a retainRV/claimRV call to the normal destination blocks of invokes
@@ -155,6 +156,9 @@ class BundledRetainClaimRVs {
DenseMap<CallInst *, CallBase *> RVCalls;
bool ContractPass;
+
+ /// Indicates whether the target uses a special inline-asm marker.
+ bool UseMarker;
};
} // end namespace objcarc
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 185a19fc47f40..c2ed94e8e1f62 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -434,13 +434,21 @@ bool ObjCARCContract::tryToPeepholeInstruction(
LLVM_FALLTHROUGH;
case ARCInstKind::RetainRV:
case ARCInstKind::ClaimRV: {
- // If we're compiling for a target which needs a special inline-asm
- // marker to do the return value optimization and the retainRV/claimRV call
- // wasn't bundled with a call, insert the marker now.
+ bool IsInstContainedInBundle = BundledInsts->contains(Inst);
+
+ // Return now if the target doesn't need a special inline-asm marker. Return
+ // true if this is a bundled retainRV/claimRV call, which is going to be
+ // erased at the end of this pass, to avoid undoing objc-arc-expand and
+ // replacing uses of the retainRV/claimRV call's argument with its result.
if (!RVInstMarker)
- return false;
+ return IsInstContainedInBundle;
+
+ // The target needs a special inline-asm marker.
- if (BundledInsts->contains(Inst))
+ // We don't have to emit the marker if this is a bundled call since the
+ // backend is responsible for emitting it. Return false to undo
+ // objc-arc-expand.
+ if (IsInstContainedInBundle)
return false;
BasicBlock::iterator BBI = Inst->getIterator();
@@ -540,7 +548,7 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
AA = A;
DT = D;
PA.setAA(A);
- BundledRetainClaimRVs BRV(true);
+ BundledRetainClaimRVs BRV(true, RVInstMarker);
BundledInsts = &BRV;
std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index bb9d92c7dea49..0fa4904456cdb 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -2461,7 +2461,7 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) {
return false;
Changed = CFGChanged = false;
- BundledRetainClaimRVs BRV(false);
+ BundledRetainClaimRVs BRV(false, objcarc::getRVInstMarker(*F.getParent()));
BundledInsts = &BRV;
LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName()
diff --git a/llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll b/llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll
new file mode 100644
index 0000000000000..4fc238d7407d6
--- /dev/null
+++ b/llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll
@@ -0,0 +1,24 @@
+; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
+; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s
+
+; CHECK-LABEL: define void @test0() {
+; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
+; CHECK-NEXT: ret void
+
+define void @test0() {
+ %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
+ ret void
+}
+
+; CHECK-LABEL: define void @test1() {
+; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
+; CHECK-NEXT: ret void
+
+define void @test1() {
+ %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
+ ret void
+}
+
+declare i8* @foo()
+declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
+declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
More information about the llvm-commits
mailing list