[PATCH] ArgumentPromotion: Drop sret attribute on functions that are only called directly.
Peter Collingbourne
peter at pcc.me.uk
Wed Jun 10 14:19:05 PDT 2015
REPOSITORY
rL LLVM
http://reviews.llvm.org/D10353
Files:
llvm/trunk/lib/IR/Function.cpp
llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
llvm/trunk/test/Transforms/ArgumentPromotion/sret.ll
Index: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
===================================================================
--- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -245,6 +245,24 @@
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
Index: llvm/trunk/lib/IR/Function.cpp
===================================================================
--- llvm/trunk/lib/IR/Function.cpp
+++ llvm/trunk/lib/IR/Function.cpp
@@ -154,10 +154,8 @@
/// 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
Index: llvm/trunk/test/Transforms/ArgumentPromotion/sret.ll
===================================================================
--- llvm/trunk/test/Transforms/ArgumentPromotion/sret.ll
+++ llvm/trunk/test/Transforms/ArgumentPromotion/sret.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -argpromotion -S | FileCheck %s
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+; CHECK: define internal void @add(i32 %[[THIS1:.*]], i32 %[[THIS2:.*]], i32* noalias %[[SR:.*]])
+define internal void @add({i32, i32}* %this, i32* sret %r) {
+ %ap = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 0
+ %bp = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 1
+ %a = load i32, i32* %ap
+ %b = load i32, i32* %bp
+ ; CHECK: %[[AB:.*]] = add i32 %[[THIS1]], %[[THIS2]]
+ %ab = add i32 %a, %b
+ ; CHECK: store i32 %[[AB]], i32* %[[SR]]
+ store i32 %ab, i32* %r
+ ret void
+}
+
+; CHECK: define void @f()
+define void @f() {
+ ; CHECK: %[[R:.*]] = alloca i32
+ %r = alloca i32
+ %pair = alloca {i32, i32}
+
+ ; CHECK: call void @add(i32 %{{.*}}, i32 %{{.*}}, i32* noalias %[[R]])
+ call void @add({i32, i32}* %pair, i32* sret %r)
+ ret void
+}
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D10353.27465.patch
Type: text/x-patch
Size: 3225 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150610/a129b567/attachment.bin>
More information about the llvm-commits
mailing list