Packed Structures

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32361 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Lenharth
2006-12-08 18:06:16 +00:00
parent 8894255fc0
commit 38ecbf18eb
10 changed files with 75 additions and 20 deletions

View File

@ -370,7 +370,7 @@ public:
/// get() - Static factory methods - Return objects of the specified value /// 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 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... /// getType() specialization - Reduce amount of casting...
/// ///

View File

@ -163,13 +163,14 @@ protected:
/// ///
/// Private ctor - Only can be created by a static member... /// 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: public:
/// StructType::get - This static method is the primary way to create a /// StructType::get - This static method is the primary way to create a
/// StructType. /// 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 // Iterator access to the elements
typedef std::vector<PATypeHandle>::const_iterator element_iterator; typedef std::vector<PATypeHandle>::const_iterator element_iterator;
@ -198,6 +199,8 @@ public:
static inline bool classof(const Type *T) { static inline bool classof(const Type *T) {
return T->getTypeID() == StructTyID; return T->getTypeID() == StructTyID;
} }
bool isPacked() const { return getSubclassData(); }
}; };

View File

@ -85,6 +85,7 @@ public:
ArrayTyID , PointerTyID, // Array... pointer... ArrayTyID , PointerTyID, // Array... pointer...
OpaqueTyID, // Opaque type instances... OpaqueTyID, // Opaque type instances...
PackedTyID, // SIMD 'packed' format... PackedTyID, // SIMD 'packed' format...
BC_ONLY_PackedStructTyID, // packed struct, for BC rep only
//... //...
NumTypeIDs, // Must remain as last defined ID NumTypeIDs, // Must remain as last defined ID
@ -95,6 +96,7 @@ public:
private: private:
TypeID ID : 8; // The current base type of this type. TypeID ID : 8; // The current base type of this type.
bool Abstract : 1; // True if type contains an OpaqueType 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 /// 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 /// this type. When this number falls to zero, if the type is abstract and
@ -117,6 +119,9 @@ protected:
unsigned getRefCount() const { return RefCount; } 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 /// 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 /// abstract types. When types are refined to other types, this field is set
/// to the more refined type. Only abstract types can be forwarded. /// to the more refined type. Only abstract types can be forwarded.

View File

