[cfe-commits] r166537 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/attributes.c test/CodeGen/stdcall-fastcall.c test/CodeGenCXX/fastcall.cpp
Rafael Espindola
rafael.espindola at gmail.com
Tue Oct 23 18:58:58 PDT 2012
Author: rafael
Date: Tue Oct 23 20:58:58 2012
New Revision: 166537
URL: http://llvm.org/viewvc/llvm-project?rev=166537&view=rev
Log:
Add inreg markers with the x86_fastcallcc calling convention.
Added:
cfe/trunk/test/CodeGenCXX/fastcall.cpp
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
cfe/trunk/test/CodeGen/attributes.c
cfe/trunk/test/CodeGen/stdcall-fastcall.c
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=166537&r1=166536&r2=166537&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Oct 23 20:58:58 2012
@@ -528,8 +528,10 @@
Class classify(QualType Ty) const;
ABIArgInfo classifyReturnType(QualType RetTy,
unsigned callingConvention) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs) const;
- bool shouldUseInReg(QualType Ty, unsigned &FreeRegs) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs,
+ bool IsFastCall) const;
+ bool shouldUseInReg(QualType Ty, unsigned &FreeRegs,
+ bool IsFastCall) const;
public:
@@ -804,12 +806,14 @@
return Integer;
}
-bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs) const {
+bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
+ bool IsFastCall) const {
Class C = classify(Ty);
if (C == Float)
return false;
- unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
+ unsigned Size = getContext().getTypeSize(Ty);
+ unsigned SizeInRegs = (Size + 31) / 32;
if (SizeInRegs == 0)
return false;
@@ -820,11 +824,29 @@
}
FreeRegs -= SizeInRegs;
+
+ if (IsFastCall) {
+ if (Size > 32)
+ return false;
+
+ if (Ty->isIntegralOrEnumerationType())
+ return true;
+
+ if (Ty->isPointerType())
+ return true;
+
+ if (Ty->isReferenceType())
+ return true;
+
+ return false;
+ }
+
return true;
}
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
- unsigned &FreeRegs) const {
+ unsigned &FreeRegs,
+ bool IsFastCall) const {
// FIXME: Set alignment on indirect arguments.
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
@@ -842,7 +864,7 @@
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- if (shouldUseInReg(Ty, FreeRegs)) {
+ if (shouldUseInReg(Ty, FreeRegs, IsFastCall)) {
unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
llvm::LLVMContext &LLVMContext = getVMContext();
llvm::Type *Int32 = llvm::Type::getInt32Ty(LLVMContext);
@@ -892,7 +914,7 @@
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- bool InReg = shouldUseInReg(Ty, FreeRegs);
+ bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall);
if (Ty->isPromotableIntegerType()) {
if (InReg)
@@ -908,8 +930,15 @@
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
FI.getCallingConvention());
- unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() :
- DefaultNumRegisterParameters;
+ unsigned CC = FI.getCallingConvention();
+ bool IsFastCall = CC == llvm::CallingConv::X86_FastCall;
+ unsigned FreeRegs;
+ if (IsFastCall)
+ FreeRegs = 2;
+ else if (FI.getHasRegParm())
+ FreeRegs = FI.getRegParm();
+ else
+ FreeRegs = DefaultNumRegisterParameters;
// If the return value is indirect, then the hidden argument is consuming one
// integer register.
@@ -923,7 +952,7 @@
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
- it->info = classifyArgumentType(it->type, FreeRegs);
+ it->info = classifyArgumentType(it->type, FreeRegs, IsFastCall);
}
llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
Modified: cfe/trunk/test/CodeGen/attributes.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attributes.c?rev=166537&r1=166536&r2=166537&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/attributes.c (original)
+++ cfe/trunk/test/CodeGen/attributes.c Tue Oct 23 20:58:58 2012
@@ -80,7 +80,7 @@
fptr(10);
}
// CHECK: [[FPTRVAR:%[a-z0-9]+]] = load void (i32)** @fptr
-// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 10)
+// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 inreg 10)
// PR9356: We might want to err on this, but for now at least make sure we
Modified: cfe/trunk/test/CodeGen/stdcall-fastcall.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/stdcall-fastcall.c?rev=166537&r1=166536&r2=166537&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/stdcall-fastcall.c (original)
+++ cfe/trunk/test/CodeGen/stdcall-fastcall.c Tue Oct 23 20:58:58 2012
@@ -48,3 +48,99 @@
f7(0);
// CHECK: call x86_stdcallcc void @f7(i32 0)
}
+
+void __attribute__((fastcall)) foo1(int y);
+void bar1(int y) {
+ // CHECK: define void @bar1
+ // CHECK: call x86_fastcallcc void @foo1(i32 inreg %
+ foo1(y);
+}
+
+struct S1 {
+ int x;
+};
+void __attribute__((fastcall)) foo2(struct S1 y);
+void bar2(struct S1 y) {
+ // CHECK: define void @bar2
+ // CHECK: call x86_fastcallcc void @foo2(i32 %
+ foo2(y);
+}
+
+void __attribute__((fastcall)) foo3(int *y);
+void bar3(int *y) {
+ // CHECK: define void @bar3
+ // CHECK: call x86_fastcallcc void @foo3(i32* inreg %
+ foo3(y);
+}
+
+enum Enum {Eval};
+void __attribute__((fastcall)) foo4(enum Enum y);
+void bar4(enum Enum y) {
+ // CHECK: define void @bar4
+ // CHECK: call x86_fastcallcc void @foo4(i32 inreg %
+ foo4(y);
+}
+
+struct S2 {
+ int x1;
+ double x2;
+ double x3;
+};
+void __attribute__((fastcall)) foo5(struct S2 y);
+void bar5(struct S2 y) {
+ // CHECK: define void @bar5
+ // CHECK: call x86_fastcallcc void @foo5(%struct.S2* byval align 4 %
+ foo5(y);
+}
+
+void __attribute__((fastcall)) foo6(long long y);
+void bar6(long long y) {
+ // CHECK: define void @bar6
+ // CHECK: call x86_fastcallcc void @foo6(i64 %
+ foo6(y);
+}
+
+void __attribute__((fastcall)) foo7(int a, struct S1 b, int c);
+void bar7(int a, struct S1 b, int c) {
+ // CHECK: define void @bar7
+ // CHECK: call x86_fastcallcc void @foo7(i32 inreg %{{.*}}, i32 %{{.*}}, i32 %{{.*}}
+ foo7(a, b, c);
+}
+
+void __attribute__((fastcall)) foo8(struct S1 a, int b);
+void bar8(struct S1 a, int b) {
+ // CHECK: define void @bar8
+ // CHECK: call x86_fastcallcc void @foo8(i32 %{{.*}}, i32 inreg %
+ foo8(a, b);
+}
+
+void __attribute__((fastcall)) foo9(struct S2 a, int b);
+void bar9(struct S2 a, int b) {
+ // CHECK: define void @bar9
+ // CHECK: call x86_fastcallcc void @foo9(%struct.S2* byval align 4 %{{.*}}, i32 %
+ foo9(a, b);
+}
+
+void __attribute__((fastcall)) foo10(float y, int x);
+void bar10(float y, int x) {
+ // CHECK: define void @bar10
+ // CHECK: call x86_fastcallcc void @foo10(float %{{.*}}, i32 inreg %
+ foo10(y, x);
+}
+
+void __attribute__((fastcall)) foo11(double y, int x);
+void bar11(double y, int x) {
+ // CHECK: define void @bar11
+ // CHECK: call x86_fastcallcc void @foo11(double %{{.*}}, i32 inreg %
+ foo11(y, x);
+}
+
+struct S3 {
+ float x;
+};
+void __attribute__((fastcall)) foo12(struct S3 y, int x);
+void bar12(struct S3 y, int x) {
+ // CHECK: define void @bar12
+ // CHECK: call x86_fastcallcc void @foo12(float %{{.*}}, i32 inreg %
+ foo12(y, x);
+}
Added: cfe/trunk/test/CodeGenCXX/fastcall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/fastcall.cpp?rev=166537&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/fastcall.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/fastcall.cpp Tue Oct 23 20:58:58 2012
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((fastcall)) foo1(int &y);
+void bar1(int &y) {
+ // CHECK: define void @_Z4bar1Ri
+ // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg %
+ foo1(y);
+}
+
+struct S1 {
+ int x;
+ S1(const S1 &y);
+};
+
+void __attribute__((fastcall)) foo2(S1 a, int b);
+void bar2(S1 a, int b) {
+ // CHECK: define void @_Z4bar22S1i
+ // CHECK: call x86_fastcallcc void @_Z4foo22S1i(%struct.S1* inreg %{{.*}}, i32 inreg %
+ foo2(a, b);
+}
More information about the cfe-commits
mailing list