[cfe-commits] r167159 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/arm-homogenous.c
Manman Ren
mren at apple.com
Wed Oct 31 12:02:26 PDT 2012
Author: mren
Date: Wed Oct 31 14:02:26 2012
New Revision: 167159
URL: http://llvm.org/viewvc/llvm-project?rev=167159&view=rev
Log:
ARM AAPCS-VFP: fix tracking of allocated VFP registers.
According to the spec, we can backfill VFP registers that were skipped due
to alignment constraints.
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
cfe/trunk/test/CodeGen/arm-homogenous.c
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=167159&r1=167158&r2=167159&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Oct 31 14:02:26 2012
@@ -2863,7 +2863,8 @@
ABIKind getABIKind() const { return Kind; }
ABIArgInfo classifyReturnType(QualType RetTy) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &AllocatedVFP,
+ ABIArgInfo classifyArgumentType(QualType RetTy, int *VFPRegs,
+ unsigned &AllocatedVFP,
bool &IsHA) const;
bool isIllegalVectorType(QualType Ty) const;
@@ -2909,13 +2910,14 @@
void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
// To correctly handle Homogeneous Aggregate, we need to keep track of the
- // number of VFP registers allocated so far.
+ // VFP registers allocated so far.
// C.1.vfp If the argument is a VFP CPRC and there are sufficient consecutive
// VFP registers of the appropriate type unallocated then the argument is
// allocated to the lowest-numbered sequence of such registers.
// C.2.vfp If the argument is a VFP CPRC then any VFP registers that are
// unallocated are marked as unavailable.
unsigned AllocatedVFP = 0;
+ int VFPRegs[16] = { 0 };
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it) {
@@ -2924,7 +2926,7 @@
// 6.1.2.3 There is one VFP co-processor register class using registers
// s0-s15 (d0-d7) for passing arguments.
const unsigned NumVFPs = 16;
- it->info = classifyArgumentType(it->type, AllocatedVFP, IsHA);
+ it->info = classifyArgumentType(it->type, VFPRegs, AllocatedVFP, IsHA);
// If we do not have enough VFP registers for the HA, any VFP registers
// that are unallocated are marked as unavailable. To achieve this, we add
// padding of (NumVFPs - PreAllocation) floats.
@@ -3035,7 +3037,40 @@
return (Members > 0 && Members <= 4);
}
-ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, unsigned &AllocatedVFP,
+/// markAllocatedVFPs - update VFPRegs according to the alignment and
+/// number of VFP registers (unit is S register) requested.
+static void markAllocatedVFPs(int *VFPRegs, unsigned &AllocatedVFP,
+ unsigned Alignment,
+ unsigned NumRequired) {
+ // Early Exit.
+ if (AllocatedVFP >= 16)
+ return;
+ // C.1.vfp If the argument is a VFP CPRC and there are sufficient consecutive
+ // VFP registers of the appropriate type unallocated then the argument is
+ // allocated to the lowest-numbered sequence of such registers.
+ for (unsigned I = 0; I < 16; I += Alignment) {
+ bool FoundSlot = true;
+ for (unsigned J = I, JEnd = I + NumRequired; J < JEnd; J++)
+ if (J >= 16 || VFPRegs[J]) {
+ FoundSlot = false;
+ break;
+ }
+ if (FoundSlot) {
+ for (unsigned J = I, JEnd = I + NumRequired; J < JEnd; J++)
+ VFPRegs[J] = 1;
+ AllocatedVFP += NumRequired;
+ return;
+ }
+ }
+ // C.2.vfp If the argument is a VFP CPRC then any VFP registers that are
+ // unallocated are marked as unavailable.
+ for (unsigned I = 0; I < 16; I++)
+ VFPRegs[I] = 1;
+ AllocatedVFP = 17; // We do not have enough VFP registers.
+}
+
+ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs,
+ unsigned &AllocatedVFP,
bool &IsHA) const {
// We update number of allocated VFPs according to
// 6.1.2.1 The following argument types are VFP CPRCs:
@@ -3057,37 +3092,31 @@
if (Size == 64) {
llvm::Type *ResType = llvm::VectorType::get(
llvm::Type::getInt32Ty(getVMContext()), 2);
- // Align AllocatedVFP to an even number to use a D register.
- AllocatedVFP = llvm::RoundUpToAlignment(AllocatedVFP, 2);
- AllocatedVFP += 2; // 1 D register = 2 S registers
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, 2);
return ABIArgInfo::getDirect(ResType);
}
if (Size == 128) {
llvm::Type *ResType = llvm::VectorType::get(
llvm::Type::getInt32Ty(getVMContext()), 4);
- AllocatedVFP = llvm::RoundUpToAlignment(AllocatedVFP, 4);
- AllocatedVFP += 4; // 1 Q register = 4 S registers
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, 4, 4);
return ABIArgInfo::getDirect(ResType);
}
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
}
- // Update AllocatedVFP for legal vector types.
+ // Update VFPRegs for legal vector types.
if (const VectorType *VT = Ty->getAs<VectorType>()) {
uint64_t Size = getContext().getTypeSize(VT);
// Size of a legal vector should be power of 2 and above 64.
- AllocatedVFP = llvm::RoundUpToAlignment(AllocatedVFP, Size >= 128 ? 4 : 2);
- AllocatedVFP += (Size / 32);
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, Size >= 128 ? 4 : 2, Size / 32);
}
- // Update AllocatedVFP for floating point types.
+ // Update VFPRegs for floating point types.
if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
if (BT->getKind() == BuiltinType::Half ||
BT->getKind() == BuiltinType::Float)
- AllocatedVFP += 1;
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, 1, 1);
if (BT->getKind() == BuiltinType::Double ||
- BT->getKind() == BuiltinType::LongDouble) {
- AllocatedVFP = llvm::RoundUpToAlignment(AllocatedVFP, 2);
- AllocatedVFP += 2;
- }
+ BT->getKind() == BuiltinType::LongDouble)
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, 2);
}
if (!isAggregateTypeForABI(Ty)) {
@@ -3119,16 +3148,13 @@
if (Base->isVectorType()) {
// ElementSize is in number of floats.
unsigned ElementSize = getContext().getTypeSize(Base) == 64 ? 2 : 4;
- AllocatedVFP = llvm::RoundUpToAlignment(AllocatedVFP,
- ElementSize);
- AllocatedVFP += Members * ElementSize;
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, ElementSize, Members * ElementSize);
} else if (Base->isSpecificBuiltinType(BuiltinType::Float))
- AllocatedVFP += Members;
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, 1, Members);
else {
assert(Base->isSpecificBuiltinType(BuiltinType::Double) ||
Base->isSpecificBuiltinType(BuiltinType::LongDouble));
- AllocatedVFP = llvm::RoundUpToAlignment(AllocatedVFP, 2);
- AllocatedVFP += Members * 2; // Base type is double.
+ markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, Members * 2);
}
IsHA = true;
return ABIArgInfo::getExpand();
Modified: cfe/trunk/test/CodeGen/arm-homogenous.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-homogenous.c?rev=167159&r1=167158&r2=167159&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-homogenous.c (original)
+++ cfe/trunk/test/CodeGen/arm-homogenous.c Wed Oct 31 14:02:26 2012
@@ -173,6 +173,13 @@
takes_struct_of_four_doubles(3.0, g_s4d, g_s4d, 4.0);
}
+extern void takes_struct_with_backfill(float f1, double a, float f2, struct_of_four_doubles b, struct_of_four_doubles c, double d);
+void test_struct_with_backfill(void) {
+// CHECK: test_struct_with_backfill
+// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [4 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
+ takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d, g_s4d, 4.0);
+}
+
typedef __attribute__(( ext_vector_type(8) )) char __char8;
typedef __attribute__(( ext_vector_type(4) )) short __short4;
typedef struct {
More information about the cfe-commits
mailing list