summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/ABIInfo.h
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-07-29 06:26:06 +0000
committerChris Lattner <sabre@nondot.org>2010-07-29 06:26:06 +0000
commit800588fd230d2c37ddce8fbf4a3881352715d700 (patch)
tree4e080d2e6f3a76307af7d5f51dc7301b3bc2c6a6 /lib/CodeGen/ABIInfo.h
parent15842bd05bd6d3b7450385ac8f73aaee5f807e19 (diff)
Kill off the 'coerce' ABI passing form. Now 'direct' and 'extend' always
have a "coerce to" type which often matches the default lowering of Clang type to LLVM IR type, but the coerce case can be handled by making them not be the same. This simplifies things and fixes issues where X86-64 abi lowering would return coerce after making preferred types exactly match up. This caused us to compile: typedef float v4f32 __attribute__((__vector_size__(16))); v4f32 foo(v4f32 X) { return X+X; } into this code at -O0: define <4 x float> @foo(<4 x float> %X.coerce) nounwind { entry: %retval = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2] %coerce = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2] %X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3] store <4 x float> %X.coerce, <4 x float>* %coerce %X = load <4 x float>* %coerce ; <<4 x float>> [#uses=1] store <4 x float> %X, <4 x float>* %X.addr %tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1] %tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1] %add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1] store <4 x float> %add, <4 x float>* %retval %0 = load <4 x float>* %retval ; <<4 x float>> [#uses=1] ret <4 x float> %0 } Now we get: define <4 x float> @foo(<4 x float> %X) nounwind { entry: %X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3] store <4 x float> %X, <4 x float>* %X.addr %tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1] %tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1] %add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1] ret <4 x float> %add } This implements rdar://8248065 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/ABIInfo.h')
-rw-r--r--lib/CodeGen/ABIInfo.h32
1 files changed, 16 insertions, 16 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 30f99c31e3..642fddb5c8 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -38,17 +38,13 @@ namespace clang {
class ABIArgInfo {
public:
enum Kind {
- Direct, /// Pass the argument directly using the normal
- /// converted LLVM type. Complex and structure types
- /// are passed using first class aggregates.
+ Direct, /// Pass the argument directly using the normal converted LLVM
+ /// type, or by coercing to another specified type
+ /// (stored in 'CoerceToType').
Extend, /// Valid only for integer argument types. Same as 'direct'
/// but also emit a zero/sign extension attribute.
- Coerce, /// Only valid for aggregate return types, the argument
- /// should be accessed by coercion to a provided type.
-
-
Indirect, /// Pass the argument indirectly via a hidden pointer
/// with the specified alignment (0 indicates default
/// alignment).
@@ -79,8 +75,8 @@ namespace clang {
public:
ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
- static ABIArgInfo getDirect() {
- return ABIArgInfo(Direct);
+ static ABIArgInfo getDirect(const llvm::Type *T = 0) {
+ return ABIArgInfo(Direct, T);
}
static ABIArgInfo getExtend() {
return ABIArgInfo(Extend);
@@ -88,9 +84,6 @@ namespace clang {
static ABIArgInfo getIgnore() {
return ABIArgInfo(Ignore);
}
- static ABIArgInfo getCoerce(const llvm::Type *T) {
- return ABIArgInfo(Coerce, T);
- }
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
return ABIArgInfo(Indirect, 0, Alignment, ByVal);
}
@@ -102,16 +95,23 @@ namespace clang {
bool isDirect() const { return TheKind == Direct; }
bool isExtend() const { return TheKind == Extend; }
bool isIgnore() const { return TheKind == Ignore; }
- bool isCoerce() const { return TheKind == Coerce; }
bool isIndirect() const { return TheKind == Indirect; }
bool isExpand() const { return TheKind == Expand; }
- // Coerce accessors
+ bool canHaveCoerceToType() const {
+ return TheKind == Direct || TheKind == Extend;
+ }
+
+ // Direct/Extend accessors
const llvm::Type *getCoerceToType() const {
- assert(TheKind == Coerce && "Invalid kind!");
+ assert(canHaveCoerceToType() && "Invalid kind!");
return TypeData;
}
-
+
+ void setCoerceToType(const llvm::Type *T) {
+ assert(canHaveCoerceToType() && "Invalid kind!");
+ TypeData = T;
+ }
// Indirect accessors
unsigned getIndirectAlign() const {
assert(TheKind == Indirect && "Invalid kind!");