Fixed packed structure breakage from earlier TargetData patch; applied

Chris Lattner's code style suggestions.

Patch by Scott Michel!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34292 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer
2007-02-15 02:11:06 +00:00
parent 480cbb9387
commit b7d61101b1
2 changed files with 35 additions and 84 deletions

View File

@@ -48,7 +48,7 @@ enum AlignTypeEnum {
/// @note The unusual order of elements in the structure attempts to reduce /// @note The unusual order of elements in the structure attempts to reduce
/// padding and make the structure slightly more cache friendly. /// padding and make the structure slightly more cache friendly.
struct TargetAlignElem { struct TargetAlignElem {
unsigned char AlignType; //< Alignment type (AlignTypeEnum) AlignTypeEnum AlignType : 8; //< Alignment type (AlignTypeEnum)
unsigned char ABIAlign; //< ABI alignment for this type/bitw unsigned char ABIAlign; //< ABI alignment for this type/bitw
unsigned char PrefAlign; //< Pref. alignment for this type/bitw unsigned char PrefAlign; //< Pref. alignment for this type/bitw
short TypeBitWidth; //< Type bit width short TypeBitWidth; //< Type bit width
@@ -64,18 +64,12 @@ struct TargetAlignElem {
std::ostream &dump(std::ostream &os) const; std::ostream &dump(std::ostream &os) const;
}; };
//! TargetAlignElem output stream inserter
/*!
@sa TargetAlignElem::dump()
*/
std::ostream &operator<<(std::ostream &os, const TargetAlignElem &elem);
class TargetData : public ImmutablePass { class TargetData : public ImmutablePass {
private: private:
bool LittleEndian; ///< Defaults to false bool LittleEndian; ///< Defaults to false
unsigned char PointerMemSize; ///< Pointer size in bytes unsigned char PointerMemSize; ///< Pointer size in bytes
unsigned char PointerABIAlign; ///< Pointer ABI alignment unsigned char PointerABIAlign; ///< Pointer ABI alignment
unsigned char PointerPrefAlign; ///< Pointer preferred global alignment unsigned char PointerPrefAlign; ///< Pointer preferred alignment
//! Where the primitive type alignment data is stored. //! Where the primitive type alignment data is stored.
/*! /*!
@@ -99,7 +93,8 @@ private:
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
unsigned char pref_align, short bit_width); unsigned char pref_align, short bit_width);
//! Get TargetAlignElem from alignment type and bit width //! Get TargetAlignElem from alignment type and bit width
const TargetAlignElem &getAlignment(AlignTypeEnum, short) const; const TargetAlignElem &getAlignment(AlignTypeEnum align_type,
short bit_width) const;
//! Internal helper method that returns requested alignment for type. //! Internal helper method that returns requested alignment for type.
unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const; unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const;

View File

@@ -50,8 +50,8 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
const Type *Ty = ST->getElementType(i); const Type *Ty = ST->getElementType(i);
unsigned TyAlign; unsigned TyAlign;
uint64_t TySize; uint64_t TySize;
TyAlign = (unsigned) TD.getABITypeAlignment(Ty); TyAlign = (ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty));
TySize = (unsigned) TD.getTypeSize(Ty); TySize = TD.getTypeSize(Ty);
// 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)
@@ -94,8 +94,7 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
TargetAlignElem TargetAlignElem
TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align, TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align,
unsigned char pref_align, short bit_width) unsigned char pref_align, short bit_width) {
{
TargetAlignElem retval; TargetAlignElem retval;
retval.AlignType = align_type; retval.AlignType = align_type;
retval.ABIAlign = abi_align; retval.ABIAlign = abi_align;
@@ -105,15 +104,13 @@ TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align,
} }
bool bool
TargetAlignElem::operator<(const TargetAlignElem &rhs) const TargetAlignElem::operator<(const TargetAlignElem &rhs) const {
{
return ((AlignType < rhs.AlignType) return ((AlignType < rhs.AlignType)
|| (AlignType == rhs.AlignType && TypeBitWidth < rhs.TypeBitWidth)); || (AlignType == rhs.AlignType && TypeBitWidth < rhs.TypeBitWidth));
} }
bool bool
TargetAlignElem::operator==(const TargetAlignElem &rhs) const TargetAlignElem::operator==(const TargetAlignElem &rhs) const {
{
return (AlignType == rhs.AlignType return (AlignType == rhs.AlignType
&& ABIAlign == rhs.ABIAlign && ABIAlign == rhs.ABIAlign
&& PrefAlign == rhs.PrefAlign && PrefAlign == rhs.PrefAlign
@@ -121,20 +118,13 @@ TargetAlignElem::operator==(const TargetAlignElem &rhs) const
} }
std::ostream & std::ostream &
TargetAlignElem::dump(std::ostream &os) const TargetAlignElem::dump(std::ostream &os) const {
{
return os << AlignType return os << AlignType
<< TypeBitWidth << TypeBitWidth
<< ":" << (int) (ABIAlign * 8) << ":" << (int) (ABIAlign * 8)
<< ":" << (int) (PrefAlign * 8); << ":" << (int) (PrefAlign * 8);
} }
std::ostream &
llvm::operator<<(std::ostream &os, const TargetAlignElem &elem)
{
return elem.dump(os);
}
const TargetAlignElem TargetData::InvalidAlignmentElem = const TargetAlignElem TargetData::InvalidAlignmentElem =
TargetAlignElem::get((AlignTypeEnum) -1, 0, 0, 0); TargetAlignElem::get((AlignTypeEnum) -1, 0, 0, 0);
@@ -146,9 +136,9 @@ const TargetAlignElem TargetData::InvalidAlignmentElem =
A TargetDescription string consists of a sequence of hyphen-delimited A TargetDescription string consists of a sequence of hyphen-delimited
specifiers for target endianness, pointer size and alignments, and various specifiers for target endianness, pointer size and alignments, and various
primitive type sizes and alignments. A typical string looks something like: primitive type sizes and alignments. A typical string looks something like:
<br> <br><br>
"E-p:32:32:32-i1:8:8-i8:8:8-i32:32:32-i64:32:64-f32:32:32-f64:32:64" "E-p:32:32:32-i1:8:8-i8:8:8-i32:32:32-i64:32:64-f32:32:32-f64:32:64"
<br> <br><br>
(note: this string is not fully specified and is only an example.) (note: this string is not fully specified and is only an example.)
\p \p
Alignments come in two flavors: ABI and preferred. ABI alignment (abi_align, Alignments come in two flavors: ABI and preferred. ABI alignment (abi_align,
@@ -187,16 +177,16 @@ void TargetData::init(const std::string &TargetDescription) {
PointerPrefAlign = PointerABIAlign; PointerPrefAlign = PointerABIAlign;
// Default alignments // Default alignments
setAlignment(INTEGER_ALIGN, 1, 1, 1); // Bool setAlignment(INTEGER_ALIGN, 1, 1, 1); // Bool
setAlignment(INTEGER_ALIGN, 1, 1, 8); // Byte setAlignment(INTEGER_ALIGN, 1, 1, 8); // Byte
setAlignment(INTEGER_ALIGN, 2, 2, 16); // short setAlignment(INTEGER_ALIGN, 2, 2, 16); // short
setAlignment(INTEGER_ALIGN, 4, 4, 32); // int setAlignment(INTEGER_ALIGN, 4, 4, 32); // int
setAlignment(INTEGER_ALIGN, 0, 8, 64); // long setAlignment(INTEGER_ALIGN, 4, 8, 64); // long
setAlignment(FLOAT_ALIGN, 4, 4, 32); // float setAlignment(FLOAT_ALIGN, 4, 4, 32); // float
setAlignment(FLOAT_ALIGN, 0, 8, 64); // double setAlignment(FLOAT_ALIGN, 8, 8, 64); // double
setAlignment(PACKED_ALIGN, 8, 8, 64); // v2i32 setAlignment(PACKED_ALIGN, 8, 8, 64); // v2i32
setAlignment(PACKED_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ... setAlignment(PACKED_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
setAlignment(AGGREGATE_ALIGN, 0, 0, 0); // struct, union, class, ... setAlignment(AGGREGATE_ALIGN, 0, 0, 0); // struct, union, class, ...
while (!temp.empty()) { while (!temp.empty()) {
std::string token = getToken(temp, "-"); std::string token = getToken(temp, "-");
@@ -241,17 +231,6 @@ void TargetData::init(const std::string &TargetDescription) {
break; break;
} }
} }
// Unless explicitly specified, the alignments for longs and doubles is
// capped by pointer size.
// FIXME: Is this still necessary?
const TargetAlignElem &long_align = getAlignment(INTEGER_ALIGN, 64);
if (long_align.ABIAlign == 0)
setAlignment(INTEGER_ALIGN, PointerMemSize, PointerMemSize, 64);
const TargetAlignElem &double_align = getAlignment(FLOAT_ALIGN, 64);
if (double_align.ABIAlign == 0)
setAlignment(FLOAT_ALIGN, PointerMemSize, PointerMemSize, 64);
} }
TargetData::TargetData(const Module *M) { TargetData::TargetData(const Module *M) {
@@ -377,44 +356,21 @@ void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
} }
struct hyphen_delimited :
public std::iterator<std::output_iterator_tag, void, void, void, void>
{
std::ostream &o;
hyphen_delimited(std::ostream &os) :
o(os)
{ }
hyphen_delimited &operator=(const TargetAlignElem &elem)
{
o << "-" << elem;
return *this;
}
hyphen_delimited &operator*()
{
return *this;
}
hyphen_delimited &operator++()
{
return *this;
}
};
std::string TargetData::getStringRepresentation() const { std::string TargetData::getStringRepresentation() const {
std::stringstream repr; std::string repr;
repr.append(LittleEndian ? "e" : "E");
if (LittleEndian) repr.append("-p:").append(itostr((int64_t) (PointerMemSize * 8))).
repr << "e"; append(":").append(itostr((int64_t) (PointerABIAlign * 8))).
else append(":").append(itostr((int64_t) (PointerPrefAlign * 8)));
repr << "E"; for (align_const_iterator I = Alignments.begin();
repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlign * 8) I != Alignments.end();
<< ":" << (PointerPrefAlign * 8); ++I) {
std::copy(Alignments.begin(), Alignments.end(), hyphen_delimited(repr)); repr.append("-").append(1, (char) I->AlignType).
return repr.str(); append(utostr((int64_t) I->TypeBitWidth)).
append(":").append(utostr((uint64_t) (I->ABIAlign * 8))).
append(":").append(utostr((uint64_t) (I->PrefAlign * 8)));
}
return repr;
} }