diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 40b9c46de23..3d75db8a03f 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -181,8 +181,9 @@ public: /// @brief Determine if the function does not access or only reads memory. bool onlyReadsMemory() const; - /// @brief Determine if the function returns a structure. - bool isStructReturn() const; + /// @brief Determine if the function returns a structure through first + /// pointer argument. + bool hasStructRetAttr() const; /// deleteBody - This method deletes the body of the function, and converts /// the linkage to external. diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 2e6b85b729b..3dd42797c63 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -957,8 +957,9 @@ public: bool doesNotThrow() const; void setDoesNotThrow(bool doesNotThrow = true); - /// @brief Determine if the call returns a structure. - bool isStructReturn() const; + /// @brief Determine if the call returns a structure through first + /// pointer argument. + bool hasStructRetAttr() const; /// @brief Determine if any call argument is an aggregate passed by value. bool hasByValArgument() const; @@ -1769,8 +1770,9 @@ public: bool doesNotThrow() const; void setDoesNotThrow(bool doesNotThrow = true); - /// @brief Determine if the call returns a structure. - bool isStructReturn() const; + /// @brief Determine if the call returns a structure through first + /// pointer argument. + bool hasStructRetAttr() const; /// getCalledFunction - Return the function called, or null if this is an /// indirect function invocation. diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 946a2831521..3a4e97e276c 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -1904,7 +1904,7 @@ void CWriter::printContainedStructs(const Type *Ty, void CWriter::printFunctionSignature(const Function *F, bool Prototype) { /// isStructReturn - Should this function actually return a struct by-value? - bool isStructReturn = F->isStructReturn(); + bool isStructReturn = F->hasStructRetAttr(); if (F->hasInternalLinkage()) Out << "static "; if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; @@ -2024,7 +2024,7 @@ static inline bool isFPIntBitCast(const Instruction &I) { void CWriter::printFunction(Function &F) { /// isStructReturn - Should this function actually return a struct by-value? - bool isStructReturn = F.isStructReturn(); + bool isStructReturn = F.hasStructRetAttr(); printFunctionSignature(&F, false); Out << " {\n"; @@ -2148,7 +2148,7 @@ void CWriter::printBasicBlock(BasicBlock *BB) { // void CWriter::visitReturnInst(ReturnInst &I) { // If this is a struct return function, return the temporary struct. - bool isStructReturn = I.getParent()->getParent()->isStructReturn(); + bool isStructReturn = I.getParent()->getParent()->hasStructRetAttr(); if (isStructReturn) { Out << " return StructReturn;\n"; @@ -2584,7 +2584,7 @@ void CWriter::visitCallInst(CallInst &I) { // parameter instead of passing it to the call. const ParamAttrsList *PAL = I.getParamAttrs(); bool hasByVal = I.hasByValArgument(); - bool isStructRet = I.isStructReturn(); + bool isStructRet = I.hasStructRetAttr(); if (isStructRet) { writeOperandDeref(I.getOperand(1)); Out << " = "; diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 9720100e370..98e7d9c1e81 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -102,13 +102,13 @@ void X86SharedAsmPrinter::decorateName(std::string &Name, case StdCall: // "Pure" variadic functions do not receive @0 suffix. if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->isStructReturn())) + (FT->getNumParams() == 1 && F->hasStructRetAttr())) Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); break; case FastCall: // "Pure" variadic functions do not receive @0 suffix. if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->isStructReturn())) + (FT->getNumParams() == 1 && F->hasStructRetAttr())) Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); if (Name[0] == '_') { diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index 2ee54510e6b..088269d816d 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -255,7 +255,7 @@ DAE::Liveness DAE::getArgumentLiveness(const Argument &A) { const Function *F = A.getParent(); // If this is the return value of a struct function, it's not really dead. - if (F->isStructReturn() && &*(F->arg_begin()) == &A) + if (F->hasStructRetAttr() && &*(F->arg_begin()) == &A) return Live; if (A.use_empty()) // First check, directly dead? diff --git a/lib/Transforms/IPO/StructRetPromotion.cpp b/lib/Transforms/IPO/StructRetPromotion.cpp index 1de066e3122..298b5b1c1f1 100644 --- a/lib/Transforms/IPO/StructRetPromotion.cpp +++ b/lib/Transforms/IPO/StructRetPromotion.cpp @@ -75,7 +75,7 @@ bool SRETPromotion::PromoteReturn(CallGraphNode *CGN) { return false; // Make sure that function returns struct. - if (F->arg_size() == 0 || !F->isStructReturn() || F->doesNotReturn()) + if (F->arg_size() == 0 || !F->hasStructRetAttr() || F->doesNotReturn()) return false; assert (F->getReturnType() == Type::VoidTy && "Invalid function return type"); diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 92737f66d92..f5712e7561b 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -168,10 +168,10 @@ bool Function::onlyReadsMemory() const { return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly); } -/// @brief Determine if the function returns a structure. -bool Function::isStructReturn() const { - return paramHasAttr(1, ParamAttr::StructRet) - || isa(getReturnType()); +/// @brief Determine if the function returns a structure through first +/// pointer argument. +bool Function::hasStructRetAttr() const { + return paramHasAttr(1, ParamAttr::StructRet); } //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index dfd3b830caa..f7401ec9797 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -419,8 +419,9 @@ bool CallInst::doesNotThrow() const { return paramHasAttr(0, ParamAttr::NoUnwind); } -/// @brief Determine if the call returns a structure. -bool CallInst::isStructReturn() const { +/// @brief Determine if the call returns a structure through first +/// pointer argument. +bool CallInst::hasStructRetAttr() const { // Be friendly and also check the callee. return paramHasAttr(1, ParamAttr::StructRet); } @@ -560,8 +561,9 @@ void InvokeInst::setDoesNotThrow(bool doesNotThrow) { setParamAttrs(PAL); } -/// @brief Determine if the call returns a structure. -bool InvokeInst::isStructReturn() const { +/// @brief Determine if the invoke returns a structure through first +/// pointer argument. +bool InvokeInst::hasStructRetAttr() const { // Be friendly and also check the callee. return paramHasAttr(1, ParamAttr::StructRet); } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 3d6832475f6..9ce886cd862 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -455,6 +455,9 @@ void Verifier::visitFunction(Function &F) { isa(F.getReturnType()), "Functions cannot return aggregate values!", &F); + Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy, + "Invalid struct return type!", &F); + const ParamAttrsList *Attrs = F.getParamAttrs(); Assert1(!Attrs ||