[cfe-commits] r166538 - in /cfe/trunk: lib/CodeGen/ABIInfo.h lib/CodeGen/CGCall.cpp lib/CodeGen/TargetInfo.cpp test/CodeGen/stdcall-fastcall.c

Rafael Espindola rafael.espindola at gmail.com
Tue Oct 23 18:59:01 PDT 2012


Author: rafael
Date: Tue Oct 23 20:59:00 2012
New Revision: 166538

URL: http://llvm.org/viewvc/llvm-project?rev=166538&view=rev
Log:
Add padding inreg registers to cause llvm to skip ecx when needed with
the x86_fastcallcc calling convention.

Modified:
    cfe/trunk/lib/CodeGen/ABIInfo.h
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/stdcall-fastcall.c

Modified: cfe/trunk/lib/CodeGen/ABIInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ABIInfo.h?rev=166538&r1=166537&r2=166538&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ABIInfo.h (original)
+++ cfe/trunk/lib/CodeGen/ABIInfo.h Tue Oct 23 20:59:00 2012
@@ -70,46 +70,52 @@
   private:
     Kind TheKind;
     llvm::Type *TypeData;
-    llvm::Type *PaddingType; // Currently allowed only for Direct.
+    llvm::Type *PaddingType;
     unsigned UIntData;
     bool BoolData0;
     bool BoolData1;
     bool InReg;
+    bool PaddingInReg;
 
     ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR,
-               llvm::Type* P)
+               bool PIR, llvm::Type* P)
       : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
-        BoolData1(B1), InReg(IR) {}
+        BoolData1(B1), InReg(IR), PaddingInReg(PIR) {}
 
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
 
     static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
                                 llvm::Type *Padding = 0) {
-      return ABIArgInfo(Direct, T, Offset, false, false, false, Padding);
+      return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding);
     }
     static ABIArgInfo getDirectInReg(llvm::Type *T = 0) {
-      return ABIArgInfo(Direct, T, 0, false, false, true, 0);
+      return ABIArgInfo(Direct, T, 0, false, false, true, false, 0);
     }
     static ABIArgInfo getExtend(llvm::Type *T = 0) {
-      return ABIArgInfo(Extend, T, 0, false, false, false, 0);
+      return ABIArgInfo(Extend, T, 0, false, false, false, false, 0);
     }
     static ABIArgInfo getExtendInReg(llvm::Type *T = 0) {
-      return ABIArgInfo(Extend, T, 0, false, false, true, 0);
+      return ABIArgInfo(Extend, T, 0, false, false, true, false, 0);
     }
     static ABIArgInfo getIgnore() {
-      return ABIArgInfo(Ignore, 0, 0, false, false, false, 0);
+      return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0);
     }
     static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
                                   , bool Realign = false) {
-      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, 0);
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false, 0);
     }
     static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true
                                   , bool Realign = false) {
-      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, 0);
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0);
     }
     static ABIArgInfo getExpand() {
-      return ABIArgInfo(Expand, 0, 0, false, false, false, 0);
+      return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0);
+    }
+    static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
+                                           llvm::Type *Padding) {
+     return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg,
+                       Padding);
     }
 
     Kind getKind() const { return TheKind; }
@@ -133,6 +139,10 @@
       return PaddingType;
     }
 
