[cfe-commits] r64529 - in /cfe/trunk: lib/CodeGen/CGCall.cpp test/CodeGen/x86_64-arguments.c

Daniel Dunbar daniel at zuster.org
Fri Feb 13 18:09:25 PST 2009


Author: ddunbar
Date: Fri Feb 13 20:09:24 2009
New Revision: 64529

URL: http://llvm.org/viewvc/llvm-project?rev=64529&view=rev
Log:
x86_64 ABI: Pass simple types directly when possible. This is
important for both keeping the generated LLVM simple and for ensuring
that integer types are passed/promoted correctly.

Added:
    cfe/trunk/test/CodeGen/x86_64-arguments.c
Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=64529&r1=64528&r2=64529&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Feb 13 20:09:24 2009
@@ -423,6 +423,20 @@
   void classify(QualType T, ASTContext &Context, uint64_t OffsetBase,
                 Class &Lo, Class &Hi) const;
   
+  /// getCoerceResult - Given a source type \arg Ty and an LLVM type
+  /// to coerce to, chose the best way to pass Ty in the same place
+  /// that \arg CoerceTo would be passed, but while keeping the
+  /// emitted code as simple as possible.
+  ///
+  /// FIXME: Note, this should be cleaned up to just take an
+  /// enumeration of all the ways we might want to pass things,
+  /// instead of constructing an LLVM type. This makes this code more
+  /// explicit, and it makes it clearer that we are also doing this
+  /// for correctness in the case of passing scalar types.
+  ABIArgInfo getCoerceResult(QualType Ty,
+                             const llvm::Type *CoerceTo,
+                             ASTContext &Context) const;
+
   ABIArgInfo classifyReturnType(QualType RetTy, 
                                 ASTContext &Context) const;  
 
@@ -647,6 +661,22 @@
   }
 }
 
+ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
+                                          const llvm::Type *CoerceTo,
+                                          ASTContext &Context) const {
+  if (CoerceTo == llvm::Type::Int64Ty) {
+    // Integer and pointer types will end up in a general purpose
+    // register.
+    if (Ty->isIntegerType() || Ty->isPointerType())
+      return ABIArgInfo::getDirect();
+  } else if (CoerceTo == llvm::Type::DoubleTy) {
+    // Float and double end up in a single SSE reg.
+    if (Ty == Context.FloatTy || Ty == Context.DoubleTy)
+      return ABIArgInfo::getDirect();
+  }
+
+  return ABIArgInfo::getCoerce(CoerceTo);
+}
 
 ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
                                             ASTContext &Context) const {
@@ -733,7 +763,7 @@
     break;
   }
 
-  return ABIArgInfo::getCoerce(ResType);
+  return getCoerceResult(RetTy, ResType, Context);
 }
 
 ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, ASTContext &Context,
@@ -819,7 +849,7 @@
     break;
   }
 
-  return ABIArgInfo::getCoerce(ResType);
+  return getCoerceResult(Ty, ResType, Context);
 }
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context) const {

Added: cfe/trunk/test/CodeGen/x86_64-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-arguments.c?rev=64529&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/x86_64-arguments.c (added)
+++ cfe/trunk/test/CodeGen/x86_64-arguments.c Fri Feb 13 20:09:24 2009
@@ -0,0 +1,29 @@
+// RUN: clang -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
+// RUN: grep 'define signext i8 @f0()' %t &&
+// RUN: grep 'define signext i16 @f1()' %t &&
+// RUN: grep 'define i32 @f2()' %t &&
+// RUN: grep 'define float @f3()' %t &&
+// RUN: grep 'define double @f4()' %t &&
+// RUN: grep 'define x86_fp80 @f5()' %t &&
+// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t
+
+char f0(void) {
+}
+
+short f1(void) {
+}
+
+int f2(void) {
+}
+
+float f3(void) {
+}
+
+double f4(void) {
+}
+
+long double f5(void) {
+}
+
+void f6(char a0, short a1, int a2, long long a3, void *a4) {
+}





More information about the cfe-commits mailing list