r216535 - Move some ARM-specific code from CGCall.cpp to TargetInfo.cpp
Oliver Stannard
oliver.stannard at arm.com
Wed Aug 27 03:43:15 PDT 2014
Author: olista01
Date: Wed Aug 27 05:43:15 2014
New Revision: 216535
URL: http://llvm.org/viewvc/llvm-project?rev=216535&view=rev
Log:
Move some ARM-specific code from CGCall.cpp to TargetInfo.cpp
This tidies up some ARM-specific code added by r208417 to move it out
of the target-independent parts of clang into TargetInfo.cpp. This
also has the advantage that we can now flatten struct arguments to
variadic AAPCS functions.
Modified:
cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/CodeGen/TargetInfo.cpp
cfe/trunk/test/CodeGen/arm-homogenous.c
Modified: cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h?rev=216535&r1=216534&r2=216535&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h (original)
+++ cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h Wed Aug 27 05:43:15 2014
@@ -87,6 +87,7 @@ private:
bool IndirectRealign : 1; // isIndirect()
bool SRetAfterThis : 1; // isIndirect()
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
+ bool CanBeFlattened: 1; // isDirect()
ABIArgInfo(Kind K)
: PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
@@ -97,11 +98,13 @@ public:
TheKind(Direct), PaddingInReg(false), InReg(false) {}
static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
- llvm::Type *Padding = nullptr) {
+ llvm::Type *Padding = nullptr,
+ bool CanBeFlattened = true) {
auto AI = ABIArgInfo(Direct);
AI.setCoerceToType(T);
AI.setDirectOffset(Offset);
AI.setPaddingType(Padding);
+ AI.setCanBeFlattened(CanBeFlattened);
return AI;
}
static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
@@ -265,6 +268,16 @@ public:
InAllocaSRet = SRet;
}
+ bool getCanBeFlattened() const {
+ assert(isDirect() && "Invalid kind!");
+ return CanBeFlattened;
+ }
+
+ void setCanBeFlattened(bool Flatten) {
+ assert(isDirect() && "Invalid kind!");
+ CanBeFlattened = Flatten;
+ }
+
void dump() const;
};
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=216535&r1=216534&r2=216535&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Aug 27 05:43:15 2014
@@ -139,23 +139,6 @@ static CallingConv getCallingConventionF
return CC_C;
}
-static bool isAAPCSVFP(const CGFunctionInfo &FI, const TargetInfo &Target) {
- switch (FI.getEffectiveCallingConvention()) {
- case llvm::CallingConv::C:
- switch (Target.getTriple().getEnvironment()) {
- case llvm::Triple::EABIHF:
- case llvm::Triple::GNUEABIHF:
- return true;
- default:
- return false;
- }
- case llvm::CallingConv::ARM_AAPCS_VFP:
- return true;
- default:
- return false;
- }
-}
-
/// Arrange the argument and result information for a call to an
/// unknown C++ non-static member function of the given abstract type.
/// (Zero value of RD means we don't have any meaningful "this" argument type,
@@ -989,14 +972,11 @@ CodeGenTypes::GetFunctionType(const CGFu
case ABIArgInfo::Extend:
case ABIArgInfo::Direct: {
- // If the coerce-to type is a first class aggregate, flatten it. Either
- // way is semantically identical, but fast-isel and the optimizer
- // generally likes scalar values better than FCAs.
- // We cannot do this for functions using the AAPCS calling convention,
- // as structures are treated differently by that calling convention.
+ // Fast-isel and the optimizer generally like scalar values better than
+ // FCAs, so we flatten them if this is safe to do for this argument.
llvm::Type *argType = argAI.getCoerceToType();
llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
- if (st && !isAAPCSVFP(FI, getTarget())) {
+ if (st && argAI.isDirect() && argAI.getCanBeFlattened()) {
for (unsigned i = 0, e = st->getNumElements(); i != e; ++i)
argTypes.push_back(st->getElementType(i));
} else {
@@ -1134,7 +1114,7 @@ void ClangToLLVMArgMapping::construct(Co
case ABIArgInfo::Direct: {
// FIXME: handle sseregparm someday...
llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.getCoerceToType());
- if (!isAAPCSVFP(FI, CGM.getTarget()) && STy) {
+ if (AI.isDirect() && AI.getCanBeFlattened() && STy) {
IRArgs.NumberOfArgs = STy->getNumElements();
} else {
IRArgs.NumberOfArgs = 1;
@@ -1671,13 +1651,11 @@ void CodeGenFunction::EmitFunctionProlog
llvm::PointerType::getUnqual(ArgI.getCoerceToType()));
}
- // If the coerce-to type is a first class aggregate, we flatten it and
- // pass the elements. Either way is semantically identical, but fast-isel
- // and the optimizer generally likes scalar values better than FCAs.
- // We cannot do this for functions using the AAPCS calling convention,
- // as structures are treated differently by that calling convention.
+ // Fast-isel and the optimizer generally like scalar values better than
+ // FCAs, so we flatten them if this is safe to do for this argument.
llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
- if (!isAAPCSVFP(FI, getTarget()) && STy && STy->getNumElements() > 1) {
+ if (ArgI.isDirect() && ArgI.getCanBeFlattened() && STy &&
+ STy->getNumElements() > 1) {
uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(STy);
llvm::Type *DstTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
@@ -2928,14 +2906,11 @@ RValue CodeGenFunction::EmitCall(const C
}
- // If the coerce-to type is a first class aggregate, we flatten it and
- // pass the elements. Either way is semantically identical, but fast-isel
- // and the optimizer generally likes scalar values better than FCAs.
- // We cannot do this for functions using the AAPCS calling convention,
- // as structures are treated differently by that calling convention.
+ // Fast-isel and the optimizer generally like scalar values better than
+ // FCAs, so we flatten them if this is safe to do for this argument.
llvm::StructType *STy =
dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType());
- if (STy && !isAAPCSVFP(CallInfo, getTarget())) {
+ if (STy && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) {
llvm::Type *SrcTy =
cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=216535&r1=216534&r2=216535&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Aug 27 05:43:15 2014
@@ -4169,6 +4169,9 @@ void ARMABIInfo::computeInfo(CGFunctionI
// unallocated are marked as unavailable.
resetAllocatedRegs();
+ const bool isAAPCS_VFP =
+ getABIKind() == ARMABIInfo::AAPCS_VFP && !FI.isVariadic();
+
if (getCXXABI().classifyReturnType(FI)) {
if (FI.getReturnInfo().isIndirect())
markAllocatedGPRs(1, 1);
@@ -4199,10 +4202,10 @@ void ARMABIInfo::computeInfo(CGFunctionI
llvm::Type::getInt32Ty(getVMContext()), NumGPRs - PreAllocationGPRs);
if (I.info.canHaveCoerceToType()) {
I.info = ABIArgInfo::getDirect(I.info.getCoerceToType() /* type */, 0 /* offset */,
- PaddingTy);
+ PaddingTy, !isAAPCS_VFP);
} else {
I.info = ABIArgInfo::getDirect(nullptr /* type */, 0 /* offset */,
- PaddingTy);
+ PaddingTy, !isAAPCS_VFP);
}
}
}
@@ -4398,6 +4401,9 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
// 64-bit containerized vectors or 128-bit containerized vectors with one
// to four Elements.
+ const bool isAAPCS_VFP =
+ getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic;
+
// Handle illegal vector types here.
if (isIllegalVectorType(Ty)) {
uint64_t Size = getContext().getTypeSize(Ty);
@@ -4405,7 +4411,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
llvm::Type *ResType =
llvm::Type::getInt32Ty(getVMContext());
markAllocatedGPRs(1, 1);
- return ABIArgInfo::getDirect(ResType);
+ return ABIArgInfo::getDirect(ResType, 0, nullptr, !isAAPCS_VFP);
}
if (Size == 64) {
llvm::Type *ResType = llvm::VectorType::get(
@@ -4416,7 +4422,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
markAllocatedVFPs(2, 2);
IsCPRC = true;
}
- return ABIArgInfo::getDirect(ResType);
+ return ABIArgInfo::getDirect(ResType, 0, nullptr, !isAAPCS_VFP);
}
if (Size == 128) {
llvm::Type *ResType = llvm::VectorType::get(
@@ -4427,7 +4433,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
markAllocatedVFPs(4, 4);
IsCPRC = true;
}
- return ABIArgInfo::getDirect(ResType);
+ return ABIArgInfo::getDirect(ResType, 0, nullptr, !isAAPCS_VFP);
}
markAllocatedGPRs(1, 1);
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
@@ -4466,8 +4472,9 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
unsigned Size = getContext().getTypeSize(Ty);
if (!IsCPRC)
markAllocatedGPRs(Size > 32 ? 2 : 1, (Size + 31) / 32);
- return (Ty->isPromotableIntegerType() ?
- ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+ return (Ty->isPromotableIntegerType()
+ ? ABIArgInfo::getExtend()
+ : ABIArgInfo::getDirect(nullptr, 0, nullptr, !isAAPCS_VFP));
}
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
@@ -4479,7 +4486,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) {
+ if (isAAPCS_VFP) {
// Homogeneous Aggregates need to be expanded when we can fit the aggregate
// into VFP registers.
const Type *Base = nullptr;
@@ -4500,7 +4507,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
markAllocatedVFPs(2, Members * 2);
}
IsCPRC = true;
- return ABIArgInfo::getDirect();
+ return ABIArgInfo::getDirect(nullptr, 0, nullptr, !isAAPCS_VFP);
}
}
@@ -4540,7 +4547,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT
llvm::Type *STy =
llvm::StructType::get(llvm::ArrayType::get(ElemTy, SizeRegs), NULL);
- return ABIArgInfo::getDirect(STy);
+ return ABIArgInfo::getDirect(STy, 0, nullptr, !isAAPCS_VFP);
}
static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
@@ -4630,6 +4637,9 @@ static bool isIntegerLikeType(QualType T
ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
bool isVariadic) const {
+ const bool isAAPCS_VFP =
+ getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic;
+
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -4644,8 +4654,9 @@ ABIArgInfo ARMABIInfo::classifyReturnTyp
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
- return (RetTy->isPromotableIntegerType() ?
- ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+ return (RetTy->isPromotableIntegerType()
+ ? ABIArgInfo::getExtend()
+ : ABIArgInfo::getDirect(nullptr, 0, nullptr, !isAAPCS_VFP));
}
// Are we following APCS?
@@ -4658,8 +4669,8 @@ ABIArgInfo ARMABIInfo::classifyReturnTyp
// FIXME: Consider using 2 x vector types if the back end handles them
// correctly.
if (RetTy->isAnyComplexType())
- return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
- getContext().getTypeSize(RetTy)));
+ return ABIArgInfo::getDirect(llvm::IntegerType::get(
+ getVMContext(), getContext().getTypeSize(RetTy)));
// Integer like structures are returned in r0.
if (isIntegerLikeType(RetTy, getContext(), getVMContext())) {
@@ -4688,7 +4699,7 @@ ABIArgInfo ARMABIInfo::classifyReturnTyp
if (isHomogeneousAggregate(RetTy, Base, getContext())) {
assert(Base && "Base class should be set for homogeneous aggregate");
// Homogeneous Aggregates are returned directly.
- return ABIArgInfo::getDirect();
+ return ABIArgInfo::getDirect(nullptr, 0, nullptr, !isAAPCS_VFP);
}
}
@@ -4698,14 +4709,18 @@ ABIArgInfo ARMABIInfo::classifyReturnTyp
if (Size <= 32) {
if (getDataLayout().isBigEndian())
// Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4)
- return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
+ return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()), 0,
+ nullptr, !isAAPCS_VFP);
// Return in the smallest viable integer type.
if (Size <= 8)
- return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
+ return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()), 0,
+ nullptr, !isAAPCS_VFP);
if (Size <= 16)
- return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
- return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
+ return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()), 0,
+ nullptr, !isAAPCS_VFP);
+ return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()), 0,
+ nullptr, !isAAPCS_VFP);
}
markAllocatedGPRs(1, 1);
Modified: cfe/trunk/test/CodeGen/arm-homogenous.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-homogenous.c?rev=216535&r1=216534&r2=216535&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-homogenous.c (original)
+++ cfe/trunk/test/CodeGen/arm-homogenous.c Wed Aug 27 05:43:15 2014
@@ -186,7 +186,7 @@ extern void takes_struct_of_four_doubles
void test_struct_of_four_doubles_variadic(void) {
// CHECK: test_struct_of_four_doubles_variadic
-// CHECK: call arm_aapcs_vfpcc void (double, { [4 x i64] }, { [4 x i64] }, double, ...)* @takes_struct_of_four_doubles_variadic(double {{.*}}, { [4 x i64] } {{.*}}, { [4 x i64] } {{.*}}, double {{.*}})
+// CHECK: call arm_aapcs_vfpcc void (double, [4 x i64], [4 x i64], double, ...)* @takes_struct_of_four_doubles_variadic(double {{.*}}, [4 x i64] {{.*}}, [4 x i64] {{.*}}, double {{.*}})
takes_struct_of_four_doubles_variadic(3.0, g_s4d, g_s4d, 4.0);
}
More information about the cfe-commits
mailing list