[llvm-commits] [llvm-gcc-4.2] r48440 - in /llvm-gcc-4.2/trunk/gcc: config/rs6000/llvm-rs6000.cpp config/rs6000/rs6000.h llvm-abi.h
Dale Johannesen
dalej at apple.com
Sun Mar 16 19:21:44 PDT 2008
Author: johannes
Date: Sun Mar 16 21:21:44 2008
New Revision: 48440
URL: http://llvm.org/viewvc/llvm-project?rev=48440&view=rev
Log:
Adjustments for ppc32 ABI. Pass single-elt structs
(except long double) as if they were the type of the
element. Handle complex long long & complex double.
Modified:
llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp
llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp?rev=48440&r1=48439&r2=48440&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/llvm-rs6000.cpp Sun Mar 16 21:21:44 2008
@@ -26,6 +26,7 @@
#include "llvm-abi.h"
#include "llvm-internal.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"
@@ -389,30 +390,61 @@
if (Bytes == 0)
return false;
- // If this is a small fixed size type, investigate it.
+ // Large types always use byval. If this is a small fixed size type,
+ // investigate it.
if (Bytes <= 0 || Bytes > 16)
return true;
// ppc32 passes aggregates by copying, either in int registers or on the
- // stack. If this is an extremely simple aggregate whose elements would be
- // passed the same if passed as scalars, pass them that way in order to
- // promote SROA on the caller and callee side.
- // Note that we can't support passing all structs this way. For example,
- // {i16, i16} should be passed in on 32-bit unit, which is not how "i16, i16"
- // would be passed as stand-alone arguments. And any floating point element
- // would be passed in float regs, not int.
+ // stack.
const StructType *STy = dyn_cast<StructType>(Ty);
if (!STy || STy->isPacked()) return true;
- for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- const Type *EltTy = STy->getElementType(i);
- // 32 and 64-bit integers are fine, as are pointers.
- // Shorter ints do not work, nor do floating point or vectors.
- if (EltTy != Type::Int32Ty && EltTy != Type::Int64Ty &&
- !isa<PointerType>(EltTy))
- return true;
+ // A struct containing only a float, double or vector field, possibly with
+ // some zero-length fields as well, must be passed as the field type.
+ // Note this does not apply to long double.
+ // This is required for ABI correctness.
+ tree tType = isSingleElementStructOrArray(TreeType, true, false);
+ if (tType && int_size_in_bytes(tType)==Bytes && TYPE_MODE(tType)!=TFmode)
+ return false;
+
+ return true;
+}
+
+/* Target hook for llvm-abi.h. It returns true if an aggregate of the
+ specified type should be passed in a number of registers of mixed types.
+ It also returns a vector of types that correspond to the registers used
+ for parameter passing. */
+bool
+llvm_rs6000_should_pass_aggregate_in_mixed_regs(tree TreeType, const Type* Ty,
+ std::vector<const Type*>&Elts) {
+ // FIXME there are plenty of ppc64 cases that need this.
+ if (TARGET_64BIT)
+ return false;
+
+ // If this is a small fixed size type, investigate it.
+ HOST_WIDE_INT SrcSize = int_size_in_bytes(TreeType);
+ if (SrcSize <= 0 || SrcSize > 16)
+ return false;
+
+ const StructType *STy = dyn_cast<StructType>(Ty);
+ if (!STy || STy->isPacked()) return false;
+
+ // A struct containing only a float, double or vector field, possibly with
+ // some zero-length fields as well, must be passed as the field type.
+ // Note this does not apply to long double.
+ // Other single-element structs may be passed this way as well, but
+ // only if the type size matches the element's type size (structs that
+ // violate this can be created with __aligned__).
+ tree tType = isSingleElementStructOrArray(TreeType, true, false);
+ if (tType && int_size_in_bytes(tType)==SrcSize && TYPE_MODE(tType)!=TFmode) {
+ Elts.push_back(ConvertType(tType));
+ return true;
}
+
+ Elts.clear();
return false;
}
+
/* LLVM LOCAL end (ENTIRE FILE!) */
Modified: llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h?rev=48440&r1=48439&r2=48440&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h Sun Mar 16 21:21:44 2008
@@ -3478,7 +3478,15 @@
#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
llvm_rs6000_should_pass_aggregate_byval(X, TY)
-#endif
+
+extern bool llvm_rs6000_should_pass_aggregate_in_mixed_regs(tree, const Type*,
+ std::vector<const Type*>&);
+
+// FIXME this is needed for 64-bit
+#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, E) \
+ llvm_rs6000_should_pass_aggregate_in_mixed_regs((T), (TY), (E))
+
+#endif /* LLVM_ABI_H */
/* LLVM LOCAL end */
Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=48440&r1=48439&r2=48440&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Sun Mar 16 21:21:44 2008
@@ -243,10 +243,7 @@
// Return scalar values normally.
C.HandleScalarResult(Ty);
} else if (TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST &&
- !aggregate_value_p(type, current_function_decl) &&
- // FIXME: this is a hack around returning 'complex double' by-val
- // which returns in r3/r4/r5/r6 on PowerPC.
- TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) <= 8) {
+ !aggregate_value_p(type, current_function_decl)) {
tree SingleElt = LLVM_SHOULD_RETURN_STRUCT_AS_SCALAR(type);
if (SingleElt && TYPE_SIZE(SingleElt) &&
TREE_CODE(TYPE_SIZE(SingleElt)) == INTEGER_CST &&
@@ -267,6 +264,10 @@
C.HandleAggregateResultAsScalar(Type::Int32Ty);
else if (Size <= 8)
C.HandleAggregateResultAsScalar(Type::Int64Ty);
+ else if (Size <= 16)
+ C.HandleAggregateResultAsScalar(IntegerType::get(128));
+ else if (Size <= 32)
+ C.HandleAggregateResultAsScalar(IntegerType::get(256));
else {
assert(0 && "Cannot return this aggregate as a scalar!");
abort();
More information about the llvm-commits
mailing list