[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