Skip to content

Commit 55f31ca

Browse files
committed
[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 (cherry picked from commit 8f8d9f7)
1 parent 5d3e557 commit 55f31ca

File tree

5 files changed

+56
-15
lines changed

5 files changed

+56
-15
lines changed

llvm/lib/Transforms/ObjCARC/ObjCARC.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,19 @@ BundledRetainClaimRVs::~BundledRetainClaimRVs() {
124124
if (auto *CI = dyn_cast<CallInst>(CB))
125125
CI->setTailCallKind(CallInst::TCK_NoTail);
126126

127-
// Remove the ARC intrinsic function operand from the operand bundle.
128-
OperandBundleDef OB("clang.arc.attachedcall", None);
129-
auto *NewCB = CallBase::Create(CB, OB, CB);
130-
CB->replaceAllUsesWith(NewCB);
131-
CB->eraseFromParent();
132-
} else {
133-
EraseInstruction(P.first);
127+
if (UseMarker) {
128+
// Remove the retainRV/claimRV function operand from the operand bundle
129+
// to reflect the fact that the backend is responsible for emitting only
130+
// the marker instruction, but not the retainRV/claimRV call.
131+
OperandBundleDef OB("clang.arc.attachedcall", None);
132+
auto *NewCB = CallBase::Create(CB, OB, CB);
133+
CB->replaceAllUsesWith(NewCB);
134+
CB->eraseFromParent();
135+
}
134136
}
137+
138+
if (!ContractPass || !UseMarker)
139+
EraseInstruction(P.first);
135140
}
136141

137142
RVCalls.clear();

llvm/lib/Transforms/ObjCARC/ObjCARC.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ CallInst *createCallInstWithColors(
105105

106106
class BundledRetainClaimRVs {
107107
public:
108-
BundledRetainClaimRVs(bool ContractPass) : ContractPass(ContractPass) {}
108+
BundledRetainClaimRVs(bool ContractPass, bool UseMarker)
109+
: ContractPass(ContractPass), UseMarker(UseMarker) {}
109110
~BundledRetainClaimRVs();
110111

111112
/// Insert a retainRV/claimRV call to the normal destination blocks of invokes
@@ -155,6 +156,9 @@ class BundledRetainClaimRVs {
155156
DenseMap<CallInst *, CallBase *> RVCalls;
156157

157158
bool ContractPass;
159+
160+
/// Indicates whether the target uses a special inline-asm marker.
161+
bool UseMarker;
158162
};
159163

160164
} // end namespace objcarc

llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,13 +434,21 @@ bool ObjCARCContract::tryToPeepholeInstruction(
434434
LLVM_FALLTHROUGH;
435435
case ARCInstKind::RetainRV:
436436
case ARCInstKind::ClaimRV: {
437-
// If we're compiling for a target which needs a special inline-asm
438-
// marker to do the return value optimization and the retainRV/claimRV call
439-
// wasn't bundled with a call, insert the marker now.
437+
bool IsInstContainedInBundle = BundledInsts->contains(Inst);
438+
439+
// Return now if the target doesn't need a special inline-asm marker. Return
440+
// true if this is a bundled retainRV/claimRV call, which is going to be
441+
// erased at the end of this pass, to avoid undoing objc-arc-expand and
442+
// replacing uses of the retainRV/claimRV call's argument with its result.
440443
if (!RVInstMarker)
441-
return false;
444+
return IsInstContainedInBundle;
445+
446+
// The target needs a special inline-asm marker.
442447

443-
if (BundledInsts->contains(Inst))
448+
// We don't have to emit the marker if this is a bundled call since the
449+
// backend is responsible for emitting it. Return false to undo
450+
// objc-arc-expand.
451+
if (IsInstContainedInBundle)
444452
return false;
445453

446454
BasicBlock::iterator BBI = Inst->getIterator();
@@ -540,7 +548,7 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
540548
AA = A;
541549
DT = D;
542550
PA.setAA(A);
543-
BundledRetainClaimRVs BRV(true);
551+
BundledRetainClaimRVs BRV(true, RVInstMarker);
544552
BundledInsts = &BRV;
545553

546554
std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);

llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2462,7 +2462,7 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) {
24622462
return false;
24632463

24642464
Changed = CFGChanged = false;
2465-
BundledRetainClaimRVs BRV(false);
2465+
BundledRetainClaimRVs BRV(false, objcarc::getRVInstMarker(*F.getParent()));
24662466
BundledInsts = &BRV;
24672467

24682468
LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
2+
; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s
3+
4+
; CHECK-LABEL: define void @test0() {
5+
; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
6+
; CHECK-NEXT: ret void
7+
8+
define void @test0() {
9+
%call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
10+
ret void
11+
}
12+
13+
; CHECK-LABEL: define void @test1() {
14+
; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
15+
; CHECK-NEXT: ret void
16+
17+
define void @test1() {
18+
%call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
19+
ret void
20+
}
21+
22+
declare i8* @foo()
23+
declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
24+
declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)

0 commit comments

Comments
 (0)