Skip to content

Commit 6f743d5

Browse files
Merge pull request #67155 from aschwaighofer/use_clang_arc_attachedcall
Use clang.arc.attachedcall for emission of objc_retainAutoreleasedReturnValue
2 parents 8b73c98 + bb84f17 commit 6f743d5

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

lib/IRGen/GenObjC.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,47 @@ llvm::InlineAsm *IRGenModule::getObjCRetainAutoreleasedReturnValueMarker() {
150150
/// Reclaim an autoreleased return value.
151151
llvm::Value *irgen::emitObjCRetainAutoreleasedReturnValue(IRGenFunction &IGF,
152152
llvm::Value *value) {
153+
auto &IGM = IGF.IGM;
153154
// Call the inline-assembly marker if we need one.
154-
if (auto marker = IGF.IGM.getObjCRetainAutoreleasedReturnValueMarker()) {
155+
if (auto marker = IGM.getObjCRetainAutoreleasedReturnValueMarker()) {
155156
IGF.Builder.CreateAsmCall(marker, {});
156157
}
157158

159+
const auto &triple = IGF.IGM.Context.LangOpts.Target;
160+
const auto &arch = triple.getArch();
161+
162+
// FIXME: Do this on all targets and at -O0 too. This can be enabled only if
163+
// the target backend knows how to handle the operand bundle.
164+
// Don't use clang.arc.attachedcall on non-darwin platforms for now. On these
165+
// platforms we have a workaround in-place to deal with the un-availability of
166+
// a arc runtime -- we have implemented objc_retainAutoreleasedReturnValue in
167+
// a library (src/swift/DispatchStubs.cc) as swift_retain.
168+
// Using clang.arc.attachedcall enables a LLVM optimization that can transform
169+
// objc_retainAutoreleasedReturnValue into objc_retain in some circumstances.
170+
// There is no objc_retain stub defined and we would run into missing symbol
171+
// errors.
172+
if (IGM.getOptions().shouldOptimize() && triple.isOSDarwin() &&
173+
(arch == llvm::Triple::aarch64 ||
174+
arch == llvm::Triple::x86_64)) {
175+
auto EP = llvm::Intrinsic::getDeclaration(&IGM.Module,
176+
(llvm::Intrinsic::ID)llvm::Intrinsic::objc_retainAutoreleasedReturnValue);
177+
llvm::Value *bundleArgs[] = {EP};
178+
llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);
179+
auto *oldCall = cast<llvm::CallBase>(value);
180+
llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
181+
oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB, oldCall);
182+
newCall->copyMetadata(*oldCall);
183+
oldCall->replaceAllUsesWith(newCall);
184+
oldCall->eraseFromParent();
185+
auto noop = IGF.Builder.CreateIntrinsicCall(llvm::Intrinsic::objc_clang_arc_noop_use, newCall);
186+
noop->addFnAttr(llvm::Attribute::NoUnwind);
187+
return newCall;
188+
}
158189
CastToInt8PtrTy savedType(IGF, value);
159190

160191
auto call = IGF.Builder.CreateIntrinsicCall(
161192
llvm::Intrinsic::objc_retainAutoreleasedReturnValue, value);
162193

163-
const llvm::Triple &triple = IGF.IGM.Context.LangOpts.Target;
164194
if (triple.getArch() == llvm::Triple::x86_64) {
165195
// Don't tail call objc_retainAutoreleasedReturnValue. This blocks the
166196
// autoreleased return optimization.

test/IRGen/objc_retainAutoreleasedReturnValue.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %target-swift-frontend -module-name objc_retainAutoreleasedReturnValue -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir | %FileCheck %s
2-
// RUN: %target-swift-frontend -module-name objc_retainAutoreleasedReturnValue -O -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir | %FileCheck %s --check-prefix=OPT
2+
// RUN: %target-swift-frontend -module-name objc_retainAutoreleasedReturnValue -O -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir -disable-llvm-optzns | %FileCheck %s --check-prefix=OPT
33

44
// REQUIRES: objc_interop
55
// REQUIRES: CPU=x86_64
@@ -32,6 +32,6 @@ public func test(_ dict: NSDictionary) {
3232

3333
// OPT-LABEL: define {{.*}}swiftcc void @"$s34objc_retainAutoreleasedReturnValue10useClosureyySo12NSDictionaryC_yADXEtF09$s34objc_bcd16Value4testyySo12H10CFyADXEfU_Tf1nc_n"(ptr %0)
3434
// OPT: entry:
35-
// OPT: call {{.*}}@objc_msgSend
36-
// OPT: notail call ptr @llvm.objc.retainAutoreleasedReturnValue
35+
// OPT: [[R:%.*]] = call ptr @objc_msgSend({{.*}}) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue)
36+
// OPT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[R]])
3737
// OPT: ret void

0 commit comments

Comments
 (0)