[llvm-commits] [llvm-gcc-4.2] r57454 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp llvm-abi.h llvm-convert.cpp llvm-types.cpp
Evan Cheng
evan.cheng at apple.com
Mon Oct 13 11:03:01 PDT 2008
Author: evancheng
Date: Mon Oct 13 13:03:01 2008
New Revision: 57454
URL: http://llvm.org/viewvc/llvm-project?rev=57454&view=rev
Log:
On x86, pass _Complex * as a first class aggregate instead of ByVal. The exceptions are _Complex char, _Complex short, and _Complex int which codegen are not yet generating ABI compatible code.
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
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-types.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=57454&r1=57453&r2=57454&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 Mon Oct 13 13:03:01 2008
@@ -181,6 +181,16 @@
#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_as_fca(tree type, const Type *);
+
+/* LLVM_SHOULD_PASS_AGGREGATE_AS_FCA - Return true if an aggregate of the
+ specified type should be passed as a first-class aggregate. */
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+ llvm_x86_should_pass_aggregate_as_fca(X, TY)
+#endif
+
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=57454&r1=57453&r2=57454&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 Mon Oct 13 13:03:01 2008
@@ -619,9 +619,28 @@
return true;
}
+/* It returns true if an aggregate of the specified type should be passed as a
+ first class aggregate. */
+bool llvm_x86_should_pass_aggregate_as_fca(tree type, const Type *Ty) {
+ if (TREE_CODE(type) != COMPLEX_TYPE)
+ return false;
+ const StructType *STy = dyn_cast<StructType>(Ty);
+ if (!STy || STy->isPacked()) return false;
+
+ // FIXME: Currently codegen isn't lowering _Complex char / short and _Complex
+ // int in x86-64 in a way that makes it ABI compatible.
+ const Type *EltTy = STy->getElementType(0);
+ return !((TARGET_64BIT && EltTy == Type::Int32Ty) ||
+ EltTy == Type::Int16Ty ||
+ EltTy == Type::Int8Ty);
+}
+
/* Target hook for llvm-abi.h. It returns true if an aggregate of the
specified type should be passed in memory. */
bool llvm_x86_should_pass_aggregate_in_memory(tree TreeType, const Type *Ty) {
+ if (llvm_x86_should_pass_aggregate_as_fca(TreeType, Ty))
+ return false;
+
enum machine_mode Mode = ix86_getNaturalModeForType(TreeType);
HOST_WIDE_INT Bytes =
(Mode == BLKmode) ? int_size_in_bytes(TreeType) : (int) GET_MODE_SIZE(Mode);
@@ -723,6 +742,9 @@
bool
llvm_x86_64_should_pass_aggregate_in_mixed_regs(tree TreeType, const Type *Ty,
std::vector<const Type*> &Elts){
+ if (llvm_x86_should_pass_aggregate_as_fca(TreeType, Ty))
+ return false;
+
enum x86_64_reg_class Class[MAX_CLASSES];
enum machine_mode Mode = ix86_getNaturalModeForType(TreeType);
bool totallyEmpty = true;
@@ -1362,9 +1384,9 @@
/// llvm_store_scalar_argument - Store scalar argument ARGVAL of type
/// LLVMTY at location LOC.
void llvm_x86_store_scalar_argument(Value *Loc, Value *ArgVal,
- const llvm::Type *LLVMTy,
- unsigned RealSize,
- LLVMBuilder &Builder) {
+ const llvm::Type *LLVMTy,
+ unsigned RealSize,
+ LLVMBuilder &Builder) {
if (RealSize) {
// Do byte wise store because actaul argument type does not match LLVMTy.
Loc = Builder.CreateBitCast(Loc,
@@ -1413,8 +1435,7 @@
/// register. This means we'll be loading bytes off the end of the object
/// in some cases. That's what gcc does, so it must be OK, right? Right?
bool llvm_x86_should_pass_aggregate_in_integer_regs(tree type, unsigned *size,
- bool *DontCheckAlignment)
-{
+ bool *DontCheckAlignment) {
*size = 0;
if (TARGET_64BIT) {
enum x86_64_reg_class Class[MAX_CLASSES];
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=57454&r1=57453&r2=57454&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Mon Oct 13 13:03:01 2008
@@ -94,6 +94,10 @@
/// argument is passed by value.
void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {}
+ /// HandleFCAArgument - This callback is invoked if the aggregate function
+ /// argument is passed by value as a first class aggregate.
+ void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {}
+
/// EnterField - Called when we're about the enter the field of a struct
/// or union. FieldNo is the number of the element we are entering in the
/// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
@@ -251,6 +255,14 @@
false
#endif
+// LLVM_SHOULD_PASS_AGGREGATE_USING_BYVAL_ATTR - Return true if this aggregate
+// value should be passed by value as a first class aggregate. The default is
+// false.
+#ifndef LLVM_SHOULD_PASS_AGGREGATE_AS_FCA
+#define LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(X, TY) \
+ false
+#endif
+
// LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS - Return true if this aggregate
// value should be passed in a mixture of integer, floating point, and vector
// registers. The routine should also return by reference a vector of the
@@ -441,6 +453,8 @@
} else if (Ty->isSingleValueType()) {
C.HandleScalarArgument(Ty, type);
ScalarElts.push_back(Ty);
+ } else if (LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(type, Ty)) {
+ C.HandleFCAArgument(Ty, type);
} else if (LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(type, Ty, Elts)) {
if (!LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(Elts, ScalarElts))
PassInMixedRegisters(type, Ty, Elts, ScalarElts);
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=57454&r1=57453&r2=57454&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Oct 13 13:03:01 2008
@@ -513,6 +513,15 @@
abort();
}
+ void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {
+ // Store the FCA argument into alloca.
+ assert(!LocStack.empty());
+ Value *Loc = LocStack.back();
+ Builder.CreateStore(AI, Loc);
+ AI->setName(NameStack.back());
+ ++AI;
+ }
+
void HandleAggregateResultAsScalar(const Type *ScalarTy, unsigned Offset=0){
this->Offset = Offset;
}
@@ -2270,7 +2279,7 @@
// value out of the specified register.
return EmitReadOfRegisterVariable(exp, DestLoc);
}
-
+
LValue LV = EmitLV(exp);
bool isVolatile = TREE_THIS_VOLATILE(exp);
const Type *Ty = ConvertType(TREE_TYPE(exp));
@@ -2649,6 +2658,14 @@
CallOperands.push_back(Loc);
}
+ /// HandleFCAArgument - This callback is invoked if the aggregate function
+ /// argument is passed as a first class aggregate.
+ void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {
+ Value *Loc = getAddress();
+ assert(PointerType::getUnqual(LLVMTy) == Loc->getType());
+ CallOperands.push_back(Builder.CreateLoad(Loc));
+ }
+
/// EnterField - Called when we're about the enter the field of a struct
/// or union. FieldNo is the number of the element we are entering in the
/// LLVM Struct, StructTy is the LLVM type of the struct we are entering.
@@ -2735,12 +2752,17 @@
// Loop over the arguments, expanding them and adding them to the op list.
std::vector<const Type*> ScalarArgs;
for (tree arg = TREE_OPERAND(exp, 1); arg; arg = TREE_CHAIN(arg)) {
- const Type *ArgTy = ConvertType(TREE_TYPE(TREE_VALUE(arg)));
+ tree type = TREE_TYPE(TREE_VALUE(arg));
+ const Type *ArgTy = ConvertType(type);
// Push the argument.
if (ArgTy->isSingleValueType()) {
// A scalar - push the value.
Client.pushValue(Emit(TREE_VALUE(arg), 0));
+ } else if (LLVM_SHOULD_PASS_AGGREGATE_AS_FCA(type, ArgTy)) {
+ // A first class aggregate - push the value.
+ LValue ArgVal = EmitLV(TREE_VALUE(arg));
+ Client.pushValue(Builder.CreateLoad(ArgVal.Ptr));
} else {
// An aggregate - push the address.
LValue ArgVal = EmitLV(TREE_VALUE(arg));
@@ -2749,8 +2771,7 @@
}
Attributes Attrs = Attribute::None;
- ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)), ScalarArgs,
- &Attrs);
+ ABIConverter.HandleArgument(type, ScalarArgs, &Attrs);
if (Attrs != Attribute::None)
PAL = PAL.addAttr(CallOperands.size(), Attrs);
@@ -5848,7 +5869,7 @@
mark_referenced(ID);
}
}
-
+
const Type *Ty = ConvertType(TREE_TYPE(exp));
// If we have "extern void foo", make the global have type {} instead of
// type void.
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=57454&r1=57453&r2=57454&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Oct 13 13:03:01 2008
@@ -1021,6 +1021,12 @@
void HandleByValArgument(const llvm::Type *LLVMTy, tree type) {
HandleScalarArgument(PointerType::getUnqual(LLVMTy), type);
}
+
+ /// HandleFCAArgument - This callback is invoked if the aggregate function
+ /// argument is a first class aggregate passed by value.
+ void HandleFCAArgument(const llvm::Type *LLVMTy, tree type) {
+ ArgTypes.push_back(LLVMTy);
+ }
};
}
More information about the llvm-commits
mailing list