Add support for having different alignment for objects on call frames.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 7 Sep 2007 14:52:14 +0000 (14:52 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 7 Sep 2007 14:52:14 +0000 (14:52 +0000)
The x86-64 ABI states that objects passed on the stack have
8 byte alignment. Implement that.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41768 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetData.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/TargetData.cpp
lib/Target/X86/X86Subtarget.h
test/CodeGen/X86/byval3.ll [new file with mode: 0644]

index 6003e607b7ab05ebc1505205f556a9df96ce1f77..f2e55f10e11096dc2ade988a26bd31c263d0e54c 100644 (file)
@@ -38,7 +38,8 @@ enum AlignTypeEnum {
   INTEGER_ALIGN = 'i',               ///< Integer type alignment
   VECTOR_ALIGN = 'v',                ///< Vector type alignment
   FLOAT_ALIGN = 'f',                 ///< Floating point type alignment
-  AGGREGATE_ALIGN = 'a'              ///< Aggregate alignment
+  AGGREGATE_ALIGN = 'a',             ///< Aggregate alignment
+  STACK_ALIGN = 's'                  ///< Stack objects alignment
 };
 /// Target alignment element.
 ///
@@ -166,6 +167,11 @@ public:
   /// specified type.
   unsigned char getABITypeAlignment(const Type *Ty) const;
 
+  /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
+  /// for the specified type when it is part of a call frame.
+  unsigned char getCallFrameTypeAlignment(const Type *Ty) const;
+
+
   /// getPrefTypeAlignment - Return the preferred stack/global alignment for
   /// the specified type.
   unsigned char getPrefTypeAlignment(const Type *Ty) const;
index d512ef9b1d1e54944e6a3e0a48e870a72de0aeae..e18beb5018ad4e5c3420afdad7bc5faf1e5187b1 100644 (file)
@@ -3870,7 +3870,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
       Flags |= ISD::ParamFlags::ByVal;
       const PointerType *Ty = cast<PointerType>(I->getType());
       const StructType *STy = cast<StructType>(Ty->getElementType());
-      unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+      unsigned StructAlign =
+          Log2_32(getTargetData()->getCallFrameTypeAlignment(STy));
       unsigned StructSize  = getTargetData()->getTypeSize(STy);
       Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
       Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
@@ -3999,7 +4000,8 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
       Flags |= ISD::ParamFlags::ByVal;
       const PointerType *Ty = cast<PointerType>(Args[i].Ty);
       const StructType *STy = cast<StructType>(Ty->getElementType());
-      unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+      unsigned StructAlign =
+          Log2_32(getTargetData()->getCallFrameTypeAlignment(STy));
       unsigned StructSize  = getTargetData()->getTypeSize(STy);
       Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
       Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
index bb1fff5de5fb2edce4cd00693c05970d8b4fcafb..9f7cb003791900661560362ca2f412de74090678 100644 (file)
@@ -182,7 +182,8 @@ void TargetData::init(const std::string &TargetDescription) {
   setAlignment(VECTOR_ALIGN,    8,  8, 64);  // v2i32
   setAlignment(VECTOR_ALIGN,   16, 16, 128); // v16i8, v8i16, v4i32, ...
   setAlignment(AGGREGATE_ALIGN, 0,  8,  0);  // struct, union, class, ...
-  
+  setAlignment(STACK_ALIGN,     0,  8,  0);  // objects on the stack
+
   while (!temp.empty()) {
     std::string token = getToken(temp, "-");
     std::string arg0 = getToken(token, ":");
@@ -204,10 +205,16 @@ void TargetData::init(const std::string &TargetDescription) {
     case 'i':
     case 'v':
     case 'f':
-    case 'a': {
-      AlignTypeEnum align_type = 
-        (*p == 'i' ? INTEGER_ALIGN : (*p == 'f' ? FLOAT_ALIGN :
-           (*p == 'v' ? VECTOR_ALIGN : AGGREGATE_ALIGN)));
+    case 'a':
+    case 's': {
+      AlignTypeEnum align_type;
+      switch(*p) {
+        case 'i': align_type = INTEGER_ALIGN; break;
+        case 'v': align_type = VECTOR_ALIGN; break;
+        case 'f': align_type = FLOAT_ALIGN; break;
+        case 'a': align_type = AGGREGATE_ALIGN; break;
+        case 's': align_type = STACK_ALIGN; break;
+      }
       uint32_t size = (uint32_t) atoi(++p);
       unsigned char abi_align = atoi(getToken(token, ":").c_str()) / 8;
       unsigned char pref_align = atoi(getToken(token, ":").c_str()) / 8;
@@ -529,6 +536,14 @@ unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
   return getAlignment(Ty, true);
 }
 
+unsigned char TargetData::getCallFrameTypeAlignment(const Type *Ty) const {
+  for (unsigned i = 0, e = Alignments.size(); i != e; ++i)
+    if (Alignments[i].AlignType == STACK_ALIGN)
+      return Alignments[i].ABIAlign;
+
+  return getABITypeAlignment(Ty);
+}
+
 unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
   return getAlignment(Ty, false);
 }
index 493c801f8ce427e7b4fe54b9d554fb302754017d..d939bc00c54d5d4d90f5ccee91423272a221c703 100644 (file)
@@ -146,7 +146,7 @@ public:
   std::string getDataLayout() const {
     const char *p;
     if (is64Bit())
-      p = "e-p:64:64-f64:64:64-i64:64:64-f80:128:128";
+      p = "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128";
     else {
       if (isTargetDarwin())
         p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128";
diff --git a/test/CodeGen/X86/byval3.ll b/test/CodeGen/X86/byval3.ll
new file mode 100644 (file)
index 0000000..f494286
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | llc -march=x86-64 | grep rep.movsl | count 2
+
+%struct.s = type { i32, i32, i32, i32, i32, i32 }
+
+define void @g(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6) {
+entry:
+        %d = alloca %struct.s, align 16
+        %tmp = getelementptr %struct.s* %d, i32 0, i32 0
+        store i32 %a1, i32* %tmp, align 16
+        %tmp2 = getelementptr %struct.s* %d, i32 0, i32 1
+        store i32 %a2, i32* %tmp2, align 16
+        %tmp4 = getelementptr %struct.s* %d, i32 0, i32 2
+        store i32 %a3, i32* %tmp4, align 16
+        %tmp6 = getelementptr %struct.s* %d, i32 0, i32 3
+        store i32 %a4, i32* %tmp6, align 16
+        %tmp8 = getelementptr %struct.s* %d, i32 0, i32 4
+        store i32 %a5, i32* %tmp8, align 16
+        %tmp10 = getelementptr %struct.s* %d, i32 0, i32 5
+        store i32 %a6, i32* %tmp10, align 16
+        call void @f( %struct.s* %d byval)
+        call void @f( %struct.s* %d byval)
+        ret void
+}
+
+declare void @f(%struct.s* byval)