mirror of
https://github.com/RPCS3/llvm.git
synced 2025-03-03 08:07:51 +00:00
[Alignment][NFC] migrate DataLayout internal struct to llvm::Align
Summary: This is patch is part of a series to introduce an Alignment type. See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html See this patch for the introduction of the type: https://reviews.llvm.org/D64790 With this patch the PointerAlignElem struct goes from 20B to 16B. Reviewers: courbet Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67400 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372390 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0b85459856
commit
080ee770b9
@ -72,11 +72,11 @@ struct LayoutAlignElem {
|
|||||||
/// Alignment type from \c AlignTypeEnum
|
/// Alignment type from \c AlignTypeEnum
|
||||||
unsigned AlignType : 8;
|
unsigned AlignType : 8;
|
||||||
unsigned TypeBitWidth : 24;
|
unsigned TypeBitWidth : 24;
|
||||||
unsigned ABIAlign : 16;
|
llvm::Align ABIAlign;
|
||||||
unsigned PrefAlign : 16;
|
llvm::Align PrefAlign;
|
||||||
|
|
||||||
static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
|
static LayoutAlignElem get(AlignTypeEnum align_type, llvm::Align abi_align,
|
||||||
unsigned pref_align, uint32_t bit_width);
|
llvm::Align pref_align, uint32_t bit_width);
|
||||||
|
|
||||||
bool operator==(const LayoutAlignElem &rhs) const;
|
bool operator==(const LayoutAlignElem &rhs) const;
|
||||||
};
|
};
|
||||||
@ -88,15 +88,15 @@ struct LayoutAlignElem {
|
|||||||
/// \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 PointerAlignElem {
|
struct PointerAlignElem {
|
||||||
unsigned ABIAlign;
|
llvm::Align ABIAlign;
|
||||||
unsigned PrefAlign;
|
llvm::Align PrefAlign;
|
||||||
uint32_t TypeByteWidth;
|
uint32_t TypeByteWidth;
|
||||||
uint32_t AddressSpace;
|
uint32_t AddressSpace;
|
||||||
uint32_t IndexWidth;
|
uint32_t IndexWidth;
|
||||||
|
|
||||||
/// Initializer
|
/// Initializer
|
||||||
static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
|
static PointerAlignElem get(uint32_t AddressSpace, llvm::Align ABIAlign,
|
||||||
unsigned PrefAlign, uint32_t TypeByteWidth,
|
llvm::Align PrefAlign, uint32_t TypeByteWidth,
|
||||||
uint32_t IndexWidth);
|
uint32_t IndexWidth);
|
||||||
|
|
||||||
bool operator==(const PointerAlignElem &rhs) const;
|
bool operator==(const PointerAlignElem &rhs) const;
|
||||||
@ -173,12 +173,12 @@ private:
|
|||||||
/// well-defined bitwise representation.
|
/// well-defined bitwise representation.
|
||||||
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
|
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
|
||||||
|
|
||||||
void setAlignment(AlignTypeEnum align_type, unsigned abi_align,
|
void setAlignment(AlignTypeEnum align_type, llvm::Align abi_align,
|
||||||
unsigned pref_align, uint32_t bit_width);
|
llvm::Align pref_align, uint32_t bit_width);
|
||||||
unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
|
unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
|
||||||
bool ABIAlign, Type *Ty) const;
|
bool ABIAlign, Type *Ty) const;
|
||||||
void setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
|
void setPointerAlignment(uint32_t AddrSpace, llvm::Align ABIAlign,
|
||||||
unsigned PrefAlign, uint32_t TypeByteWidth,
|
llvm::Align PrefAlign, uint32_t TypeByteWidth,
|
||||||
uint32_t IndexWidth);
|
uint32_t IndexWidth);
|
||||||
|
|
||||||
/// Internal helper method that returns requested alignment for type.
|
/// Internal helper method that returns requested alignment for type.
|
||||||
@ -558,7 +558,7 @@ inline LLVMTargetDataRef wrap(const DataLayout *P) {
|
|||||||
/// based on the DataLayout structure.
|
/// based on the DataLayout structure.
|
||||||
class StructLayout {
|
class StructLayout {
|
||||||
uint64_t StructSize;
|
uint64_t StructSize;
|
||||||
unsigned StructAlignment;
|
llvm::Align StructAlignment;
|
||||||
unsigned IsPadded : 1;
|
unsigned IsPadded : 1;
|
||||||
unsigned NumElements : 31;
|
unsigned NumElements : 31;
|
||||||
uint64_t MemberOffsets[1]; // variable sized array!
|
uint64_t MemberOffsets[1]; // variable sized array!
|
||||||
@ -568,7 +568,7 @@ public:
|
|||||||
|
|
||||||
uint64_t getSizeInBits() const { return 8 * StructSize; }
|
uint64_t getSizeInBits() const { return 8 * StructSize; }
|
||||||
|
|
||||||
unsigned getAlignment() const { return StructAlignment; }
|
unsigned getAlignment() const { return StructAlignment.value(); }
|
||||||
|
|
||||||
/// Returns whether the struct has padding or not between its fields.
|
/// Returns whether the struct has padding or not between its fields.
|
||||||
/// NB: Padding in nested element is not taken into account.
|
/// NB: Padding in nested element is not taken into account.
|
||||||
|
@ -44,7 +44,6 @@ using namespace llvm;
|
|||||||
|
|
||||||
StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
|
StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
|
||||||
assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
|
assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
|
||||||
StructAlignment = 0;
|
|
||||||
StructSize = 0;
|
StructSize = 0;
|
||||||
IsPadded = false;
|
IsPadded = false;
|
||||||
NumElements = ST->getNumElements();
|
NumElements = ST->getNumElements();
|
||||||
@ -52,10 +51,10 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
|
|||||||
// Loop over each of the elements, placing them in memory.
|
// Loop over each of the elements, placing them in memory.
|
||||||
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
||||||
Type *Ty = ST->getElementType(i);
|
Type *Ty = ST->getElementType(i);
|
||||||
unsigned TyAlign = ST->isPacked() ? 1 : DL.getABITypeAlignment(Ty);
|
const llvm::Align TyAlign(ST->isPacked() ? 1 : DL.getABITypeAlignment(Ty));
|
||||||
|
|
||||||
// Add padding if necessary to align the data element properly.
|
// Add padding if necessary to align the data element properly.
|
||||||
if ((StructSize & (TyAlign-1)) != 0) {
|
if (!isAligned(TyAlign, StructSize)) {
|
||||||
IsPadded = true;
|
IsPadded = true;
|
||||||
StructSize = alignTo(StructSize, TyAlign);
|
StructSize = alignTo(StructSize, TyAlign);
|
||||||
}
|
}
|
||||||
@ -67,12 +66,9 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
|
|||||||
StructSize += DL.getTypeAllocSize(Ty); // Consume space for this data item
|
StructSize += DL.getTypeAllocSize(Ty); // Consume space for this data item
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty structures have alignment of 1 byte.
|
|
||||||
if (StructAlignment == 0) StructAlignment = 1;
|
|
||||||
|
|
||||||
// Add padding to the end of the struct so that it could be put in an array
|
// Add padding to the end of the struct so that it could be put in an array
|
||||||
// and all array elements would be aligned correctly.
|
// and all array elements would be aligned correctly.
|
||||||
if ((StructSize & (StructAlignment-1)) != 0) {
|
if (!isAligned(StructAlignment, StructSize)) {
|
||||||
IsPadded = true;
|
IsPadded = true;
|
||||||
StructSize = alignTo(StructSize, StructAlignment);
|
StructSize = alignTo(StructSize, StructAlignment);
|
||||||
}
|
}
|
||||||
@ -102,9 +98,10 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
|
|||||||
// LayoutAlignElem, LayoutAlign support
|
// LayoutAlignElem, LayoutAlign support
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
LayoutAlignElem
|
LayoutAlignElem LayoutAlignElem::get(AlignTypeEnum align_type,
|
||||||
LayoutAlignElem::get(AlignTypeEnum align_type, unsigned abi_align,
|
llvm::Align abi_align,
|
||||||
unsigned pref_align, uint32_t bit_width) {
|
llvm::Align pref_align,
|
||||||
|
uint32_t bit_width) {
|
||||||
assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
|
assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
|
||||||
LayoutAlignElem retval;
|
LayoutAlignElem retval;
|
||||||
retval.AlignType = align_type;
|
retval.AlignType = align_type;
|
||||||
@ -126,9 +123,10 @@ LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
|
|||||||
// PointerAlignElem, PointerAlign support
|
// PointerAlignElem, PointerAlign support
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
PointerAlignElem
|
PointerAlignElem PointerAlignElem::get(uint32_t AddressSpace,
|
||||||
PointerAlignElem::get(uint32_t AddressSpace, unsigned ABIAlign,
|
llvm::Align ABIAlign,
|
||||||
unsigned PrefAlign, uint32_t TypeByteWidth,
|
llvm::Align PrefAlign,
|
||||||
|
uint32_t TypeByteWidth,
|
||||||
uint32_t IndexWidth) {
|
uint32_t IndexWidth) {
|
||||||
assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
|
assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
|
||||||
PointerAlignElem retval;
|
PointerAlignElem retval;
|
||||||
@ -162,18 +160,19 @@ const char *DataLayout::getManglingComponent(const Triple &T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const LayoutAlignElem DefaultAlignments[] = {
|
static const LayoutAlignElem DefaultAlignments[] = {
|
||||||
{ INTEGER_ALIGN, 1, 1, 1 }, // i1
|
{INTEGER_ALIGN, 1, llvm::Align(1), llvm::Align(1)}, // i1
|
||||||
{ INTEGER_ALIGN, 8, 1, 1 }, // i8
|
{INTEGER_ALIGN, 8, llvm::Align(1), llvm::Align(1)}, // i8
|
||||||
{ INTEGER_ALIGN, 16, 2, 2 }, // i16
|
{INTEGER_ALIGN, 16, llvm::Align(2), llvm::Align(2)}, // i16
|
||||||
{ INTEGER_ALIGN, 32, 4, 4 }, // i32
|
{INTEGER_ALIGN, 32, llvm::Align(4), llvm::Align(4)}, // i32
|
||||||
{ INTEGER_ALIGN, 64, 4, 8 }, // i64
|
{INTEGER_ALIGN, 64, llvm::Align(4), llvm::Align(8)}, // i64
|
||||||
{ FLOAT_ALIGN, 16, 2, 2 }, // half
|
{FLOAT_ALIGN, 16, llvm::Align(2), llvm::Align(2)}, // half
|
||||||
{ FLOAT_ALIGN, 32, 4, 4 }, // float
|
{FLOAT_ALIGN, 32, llvm::Align(4), llvm::Align(4)}, // float
|
||||||
{ FLOAT_ALIGN, 64, 8, 8 }, // double
|
{FLOAT_ALIGN, 64, llvm::Align(8), llvm::Align(8)}, // double
|
||||||
{ FLOAT_ALIGN, 128, 16, 16 }, // ppcf128, quad, ...
|
{FLOAT_ALIGN, 128, llvm::Align(16), llvm::Align(16)}, // ppcf128, quad, ...
|
||||||
{ VECTOR_ALIGN, 64, 8, 8 }, // v2i32, v1i64, ...
|
{VECTOR_ALIGN, 64, llvm::Align(8), llvm::Align(8)}, // v2i32, v1i64, ...
|
||||||
{ VECTOR_ALIGN, 128, 16, 16 }, // v16i8, v8i16, v4i32, ...
|
{VECTOR_ALIGN, 128, llvm::Align(16),
|
||||||
{ AGGREGATE_ALIGN, 0, 0, 8 } // struct
|
llvm::Align(16)}, // v16i8, v8i16, v4i32, ...
|
||||||
|
{AGGREGATE_ALIGN, 0, llvm::Align(1), llvm::Align(8)} // struct
|
||||||
};
|
};
|
||||||
|
|
||||||
void DataLayout::reset(StringRef Desc) {
|
void DataLayout::reset(StringRef Desc) {
|
||||||
@ -194,7 +193,7 @@ void DataLayout::reset(StringRef Desc) {
|
|||||||
setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign,
|
setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign,
|
||||||
E.TypeBitWidth);
|
E.TypeBitWidth);
|
||||||
}
|
}
|
||||||
setPointerAlignment(0, 8, 8, 8, 8);
|
setPointerAlignment(0, llvm::Align(8), llvm::Align(8), 8, 8);
|
||||||
|
|
||||||
parseSpecifier(Desc);
|
parseSpecifier(Desc);
|
||||||
}
|
}
|
||||||
@ -320,8 +319,9 @@ void DataLayout::parseSpecifier(StringRef Desc) {
|
|||||||
report_fatal_error("Invalid index size of 0 bytes");
|
report_fatal_error("Invalid index size of 0 bytes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setPointerAlignment(AddrSpace, PointerABIAlign, PointerPrefAlign,
|
setPointerAlignment(AddrSpace, assumeAligned(PointerABIAlign),
|
||||||
PointerMemSize, IndexSize);
|
assumeAligned(PointerPrefAlign), PointerMemSize,
|
||||||
|
IndexSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'i':
|
case 'i':
|
||||||
@ -349,11 +349,16 @@ void DataLayout::parseSpecifier(StringRef Desc) {
|
|||||||
report_fatal_error(
|
report_fatal_error(
|
||||||
"Missing alignment specification in datalayout string");
|
"Missing alignment specification in datalayout string");
|
||||||
Split = split(Rest, ':');
|
Split = split(Rest, ':');
|
||||||
unsigned ABIAlign = inBytes(getInt(Tok));
|
const unsigned ABIAlign = inBytes(getInt(Tok));
|
||||||
if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
|
if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
|
||||||
report_fatal_error(
|
report_fatal_error(
|
||||||
"ABI alignment specification must be >0 for non-aggregate types");
|
"ABI alignment specification must be >0 for non-aggregate types");
|
||||||
|
|
||||||
|
if (!isUInt<16>(ABIAlign))
|
||||||
|
report_fatal_error("Invalid ABI alignment, must be a 16bit integer");
|
||||||
|
if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
|
||||||
|
report_fatal_error("Invalid ABI alignment, must be a power of 2");
|
||||||
|
|
||||||
// Preferred alignment.
|
// Preferred alignment.
|
||||||
unsigned PrefAlign = ABIAlign;
|
unsigned PrefAlign = ABIAlign;
|
||||||
if (!Rest.empty()) {
|
if (!Rest.empty()) {
|
||||||
@ -361,7 +366,14 @@ void DataLayout::parseSpecifier(StringRef Desc) {
|
|||||||
PrefAlign = inBytes(getInt(Tok));
|
PrefAlign = inBytes(getInt(Tok));
|
||||||
}
|
}
|
||||||
|
|
||||||
setAlignment(AlignType, ABIAlign, PrefAlign, Size);
|
if (!isUInt<16>(PrefAlign))
|
||||||
|
report_fatal_error(
|
||||||
|
"Invalid preferred alignment, must be a 16bit integer");
|
||||||
|
if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))
|
||||||
|
report_fatal_error("Invalid preferred alignment, must be a power of 2");
|
||||||
|
|
||||||
|
setAlignment(AlignType, assumeAligned(ABIAlign), assumeAligned(PrefAlign),
|
||||||
|
Size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -474,20 +486,15 @@ DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void DataLayout::setAlignment(AlignTypeEnum align_type, llvm::Align abi_align,
|
||||||
DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
|
llvm::Align pref_align, uint32_t bit_width) {
|
||||||
unsigned pref_align, uint32_t bit_width) {
|
// AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as
|
||||||
|
// uint16_t, it is unclear if there are requirements for alignment to be less
|
||||||
|
// than 2^16 other than storage. In the meantime we leave the restriction as
|
||||||
|
// an assert. See D67400 for context.
|
||||||
|
assert(Log2(abi_align) < 16 && Log2(pref_align) < 16 && "Alignment too big");
|
||||||
if (!isUInt<24>(bit_width))
|
if (!isUInt<24>(bit_width))
|
||||||
report_fatal_error("Invalid bit width, must be a 24bit integer");
|
report_fatal_error("Invalid bit width, must be a 24bit integer");
|
||||||
if (!isUInt<16>(abi_align))
|
|
||||||
report_fatal_error("Invalid ABI alignment, must be a 16bit integer");
|
|
||||||
if (!isUInt<16>(pref_align))
|
|
||||||
report_fatal_error("Invalid preferred alignment, must be a 16bit integer");
|
|
||||||
if (abi_align != 0 && !isPowerOf2_64(abi_align))
|
|
||||||
report_fatal_error("Invalid ABI alignment, must be a power of 2");
|
|
||||||
if (pref_align != 0 && !isPowerOf2_64(pref_align))
|
|
||||||
report_fatal_error("Invalid preferred alignment, must be a power of 2");
|
|
||||||
|
|
||||||
if (pref_align < abi_align)
|
if (pref_align < abi_align)
|
||||||
report_fatal_error(
|
report_fatal_error(
|
||||||
"Preferred alignment cannot be less than the ABI alignment");
|
"Preferred alignment cannot be less than the ABI alignment");
|
||||||
@ -513,8 +520,9 @@ DataLayout::findPointerLowerBound(uint32_t AddressSpace) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
|
void DataLayout::setPointerAlignment(uint32_t AddrSpace, llvm::Align ABIAlign,
|
||||||
unsigned PrefAlign, uint32_t TypeByteWidth,
|
llvm::Align PrefAlign,
|
||||||
|
uint32_t TypeByteWidth,
|
||||||
uint32_t IndexWidth) {
|
uint32_t IndexWidth) {
|
||||||
if (PrefAlign < ABIAlign)
|
if (PrefAlign < ABIAlign)
|
||||||
report_fatal_error(
|
report_fatal_error(
|
||||||
@ -543,14 +551,14 @@ unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
|
|||||||
// the lower_bound will point to when it fails an exact match.
|
// the lower_bound will point to when it fails an exact match.
|
||||||
if (I != Alignments.end() && I->AlignType == (unsigned)AlignType &&
|
if (I != Alignments.end() && I->AlignType == (unsigned)AlignType &&
|
||||||
(I->TypeBitWidth == BitWidth || AlignType == INTEGER_ALIGN))
|
(I->TypeBitWidth == BitWidth || AlignType == INTEGER_ALIGN))
|
||||||
return ABIInfo ? I->ABIAlign : I->PrefAlign;
|
return (ABIInfo ? I->ABIAlign : I->PrefAlign).value();
|
||||||
|
|
||||||
if (AlignType == INTEGER_ALIGN) {
|
if (AlignType == INTEGER_ALIGN) {
|
||||||
// If we didn't have a larger value try the largest value we have.
|
// If we didn't have a larger value try the largest value we have.
|
||||||
if (I != Alignments.begin()) {
|
if (I != Alignments.begin()) {
|
||||||
--I; // Go to the previous entry and see if its an integer.
|
--I; // Go to the previous entry and see if its an integer.
|
||||||
if (I->AlignType == INTEGER_ALIGN)
|
if (I->AlignType == INTEGER_ALIGN)
|
||||||
return ABIInfo ? I->ABIAlign : I->PrefAlign;
|
return (ABIInfo ? I->ABIAlign : I->PrefAlign).value();
|
||||||
}
|
}
|
||||||
} else if (AlignType == VECTOR_ALIGN) {
|
} else if (AlignType == VECTOR_ALIGN) {
|
||||||
// By default, use natural alignment for vector types. This is consistent
|
// By default, use natural alignment for vector types. This is consistent
|
||||||
@ -636,7 +644,7 @@ unsigned DataLayout::getPointerABIAlignment(unsigned AS) const {
|
|||||||
I = findPointerLowerBound(0);
|
I = findPointerLowerBound(0);
|
||||||
assert(I->AddressSpace == 0);
|
assert(I->AddressSpace == 0);
|
||||||
}
|
}
|
||||||
return I->ABIAlign;
|
return I->ABIAlign.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DataLayout::getPointerPrefAlignment(unsigned AS) const {
|
unsigned DataLayout::getPointerPrefAlignment(unsigned AS) const {
|
||||||
@ -645,7 +653,7 @@ unsigned DataLayout::getPointerPrefAlignment(unsigned AS) const {
|
|||||||
I = findPointerLowerBound(0);
|
I = findPointerLowerBound(0);
|
||||||
assert(I->AddressSpace == 0);
|
assert(I->AddressSpace == 0);
|
||||||
}
|
}
|
||||||
return I->PrefAlign;
|
return I->PrefAlign.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DataLayout::getPointerSize(unsigned AS) const {
|
unsigned DataLayout::getPointerSize(unsigned AS) const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user