[llvm-commits] [llvm-gcc-4.2] r49834 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp llvm-abi.h
Devang Patel
dpatel at apple.com
Wed Apr 16 17:33:04 PDT 2008
Author: dpatel
Date: Wed Apr 16 19:33:04 2008
New Revision: 49834
URL: http://llvm.org/viewvc/llvm-project?rev=49834&view=rev
Log:
_Complex deserves special treatement.
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/llvm-abi.h
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=49834&r1=49833&r2=49834&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 Wed Apr 16 19:33:04 2008
@@ -151,6 +151,15 @@
#define LLVM_SHOULD_RETURN_VECTOR_AS_SHADOW(X,isBuiltin)\
llvm_x86_should_return_vector_as_shadow((X),(isBuiltin))
+extern bool
+llvm_x86_should_not_return_complex_in_memory(tree type);
+
+/* LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+ special _Complex handling. Return true if X should be returned using
+ multiple value return instruction. */
+#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+ llvm_x86_should_not_return_complex_in_memory((X))
+
extern bool llvm_x86_should_pass_aggregate_in_memory(tree, const Type *);
#define LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR(X, TY) \
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=49834&r1=49833&r2=49834&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 Wed Apr 16 19:33:04 2008
@@ -900,12 +900,27 @@
return false;
}
+// llvm_x86_should_not_return_complex_in_memory - Return true if TYPE
+// should be returned using multiple value return instruction.
+bool llvm_x86_should_not_return_complex_in_memory(tree type) {
+ if (!TARGET_64BIT)
+ return false;
+
+ if (AGGREGATE_TYPE_P(type)) {
+ tree field = TYPE_FIELDS(type);
+ if (field && TREE_CHAIN(field) == NULL
+ && TREE_CODE(TREE_TYPE(field)) == COMPLEX_TYPE)
+ return true;
+ }
+ return false;
+}
+
// llvm_suitable_multiple_ret_value_type - Return TRUE if return value
// of type TY should be returned using multiple value return instruction.
static bool llvm_suitable_multiple_ret_value_type(const Type *Ty,
tree TreeType) {
//NOTE: Work in progress. Do not open the flood gate yet.
- return false;
+ // return false;
if (!TARGET_64BIT)
return false;
@@ -914,6 +929,9 @@
if (!STy)
return false;
+ if (llvm_x86_should_not_return_complex_in_memory(TreeType))
+ return true;
+
// llvm only accepts first class types for multiple values in ret instruction.
bool foundNonInt = false;
bool foundInt = false;
@@ -922,7 +940,7 @@
const Type *ETy = STy->getElementType(i);
if (const ArrayType *ATy = dyn_cast<ArrayType>(ETy))
ETy = ATy->getElementType();
- if (!ETy->isFirstClassType())
+ if (!ETy->isFirstClassType() && ETy->getTypeID() != Type::X86_FP80TyID)
return false;
if (!ETy->isInteger())
foundNonInt = true;
@@ -987,8 +1005,15 @@
const StructType *STy = cast<StructType>(Ty);
unsigned NumElements = STy->getNumElements();
-
std::vector<const Type *> ElementTypes;
+
+ // Special handling for _Complex.
+ if (llvm_x86_should_not_return_complex_in_memory(type)) {
+ ElementTypes.push_back(Type::X86_FP80Ty);
+ ElementTypes.push_back(Type::X86_FP80Ty);
+ return StructType::get(ElementTypes, STy->isPacked());
+ }
+
for (unsigned i = 0; i < NumElements; ++i) {
const Type *T = STy->getElementType(i);
@@ -1086,8 +1111,22 @@
++RNO;
++SNO;
continue;
+ }
+ // Special treatement for _Complex.
+ if (const StructType *ComplexType = dyn_cast<StructType>(ElemType)) {
+ llvm::Value *Idxs[3];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, RNO);
+ Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Value *GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv_gep");
+ RetVals.push_back(Builder.CreateLoad(GEP, "mrv"));
+ Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+ GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv_gep");
+ RetVals.push_back(Builder.CreateLoad(GEP, "mrv"));
+ ++RNO;
+ ++SNO;
+ continue;
}
-
const ArrayType *ATy = cast<ArrayType>(ElemType);
unsigned ArraySize = ATy->getNumElements();
unsigned AElemNo = 0;
@@ -1172,6 +1211,26 @@
++DNO; ++SNO;
continue;
}
+
+ // Special treatement for _Complex.
+ if (const StructType *ComplexType = dyn_cast<StructType>(DestElemType)) {
+ llvm::Value *Idxs[3];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, DNO);
+
+ Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Value *GEP = Builder.CreateGEP(Dest, Idxs, Idxs+3, "mrv_gep");
+ GetResultInst *GR = Builder.CreateGetResult(Src, 0, "mrv_gr");
+ Builder.CreateStore(GR, GEP, isVolatile);
+ ++SNO;
+
+ Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, 1);
+ GEP = Builder.CreateGEP(Dest, Idxs, Idxs+3, "mrv_gep");
+ GR = Builder.CreateGetResult(Src, 1, "mrv_gr");
+ Builder.CreateStore(GR, GEP, isVolatile);
+ ++DNO; ++SNO;
+ continue;
+ }
// Access array elements individually. Note, Src and Dest type may
// not match. For example { <2 x float>, float } and { float[3]; }
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=49834&r1=49833&r2=49834&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Wed Apr 16 19:33:04 2008
@@ -104,6 +104,14 @@
TREE_CODE(type) == COMPLEX_TYPE;
}
+// LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY - A hook to allow
+// special _Complex handling. Return true if X should be returned using
+// multiple value return instruction.
+#ifndef LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY
+#define LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(X) \
+ false
+#endif
+
// doNotUseShadowReturn - Return true if the specified GCC type
// should not be returned using a pointer to struct parameter.
static bool doNotUseShadowReturn(tree type, tree fndecl) {
@@ -111,6 +119,9 @@
return false;
if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
return false;
+ // LLVM says do no use shadow argument.
+ if (LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(type))
+ return true;
// GCC says use shadow argument.
if (aggregate_value_p(type, fndecl))
return false;
More information about the llvm-commits
mailing list