[llvm-commits] [llvm-gcc-4.2] r48608 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp config/rs6000/llvm-rs6000.cpp config/rs6000/rs6000.h llvm-abi.h llvm-convert.cpp
Dale Johannesen
dalej at apple.com
Thu Mar 20 11:42:57 PDT 2008
Author: johannes
Date: Thu Mar 20 13:42:57 2008
New Revision: 48608
URL: http://llvm.org/viewvc/llvm-project?rev=48608&view=rev
Log:
Add vector handling for ppc32. Move x86 vector
logic from header file macros into functions. Rewrite
llvm-convert changes for sret-returning vectors (and
add one more) per patch feedback.
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
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
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=48608&r1=48607&r2=48608&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Thu Mar 20 13:42:57 2008
@@ -98,40 +98,26 @@
isSingleElementStructOrArray(X, true, false)
#endif
+extern bool llvm_x86_should_pass_vector_in_integer_regs(tree);
+
+/* Vectors which are not MMX nor SSE should be passed as integers. */
+#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X) \
+ llvm_x86_should_pass_vector_in_integer_regs((X))
+
+extern tree llvm_x86_should_return_vector_as_scalar(tree, bool);
+
/* The MMX vector v1i64 is returned in EAX and EDX on Darwin. Communicate
this by returning i64 here. Likewise, (generic) vectors such as v2i16
are returned in EAX. */
#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin)\
- ((TARGET_MACHO && \
- !isBuiltin && \
- !TARGET_64BIT && \
- TREE_CODE(X) == VECTOR_TYPE && \
- TYPE_SIZE(X) && \
- TREE_CODE(TYPE_SIZE(X))==INTEGER_CST) \
- ? (TREE_INT_CST_LOW(TYPE_SIZE(X))==64 && \
- TYPE_VECTOR_SUBPARTS(X)==1) \
- ? uint64_type_node \
- : (TREE_INT_CST_LOW(TYPE_SIZE(X))==32) \
- ? uint32_type_node \
- : 0 \
- : 0)
+ llvm_x86_should_return_vector_as_scalar((X), (isBuiltin))
+
+extern bool llvm_x86_should_return_vector_as_shadow(tree, bool);
/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
32-bit. Vectors bigger than 128 are returned using sret. */
#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
- ((TARGET_MACHO && \
- !isBuiltin && \
- !TARGET_64BIT && \
- TREE_CODE(X) == VECTOR_TYPE && \
- TYPE_SIZE(X) && \
- TREE_CODE(TYPE_SIZE(X))==INTEGER_CST) \
- ? (TREE_INT_CST_LOW(TYPE_SIZE(X))==64 && \
- TYPE_VECTOR_SUBPARTS(X)>1) \
- ? true \
- : (TREE_INT_CST_LOW(TYPE_SIZE(X))>128) \
- ? true \
- : false \
- : false)
+ llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
extern bool llvm_x86_should_pass_aggregate_in_memory(tree, const Type *);
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=48608&r1=48607&r2=48608&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Thu Mar 20 13:42:57 2008
@@ -759,4 +759,57 @@
}
return true;
}
+
+/* Vectors which are not MMX nor SSE should be passed as integers. */
+bool llvm_x86_should_pass_vector_in_integer_regs(tree type) {
+ if (TARGET_MACHO &&
+ !TARGET_64BIT &&
+ TREE_CODE(type) == VECTOR_TYPE &&
+ TYPE_SIZE(type) &&
+ TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64 && TARGET_MMX)
+ return false;
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))==128 && TARGET_SSE)
+ return false;
+ }
+ return true;
+}
+
+/* The MMX vector v1i64 is returned in EAX and EDX on Darwin. Communicate
+ this by returning i64 here. Likewise, (generic) vectors such as v2i16
+ are returned in EAX. */
+tree llvm_x86_should_return_vector_as_scalar(tree type, bool isBuiltin) {
+ if (TARGET_MACHO &&
+ !isBuiltin &&
+ !TARGET_64BIT &&
+ TREE_CODE(type) == VECTOR_TYPE &&
+ TYPE_SIZE(type) &&
+ TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64 &&
+ TYPE_VECTOR_SUBPARTS(type)==1)
+ return uint64_type_node;
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))==32)
+ return uint32_type_node;
+ }
+ return 0;
+}
+
+/* MMX vectors v2i32, v4i16, v8i8, v2f32 are returned using sret on Darwin
+ 32-bit. Vectors bigger than 128 are returned using sret. */
+bool llvm_x86_should_return_vector_as_shadow(tree type, bool isBuiltin) {
+ if (TARGET_MACHO &&
+ !isBuiltin &&
+ !TARGET_64BIT &&
+ TREE_CODE(type) == VECTOR_TYPE &&
+ TYPE_SIZE(type) &&
+ TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64 &&
+ TYPE_VECTOR_SUBPARTS(type)>1)
+ return true;
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))>128)
+ return true;
+ }
+ return false;
+}
+
/* LLVM LOCAL end (ENTIRE FILE!) */
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=48608&r1=48607&r2=48608&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 Thu Mar 20 13:42:57 2008
@@ -448,5 +448,44 @@
return false;
}
+/* Non-Altivec vectors are passed in integer regs. */
+bool llvm_rs6000_should_pass_vector_in_integer_regs(tree type) {
+ if (!TARGET_64BIT &&
+ TREE_CODE(type) == VECTOR_TYPE &&
+ TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type))==INTEGER_CST &&
+ TREE_INT_CST_LOW(TYPE_SIZE(type)) != 128)
+ return true;
+ return false;
+}
+
+/* (Generic) vectors 4 bytes long are returned as an int.
+ Vectors 8 bytes long are returned as 2 ints. */
+tree llvm_rs6000_should_return_vector_as_scalar(tree type,
+ bool isBuiltin ATTRIBUTE_UNUSED) {
+ if (!TARGET_64BIT &&
+ TREE_CODE(type) == VECTOR_TYPE &&
+ TYPE_SIZE(type) &&
+ TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
+ if (TREE_INT_CST_LOW(TYPE_SIZE(type))==32)
+ return uint32_type_node;
+ else if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64)
+ return uint64_type_node;
+ }
+ return 0;
+}
+
+/* Non-altivec vectors bigger than 8 bytes are returned by sret. */
+bool llvm_rs6000_should_return_vector_as_shadow(tree type,
+ bool isBuiltin ATTRIBUTE_UNUSED) {
+ if (!TARGET_64BIT &&
+ TREE_CODE(type) == VECTOR_TYPE &&
+ TYPE_SIZE(type) &&
+ TREE_CODE(TYPE_SIZE(type))==INTEGER_CST &&
+ TREE_INT_CST_LOW(TYPE_SIZE(type))>64 &&
+ TREE_INT_CST_LOW(TYPE_SIZE(type))!=128)
+ return true;
+ 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=48608&r1=48607&r2=48608&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/rs6000/rs6000.h Thu Mar 20 13:42:57 2008
@@ -638,7 +638,7 @@
We must map them here to avoid huge unwinder tables mostly consisting
of unused space. */
/* APPLE LOCAL begin 3399553 */
-#define DWARF_REG_TO_UNWIND_COLUMN(r) \
+#define DWARF_REG_TO_UNWIND_COLUMN(r) \
((r) > 1200 ? ((r) - 1200 + LAST_PHYSICAL_REGISTER) : (r))
/* APPLE LOCAL end 3399553 */
@@ -3479,7 +3479,13 @@
extern bool llvm_rs6000_should_pass_aggregate_byval(tree, const Type *);
#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
- llvm_rs6000_should_pass_aggregate_byval(X, TY)
+ llvm_rs6000_should_pass_aggregate_byval((X), (TY))
+
+extern bool llvm_rs6000_should_pass_vector_in_integer_regs(tree);
+
+/* All non-Altivec vectors are passed in integer regs. */
+#define LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(X) \
+ llvm_rs6000_should_pass_vector_in_integer_regs((X))
extern bool llvm_rs6000_should_pass_aggregate_in_mixed_regs(tree, const Type*,
std::vector<const Type*>&);
@@ -3488,15 +3494,18 @@
#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, E) \
llvm_rs6000_should_pass_aggregate_in_mixed_regs((T), (TY), (E))
-/* Non-altivec vectors bigger than 4 bytes are returned by sret. */
+extern tree llvm_rs6000_should_return_vector_as_scalar(tree, bool);
+
+/* (Generic) vectors 4 bytes long are returned as an int.
+ Vectors 8 bytes long are returned as 2 ints. */
+#define LLVM_SHOULD_RETURN_VECTOR_AS_SCALAR(X,isBuiltin) \
+ llvm_rs6000_should_return_vector_as_scalar((X), (isBuiltin))
+
+extern bool llvm_rs6000_should_return_vector_as_shadow(tree, bool);
+
+/* Non-altivec vectors bigger than 8 bytes are returned by sret. */
#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
- ((!TARGET_64BIT && \
- TREE_CODE(X) == VECTOR_TYPE && \
- TYPE_SIZE(X) && \
- TREE_CODE(TYPE_SIZE(X))==INTEGER_CST && \
- TREE_INT_CST_LOW(TYPE_SIZE(X))>32 && \
- TREE_INT_CST_LOW(TYPE_SIZE(X))!=128) \
- ? true : false)
+ llvm_rs6000_should_return_vector_as_shadow((X), (isBuiltin))
#endif /* LLVM_ABI_H */
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=48608&r1=48607&r2=48608&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu Mar 20 13:42:57 2008
@@ -321,10 +321,11 @@
if (isPassedByInvisibleReference(type)) { // variable size -> by-ref.
C.HandleScalarArgument(PointerType::getUnqual(Ty), type);
} else if (Ty->getTypeID()==Type::VectorTyID) {
- if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type))
+ if (LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(type)) {
PassInIntegerRegisters(type, Ty);
- else
+ } else {
C.HandleScalarArgument(Ty, type);
+ }
} else if (Ty->isFirstClassType()) {
C.HandleScalarArgument(Ty, type);
} else if (LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(type, Ty, Elts)) {
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=48608&r1=48607&r2=48608&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Mar 20 13:42:57 2008
@@ -825,14 +825,7 @@
}
Value *TreeToLLVM::Emit(tree exp, const MemRef *DestLoc) {
- tree fndecl;
- // Some vectors are returned using sret; these should have DestLoc provided.
- assert(((isAggregateTreeType(TREE_TYPE(exp)) == (DestLoc != 0)) ||
- (TREE_CODE(exp)==CALL_EXPR &&
- TREE_CODE(TREE_TYPE(exp))==VECTOR_TYPE &&
- LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(TREE_TYPE(exp),
- ((fndecl = get_callee_fndecl(exp)) ? DECL_BUILT_IN(fndecl) :
- false))) ||
+ assert((isAggregateTreeType(TREE_TYPE(exp)) == (DestLoc != 0) ||
TREE_CODE(exp) == MODIFY_EXPR) &&
"Didn't pass DestLoc to an aggregate expr, or passed it to scalar!");
@@ -2279,8 +2272,24 @@
// parameter for the chain.
Callee = BitCastToType(Callee, PointerType::getUnqual(Ty));
- //EmitCall(exp, DestLoc);
- Value *Result = EmitCallOf(Callee, exp, DestLoc, PAL);
+ Value *Result;
+ if (TREE_CODE(TREE_TYPE(exp))==VECTOR_TYPE &&
+ LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(TREE_TYPE(exp),
+ fndecl ? DECL_BUILT_IN(fndecl) : false)) {
+ // Vectors are first class types, so we need to return a value,
+ // but this one is to be passed using sret. Pass in a DestLoc, if
+ // there isn't one already, and return a Load from it as the value.
+ if (!DestLoc) {
+ MemRef NewLoc = CreateTempLoc(ConvertType(TREE_TYPE(exp)));
+ DestLoc = &NewLoc;
+ }
+ EmitCallOf(Callee, exp, DestLoc, PAL);
+ LoadInst *LI = Builder.CreateLoad(DestLoc->Ptr, false, "tmp");
+ Result = LI;
+ } else {
+ //EmitCall(exp, DestLoc);
+ Result = EmitCallOf(Callee, exp, DestLoc, PAL);
+ }
// If the function has the volatile bit set, then it is a "noreturn" function.
// Output an unreachable instruction right after the function to prevent LLVM
@@ -2505,8 +2514,20 @@
CallOperands.push_back(BitCastToType(Ptr, ArgTy));
} else if (ActualArgTy->isFirstClassType()) {
Value *V = Emit(TREE_VALUE(arg), 0);
- bool isSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(arg)));
- CallOperands.push_back(CastToAnyType(V, isSigned, ArgTy, false));
+ if (TREE_CODE(TREE_TYPE(TREE_VALUE(arg)))==VECTOR_TYPE &&
+ LLVM_SHOULD_PASS_VECTOR_IN_INTEGER_REGS(TREE_TYPE(TREE_VALUE(arg)))) {
+ // Passed as integer registers. We need a stack object, not a value.
+ MemRef NewLoc = CreateTempLoc(ConvertType(TREE_TYPE(TREE_VALUE(arg))));
+ StoreInst *St = Builder.CreateStore(V, NewLoc.Ptr, false);
+ Client.setLocation(NewLoc.Ptr);
+ ParameterAttributes Attributes = ParamAttr::None;
+ ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)), &Attributes);
+ if (Attributes != ParamAttr::None)
+ PAL = PAL.addAttr(CallOperands.size(), Attributes);
+ } else {
+ bool isSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_VALUE(arg)));
+ CallOperands.push_back(CastToAnyType(V, isSigned, ArgTy, false));
+ }
} else {
// If this is an aggregate value passed by-value, use the current ABI to
// determine how the parameters are passed.
@@ -2654,26 +2675,7 @@
HandleMultiplyDefinedGCCTemp(lhs);
return EmitMODIFY_EXPR(exp, DestLoc);
}
- // Some types (so far, generic vectors on x86-32 and ppc32) can have
- // GCC SSA temporaries for them, but are passed using sret, which means
- // Emit will return 0. Handle this.
- Value *RHS;
- tree fndecl;
- if (TREE_CODE(rhs)==CALL_EXPR &&
- TREE_CODE(TREE_TYPE(rhs))==VECTOR_TYPE &&
- LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(TREE_TYPE(rhs),
- ((fndecl = get_callee_fndecl(rhs)) ? DECL_BUILT_IN(fndecl) :
- false))) {
- bool isVolatile = TREE_THIS_VOLATILE(lhs);
- unsigned Alignment = expr_align(lhs) / 8;
- MemRef NewLoc = CreateTempLoc(ConvertType(TREE_TYPE(rhs)));
- Emit(rhs, &NewLoc);
- LoadInst *LI = Builder.CreateLoad(NewLoc.Ptr, isVolatile, "tmp");
- LI->setAlignment(Alignment);
- RHS = LI;
- } else {
- RHS = Emit(rhs, 0);
- }
+ Value *RHS = Emit(rhs, 0);
RHS = CastToAnyType(RHS, RHSSigned, ConvertType(TREE_TYPE(lhs)), LHSSigned);
SET_DECL_LLVM(lhs, RHS);
return RHS;
More information about the llvm-commits
mailing list