+    bool getPaddingInReg() const {
+      return PaddingInReg;
+    }
+
     llvm::Type *getCoerceToType() const {
       assert(canHaveCoerceToType() && "Invalid kind!");
       return TypeData;

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=166538&r1=166537&r2=166538&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Oct 23 20:59:00 2012
@@ -867,6 +867,10 @@
          ie = FI.arg_end(); it != ie; ++it) {
     const ABIArgInfo &argAI = it->info;
 
+    // Insert a padding type to ensure proper alignment.
+    if (llvm::Type *PaddingType = argAI.getPaddingType())
+      argTypes.push_back(PaddingType);
+
     switch (argAI.getKind()) {
     case ABIArgInfo::Ignore:
       break;
@@ -880,9 +884,6 @@
 
     case ABIArgInfo::Extend:
     case ABIArgInfo::Direct: {
-      // Insert a padding type to ensure proper alignment.
-      if (llvm::Type *PaddingType = argAI.getPaddingType())
-        argTypes.push_back(PaddingType);
       // 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.
@@ -1019,6 +1020,18 @@
     const ABIArgInfo &AI = it->info;
     llvm::AttrBuilder Attrs;
 
+    if (AI.getPaddingType()) {
+      if (AI.getPaddingInReg()) {
+        llvm::AttrBuilder PadAttrs;
+        PadAttrs.addAttribute(llvm::Attributes::InReg);
+
+        llvm::Attributes A =llvm::Attributes::get(getLLVMContext(), PadAttrs);
+        PAL.push_back(llvm::AttributeWithIndex::get(Index, A));
+      }
+      // Increment Index if there is padding.
+      ++Index;
+    }
+
     // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
     // have the corresponding parameter variable.  It doesn't make
     // sense to do it here because parameters are so messed up.
@@ -1035,9 +1048,6 @@
 
       // FIXME: handle sseregparm someday...
 
-      // Increment Index if there is padding.
-      Index += (AI.getPaddingType() != 0);
-
       if (llvm::StructType *STy =
           dyn_cast<llvm::StructType>(AI.getCoerceToType())) {
         unsigned Extra = STy->getNumElements()-1;  // 1 will be added below.
@@ -1155,6 +1165,10 @@
     bool isPromoted =
       isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
 
+    // Skip the dummy padding argument.
+    if (ArgI.getPaddingType())
+      ++AI;
+
     switch (ArgI.getKind()) {
     case ABIArgInfo::Indirect: {
       llvm::Value *V = AI;
@@ -1196,9 +1210,6 @@
 
     case ABIArgInfo::Extend:
     case ABIArgInfo::Direct: {
-      // Skip the dummy padding argument.
-      if (ArgI.getPaddingType())
-        ++AI;
 
       // If we have the trivial case, handle it with no muss and fuss.
       if (!isa<llvm::StructType>(ArgI.getCoerceToType()) &&
@@ -1976,6 +1987,13 @@
 
     unsigned TypeAlign =
       getContext().getTypeAlignInChars(I->Ty).getQuantity();
+
+    // Insert a padding argument to ensure proper alignment.
+    if (llvm::Type *PaddingType = ArgInfo.getPaddingType()) {
+      Args.push_back(llvm::UndefValue::get(PaddingType));
+      ++IRArgNo;
+    }
+
     switch (ArgInfo.getKind()) {
     case ABIArgInfo::Indirect: {
       if (RV.isScalar() || RV.isComplex()) {
@@ -2031,12 +2049,6 @@
 
     case ABIArgInfo::Extend:
     case ABIArgInfo::Direct: {
-      // Insert a padding argument to ensure proper alignment.
-      if (llvm::Type *PaddingType = ArgInfo.getPaddingType()) {
-        Args.push_back(llvm::UndefValue::get(PaddingType));
-        ++IRArgNo;
-      }
-
       if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) &&
           ArgInfo.getCoerceToType() == ConvertType(info_it->type) &&
           ArgInfo.getDirectOffset() == 0) {

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=166538&r1=166537&r2=166538&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Oct 23 20:59:00 2012
@@ -531,7 +531,7 @@
   ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs,
                                   bool IsFastCall) const;
   bool shouldUseInReg(QualType Ty, unsigned &FreeRegs,
-                      bool IsFastCall) const;
+                      bool IsFastCall, bool &NeedsPadding) const;
 
 public:
 
@@ -807,7 +807,8 @@
 }
 
 bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
-                                   bool IsFastCall) const {
+                                   bool IsFastCall, bool &NeedsPadding) const {
+  NeedsPadding = false;
   Class C = classify(Ty);
   if (C == Float)
     return false;
@@ -838,6 +839,9 @@
     if (Ty->isReferenceType())
       return true;
 
+    if (FreeRegs)
+      NeedsPadding = true;
+
     return false;
   }
 
@@ -864,16 +868,18 @@
     if (isEmptyRecord(getContext(), Ty, true))
       return ABIArgInfo::getIgnore();
 
-    if (shouldUseInReg(Ty, FreeRegs, IsFastCall)) {
+    llvm::LLVMContext &LLVMContext = getVMContext();
+    llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
+    bool NeedsPadding;
+    if (shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding)) {
       unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
-      llvm::LLVMContext &LLVMContext = getVMContext();
-      llvm::Type *Int32 = llvm::Type::getInt32Ty(LLVMContext);
       SmallVector<llvm::Type*, 3> Elements;
       for (unsigned I = 0; I < SizeInRegs; ++I)
         Elements.push_back(Int32);
       llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
       return ABIArgInfo::getDirectInReg(Result);
     }
+    llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : 0;
 
     // Expand small (<= 128-bit) record types when we know that the stack layout
     // of those arguments will match the struct. This is important because the
@@ -881,7 +887,7 @@
     // optimizations.
     if (getContext().getTypeSize(Ty) <= 4*32 &&
         canExpandIndirectArgument(Ty, getContext()))
-      return ABIArgInfo::getExpand();
+      return ABIArgInfo::getExpandWithPadding(IsFastCall, PaddingType);
 
     return getIndirectResult(Ty, true, FreeRegs);
   }
@@ -914,7 +920,8 @@
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 
-  bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall);
+  bool NeedsPadding;
+  bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding);
 
   if (Ty->isPromotableIntegerType()) {
     if (InReg)

Modified: cfe/trunk/test/CodeGen/stdcall-fastcall.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/stdcall-fastcall.c?rev=166538&r1=166537&r2=166538&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/stdcall-fastcall.c (original)
+++ cfe/trunk/test/CodeGen/stdcall-fastcall.c Tue Oct 23 20:59:00 2012
@@ -62,7 +62,7 @@
 void __attribute__((fastcall)) foo2(struct S1 y);
 void bar2(struct S1 y) {
   // CHECK: define void @bar2
-  // CHECK: call x86_fastcallcc void @foo2(i32 %
+  // CHECK: call x86_fastcallcc void @foo2(i32 inreg undef, i32 %
   foo2(y);
 }
 
@@ -110,7 +110,7 @@
 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 %
+  // CHECK: call x86_fastcallcc void @foo8(i32 inreg undef, i32 %{{.*}}, i32 inreg %
   foo8(a, b);
 }
 





More information about the cfe-commits mailing list