mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-24 08:24:33 +00:00
Packed Structures
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32361 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -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...
|
||||||
///
|
///
|
||||||
|
@ -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(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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");
|
||||||
|
@ -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: {
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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)) {
|
||||||
|
@ -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 "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
Reference in New Issue
Block a user