From: Tim Northover Date: Sat, 29 Mar 2014 13:28:05 +0000 (+0000) Subject: ObjC: allow targets to decide when to use stret for blocks. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0ed153b0b4a41eee8eddb1258ca60ba1bf678cac;p=clang ObjC: allow targets to decide when to use stret for blocks. This was originally part of the ARM64 patch, but seems semantically separate. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205097 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index ce2a193870..15b08d476c 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -1121,7 +1121,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const CGFunctionInfo &fnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration( fnType->getReturnType(), args, fnType->getExtInfo(), fnType->isVariadic()); - if (CGM.ReturnTypeUsesSRet(fnInfo)) + if (CGM.ReturnSlotInterferesWithArgs(fnInfo)) blockInfo.UsesStret = true; llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 6d5324d4a1..6bef76934e 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -878,6 +878,11 @@ bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) { return FI.getReturnInfo().isIndirect(); } +bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) { + return ReturnTypeUsesSRet(FI) && + getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs(); +} + bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) { if (const BuiltinType *BT = ResultType->getAs()) { switch (BT->getKind()) { diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 10199c8dfc..51fbbed32c 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1881,7 +1881,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, NullReturnState nullReturn; llvm::Constant *Fn = NULL; - if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { + if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) { if (!IsSuper) nullReturn.init(CGF, Arg0); Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) : ObjCTypes.getSendStretFn(IsSuper); @@ -1892,6 +1892,10 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper) : ObjCTypes.getSendFp2retFn(IsSuper); } else { + // arm64 uses objc_msgSend for stret methods and yet null receiver check + // must be made for it. + if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo)) + nullReturn.init(CGF, Arg0); Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) : ObjCTypes.getSendFn(IsSuper); } @@ -6517,7 +6521,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, // FIXME: don't use this for that. llvm::Constant *fn = 0; std::string messageRefName("\01l_"); - if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { + if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) { if (isSuper) { fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); messageRefName += "objc_msgSendSuper2_stret_fixup"; diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 7694eed1a1..0d13bdcc2f 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -908,6 +908,10 @@ public: /// as a return type. bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); + /// ReturnSlotInterferesWithArgs - Return true iff the given type uses an + /// argument slot when 'sret' is used as a return type. + bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); + /// ReturnTypeUsesFPRet - Return true iff the given type uses 'fpret' when /// used as a return type. bool ReturnTypeUsesFPRet(QualType ResultType); diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h index 11cae6c5aa..6c3ab64834 100644 --- a/lib/CodeGen/TargetInfo.h +++ b/lib/CodeGen/TargetInfo.h @@ -123,6 +123,10 @@ namespace clang { return Ty; } + /// doesReturnSlotInterfereWithArgs - Return true if the target uses an + /// argument slot for an 'sret' type. + virtual bool doesReturnSlotInterfereWithArgs() const { return true; } + /// Retrieve the address of a function to call immediately before /// calling objc_retainAutoreleasedReturnValue. The /// implementation of objc_autoreleaseReturnValue sniffs the