diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 18 |
2 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index cf8e3ed571e..2b439bb46bf 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -154,10 +154,8 @@ bool Argument::hasNoCaptureAttr() const { /// it in its containing function. bool Argument::hasStructRetAttr() const { if (!getType()->isPointerTy()) return false; - if (this != getParent()->arg_begin()) - return false; // StructRet param must be first param return getParent()->getAttributes(). - hasAttribute(1, Attribute::StructRet); + hasAttribute(getArgNo()+1, Attribute::StructRet); } /// hasReturnedAttr - Return true if this argument has the returned attribute on diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index c7c57ab5644..440f3f20d61 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -245,6 +245,24 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) { Argument *PtrArg = PointerArgs[i]; Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType(); + // Replace sret attribute with noalias. This reduces register pressure by + // avoiding a register copy. + if (PtrArg->hasStructRetAttr()) { + unsigned ArgNo = PtrArg->getArgNo(); + F->setAttributes( + F->getAttributes() + .removeAttribute(F->getContext(), ArgNo + 1, Attribute::StructRet) + .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias)); + for (Use &U : F->uses()) { + CallSite CS(U.getUser()); + CS.setAttributes( + CS.getAttributes() + .removeAttribute(F->getContext(), ArgNo + 1, + Attribute::StructRet) + .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias)); + } + } + // If this is a byval argument, and if the aggregate type is small, just // pass the elements, which is always safe, if the passed value is densely // packed or if we can prove the padding bytes are never accessed. This does |