Packed Structures
authorAndrew Lenharth <andrewl@lenharth.org>
Fri, 8 Dec 2006 18:06:16 +0000 (18:06 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Fri, 8 Dec 2006 18:06:16 +0000 (18:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32361 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Constants.h
include/llvm/DerivedTypes.h
include/llvm/Type.h
lib/AsmParser/llvmAsmParser.y
lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Writer/Writer.cpp
lib/Target/TargetData.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Constants.cpp
lib/VMCore/Type.cpp

index 8c31ba327591ae1ff5764678b715e4fdf23e065b..04cad0b1b7ea13fafd237b2b3fb8e12d99d7ba8f 100644 (file)
@@ -370,7 +370,7 @@ public:
   /// get() - Static factory methods - Return objects of the specified value
   ///
   static Constant *get(const StructType *T, const std::vector<Constant*> &V);
-  static Constant *get(const std::vector<Constant*> &V);
+  static Constant *get(const std::vector<Constant*> &V, bool packed = false);
 
   /// getType() specialization - Reduce amount of casting...
   ///
index 13344ba5a34ccb1399d6ac27613ee8594650fed9..fafcea490372ea1a8d43910f1026941a1444fbca 100644 (file)
@@ -163,13 +163,14 @@ protected:
   ///
   /// Private ctor - Only can be created by a static member...
   ///
-  StructType(const std::vector<const Type*> &Types);
+  StructType(const std::vector<const Type*> &Types, bool isPacked);
 
 public:
   /// StructType::get - This static method is the primary way to create a
   /// StructType.
   ///
-  static StructType *get(const std::vector<const Type*> &Params);
+  static StructType *get(const std::vector<const Type*> &Params, 
+                         bool isPacked=false);
 
   // Iterator access to the elements
   typedef std::vector<PATypeHandle>::const_iterator element_iterator;
@@ -198,6 +199,8 @@ public:
   static inline bool classof(const Type *T) {
     return T->getTypeID() == StructTyID;
   }
+
+  bool isPacked() const { return getSubclassData(); }
 };
 
 
index 4da8feb8a640dc3ea47bbe91d1c78f9f8caf3385..79fe0dfedff77484407bd52f0905c420c8c5297d 100644 (file)
@@ -85,6 +85,7 @@ public:
     ArrayTyID     , PointerTyID,        // Array... pointer...
     OpaqueTyID,                         // Opaque type instances...
     PackedTyID,                         // SIMD 'packed' format...
+    BC_ONLY_PackedStructTyID,           // packed struct, for BC rep only
     //...
 
     NumTypeIDs,                         // Must remain as last defined ID
@@ -95,6 +96,7 @@ public:
 private:
   TypeID   ID : 8;    // The current base type of this type.
   bool     Abstract : 1;  // True if type contains an OpaqueType
+  bool     SubclassData : 1; //Space for subclasses to store a flag
 
   /// RefCount - This counts the number of PATypeHolders that are pointing to
   /// this type.  When this number falls to zero, if the type is abstract and
@@ -117,6 +119,9 @@ protected:
 
   unsigned getRefCount() const { return RefCount; }
 
+  bool getSubclassData() const { return SubclassData; }
+  void setSubclassData(bool b) { SubclassData = b; }
+
   /// ForwardType - This field is used to implement the union find scheme for
   /// abstract types.  When types are refined to other types, this field is set
   /// to the more refined type.  Only abstract types can be forwarded.
index 15524baf8625f0cc5b12417cbc3b5edf99f04603..05fc57d82c87b17e9e642718119fea16bd006733 100644 (file)
@@ -1209,6 +1209,20 @@ UpRTypes : '\\' EUINT64VAL {                   // Type UpReference
     $$ = new PATypeHolder(StructType::get(std::vector<const Type*>()));
     CHECK_FOR_ERROR
   }
+  | '<' '{' TypeListI '}' '>' {
+    std::vector<const Type*> Elements;
+    for (std::list<llvm::PATypeHolder>::iterator I = $3->begin(),
+           E = $3->end(); I != E; ++I)
+      Elements.push_back(*I);
+
+    $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true)));
+    delete $3;
+    CHECK_FOR_ERROR
+  }
+  | '<' '{' '}' '>' {                         // Empty structure type?
+    $$ = new PATypeHolder(StructType::get(std::vector<const Type*>(), true));
+    CHECK_FOR_ERROR
+  }
   | UpRTypes '*' {                             // Pointer type?
     if (*$1 == Type::LabelTy)
       GEN_ERROR("Cannot form a pointer to a basic block");
index 3cc3b1d362bf9328ccdb1b873461bc8759856c83..2ac92bc94685bbcdde52c4d4c176a2f7031fddf8 100644 (file)
@@ -1192,7 +1192,18 @@ const Type *BytecodeReader::ParseType() {
       Typ = read_vbr_uint();
     }
 
-    Result = StructType::get(Elements);
+    Result = StructType::get(Elements, false);
+    break;
+  }
+  case Type::BC_ONLY_PackedStructTyID: {
+    std::vector<const Type*> Elements;
+    unsigned Typ = read_vbr_uint();
+    while (Typ) {         // List is terminated by void/0 typeid
+      Elements.push_back(getType(Typ));
+      Typ = read_vbr_uint();
+    }
+
+    Result = StructType::get(Elements, true);
     break;
   }
   case Type::PointerTyID: {
index b69c1ad8b3947157e3f50eb3b6ee2afb2d456701..c6bc22e796738afd199ed2c4654597f7c4e0610d 100644 (file)
@@ -197,7 +197,11 @@ inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
 //===----------------------------------------------------------------------===//
 
 void BytecodeWriter::outputType(const Type *T) {
-  output_vbr((unsigned)T->getTypeID());
+  const StructType* STy = dyn_cast<StructType>(T);
+  if(STy && STy->isPacked())
+    output_vbr((unsigned)Type::BC_ONLY_PackedStructTyID);
+  else
+    output_vbr((unsigned)T->getTypeID());
 
   // That's all there is to handling primitive types...
   if (T->isPrimitiveType()) {
@@ -246,10 +250,8 @@ void BytecodeWriter::outputType(const Type *T) {
     break;
   }
 
-
   case Type::StructTyID: {
     const StructType *ST = cast<StructType>(T);
-
     // Output all of the element types...
     for (StructType::element_iterator I = ST->element_begin(),
            E = ST->element_end(); I != E; ++I) {
index 03a232c67144f334b7d8617a423743d0170d3535..6dfeefde5f7f103fda270a2bb539211674ede94c 100644 (file)
@@ -53,7 +53,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
     unsigned TyAlign;
     uint64_t TySize;
     getTypeInfo(Ty, &TD, TySize, A);
-    TyAlign = A;
+    TyAlign = ST->isPacked() ? 1 : A;
 
     // Add padding if necessary to make the data element aligned properly...
     if (StructSize % TyAlign != 0)
index a0d82bc402c5dcc8aec535031e8aa93da4f6885f..1647f51da96654590f344f9d3e8e54afab1943fb 100644 (file)
@@ -287,6 +287,8 @@ static void calcTypeName(const Type *Ty,
   }
   case Type::StructTyID: {
     const StructType *STy = cast<StructType>(Ty);
+    if (STy->isPacked())
+      Result += '<';
     Result += "{ ";
     for (StructType::element_iterator I = STy->element_begin(),
            E = STy->element_end(); I != E; ++I) {
@@ -295,6 +297,8 @@ static void calcTypeName(const Type *Ty,
       calcTypeName(*I, TypeStack, TypeNames, Result);
     }
     Result += " }";
+    if (STy->isPacked())
+      Result += '>';
     break;
   }
   case Type::PointerTyID:
@@ -699,6 +703,8 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
     }
     Out << ')';
   } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+    if (STy->isPacked())
+      Out << '<';
     Out << "{ ";
     for (StructType::element_iterator I = STy->element_begin(),
            E = STy->element_end(); I != E; ++I) {
@@ -707,6 +713,8 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
       printType(*I);
     }
     Out << " }";
+    if (STy->isPacked())
+      Out << '>';
   } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
     printType(PTy->getElementType()) << '*';
   } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
index 5f1aaea909432e41786196d40840131cef405c67..b59341d9272f3aa807993e5b668395388fc50c3b 100644 (file)
@@ -1150,12 +1150,12 @@ Constant *ConstantStruct::get(const StructType *Ty,
   return ConstantAggregateZero::get(Ty);
 }
 
-Constant *ConstantStruct::get(const std::vector<Constant*> &V) {
+Constant *ConstantStruct::get(const std::vector<Constant*> &V, bool packed) {
   std::vector<const Type*> StructEls;
   StructEls.reserve(V.size());
   for (unsigned i = 0, e = V.size(); i != e; ++i)
     StructEls.push_back(V[i]->getType());
-  return get(StructType::get(StructEls), V);
+  return get(StructType::get(StructEls, packed), V);
 }
 
 // destroyConstant - Remove the constant from the constant table...
@@ -2183,4 +2183,3 @@ std::string Constant::getStringValue(bool Chop, unsigned Offset) {
   }
   return "";
 }
-
index ca8149e402234ed87a38bd4f6bc3270eca64cd44..943ea27c54894f7164d4e8d40a17bcd91e2d9817 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Debug.h"
 #include <algorithm>
 using namespace llvm;
 
@@ -29,7 +30,7 @@ using namespace llvm;
 // created and later destroyed, all in an effort to make sure that there is only
 // a single canonical version of a type.
 //
-//#define DEBUG_MERGE_TYPES 1
+// #define DEBUG_MERGE_TYPES 1
 
 AbstractTypeUser::~AbstractTypeUser() {}
 
@@ -318,7 +319,10 @@ static std::string getTypeDescription(const Type *Ty,
   }
   case Type::StructTyID: {
     const StructType *STy = cast<StructType>(Ty);
-    Result = "{ ";
+    if (STy->isPacked())
+      Result = "<{ ";
+    else
+      Result = "{ ";
     for (StructType::element_iterator I = STy->element_begin(),
            E = STy->element_end(); I != E; ++I) {
       if (I != STy->element_begin())
@@ -326,6 +330,8 @@ static std::string getTypeDescription(const Type *Ty,
       Result += getTypeDescription(*I, TypeStack);
     }
     Result += " }";
+    if (STy->isPacked())
+      Result += ">";
     break;
   }
   case Type::PointerTyID: {
@@ -454,8 +460,9 @@ FunctionType::FunctionType(const Type *Result,
   setAbstract(isAbstract);
 }
 
-StructType::StructType(const std::vector<const Type*> &Types)
+StructType::StructType(const std::vector<const Type*> &Types, bool isPacked)
   : CompositeType(StructTyID) {
+  setSubclassData(isPacked);
   ContainedTys.reserve(Types.size());
   bool isAbstract = false;
   for (unsigned i = 0; i < Types.size(); ++i) {
@@ -630,6 +637,7 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
   } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
     const StructType *STy2 = cast<StructType>(Ty2);
     if (STy->getNumElements() != STy2->getNumElements()) return false;
+    if (STy->isPacked() != STy2->isPacked()) return false;
     for (unsigned i = 0, e = STy2->getNumElements(); i != e; ++i)
       if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes))
         return false;
@@ -1137,8 +1145,10 @@ namespace llvm {
 //
 class StructValType {
   std::vector<const Type*> ElTypes;
+  bool packed;
 public:
-  StructValType(const std::vector<const Type*> &args) : ElTypes(args) {}
+  StructValType(const std::vector<const Type*> &args, bool isPacked)
+    : ElTypes(args), packed(isPacked) {}
 
   static StructValType get(const StructType *ST) {
     std::vector<const Type *> ElTypes;
@@ -1146,7 +1156,7 @@ public:
     for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i)
       ElTypes.push_back(ST->getElementType(i));
 
-    return StructValType(ElTypes);
+    return StructValType(ElTypes, ST->isPacked());
   }
 
   static unsigned hashTypeStructure(const StructType *ST) {
@@ -1160,20 +1170,23 @@ public:
   }
 
   inline bool operator<(const StructValType &STV) const {
-    return ElTypes < STV.ElTypes;
+    if (ElTypes < STV.ElTypes) return true;
+    else if (ElTypes > STV.ElTypes) return false;
+    else return (int)packed < (int)STV.packed;
   }
 };
 }
 
 static ManagedStatic<TypeMap<StructValType, StructType> > StructTypes;
 
-StructType *StructType::get(const std::vector<const Type*> &ETypes) {
-  StructValType STV(ETypes);
+StructType *StructType::get(const std::vector<const Type*> &ETypes, 
+                            bool isPacked) {
+  StructValType STV(ETypes, isPacked);
   StructType *ST = StructTypes->get(STV);
   if (ST) return ST;
 
   // Value not found.  Derive a new type!
-  StructTypes->add(STV, ST = new StructType(ETypes));
+  StructTypes->add(STV, ST = new StructType(ETypes, isPacked));
 
 #ifdef DEBUG_MERGE_TYPES
   DOUT << "Derived new type: " << *ST << "\n";