@@ -150,17 +150,38 @@ llvm::InlineAsm *IRGenModule::getObjCRetainAutoreleasedReturnValueMarker() {
150
150
// / Reclaim an autoreleased return value.
151
151
llvm::Value *irgen::emitObjCRetainAutoreleasedReturnValue (IRGenFunction &IGF,
152
152
llvm::Value *value) {
153
+ auto &IGM = IGF.IGM ;
153
154
// Call the inline-assembly marker if we need one.
154
- if (auto marker = IGF. IGM .getObjCRetainAutoreleasedReturnValueMarker ()) {
155
+ if (auto marker = IGM.getObjCRetainAutoreleasedReturnValueMarker ()) {
155
156
IGF.Builder .CreateAsmCall (marker, {});
156
157
}
157
158
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
+ if (IGM.getOptions ().shouldOptimize () && (arch == llvm::Triple::aarch64 ||
165
+ arch == llvm::Triple::x86_64)) {
166
+ auto EP = llvm::Intrinsic::getDeclaration (&IGM.Module ,
167
+ (llvm::Intrinsic::ID)llvm::Intrinsic::objc_retainAutoreleasedReturnValue);
168
+ llvm::Value *bundleArgs[] = {EP};
169
+ llvm::OperandBundleDef OB (" clang.arc.attachedcall" , bundleArgs);
170
+ auto *oldCall = cast<llvm::CallBase>(value);
171
+ llvm::CallBase *newCall = llvm::CallBase::addOperandBundle (
172
+ oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB, oldCall);
173
+ newCall->copyMetadata (*oldCall);
174
+ oldCall->replaceAllUsesWith (newCall);
175
+ oldCall->eraseFromParent ();
176
+ auto noop = IGF.Builder .CreateIntrinsicCall (llvm::Intrinsic::objc_clang_arc_noop_use, newCall);
177
+ noop->addFnAttr (llvm::Attribute::NoUnwind);
178
+ return newCall;
179
+ }
158
180
CastToInt8PtrTy savedType (IGF, value);
159
181
160
182
auto call = IGF.Builder .CreateIntrinsicCall (
161
183
llvm::Intrinsic::objc_retainAutoreleasedReturnValue, value);
162
184
163
- const llvm::Triple &triple = IGF.IGM .Context .LangOpts .Target ;
164
185
if (triple.getArch () == llvm::Triple::x86_64) {
165
186
// Don't tail call objc_retainAutoreleasedReturnValue. This blocks the
166
187
// autoreleased return optimization.
0 commit comments