@ -1209,6 +1209,20 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference
$$ = new PATypeHolder(StructType::get(std::vector<const Type*>())); $$ = new PATypeHolder(StructType::get(std::vector<const Type*>()));
CHECK_FOR_ERROR 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? | UpRTypes '*' { // Pointer type?
if (*$1 == Type::LabelTy) if (*$1 == Type::LabelTy)
GEN_ERROR("Cannot form a pointer to a basic block"); GEN_ERROR("Cannot form a pointer to a basic block");

View File

@ -1192,7 +1192,18 @@ const Type *BytecodeReader::ParseType() {
Typ = read_vbr_uint(); 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; break;
} }
case Type::PointerTyID: { case Type::PointerTyID: {

View File

@ -197,7 +197,11 @@ inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void BytecodeWriter::outputType(const Type *T) { 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... // That's all there is to handling primitive types...
if (T->isPrimitiveType()) { if (T->isPrimitiveType()) {
@ -246,10 +250,8 @@ void BytecodeWriter::outputType(const Type *T) {
break; break;
} }
case Type::StructTyID: { case Type::StructTyID: {
const StructType *ST = cast<StructType>(T); const StructType *ST = cast<StructType>(T);
// Output all of the element types... // Output all of the element types...
for (StructType::element_iterator I = ST->element_begin(), for (StructType::element_iterator I = ST->element_begin(),
E = ST->element_end(); I != E; ++I) { E = ST->element_end(); I != E; ++I) {

View File

@ -53,7 +53,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
unsigned TyAlign; unsigned TyAlign;
uint64_t TySize; uint64_t TySize;
getTypeInfo(Ty, &TD, TySize, A); getTypeInfo(Ty, &TD, TySize, A);
TyAlign = A; TyAlign = ST->isPacked() ? 1 : A;
// Add padding if necessary to make the data element aligned properly... // Add padding if necessary to make the data element aligned properly...
if (StructSize % TyAlign != 0) if (StructSize % TyAlign != 0)

View File

@ -287,6 +287,8 @@ static void calcTypeName(const Type *Ty,
} }
case Type::StructTyID: { case Type::StructTyID: {
const StructType *STy = cast<StructType>(Ty); const StructType *STy = cast<StructType>(Ty);
if (STy->isPacked())
Result += '<';
Result += "{ "; Result += "{ ";
for (StructType::element_iterator I = STy->element_begin(), for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) { E = STy->element_end(); I != E; ++I) {
@ -295,6 +297,8 @@ static void calcTypeName(const Type *Ty,
calcTypeName(*I, TypeStack, TypeNames, Result); calcTypeName(*I, TypeStack, TypeNames, Result);
} }
Result += " }"; Result += " }";
if (STy->isPacked())
Result += '>';
break; break;
} }
case Type::PointerTyID: case Type::PointerTyID:
@ -699,6 +703,8 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
} }
Out << ')'; Out << ')';
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) { } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
if (STy->isPacked())
Out << '<';
Out << "{ "; Out << "{ ";
for (StructType::element_iterator I = STy->element_begin(), for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) { E = STy->element_end(); I != E; ++I) {
@ -707,6 +713,8 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
printType(*I); printType(*I);
} }
Out << " }"; Out << " }";
if (STy->isPacked())
Out << '>';
} else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
printType(PTy->getElementType()) << '*'; printType(PTy->getElementType()) << '*';
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {

View File

@ -1150,12 +1150,12 @@ Constant *ConstantStruct::get(const StructType *Ty,
return ConstantAggregateZero::get(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; std::vector<const Type*> StructEls;
StructEls.reserve(V.size()); StructEls.reserve(V.size());
for (unsigned i = 0, e = V.size(); i != e; ++i) for (unsigned i = 0, e = V.size(); i != e; ++i)
StructEls.push_back(V[i]->getType()); 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... // destroyConstant - Remove the constant from the constant table...
@ -2183,4 +2183,3 @@ std::string Constant::getStringValue(bool Chop, unsigned Offset) {
} }
return ""; return "";
} }

View File

@ -22,6 +22,7 @@
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Debug.h"
#include <algorithm> #include <algorithm>
using namespace llvm; 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 // created and later destroyed, all in an effort to make sure that there is only
// a single canonical version of a type. // a single canonical version of a type.
// //
//#define DEBUG_MERGE_TYPES 1 // #define DEBUG_MERGE_TYPES 1
AbstractTypeUser::~AbstractTypeUser() {} AbstractTypeUser::~AbstractTypeUser() {}
@ -318,7 +319,10 @@ static std::string getTypeDescription(const Type *Ty,
} }
case Type::StructTyID: { case Type::StructTyID: {
const StructType *STy = cast<StructType>(Ty); const StructType *STy = cast<StructType>(Ty);
Result = "{ "; if (STy->isPacked())
Result = "<{ ";
else
Result = "{ ";
for (StructType::element_iterator I = STy->element_begin(), for (StructType::element_iterator I = STy->element_begin(),
E = STy->element_end(); I != E; ++I) { E = STy->element_end(); I != E; ++I) {
if (I != STy->element_begin()) if (I != STy->element_begin())
@ -326,6 +330,8 @@ static std::string getTypeDescription(const Type *Ty,
Result += getTypeDescription(*I, TypeStack); Result += getTypeDescription(*I, TypeStack);
} }
Result += " }"; Result += " }";
if (STy->isPacked())
Result += ">";
break; break;
} }
case Type::PointerTyID: { case Type::PointerTyID: {
@ -454,8 +460,9 @@ FunctionType::FunctionType(const Type *Result,
setAbstract(isAbstract); setAbstract(isAbstract);
} }
StructType::StructType(const std::vector<const Type*> &Types) StructType::StructType(const std::vector<const Type*> &Types, bool isPacked)
: CompositeType(StructTyID) { : CompositeType(StructTyID) {
setSubclassData(isPacked);
ContainedTys.reserve(Types.size()); ContainedTys.reserve(Types.size());
bool isAbstract = false; bool isAbstract = false;
for (unsigned i = 0; i < Types.size(); ++i) { 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)) { } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
const StructType *STy2 = cast<StructType>(Ty2); const StructType *STy2 = cast<StructType>(Ty2);
if (STy->getNumElements() != STy2->getNumElements()) return false; if (STy->getNumElements() != STy2->getNumElements()) return false;
if (STy->isPacked() != STy2->isPacked()) return false;
for (unsigned i = 0, e = STy2->getNumElements(); i != e; ++i) for (unsigned i = 0, e = STy2->getNumElements(); i != e; ++i)
if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes)) if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes))
return false; return false;
@ -1137,8 +1145,10 @@ namespace llvm {
// //
class StructValType { class StructValType {
std::vector<const Type*> ElTypes; std::vector<const Type*> ElTypes;
bool packed;
public: 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) { static StructValType get(const StructType *ST) {
std::vector<const Type *> ElTypes; std::vector<const Type *> ElTypes;
@ -1146,7 +1156,7 @@ public:
for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i)
ElTypes.push_back(ST->getElementType(i)); ElTypes.push_back(ST->getElementType(i));
return StructValType(ElTypes); return StructValType(ElTypes, ST->isPacked());
} }
static unsigned hashTypeStructure(const StructType *ST) { static unsigned hashTypeStructure(const StructType *ST) {
@ -1160,20 +1170,23 @@ public:
} }
inline bool operator<(const StructValType &STV) const { 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; static ManagedStatic<TypeMap<StructValType, StructType> > StructTypes;
StructType *StructType::get(const std::vector<const Type*> &ETypes) { StructType *StructType::get(const std::vector<const Type*> &ETypes,
StructValType STV(ETypes); bool isPacked) {
StructValType STV(ETypes, isPacked);
StructType *ST = StructTypes->get(STV); StructType *ST = StructTypes->get(STV);
if (ST) return ST; if (ST) return ST;
// Value not found. Derive a new type! // 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 #ifdef DEBUG_MERGE_TYPES
DOUT << "Derived new type: " << *ST << "\n"; DOUT << "Derived new type: " << *ST << "\n";