[llvm] [DataLayout] Privatize and rename '*AlignElem' structs and enum (NFC) (PR #103723)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 02:07:02 PDT 2024
https://github.com/s-barannikov created https://github.com/llvm/llvm-project/pull/103723
This removes `LayoutAlignElem` / `PointerAlignElem` and also `AlignTypeEnum` from llvm namespace and makes they nested classes of `DataLayout`.
They are also renamed to match their meaning (LangRef refers to them as "specifications").
>From 384ff1ac00f4095c783fa54a42536241e555ba3c Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 13 Aug 2024 10:35:50 +0300
Subject: [PATCH 1/3] [DataLayout] Use member initialization (NFC)
This also adds a default constructor and a few uses of it.
---
llvm/include/llvm/IR/DataLayout.h | 51 +++++++++--------
llvm/lib/IR/DataLayout.cpp | 59 ++++++++++----------
llvm/lib/IR/Module.cpp | 2 +-
llvm/unittests/Analysis/ValueLatticeTest.cpp | 2 +-
llvm/unittests/CodeGen/LowLevelTypeTest.cpp | 5 +-
llvm/unittests/IR/VectorTypesTest.cpp | 4 +-
6 files changed, 63 insertions(+), 60 deletions(-)
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 2b79facf1d8988..d73fe7ac300843 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -65,9 +65,6 @@ enum AlignTypeEnum {
/// Layout alignment element.
///
/// Stores the alignment data associated with a given type bit width.
-///
-/// \note The unusual order of elements in the structure attempts to reduce
-/// padding and make the structure slightly more cache friendly.
struct LayoutAlignElem {
uint32_t TypeBitWidth;
Align ABIAlign;
@@ -82,14 +79,11 @@ struct LayoutAlignElem {
/// Layout pointer alignment element.
///
/// Stores the alignment data associated with a given pointer and address space.
-///
-/// \note The unusual order of elements in the structure attempts to reduce
-/// padding and make the structure slightly more cache friendly.
struct PointerAlignElem {
+ uint32_t AddressSpace;
+ uint32_t TypeBitWidth;
Align ABIAlign;
Align PrefAlign;
- uint32_t TypeBitWidth;
- uint32_t AddressSpace;
uint32_t IndexBitWidth;
/// Initializer
@@ -115,16 +109,16 @@ class DataLayout {
MultipleOfFunctionAlign,
};
private:
- /// Defaults to false.
- bool BigEndian;
+ bool BigEndian = false;
- unsigned AllocaAddrSpace;
- unsigned ProgramAddrSpace;
- unsigned DefaultGlobalsAddrSpace;
+ unsigned AllocaAddrSpace = 0;
+ unsigned ProgramAddrSpace = 0;
+ unsigned DefaultGlobalsAddrSpace = 0;
MaybeAlign StackNaturalAlign;
MaybeAlign FunctionPtrAlign;
- FunctionPtrAlignType TheFunctionPtrAlignType;
+ FunctionPtrAlignType TheFunctionPtrAlignType =
+ FunctionPtrAlignType::Independent;
enum ManglingModeT {
MM_None,
@@ -136,24 +130,30 @@ class DataLayout {
MM_Mips,
MM_XCOFF
};
- ManglingModeT ManglingMode;
+ ManglingModeT ManglingMode = MM_None;
// FIXME: `unsigned char` truncates the value parsed by `parseSpecifier`.
SmallVector<unsigned char, 8> LegalIntWidths;
- /// Primitive type alignment data. This is sorted by type and bit
- /// width during construction.
- using AlignmentsTy = SmallVector<LayoutAlignElem, 4>;
- AlignmentsTy IntAlignments;
- AlignmentsTy FloatAlignments;
- AlignmentsTy VectorAlignments;
+ // Default primitive type specifications.
+ static const LayoutAlignElem DefaultIntSpecs[];
+ static const LayoutAlignElem DefaultFloatSpecs[];
+ static const LayoutAlignElem DefaultVectorSpecs[];
+
+ // Default pointer type specifications.
+ static const PointerAlignElem DefaultPointerSpecs[];
+
+ // Primitive type specifications. Sorted and uniqued by type bit width.
+ SmallVector<LayoutAlignElem, 6> IntAlignments;
+ SmallVector<LayoutAlignElem, 4> FloatAlignments;
+ SmallVector<LayoutAlignElem, 10> VectorAlignments;
+
+ // Pointer type specifications. Sorted and uniqued by address space number.
+ SmallVector<PointerAlignElem, 8> Pointers;
/// The string representation used to create this DataLayout
std::string StringRepresentation;
- using PointersTy = SmallVector<PointerAlignElem, 8>;
- PointersTy Pointers;
-
const PointerAlignElem &getPointerAlignElem(uint32_t AddressSpace) const;
// Struct type ABI and preferred alignments. The default spec is "a:8:64".
@@ -189,6 +189,9 @@ class DataLayout {
Error parseSpecifier(StringRef Desc);
public:
+ /// Constructs a DataLayout with default values.
+ DataLayout();
+
/// Constructs a DataLayout from a specification string.
/// WARNING: Aborts execution if the string is malformed. Use parse() instead.
explicit DataLayout(StringRef LayoutString);
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index c10b302870edbe..7ac91810255b2b 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -198,37 +198,38 @@ const char *DataLayout::getManglingComponent(const Triple &T) {
return "-m:e";
}
-static const std::pair<AlignTypeEnum, LayoutAlignElem> DefaultAlignments[] = {
- {INTEGER_ALIGN, {1, Align(1), Align(1)}}, // i1
- {INTEGER_ALIGN, {8, Align(1), Align(1)}}, // i8
- {INTEGER_ALIGN, {16, Align(2), Align(2)}}, // i16
- {INTEGER_ALIGN, {32, Align(4), Align(4)}}, // i32
- {INTEGER_ALIGN, {64, Align(4), Align(8)}}, // i64
- {FLOAT_ALIGN, {16, Align(2), Align(2)}}, // half, bfloat
- {FLOAT_ALIGN, {32, Align(4), Align(4)}}, // float
- {FLOAT_ALIGN, {64, Align(8), Align(8)}}, // double
- {FLOAT_ALIGN, {128, Align(16), Align(16)}}, // ppcf128, quad, ...
- {VECTOR_ALIGN, {64, Align(8), Align(8)}}, // v2i32, v1i64, ...
- {VECTOR_ALIGN, {128, Align(16), Align(16)}}, // v16i8, v8i16, v4i32, ...
+// Default primitive type specifications.
+// NOTE: These arrays must be sorted by type bit width.
+constexpr LayoutAlignElem DataLayout::DefaultIntSpecs[] = {
+ {1, Align::Constant<1>(), Align::Constant<1>()}, // i1:8:8
+ {8, Align::Constant<1>(), Align::Constant<1>()}, // i8:8:8
+ {16, Align::Constant<2>(), Align::Constant<2>()}, // i16:16:16
+ {32, Align::Constant<4>(), Align::Constant<4>()}, // i32:32:32
+ {64, Align::Constant<4>(), Align::Constant<8>()}, // i64:32:64
+};
+constexpr LayoutAlignElem DataLayout::DefaultFloatSpecs[] = {
+ {16, Align::Constant<2>(), Align::Constant<2>()}, // f16:16:16
+ {32, Align::Constant<4>(), Align::Constant<4>()}, // f32:32:32
+ {64, Align::Constant<8>(), Align::Constant<8>()}, // f64:64:64
+ {128, Align::Constant<16>(), Align::Constant<16>()}, // f128:128:128
+};
+constexpr LayoutAlignElem DataLayout::DefaultVectorSpecs[] = {
+ {64, Align::Constant<8>(), Align::Constant<8>()}, // v64:64:64
+ {128, Align::Constant<16>(), Align::Constant<16>()}, // v128:128:128
};
-DataLayout::DataLayout(StringRef LayoutString) {
- BigEndian = false;
- AllocaAddrSpace = 0;
- ProgramAddrSpace = 0;
- DefaultGlobalsAddrSpace = 0;
- TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
- ManglingMode = MM_None;
-
- // Default alignments
- for (const auto &[Kind, Layout] : DefaultAlignments) {
- if (Error Err = setAlignment(Kind, Layout.ABIAlign, Layout.PrefAlign,
- Layout.TypeBitWidth))
- report_fatal_error(std::move(Err));
- }
- if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
- report_fatal_error(std::move(Err));
+// Default pointer type specifications.
+constexpr PointerAlignElem DataLayout::DefaultPointerSpecs[] = {
+ {0, 64, Align::Constant<8>(), Align::Constant<8>(), 64} // p0:64:64:64:64
+};
+
+DataLayout::DataLayout()
+ : IntAlignments(ArrayRef(DefaultIntSpecs)),
+ FloatAlignments(ArrayRef(DefaultFloatSpecs)),
+ VectorAlignments(ArrayRef(DefaultVectorSpecs)),
+ Pointers(ArrayRef(DefaultPointerSpecs)) {}
+DataLayout::DataLayout(StringRef LayoutString) : DataLayout() {
if (Error Err = parseSpecifier(LayoutString))
report_fatal_error(std::move(Err));
}
@@ -277,7 +278,7 @@ bool DataLayout::operator==(const DataLayout &Other) const {
}
Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {
- DataLayout Layout("");
+ DataLayout Layout;
if (Error Err = Layout.parseSpecifier(LayoutDescription))
return std::move(Err);
return Layout;
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 7ba5b2784f5460..704bc8d339bc57 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -73,7 +73,7 @@ template class llvm::SymbolTableListTraits<GlobalIFunc>;
Module::Module(StringRef MID, LLVMContext &C)
: Context(C), ValSymTab(std::make_unique<ValueSymbolTable>(-1)),
- ModuleID(std::string(MID)), SourceFileName(std::string(MID)), DL(""),
+ ModuleID(std::string(MID)), SourceFileName(std::string(MID)),
IsNewDbgInfoFormat(UseNewDbgInfoFormat) {
Context.addModule(this);
}
diff --git a/llvm/unittests/Analysis/ValueLatticeTest.cpp b/llvm/unittests/Analysis/ValueLatticeTest.cpp
index b456f286e0d965..1567bce2092986 100644
--- a/llvm/unittests/Analysis/ValueLatticeTest.cpp
+++ b/llvm/unittests/Analysis/ValueLatticeTest.cpp
@@ -22,7 +22,7 @@ namespace {
class ValueLatticeTest : public testing::Test {
protected:
LLVMContext Context;
- DataLayout DL = DataLayout("");
+ DataLayout DL;
};
TEST_F(ValueLatticeTest, ValueLatticeGetters) {
diff --git a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
index b60d82b529fa3f..43aa4009897eeb 100644
--- a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
+++ b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
@@ -20,7 +20,6 @@ namespace {
TEST(LowLevelTypeTest, Token) {
LLVMContext C;
- DataLayout DL("");
const LLT TTy = LLT::token();
@@ -38,7 +37,7 @@ TEST(LowLevelTypeTest, Token) {
TEST(LowLevelTypeTest, Scalar) {
LLVMContext C;
- DataLayout DL("");
+ DataLayout DL;
for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffffU}) {
const LLT Ty = LLT::scalar(S);
@@ -70,7 +69,7 @@ TEST(LowLevelTypeTest, Scalar) {
TEST(LowLevelTypeTest, Vector) {
LLVMContext C;
- DataLayout DL("");
+ DataLayout DL;
for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffU}) {
for (auto EC :
diff --git a/llvm/unittests/IR/VectorTypesTest.cpp b/llvm/unittests/IR/VectorTypesTest.cpp
index 7ba143eeeeb81d..c592f809f7bf3e 100644
--- a/llvm/unittests/IR/VectorTypesTest.cpp
+++ b/llvm/unittests/IR/VectorTypesTest.cpp
@@ -276,7 +276,7 @@ TEST(VectorTypesTest, BaseVectorType) {
TEST(VectorTypesTest, FixedLenComparisons) {
LLVMContext Ctx;
- DataLayout DL("");
+ DataLayout DL;
Type *Int32Ty = Type::getInt32Ty(Ctx);
Type *Int64Ty = Type::getInt64Ty(Ctx);
@@ -322,7 +322,7 @@ TEST(VectorTypesTest, FixedLenComparisons) {
TEST(VectorTypesTest, ScalableComparisons) {
LLVMContext Ctx;
- DataLayout DL("");
+ DataLayout DL;
Type *Int32Ty = Type::getInt32Ty(Ctx);
Type *Int64Ty = Type::getInt64Ty(Ctx);
>From d4640dfbe89fafaed4ad1423de974daba81c7c6e Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 13 Aug 2024 22:09:36 +0300
Subject: [PATCH 2/3] [DataLayout] Inline static constructors (NFC)
The removed asserts check invariants already checked by the caller.
---
llvm/include/llvm/IR/DataLayout.h | 8 --------
llvm/lib/IR/DataLayout.cpp | 31 +++----------------------------
2 files changed, 3 insertions(+), 36 deletions(-)
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index d73fe7ac300843..bde9adb199fe05 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -70,9 +70,6 @@ struct LayoutAlignElem {
Align ABIAlign;
Align PrefAlign;
- static LayoutAlignElem get(Align ABIAlign, Align PrefAlign,
- uint32_t BitWidth);
-
bool operator==(const LayoutAlignElem &rhs) const;
};
@@ -86,11 +83,6 @@ struct PointerAlignElem {
Align PrefAlign;
uint32_t IndexBitWidth;
- /// Initializer
- static PointerAlignElem getInBits(uint32_t AddressSpace, Align ABIAlign,
- Align PrefAlign, uint32_t TypeBitWidth,
- uint32_t IndexBitWidth);
-
bool operator==(const PointerAlignElem &rhs) const;
};
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 7ac91810255b2b..a2fe6e0c0f8c0f 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -142,16 +142,6 @@ class StructLayoutMap {
// LayoutAlignElem, LayoutAlign support
//===----------------------------------------------------------------------===//
-LayoutAlignElem LayoutAlignElem::get(Align ABIAlign, Align PrefAlign,
- uint32_t BitWidth) {
- assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
- LayoutAlignElem retval;
- retval.ABIAlign = ABIAlign;
- retval.PrefAlign = PrefAlign;
- retval.TypeBitWidth = BitWidth;
- return retval;
-}
-
bool LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
return ABIAlign == rhs.ABIAlign && PrefAlign == rhs.PrefAlign &&
TypeBitWidth == rhs.TypeBitWidth;
@@ -161,20 +151,6 @@ bool LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
// PointerAlignElem, PointerAlign support
//===----------------------------------------------------------------------===//
-PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace,
- Align ABIAlign, Align PrefAlign,
- uint32_t TypeBitWidth,
- uint32_t IndexBitWidth) {
- assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
- PointerAlignElem retval;
- retval.AddressSpace = AddressSpace;
- retval.ABIAlign = ABIAlign;
- retval.PrefAlign = PrefAlign;
- retval.TypeBitWidth = TypeBitWidth;
- retval.IndexBitWidth = IndexBitWidth;
- return retval;
-}
-
bool
PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace &&
@@ -654,7 +630,7 @@ Error DataLayout::setAlignment(AlignTypeEnum AlignType, Align ABIAlign,
I->PrefAlign = PrefAlign;
} else {
// Insert before I to keep the vector sorted.
- Alignments->insert(I, LayoutAlignElem::get(ABIAlign, PrefAlign, BitWidth));
+ Alignments->insert(I, LayoutAlignElem{BitWidth, ABIAlign, PrefAlign});
}
return Error::success();
}
@@ -689,9 +665,8 @@ Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
return A.AddressSpace < AddressSpace;
});
if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
- Pointers.insert(I,
- PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign,
- TypeBitWidth, IndexBitWidth));
+ Pointers.insert(I, PointerAlignElem{AddrSpace, TypeBitWidth, ABIAlign,
+ PrefAlign, IndexBitWidth});
} else {
I->ABIAlign = ABIAlign;
I->PrefAlign = PrefAlign;
>From c0054e3ee7f25a67fc26a91333fdf804c33085f8 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Wed, 14 Aug 2024 06:40:59 +0300
Subject: [PATCH 3/3] [DataLayout] Privatize and rename '*AlignElem' structs
and enum (NFC)
---
llvm/include/llvm/IR/DataLayout.h | 110 +++++++++--------
llvm/lib/IR/DataLayout.cpp | 196 +++++++++++++++---------------
2 files changed, 155 insertions(+), 151 deletions(-)
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index bde9adb199fe05..e5f1e6d996855a 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -49,43 +49,11 @@ class StructLayout;
class Triple;
class Value;
-/// Enum used to categorize the alignment types stored by LayoutAlignElem
-enum AlignTypeEnum {
- INTEGER_ALIGN = 'i',
- VECTOR_ALIGN = 'v',
- FLOAT_ALIGN = 'f',
- AGGREGATE_ALIGN = 'a'
-};
-
// FIXME: Currently the DataLayout string carries a "preferred alignment"
// for types. As the DataLayout is module/global, this should likely be
// sunk down to an FTTI element that is queried rather than a global
// preference.
-/// Layout alignment element.
-///
-/// Stores the alignment data associated with a given type bit width.
-struct LayoutAlignElem {
- uint32_t TypeBitWidth;
- Align ABIAlign;
- Align PrefAlign;
-
- bool operator==(const LayoutAlignElem &rhs) const;
-};
-
-/// Layout pointer alignment element.
-///
-/// Stores the alignment data associated with a given pointer and address space.
-struct PointerAlignElem {
- uint32_t AddressSpace;
- uint32_t TypeBitWidth;
- Align ABIAlign;
- Align PrefAlign;
- uint32_t IndexBitWidth;
-
- bool operator==(const PointerAlignElem &rhs) const;
-};
-
/// A parsed version of the target data layout string in and methods for
/// querying it.
///
@@ -127,27 +95,54 @@ class DataLayout {
// FIXME: `unsigned char` truncates the value parsed by `parseSpecifier`.
SmallVector<unsigned char, 8> LegalIntWidths;
+ // Primitive type specifier.
+ enum class PrimitiveSpecifier {
+ Integer = 'i',
+ Float = 'f',
+ Vector = 'v',
+ // TODO: Aggregates are not primitives. This should be separated.
+ Aggregate = 'a'
+ };
+
+ // Primitive type specification.
+ struct PrimitiveSpec {
+ uint32_t TypeBitWidth;
+ Align ABIAlign;
+ Align PrefAlign;
+
+ bool operator==(const PrimitiveSpec &Other) const;
+ };
+
+ // Pointer type specification.
+ struct PointerSpec {
+ uint32_t AddressSpace;
+ uint32_t TypeBitWidth;
+ Align ABIAlign;
+ Align PrefAlign;
+ uint32_t IndexBitWidth;
+
+ bool operator==(const PointerSpec &Other) const;
+ };
+
// Default primitive type specifications.
- static const LayoutAlignElem DefaultIntSpecs[];
- static const LayoutAlignElem DefaultFloatSpecs[];
- static const LayoutAlignElem DefaultVectorSpecs[];
+ static const PrimitiveSpec DefaultIntSpecs[];
+ static const PrimitiveSpec DefaultFloatSpecs[];
+ static const PrimitiveSpec DefaultVectorSpecs[];
// Default pointer type specifications.
- static const PointerAlignElem DefaultPointerSpecs[];
+ static const PointerSpec DefaultPointerSpecs[];
// Primitive type specifications. Sorted and uniqued by type bit width.
- SmallVector<LayoutAlignElem, 6> IntAlignments;
- SmallVector<LayoutAlignElem, 4> FloatAlignments;
- SmallVector<LayoutAlignElem, 10> VectorAlignments;
+ SmallVector<PrimitiveSpec, 6> IntSpecs;
+ SmallVector<PrimitiveSpec, 4> FloatSpecs;
+ SmallVector<PrimitiveSpec, 10> VectorSpecs;
// Pointer type specifications. Sorted and uniqued by address space number.
- SmallVector<PointerAlignElem, 8> Pointers;
+ SmallVector<PointerSpec, 8> PointerSpecs;
/// The string representation used to create this DataLayout
std::string StringRepresentation;
- const PointerAlignElem &getPointerAlignElem(uint32_t AddressSpace) const;
-
// Struct type ABI and preferred alignments. The default spec is "a:8:64".
Align StructABIAlignment = Align::Constant<1>();
Align StructPrefAlignment = Align::Constant<8>();
@@ -159,16 +154,25 @@ class DataLayout {
/// well-defined bitwise representation.
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
- /// Attempts to set the alignment of the given type. Returns an error
- /// description on failure.
- Error setAlignment(AlignTypeEnum AlignType, Align ABIAlign, Align PrefAlign,
- uint32_t BitWidth);
+ // Searches for a primitive specification that matches the given bit width.
+ // Returns the end iterator if the specification is not found.
+ SmallVectorImpl<PrimitiveSpec>::const_iterator
+ getPrimitiveSpec(const SmallVectorImpl<PrimitiveSpec> &Specs,
+ uint32_t BitWidth) const;
+
+ // Attempts to set the specification for the given type.
+ // Returns an error description on failure.
+ Error setPrimitiveSpec(PrimitiveSpecifier Specifier, uint32_t BitWidth,
+ Align ABIAlign, Align PrefAlign);
+
+ // Searches for a pointer specification that matches the given address space.
+ // Returns the default address space specification if not found.
+ const PointerSpec &getPointerSpec(uint32_t AddressSpace) const;
- /// Attempts to set the alignment of a pointer in the given address space.
- /// Returns an error description on failure.
- Error setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
- Align PrefAlign, uint32_t TypeBitWidth,
- uint32_t IndexBitWidth);
+ // Attempts to set the specification for pointer in the given address space.
+ // Returns an error description on failure.
+ Error setPointerSpec(uint32_t AddrSpace, uint32_t TypeBitWidth,
+ Align ABIAlign, Align PrefAlign, uint32_t IndexBitWidth);
/// Internal helper to get alignment for integer of given bitwidth.
Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
@@ -375,7 +379,7 @@ class DataLayout {
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
unsigned getPointerSizeInBits(unsigned AS = 0) const {
- return getPointerAlignElem(AS).TypeBitWidth;
+ return getPointerSpec(AS).TypeBitWidth;
}
/// Returns the maximum index size over all address spaces.
@@ -385,7 +389,7 @@ class DataLayout {
/// Size in bits of index used for address calculation in getelementptr.
unsigned getIndexSizeInBits(unsigned AS) const {
- return getPointerAlignElem(AS).IndexBitWidth;
+ return getPointerSpec(AS).IndexBitWidth;
}
/// Layout pointer size, in bits, based on the type. If this function is
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index a2fe6e0c0f8c0f..db3c45ba893a13 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -139,29 +139,20 @@ class StructLayoutMap {
} // end anonymous namespace
//===----------------------------------------------------------------------===//
-// LayoutAlignElem, LayoutAlign support
+// DataLayout Class Implementation
//===----------------------------------------------------------------------===//
-bool LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
- return ABIAlign == rhs.ABIAlign && PrefAlign == rhs.PrefAlign &&
- TypeBitWidth == rhs.TypeBitWidth;
+bool DataLayout::PrimitiveSpec::operator==(const PrimitiveSpec &Other) const {
+ return TypeBitWidth == Other.TypeBitWidth && ABIAlign == Other.ABIAlign &&
+ PrefAlign == Other.PrefAlign;
}
-//===----------------------------------------------------------------------===//
-// PointerAlignElem, PointerAlign support
-//===----------------------------------------------------------------------===//
-
-bool
-PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
- return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace &&
- PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth &&
- IndexBitWidth == rhs.IndexBitWidth);
+bool DataLayout::PointerSpec::operator==(const PointerSpec &Other) const {
+ return AddressSpace == Other.AddressSpace &&
+ TypeBitWidth == Other.TypeBitWidth && ABIAlign == Other.ABIAlign &&
+ PrefAlign == Other.PrefAlign && IndexBitWidth == Other.IndexBitWidth;
}
-//===----------------------------------------------------------------------===//
-// DataLayout Class Implementation
-//===----------------------------------------------------------------------===//
-
const char *DataLayout::getManglingComponent(const Triple &T) {
if (T.isOSBinFormatGOFF())
return "-m:l";
@@ -176,34 +167,34 @@ const char *DataLayout::getManglingComponent(const Triple &T) {
// Default primitive type specifications.
// NOTE: These arrays must be sorted by type bit width.
-constexpr LayoutAlignElem DataLayout::DefaultIntSpecs[] = {
+constexpr DataLayout::PrimitiveSpec DataLayout::DefaultIntSpecs[] = {
{1, Align::Constant<1>(), Align::Constant<1>()}, // i1:8:8
{8, Align::Constant<1>(), Align::Constant<1>()}, // i8:8:8
{16, Align::Constant<2>(), Align::Constant<2>()}, // i16:16:16
{32, Align::Constant<4>(), Align::Constant<4>()}, // i32:32:32
{64, Align::Constant<4>(), Align::Constant<8>()}, // i64:32:64
};
-constexpr LayoutAlignElem DataLayout::DefaultFloatSpecs[] = {
+constexpr DataLayout::PrimitiveSpec DataLayout::DefaultFloatSpecs[] = {
{16, Align::Constant<2>(), Align::Constant<2>()}, // f16:16:16
{32, Align::Constant<4>(), Align::Constant<4>()}, // f32:32:32
{64, Align::Constant<8>(), Align::Constant<8>()}, // f64:64:64
{128, Align::Constant<16>(), Align::Constant<16>()}, // f128:128:128
};
-constexpr LayoutAlignElem DataLayout::DefaultVectorSpecs[] = {
+constexpr DataLayout::PrimitiveSpec DataLayout::DefaultVectorSpecs[] = {
{64, Align::Constant<8>(), Align::Constant<8>()}, // v64:64:64
{128, Align::Constant<16>(), Align::Constant<16>()}, // v128:128:128
};
// Default pointer type specifications.
-constexpr PointerAlignElem DataLayout::DefaultPointerSpecs[] = {
+constexpr DataLayout::PointerSpec DataLayout::DefaultPointerSpecs[] = {
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64} // p0:64:64:64:64
};
DataLayout::DataLayout()
- : IntAlignments(ArrayRef(DefaultIntSpecs)),
- FloatAlignments(ArrayRef(DefaultFloatSpecs)),
- VectorAlignments(ArrayRef(DefaultVectorSpecs)),
- Pointers(ArrayRef(DefaultPointerSpecs)) {}
+ : IntSpecs(ArrayRef(DefaultIntSpecs)),
+ FloatSpecs(ArrayRef(DefaultFloatSpecs)),
+ VectorSpecs(ArrayRef(DefaultVectorSpecs)),
+ PointerSpecs(ArrayRef(DefaultPointerSpecs)) {}
DataLayout::DataLayout(StringRef LayoutString) : DataLayout() {
if (Error Err = parseSpecifier(LayoutString))
@@ -223,10 +214,10 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
TheFunctionPtrAlignType = Other.TheFunctionPtrAlignType;
ManglingMode = Other.ManglingMode;
LegalIntWidths = Other.LegalIntWidths;
- IntAlignments = Other.IntAlignments;
- FloatAlignments = Other.FloatAlignments;
- VectorAlignments = Other.VectorAlignments;
- Pointers = Other.Pointers;
+ IntSpecs = Other.IntSpecs;
+ FloatSpecs = Other.FloatSpecs;
+ VectorSpecs = Other.VectorSpecs;
+ PointerSpecs = Other.PointerSpecs;
StructABIAlignment = Other.StructABIAlignment;
StructPrefAlignment = Other.StructPrefAlignment;
NonIntegralAddressSpaces = Other.NonIntegralAddressSpaces;
@@ -244,11 +235,9 @@ bool DataLayout::operator==(const DataLayout &Other) const {
FunctionPtrAlign == Other.FunctionPtrAlign &&
TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
ManglingMode == Other.ManglingMode &&
- LegalIntWidths == Other.LegalIntWidths &&
- IntAlignments == Other.IntAlignments &&
- FloatAlignments == Other.FloatAlignments &&
- VectorAlignments == Other.VectorAlignments &&
- Pointers == Other.Pointers &&
+ LegalIntWidths == Other.LegalIntWidths && IntSpecs == Other.IntSpecs &&
+ FloatSpecs == Other.FloatSpecs && VectorSpecs == Other.VectorSpecs &&
+ PointerSpecs == Other.PointerSpecs &&
StructABIAlignment == Other.StructABIAlignment &&
StructPrefAlignment == Other.StructPrefAlignment;
}
@@ -409,9 +398,9 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
return reportError("Invalid index size of 0 bytes");
}
}
- if (Error Err = setPointerAlignmentInBits(
- AddrSpace, assumeAligned(PointerABIAlign),
- assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
+ if (Error Err = setPointerSpec(
+ AddrSpace, PointerMemSize, assumeAligned(PointerABIAlign),
+ assumeAligned(PointerPrefAlign), IndexSize))
return Err;
break;
}
@@ -419,13 +408,22 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
case 'v':
case 'f':
case 'a': {
- AlignTypeEnum AlignType;
+ PrimitiveSpecifier PrimSpecifier;
switch (Specifier) {
- default: llvm_unreachable("Unexpected specifier!");
- case 'i': AlignType = INTEGER_ALIGN; break;
- case 'v': AlignType = VECTOR_ALIGN; break;
- case 'f': AlignType = FLOAT_ALIGN; break;
- case 'a': AlignType = AGGREGATE_ALIGN; break;
+ default:
+ llvm_unreachable("Unexpected specifier!");
+ case 'i':
+ PrimSpecifier = PrimitiveSpecifier::Integer;
+ break;
+ case 'v':
+ PrimSpecifier = PrimitiveSpecifier::Vector;
+ break;
+ case 'f':
+ PrimSpecifier = PrimitiveSpecifier::Float;
+ break;
+ case 'a':
+ PrimSpecifier = PrimitiveSpecifier::Aggregate;
+ break;
}
// Bit size.
@@ -434,7 +432,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
if (Error Err = getInt(Tok, Size))
return Err;
- if (AlignType == AGGREGATE_ALIGN && Size != 0)
+ if (PrimSpecifier == PrimitiveSpecifier::Aggregate && Size != 0)
return reportError(
"Sized aggregate specification in datalayout string");
@@ -447,7 +445,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
unsigned ABIAlign;
if (Error Err = getIntInBytes(Tok, ABIAlign))
return Err;
- if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
+ if (PrimSpecifier != PrimitiveSpecifier::Aggregate && !ABIAlign)
return reportError(
"ABI alignment specification must be >0 for non-aggregate types");
@@ -455,7 +453,8 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
return reportError("Invalid ABI alignment, must be a 16bit integer");
if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
return reportError("Invalid ABI alignment, must be a power of 2");
- if (AlignType == INTEGER_ALIGN && Size == 8 && ABIAlign != 1)
+ if (PrimSpecifier == PrimitiveSpecifier::Integer && Size == 8 &&
+ ABIAlign != 1)
return reportError(
"Invalid ABI alignment, i8 must be naturally aligned");
@@ -474,8 +473,9 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))
return reportError("Invalid preferred alignment, must be a power of 2");
- if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),
- assumeAligned(PrefAlign), Size))
+ if (Error Err =
+ setPrimitiveSpec(PrimSpecifier, Size, assumeAligned(ABIAlign),
+ assumeAligned(PrefAlign)))
return Err;
break;
@@ -583,16 +583,17 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
return Error::success();
}
-static SmallVectorImpl<LayoutAlignElem>::const_iterator
-findAlignmentLowerBound(const SmallVectorImpl<LayoutAlignElem> &Alignments,
- uint32_t BitWidth) {
- return partition_point(Alignments, [BitWidth](const LayoutAlignElem &E) {
+SmallVectorImpl<DataLayout::PrimitiveSpec>::const_iterator
+DataLayout::getPrimitiveSpec(const SmallVectorImpl<PrimitiveSpec> &Specs,
+ uint32_t BitWidth) const {
+ return partition_point(Specs, [BitWidth](const PrimitiveSpec &E) {
return E.TypeBitWidth < BitWidth;
});
}
-Error DataLayout::setAlignment(AlignTypeEnum AlignType, Align ABIAlign,
- Align PrefAlign, uint32_t BitWidth) {
+Error DataLayout::setPrimitiveSpec(PrimitiveSpecifier Specifier,
+ uint32_t BitWidth, Align ABIAlign,
+ Align PrefAlign) {
// 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
@@ -604,69 +605,68 @@ Error DataLayout::setAlignment(AlignTypeEnum AlignType, Align ABIAlign,
return reportError(
"Preferred alignment cannot be less than the ABI alignment");
- SmallVectorImpl<LayoutAlignElem> *Alignments;
- switch (AlignType) {
- case AGGREGATE_ALIGN:
+ SmallVectorImpl<PrimitiveSpec> *Specs;
+ switch (Specifier) {
+ case PrimitiveSpecifier::Aggregate:
StructABIAlignment = ABIAlign;
StructPrefAlignment = PrefAlign;
return Error::success();
- case INTEGER_ALIGN:
- Alignments = &IntAlignments;
+ case PrimitiveSpecifier::Integer:
+ Specs = &IntSpecs;
break;
- case FLOAT_ALIGN:
- Alignments = &FloatAlignments;
+ case PrimitiveSpecifier::Float:
+ Specs = &FloatSpecs;
break;
- case VECTOR_ALIGN:
- Alignments = &VectorAlignments;
+ case PrimitiveSpecifier::Vector:
+ Specs = &VectorSpecs;
break;
}
- auto I = partition_point(*Alignments, [BitWidth](const LayoutAlignElem &E) {
+ auto I = partition_point(*Specs, [BitWidth](const PrimitiveSpec &E) {
return E.TypeBitWidth < BitWidth;
});
- if (I != Alignments->end() && I->TypeBitWidth == BitWidth) {
+ if (I != Specs->end() && I->TypeBitWidth == BitWidth) {
// Update the abi, preferred alignments.
I->ABIAlign = ABIAlign;
I->PrefAlign = PrefAlign;
} else {
// Insert before I to keep the vector sorted.
- Alignments->insert(I, LayoutAlignElem{BitWidth, ABIAlign, PrefAlign});
+ Specs->insert(I, PrimitiveSpec{BitWidth, ABIAlign, PrefAlign});
}
return Error::success();
}
-const PointerAlignElem &
-DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
+const DataLayout::PointerSpec &
+DataLayout::getPointerSpec(uint32_t AddressSpace) const {
if (AddressSpace != 0) {
- auto I = lower_bound(Pointers, AddressSpace,
- [](const PointerAlignElem &A, uint32_t AddressSpace) {
- return A.AddressSpace < AddressSpace;
- });
- if (I != Pointers.end() && I->AddressSpace == AddressSpace)
+ auto I = lower_bound(PointerSpecs, AddressSpace,
+ [](const PointerSpec &A, uint32_t AddressSpace) {
+ return A.AddressSpace < AddressSpace;
+ });
+ if (I != PointerSpecs.end() && I->AddressSpace == AddressSpace)
return *I;
}
- assert(Pointers[0].AddressSpace == 0);
- return Pointers[0];
+ assert(PointerSpecs[0].AddressSpace == 0);
+ return PointerSpecs[0];
}
-Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
- Align PrefAlign,
- uint32_t TypeBitWidth,
- uint32_t IndexBitWidth) {
+Error DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t TypeBitWidth,
+ Align ABIAlign, Align PrefAlign,
+ uint32_t IndexBitWidth) {
if (PrefAlign < ABIAlign)
return reportError(
"Preferred alignment cannot be less than the ABI alignment");
if (IndexBitWidth > TypeBitWidth)
return reportError("Index width cannot be larger than pointer width");
- auto I = lower_bound(Pointers, AddrSpace,
- [](const PointerAlignElem &A, uint32_t AddressSpace) {
- return A.AddressSpace < AddressSpace;
- });
- if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
- Pointers.insert(I, PointerAlignElem{AddrSpace, TypeBitWidth, ABIAlign,
- PrefAlign, IndexBitWidth});
+ auto I = lower_bound(PointerSpecs, AddrSpace,
+ [](const PointerSpec &A, uint32_t AddressSpace) {
+ return A.AddressSpace < AddressSpace;
+ });
+ if (I == PointerSpecs.end() || I->AddressSpace != AddrSpace) {
+ PointerSpecs.insert(I, PointerSpec{AddrSpace, TypeBitWidth, ABIAlign,
+ PrefAlign, IndexBitWidth});
} else {
I->ABIAlign = ABIAlign;
I->PrefAlign = PrefAlign;
@@ -678,11 +678,11 @@ Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
bool abi_or_pref) const {
- auto I = findAlignmentLowerBound(IntAlignments, BitWidth);
+ auto I = getPrimitiveSpec(IntSpecs, BitWidth);
// If we don't have an exact match, use alignment of next larger integer
// type. If there is none, use alignment of largest integer type by going
// back one element.
- if (I == IntAlignments.end())
+ if (I == IntSpecs.end())
--I;
return abi_or_pref ? I->ABIAlign : I->PrefAlign;
}
@@ -712,22 +712,22 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
}
Align DataLayout::getPointerABIAlignment(unsigned AS) const {
- return getPointerAlignElem(AS).ABIAlign;
+ return getPointerSpec(AS).ABIAlign;
}
Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
- return getPointerAlignElem(AS).PrefAlign;
+ return getPointerSpec(AS).PrefAlign;
}
unsigned DataLayout::getPointerSize(unsigned AS) const {
- return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8);
+ return divideCeil(getPointerSpec(AS).TypeBitWidth, 8);
}
unsigned DataLayout::getMaxIndexSize() const {
unsigned MaxIndexSize = 0;
- for (auto &P : Pointers)
+ for (const PointerSpec &Spec : PointerSpecs)
MaxIndexSize =
- std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8));
+ std::max(MaxIndexSize, (unsigned)divideCeil(Spec.TypeBitWidth, 8));
return MaxIndexSize;
}
@@ -740,7 +740,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
}
unsigned DataLayout::getIndexSize(unsigned AS) const {
- return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8);
+ return divideCeil(getPointerSpec(AS).IndexBitWidth, 8);
}
unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
@@ -794,8 +794,8 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
case Type::FP128TyID:
case Type::X86_FP80TyID: {
unsigned BitWidth = getTypeSizeInBits(Ty).getFixedValue();
- auto I = findAlignmentLowerBound(FloatAlignments, BitWidth);
- if (I != FloatAlignments.end() && I->TypeBitWidth == BitWidth)
+ auto I = getPrimitiveSpec(FloatSpecs, BitWidth);
+ if (I != FloatSpecs.end() && I->TypeBitWidth == BitWidth)
return abi_or_pref ? I->ABIAlign : I->PrefAlign;
// If we still couldn't find a reasonable default alignment, fall back
@@ -809,8 +809,8 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
case Type::FixedVectorTyID:
case Type::ScalableVectorTyID: {
unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinValue();
- auto I = findAlignmentLowerBound(VectorAlignments, BitWidth);
- if (I != VectorAlignments.end() && I->TypeBitWidth == BitWidth)
+ auto I = getPrimitiveSpec(VectorSpecs, BitWidth);
+ if (I != VectorSpecs.end() && I->TypeBitWidth == BitWidth)
return abi_or_pref ? I->ABIAlign : I->PrefAlign;
// By default, use natural alignment for vector types. This is consistent
More information about the llvm-commits
mailing list