diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 8c31ba32759..04cad0b1b7e 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -370,7 +370,7 @@ public: /// get() - Static factory methods - Return objects of the specified value /// static Constant *get(const StructType *T, const std::vector &V); - static Constant *get(const std::vector &V); + static Constant *get(const std::vector &V, bool packed = false); /// getType() specialization - Reduce amount of casting... /// diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index 13344ba5a34..fafcea49037 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -163,13 +163,14 @@ protected: /// /// Private ctor - Only can be created by a static member... /// - StructType(const std::vector &Types); + StructType(const std::vector &Types, bool isPacked); public: /// StructType::get - This static method is the primary way to create a /// StructType. /// - static StructType *get(const std::vector &Params); + static StructType *get(const std::vector &Params, + bool isPacked=false); // Iterator access to the elements typedef std::vector::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(); } }; diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 4da8feb8a64..79fe0dfedff 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -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. diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 15524baf862..05fc57d82c8 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1209,6 +1209,20 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference $$ = new PATypeHolder(StructType::get(std::vector())); CHECK_FOR_ERROR } + | '<' '{' TypeListI '}' '>' { + std::vector Elements; + for (std::list::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(), true)); + CHECK_FOR_ERROR + } | UpRTypes '*' { // Pointer type? if (*$1 == Type::LabelTy) GEN_ERROR("Cannot form a pointer to a basic block"); diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 3cc3b1d362b..2ac92bc9468 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -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 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: { diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index b69c1ad8b39..c6bc22e7967 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -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(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(T); - // Output all of the element types... for (StructType::element_iterator I = ST->element_begin(), E = ST->element_end(); I != E; ++I) { diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 03a232c6714..6dfeefde5f7 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -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) diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index a0d82bc402c..1647f51da96 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -287,6 +287,8 @@ static void calcTypeName(const Type *Ty, } case Type::StructTyID: { const StructType *STy = cast(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(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(Ty)) { printType(PTy->getElementType()) << '*'; } else if (const ArrayType *ATy = dyn_cast(Ty)) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 5f1aaea9094..b59341d9272 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1150,12 +1150,12 @@ Constant *ConstantStruct::get(const StructType *Ty, return ConstantAggregateZero::get(Ty); } -Constant *ConstantStruct::get(const std::vector &V) { +Constant *ConstantStruct::get(const std::vector &V, bool packed) { std::vector 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 ""; } - diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index ca8149e4022..943ea27c548 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -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 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(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 &Types) +StructType::StructType(const std::vector &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(Ty)) { const StructType *STy2 = cast(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 ElTypes; + bool packed; public: - StructValType(const std::vector &args) : ElTypes(args) {} + StructValType(const std::vector &args, bool isPacked) + : ElTypes(args), packed(isPacked) {} static StructValType get(const StructType *ST) { std::vector 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 > StructTypes; -StructType *StructType::get(const std::vector &ETypes) { - StructValType STV(ETypes); +StructType *StructType::get(const std::vector &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";