[llvm-commits] [llvm-gcc-4.2] r85539 - in /llvm-gcc-4.2/trunk/gcc: config/arm/llvm-arm-target.h config/arm/llvm-arm.cpp config/i386/llvm-i386-target.h llvm-abi.h llvm-types.cpp
Evan Cheng
evan.cheng at apple.com
Fri Oct 30 00:31:24 PDT 2009
This broke llvm-gcc build:
In file included from /tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-
debug.cpp:29:
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h:419:55: error:
macro "LLVM_AGGR_TYPE_FOR_STRUCT_RETURN" passed 2 arguments, but takes\
just 1
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h:776:55: error:
macro "LLVM_AGGR_TYPE_FOR_STRUCT_RETURN" passed 2 arguments, but takes\
just 1
In file included from /tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-
convert.cpp:45:
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h: In member
function 'void DefaultABI<Client>::HandleReturnType(tree_node*,
tree_node*\
, bool)':
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h:418: error:
'LLVM_AGGR_TYPE_FOR_STRUCT_RETURN' was not declared in this scope
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h: In member
function 'void SVR4ABI<Client>::HandleReturnType(tree_node*,
tree_node*, b\
ool)':
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h:775: error:
'LLVM_AGGR_TYPE_FOR_STRUCT_RETURN' was not declared in this scope
In file included from /tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-
types.cpp:48:
/tmp/llvmgcc42.roots/llvmgcc42~obj/src/gcc/llvm-abi.h: In member
function 'void DefaultABI<Client>::HandleReturnType(tree_node*,
tree_node*\
, bool)':
I see this in llvm-abi.h:
#ifndef LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X) \
getLLVMAggregateTypeForStructReturn(X)
#endif
if (const Type *AggrTy = LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(type,
C.getCallingConv()))
This doesn't look right?
Evan
On Oct 29, 2009, at 4:35 PM, Bob Wilson wrote:
> Author: bwilson
> Date: Thu Oct 29 18:35:11 2009
> New Revision: 85539
>
> URL: http://llvm.org/viewvc/llvm-project?rev=85539&view=rev
> Log:
> Fix ARM AAPCS-VFP return of homogeneous aggregates. Patch by
> Sandeep Patel.
>
> Modified:
> llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm-target.h
> llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp
> llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
> llvm-gcc-4.2/trunk/gcc/llvm-abi.h
> llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
>
> Modified: llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm-target.h
> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm-target.h?rev=85539&r1=85538&r2=85539&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm-target.h (original)
> +++ llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm-target.h Thu Oct 29
> 18:35:11 2009
> @@ -25,17 +25,17 @@
> specification says that varargs functions must use the base
> standard
> instead of the VFP hard float variant. We check for that with
> (isVoid || hasArgList). */
> -#define TARGET_ADJUST_LLVM_CC(CC, type) \
> - { \
> - if (TARGET_AAPCS_BASED) \
> - CC = ((TARGET_VFP && TARGET_HARD_FLOAT_ABI && \
> - ((TYPE_ARG_TYPES(type) == 0) || \
> - (TREE_VALUE(tree_last(TYPE_ARG_TYPES(type))) == \
> - void_type_node))) ? \
> - CallingConv::ARM_AAPCS_VFP : \
> - CallingConv::ARM_AAPCS); \
> - else \
> - CC = CallingConv::ARM_APCS; \
> +#define TARGET_ADJUST_LLVM_CC(CC, type) \
> + { \
> + if (TARGET_AAPCS_BASED) \
> + CC = ((TARGET_VFP && TARGET_HARD_FLOAT_ABI && \
> + ((TYPE_ARG_TYPES(type) == 0) || \
> + (TREE_VALUE(tree_last(TYPE_ARG_TYPES(type))) == \
> + void_type_node))) ? \
> + CallingConv::ARM_AAPCS_VFP : \
> + CallingConv::ARM_AAPCS); \
> + else \
> + CC = CallingConv::ARM_APCS; \
> }
>
> #ifdef LLVM_ABI_H
> @@ -45,7 +45,7 @@
> CallingConv::ID&,
> std::vector<const
> Type*>&);
>
> -#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
> +#define LLVM_SHOULD_PASS_AGGREGATE_IN_MIXED_REGS(T, TY, CC, E) \
> llvm_arm_should_pass_aggregate_in_mixed_regs((T), (TY), (CC), (E))
>
> extern
> @@ -53,9 +53,35 @@
> std::vector<const
> Type*>&,
> bool,
> CallingConv::ID&);
>
> -#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
> +#define LLVM_AGGREGATE_PARTIALLY_PASSED_IN_REGS(E, SE, ISR, CC) \
> llvm_arm_aggregate_partially_passed_in_regs((E), (SE), (ISR), (CC))
>
> +extern const Type *llvm_arm_aggr_type_for_struct_return(tree type,
> +
> CallingConv::ID &CC);
> +
> +/* LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
> + returned as an aggregate, otherwise return NULL. */
> +#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
> + llvm_arm_aggr_type_for_struct_return((X), (CC))
> +
> +extern void llvm_arm_extract_multiple_return_value(Value *Src,
> Value *Dest,
> + bool isVolatile,
> + LLVMBuilder &B);
> +
> +/* LLVM_EXTRACT_MULTIPLE_RETURN_VALUE - Extract multiple return
> value from
> + SRC and assign it to DEST. */
> +#define LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Src,Dest,V,B) \
> + llvm_arm_extract_multiple_return_value((Src),(Dest),(V),(B))
> +
> +extern
> +bool llvm_arm_should_pass_or_return_aggregate_in_regs(tree TreeType,
> +
> CallingConv::ID &CC);
> +
> +/* LLVM_SHOULD_NOT_USE_SHADOW_RETURN = Return true is the given
> type should
> + not be returned via a shadow parameter with the given calling
> conventions. */
> +#define LLVM_SHOULD_NOT_USE_SHADOW_RETURN(X, CC) \
> + llvm_arm_should_pass_or_return_aggregate_in_regs((X), (CC))
> +
> #endif /* LLVM_ABI_H */
> #endif /* ENABLE_LLVM */
> /* LLVM LOCAL end (ENTIRE FILE!) */
>
> Modified: llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp?rev=85539&r1=85538&r2=85539&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp (original)
> +++ llvm-gcc-4.2/trunk/gcc/config/arm/llvm-arm.cpp Thu Oct 29
> 18:35:11 2009
> @@ -2524,24 +2524,14 @@
> llvm_arm_should_pass_aggregate_in_mixed_regs(tree TreeType, const
> Type *Ty,
> CallingConv::ID &CC,
> std::vector<const
> Type*> &Elts) {
> - // Homogeneous aggregates are an AAPCS-VFP feature.
> - if ((CC != CallingConv::ARM_AAPCS_VFP) ||
> - !(TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT_ABI))
> + if (!llvm_arm_should_pass_or_return_aggregate_in_regs(TreeType,
> CC))
> return false;
>
> - // Alas, we can't use LLVM Types to figure this out because we
> need to
> - // examine unions closely. We'll have to walk the GCC TreeType.
> - int fdt_counts[ARM_FDT_MAX] = { 0 };
> - bool result = false;
> - result = vfp_arg_homogeneous_aggregate_p(TYPE_MODE(TreeType),
> TreeType,
> - fdt_counts);
> -
> // Walk Ty and push LLVM types corresponding to register types onto
> // Elts.
> - if (result)
> - push_elts(Ty, Elts);
> + push_elts(Ty, Elts);
>
> - return result;
> + return true;
> }
>
> static bool alloc_next_spr(bool *SPRs)
> @@ -2645,4 +2635,124 @@
> return false; // it all fit in registers!
> }
>
> +// Return LLVM Type if TYPE can be returned as an aggregate,
> +// otherwise return NULL.
> +const Type *llvm_arm_aggr_type_for_struct_return(tree TreeType,
> + CallingConv::ID
> &CC) {
> + if (!llvm_arm_should_pass_or_return_aggregate_in_regs(TreeType,
> CC))
> + return NULL;
> +
> + // Walk Ty and push LLVM types corresponding to register types onto
> + // Elts.
> + std::vector<const Type*> Elts;
> + const Type *Ty = ConvertType(TreeType);
> + push_elts(Ty, Elts);
> +
> + return StructType::get(Context, Elts, false);
> +}
> +
> +// llvm_arm_extract_mrv_array_element - Helper function that helps
> extract
> +// an array element from multiple return value.
> +//
> +// Here, SRC is returning multiple values. DEST's DESTFIELDNO field
> is an array.
> +// Extract SRCFIELDNO's ELEMENO value and store it in DEST's
> FIELDNO field's
> +// ELEMENTNO.
> +//
> +static void llvm_arm_extract_mrv_array_element(Value *Src, Value
> *Dest,
> + unsigned SrcFieldNo,
> + unsigned SrcElemNo,
> + unsigned DestFieldNo,
> + unsigned DestElemNo,
> + LLVMBuilder &Builder,
> + bool isVolatile) {
> + Value *EVI = Builder.CreateExtractValue(Src, SrcFieldNo, "mrv_gr");
> + const StructType *STy = cast<StructType>(Src->getType());
> + llvm::Value *Idxs[3];
> + Idxs[0] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 0);
> + Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context),
> DestFieldNo);
> + Idxs[2] = ConstantInt::get(llvm::Type::getInt32Ty(Context),
> DestElemNo);
> + Value *GEP = Builder.CreateGEP(Dest, Idxs, Idxs+3, "mrv_gep");
> + if (isa<VectorType>(STy->getElementType(SrcFieldNo))) {
> + Value *ElemIndex = ConstantInt::get(Type::getInt32Ty(Context),
> SrcElemNo);
> + Value *EVIElem = Builder.CreateExtractElement(EVI, ElemIndex,
> "mrv");
> + Builder.CreateStore(EVIElem, GEP, isVolatile);
> + } else {
> + Builder.CreateStore(EVI, GEP, isVolatile);
> + }
> +}
> +
> +// llvm_arm_extract_multiple_return_value - Extract multiple values
> returned
> +// by SRC and store them in DEST. It is expected that SRC and
> +// DEST types are StructType, but they may not match.
> +void llvm_arm_extract_multiple_return_value(Value *Src, Value *Dest,
> + bool isVolatile,
> + LLVMBuilder &Builder) {
> +
> + const StructType *STy = cast<StructType>(Src->getType());
> + unsigned NumElements = STy->getNumElements();
> +
> + const PointerType *PTy = cast<PointerType>(Dest->getType());
> + const StructType *DestTy = cast<StructType>(PTy->getElementType());
> +
> + unsigned SNO = 0;
> + unsigned DNO = 0;
> +
> + while (SNO < NumElements) {
> +
> + const Type *DestElemType = DestTy->getElementType(DNO);
> +
> + // Directly access first class values.
> + if (DestElemType->isSingleValueType()) {
> + Value *GEP = Builder.CreateStructGEP(Dest, DNO, "mrv_gep");
> + Value *EVI = Builder.CreateExtractValue(Src, SNO, "mrv_gr");
> + Builder.CreateStore(EVI, 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]; }
> + const ArrayType *ATy = cast<ArrayType>(DestElemType);
> + unsigned ArraySize = ATy->getNumElements();
> + unsigned DElemNo = 0; // DestTy's DNO field's element number
> + while (DElemNo < ArraySize) {
> + unsigned i = 0;
> + unsigned Size = 1;
> +
> + if (const VectorType *SElemTy =
> + dyn_cast<VectorType>(STy->getElementType(SNO))) {
> + Size = SElemTy->getNumElements();
> + }
> + while (i < Size) {
> + llvm_arm_extract_mrv_array_element(Src, Dest, SNO, i++,
> + DNO, DElemNo++,
> + Builder, isVolatile);
> + }
> + // Consumed this src field. Try next one.
> + ++SNO;
> + }
> + // Finished building current dest field.
> + ++DNO;
> + }
> +}
> +
> +// Target hook for llvm-abi.h for LLVM_SHOULD_NOT_USE_SHADOW_RETURN
> and is
> +// also a utility function used for other target hooks in this
> file. Returns
> +// true if the aggregate should be passed or returned in registers.
> +bool llvm_arm_should_pass_or_return_aggregate_in_regs(tree TreeType,
> +
> CallingConv::ID &CC) {
> + // Homogeneous aggregates are an AAPCS-VFP feature.
> + if ((CC != CallingConv::ARM_AAPCS_VFP) ||
> + !(TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT_ABI))
> + return false;
> +
> + // Alas, we can't use LLVM Types to figure this out because we
> need to
> + // examine unions closely. We'll have to walk the GCC TreeType.
> + int fdt_counts[ARM_FDT_MAX] = { 0 };
> + bool result = false;
> + result = vfp_arg_homogeneous_aggregate_p(TYPE_MODE(TreeType),
> TreeType,
> + fdt_counts);
> + return result;
> +}
> +
> /* LLVM LOCAL end (ENTIRE FILE!) */
>
> 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=85539&r1=85538&r2=85539&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 Oct 29
> 18:35:11 2009
> @@ -139,7 +139,7 @@
>
> /* LLVM_AGGR_TYPE_FOR_STRUCT_RETURN - Return LLVM Type if X can be
> returned as an aggregate, otherwise return NULL. */
> -#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X) \
> +#define LLVM_AGGR_TYPE_FOR_STRUCT_RETURN(X, CC) \
> llvm_x86_aggr_type_for_struct_return(X)
>
> extern void llvm_x86_extract_multiple_return_value(Value *Src, Value
> *Dest,
>
> 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=85539&r1=85538&r2=85539&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
> +++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu Oct 29 18:35:11 2009
> @@ -126,15 +126,24 @@
> false
> #endif
>
> +// LLVM_SHOULD_NOT_USE_SHADOW_RETURN - A hook to allow aggregates
> to be
> +// returned in registers.
> +#ifndef LLVM_SHOULD_NOT_USE_SHADOW_RETURN
> +#define LLVM_SHOULD_NOT_USE_SHADOW_RETURN(X, CC) \
> + false
> +#endif
> +
> // doNotUseShadowReturn - Return true if the specified GCC type
> // should not be returned using a pointer to struct parameter.
> -static inline bool doNotUseShadowReturn(tree type, tree fndecl) {
> +static inline bool doNotUseShadowReturn(tree type, tree fndecl,
> + CallingConv::ID CC) {
> if (!TYPE_SIZE(type))
> return false;
> if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST)
> return false;
> // LLVM says do not use shadow argument.
> - if (LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(type))
> + if (LLVM_SHOULD_NOT_RETURN_COMPLEX_IN_MEMORY(type) ||
> + LLVM_SHOULD_NOT_USE_SHADOW_RETURN(type, CC))
> return true;
> // GCC says use shadow argument.
> if (aggregate_value_p(type, fndecl))
> @@ -396,7 +405,7 @@
> } else if (Ty->isSingleValueType() || Ty->isVoidTy()) {
> // Return scalar values normally.
> C.HandleScalarResult(Ty);
> - } else if (doNotUseShadowReturn(type, fn)) {
> + } else if (doNotUseShadowReturn(type, fn, C.getCallingConv())) {
> tree SingleElt = LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(type);
> if (SingleElt && TYPE_SIZE(SingleElt) &&
> TREE_CODE(TYPE_SIZE(SingleElt)) == INTEGER_CST &&
> @@ -406,7 +415,8 @@
> } else {
> // Otherwise return as an integer value large enough to hold
> the entire
> // aggregate.
> - if (const Type *AggrTy = LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
> (type))
> + if (const Type *AggrTy = LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
> (type,
> + C.getCallingConv()))
> C.HandleAggregateResultAsAggregate(AggrTy);
> else if (const Type* ScalarTy =
> LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(type, &Offset))
> @@ -752,7 +762,7 @@
> } else if (Ty->isSingleValueType() || Ty->isVoidTy()) {
> // Return scalar values normally.
> C.HandleScalarResult(Ty);
> - } else if (doNotUseShadowReturn(type, fn)) {
> + } else if (doNotUseShadowReturn(type, fn, C.getCallingConv())) {
> tree SingleElt = LLVM_SHOULD_RETURN_SELT_STRUCT_AS_SCALAR(type);
> if (SingleElt && TYPE_SIZE(SingleElt) &&
> TREE_CODE(TYPE_SIZE(SingleElt)) == INTEGER_CST &&
> @@ -762,7 +772,8 @@
> } else {
> // Otherwise return as an integer value large enough to hold
> the entire
> // aggregate.
> - if (const Type *AggrTy = LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
> (type))
> + if (const Type *AggrTy = LLVM_AGGR_TYPE_FOR_STRUCT_RETURN
> (type,
> + C.getCallingConv()))
> C.HandleAggregateResultAsAggregate(AggrTy);
> else if (const Type* ScalarTy =
> LLVM_SCALAR_TYPE_FOR_STRUCT_RETURN(type, &Offset))
>
> 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=85539&r1=85538&r2=85539&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
> +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Oct 29 18:35:11 2009
> @@ -1052,16 +1052,16 @@
> tree ReturnType = TREE_TYPE(type);
> std::vector<PATypeHolder> ArgTys;
> PATypeHolder RetTy(Type::getVoidTy(Context));
> -
> +
> FunctionTypeConversion Client(RetTy, ArgTys, CallingConv, true /
> *K&R*/);
> TheLLVMABI<FunctionTypeConversion> ABIConverter(Client);
> -
> - // Builtins are always prototyped, so this isn't one.
> - ABIConverter.HandleReturnType(ReturnType, current_function_decl,
> false);
>
> #ifdef TARGET_ADJUST_LLVM_CC
> - TARGET_ADJUST_LLVM_CC(CallingConv, type);
> + TARGET_ADJUST_LLVM_CC(CallingConv, type);
> #endif
> +
> + // Builtins are always prototyped, so this isn't one.
> + ABIConverter.HandleReturnType(ReturnType, current_function_decl,
> false);
>
> SmallVector<AttributeWithIndex, 8> Attrs;
>
> @@ -1118,15 +1118,15 @@
> bool isVarArg = false;
> FunctionTypeConversion Client(RetTy, ArgTypes, CallingConv, false/
> *not K&R*/);
> TheLLVMABI<FunctionTypeConversion> ABIConverter(Client);
> -
> - ABIConverter.HandleReturnType(TREE_TYPE(type),
> current_function_decl,
> - decl ? DECL_BUILT_IN(decl) : false);
> -
> +
> // Allow the target to set the CC for things like fastcall etc.
> #ifdef TARGET_ADJUST_LLVM_CC
> TARGET_ADJUST_LLVM_CC(CallingConv, type);
> #endif
>
> + ABIConverter.HandleReturnType(TREE_TYPE(type),
> current_function_decl,
> + decl ? DECL_BUILT_IN(decl) : false);
> +
> // Compute attributes for return type (and function attributes).
> SmallVector<AttributeWithIndex, 8> Attrs;
> Attributes FnAttributes = Attribute::None;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list