Please see the attached patch. Padding is allowed for any Direct ABIArgInfos.
I removed the assertion in getPaddingType() that ensures the ArgInfo is Direct 
so that there are fewer changes being made, but I can restore it if necessary.

________________________________________
From: Eli Friedman [[email protected]]
Sent: Thursday, January 05, 2012 4:23 PM
To: Hatanaka, Akira
Cc: [email protected]
Subject: Re: [cfe-commits] r143596 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp

On Thu, Jan 5, 2012 at 4:21 PM, Hatanaka, Akira <[email protected]> wrote:
> Yes, we should insert padding for types that are not Struct too.
>
> Can we assume PaddingType is valid only if ABIArgInfo's TheKind is Direct? Or 
> should other we be able to add PaddingType for other Kinds as well?

I'd say it's okay for the moment to only allow it for Direct, as long
as you document that in the code.  It should be easy enough to extend
if someone ends up needing it.

-Eli
Index: lib/CodeGen/ABIInfo.h
===================================================================
--- lib/CodeGen/ABIInfo.h	(revision 147607)
+++ lib/CodeGen/ABIInfo.h	(working copy)
@@ -42,7 +42,8 @@
       /// type, or by coercing to another specified type stored in
       /// 'CoerceToType').  If an offset is specified (in UIntData), then the
       /// argument passed is offset by some number of bytes in the memory
-      /// representation.
+      /// representation. A dummy argument is emitted before the real argument
+      /// if the specified type stored in "PaddingType" is not zero.
       Direct,
 
       /// Extend - Valid only for integer argument types. Same as 'direct'
@@ -69,19 +70,22 @@
   private:
     Kind TheKind;
     llvm::Type *TypeData;
+    llvm::Type *PaddingType; // Currently allowed only for Direct.
     unsigned UIntData;
     bool BoolData0;
     bool BoolData1;
 
-    ABIArgInfo(Kind K, llvm::Type *TD=0,
-               unsigned UI=0, bool B0 = false, bool B1 = false)
-      : TheKind(K), TypeData(TD), UIntData(UI), BoolData0(B0), BoolData1(B1) {}
+    ABIArgInfo(Kind K, llvm::Type *TD=0, unsigned UI=0,
+               bool B0 = false, bool B1 = false, llvm::Type* P = 0)
+      : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
+        BoolData1(B1) {}
 
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
 
-    static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0) {
-      return ABIArgInfo(Direct, T, Offset);
+    static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
+                                llvm::Type *Padding = 0) {
+      return ABIArgInfo(Direct, T, Offset, false, false, Padding);
     }
     static ABIArgInfo getExtend(llvm::Type *T = 0) {
       return ABIArgInfo(Extend, T, 0);
@@ -113,6 +117,11 @@
       assert((isDirect() || isExtend()) && "Not a direct or extend kind");
       return UIntData;
     }
+
+    llvm::Type *getPaddingType() const {
+      return PaddingType;
+    }
+
     llvm::Type *getCoerceToType() const {
       assert(canHaveCoerceToType() && "Invalid kind!");
       return TypeData;
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp	(revision 147607)
+++ lib/CodeGen/TargetInfo.cpp	(working copy)
@@ -3047,7 +3047,7 @@
     ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8) {}
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
-  ABIArgInfo classifyArgumentType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
   virtual void computeInfo(CGFunctionInfo &FI) const;
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
@@ -3132,28 +3132,41 @@
   return llvm::StructType::get(getVMContext(), ArgList);
 }
 
-ABIArgInfo MipsABIInfo::classifyArgumentType(QualType Ty) const {
+ABIArgInfo
+MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
   if (isAggregateTypeForABI(Ty)) {
     // Ignore empty aggregates.
-    if (getContext().getTypeSize(Ty) == 0)
+    uint64_t TySize = getContext().getTypeSize(Ty);
+    if (TySize == 0)
       return ABIArgInfo::getIgnore();
 
     // Records with non trivial destructors/constructors should not be passed
     // by value.
-    if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+    if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) {
+      Offset += 8;
       return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    }
 
-    llvm::Type *ResType;
-    if ((ResType = HandleStructTy(Ty)))
-      return ABIArgInfo::getDirect(ResType);
-
-    return ABIArgInfo::getIndirect(0);
+    // If we have reached here, aggregates are passed either indirectly via a
+    // byval pointer or directly by coercing to another structure type. In the
+    // latter case, padding is inserted if the offset of the aggregate is
+    // unaligned.
+    llvm::Type *ResType = HandleStructTy(Ty);
+    uint64_t Align = getContext().getTypeAlign(Ty) / 8;
+    assert(Align <= 16 && "Alignment larger than 16 not handled.");
+    llvm::Type *PaddingTy = (ResType && Align == 16 && Offset & 0xf) ?
+      llvm::IntegerType::get(getVMContext(), 64) : 0;
+    Offset = llvm::RoundUpToAlignment(Offset, std::max(Align, (uint64_t)8));
+    Offset += llvm::RoundUpToAlignment(TySize, 8);
+    return ResType ? ABIArgInfo::getDirect(ResType, 0, PaddingTy) :
+                     ABIArgInfo::getIndirect(0);
   }
 
   // Treat an enum type as its underlying type.
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 
+  Offset += 8;
   return (Ty->isPromotableIntegerType() ?
           ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
@@ -3230,9 +3243,10 @@
 
 void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
   FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+  uint64_t Offset = 0;
   for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
        it != ie; ++it)
-    it->info = classifyArgumentType(it->type);
+    it->info = classifyArgumentType(it->type, Offset);
 }
 
 llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp	(revision 147607)
+++ lib/CodeGen/CGCall.cpp	(working copy)
@@ -686,6 +686,9 @@
 
     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.
@@ -840,6 +843,9 @@
       }
       // FIXME: handle sseregparm someday...
 
+      // Increment Index if there is padding.
+      Index += (AI.getPaddingType() != 0);
+
       if (llvm::StructType *STy =
             dyn_cast<llvm::StructType>(AI.getCoerceToType()))
         Index += STy->getNumElements()-1;  // 1 will be added below.
@@ -1024,6 +1030,10 @@
                           llvm::PointerType::getUnqual(ArgI.getCoerceToType()));
       }
 
+      // Skip the dummy padding argument.
+      if (ArgI.getPaddingType())
+        ++AI;
+
       // If the coerce-to type is a first class aggregate, we flatten it and
       // pass the elements. Either way is semantically identical, but fast-isel
       // and the optimizer generally likes scalar values better than FCAs.
@@ -1658,6 +1668,12 @@
 
     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) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to