summaryrefslogtreecommitdiffstats
path: root/clang/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
commitfe34c1d53e15a9717a313120e4df3b35a10c708e (patch)
tree4d79047bd888b64916d246afead9a866b97af30e /clang/lib/CodeGen/ABIInfo.h
parent9fa15c3608ee7e0277f61b296799a69a400a65ed (diff)
downloadbcm5719-llvm-fe34c1d53e15a9717a313120e4df3b35a10c708e.tar.gz
bcm5719-llvm-fe34c1d53e15a9717a313120e4df3b35a10c708e.zip
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 llvm-svn: 109733
Diffstat (limited to 'clang/lib/CodeGen/ABIInfo.h')
-rw-r--r--clang/lib/CodeGen/ABIInfo.h32
1 files changed, 16 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h
index 30f99c31e3d..642fddb5c8d 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/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!");
OpenPOWER on IntegriCloud