aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorStephen Lin <stephenwlin@gmail.com>2013-04-20 05:14:40 +0000
committerStephen Lin <stephenwlin@gmail.com>2013-04-20 05:14:40 +0000
commit456ca048af35163b9f52187e92a23ee0a9f059e8 (patch)
treef7b4d4711424b927d5b323a9e4ef4d97742beeb4 /include
parent5c34e08b9fff9d4df2421e4f41ff15b85f638dd1 (diff)
downloadexternal_llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.zip
external_llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.gz
external_llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.bz2
Add CodeGen support for functions that always return arguments via a new parameter attribute 'returned', which is taken advantage of in target-independent tail call opportunity detection and in ARM call lowering (when placed on an integral first parameter).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179925 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/IR/Argument.h4
-rw-r--r--include/llvm/IR/Attributes.h1
-rw-r--r--include/llvm/Target/TargetCallingConv.h37
-rw-r--r--include/llvm/Target/TargetLowering.h16
4 files changed, 35 insertions, 23 deletions
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
index ef4e4fc..40d61ff 100644
--- a/include/llvm/IR/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -78,6 +78,10 @@ public:
/// containing function.
bool hasStructRetAttr() const;
+ /// \brief Return true if this argument has the returned attribute on it in
+ /// its containing function.
+ bool hasReturnedAttr() const;
+
/// \brief Add a Attribute to an argument.
void addAttr(AttributeSet AS);
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index f93f28b..c801436 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -87,6 +87,7 @@ public:
OptimizeForSize, ///< opt_size
ReadNone, ///< Function does not access memory
ReadOnly, ///< Function only reads from memory
+ Returned, ///< Return value is always equal to this argument
ReturnsTwice, ///< Function can return twice
SExt, ///< Sign extended before/after call
StackAlignment, ///< Alignment of stack for function (3 bits)
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index 2160e37..56ebfa4 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -36,10 +36,12 @@ namespace ISD {
static const uint64_t ByValOffs = 4;
static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
static const uint64_t NestOffs = 5;
- static const uint64_t ByValAlign = 0xFULL << 6; ///< Struct alignment
- static const uint64_t ByValAlignOffs = 6;
- static const uint64_t Split = 1ULL << 10;
- static const uint64_t SplitOffs = 10;
+ static const uint64_t Returned = 1ULL<<6;
+ static const uint64_t ReturnedOffs = 6;
+ static const uint64_t ByValAlign = 0xFULL<<7; ///< Struct alignment
+ static const uint64_t ByValAlignOffs = 7;
+ static const uint64_t Split = 1ULL<<11;
+ static const uint64_t SplitOffs = 11;
static const uint64_t OrigAlign = 0x1FULL<<27;
static const uint64_t OrigAlignOffs = 27;
static const uint64_t ByValSize = 0xffffffffULL << 32; ///< Struct size
@@ -51,23 +53,26 @@ namespace ISD {
public:
ArgFlagsTy() : Flags(0) { }
- bool isZExt() const { return Flags & ZExt; }
- void setZExt() { Flags |= One << ZExtOffs; }
+ bool isZExt() const { return Flags & ZExt; }
+ void setZExt() { Flags |= One << ZExtOffs; }
- bool isSExt() const { return Flags & SExt; }
- void setSExt() { Flags |= One << SExtOffs; }
+ bool isSExt() const { return Flags & SExt; }
+ void setSExt() { Flags |= One << SExtOffs; }
- bool isInReg() const { return Flags & InReg; }
- void setInReg() { Flags |= One << InRegOffs; }
+ bool isInReg() const { return Flags & InReg; }
+ void setInReg() { Flags |= One << InRegOffs; }
- bool isSRet() const { return Flags & SRet; }
- void setSRet() { Flags |= One << SRetOffs; }
+ bool isSRet() const { return Flags & SRet; }
+ void setSRet() { Flags |= One << SRetOffs; }
- bool isByVal() const { return Flags & ByVal; }
- void setByVal() { Flags |= One << ByValOffs; }
+ bool isByVal() const { return Flags & ByVal; }
+ void setByVal() { Flags |= One << ByValOffs; }
- bool isNest() const { return Flags & Nest; }
- void setNest() { Flags |= One << NestOffs; }
+ bool isNest() const { return Flags & Nest; }
+ void setNest() { Flags |= One << NestOffs; }
+
+ bool isReturned() const { return Flags & Returned; }
+ void setReturned() { Flags |= One << ReturnedOffs; }
unsigned getByValAlign() const {
return (unsigned)
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index e169bcf..1e7ccd8 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -1910,16 +1910,18 @@ public:
struct ArgListEntry {
SDValue Node;
Type* Ty;
- bool isSExt : 1;
- bool isZExt : 1;
- bool isInReg : 1;
- bool isSRet : 1;
- bool isNest : 1;
- bool isByVal : 1;
+ bool isSExt : 1;
+ bool isZExt : 1;
+ bool isInReg : 1;
+ bool isSRet : 1;
+ bool isNest : 1;
+ bool isByVal : 1;
+ bool isReturned : 1;
uint16_t Alignment;
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
- isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
+ isSRet(false), isNest(false), isByVal(false), isReturned(false),
+ Alignment(0) { }
};
typedef std::vector<ArgListEntry> ArgListTy;