Skip to content

Commit 305a1ce

Browse files
authored
[DataLayout] Refactor storage of non-integral address spaces
Instead of storing this as a separate array of non-integral pointers, add it to the PointerSpec class instead. This will allow for future simplifications such as splitting the non-integral property into multiple distinct ones: relocatable (i.e. non-stable representation) and non-integral representation (i.e. pointers with metadata). Reviewed By: arsenm Pull Request: #105734
1 parent 9ea6fcd commit 305a1ce

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

llvm/include/llvm/IR/DataLayout.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ class DataLayout {
7878
Align ABIAlign;
7979
Align PrefAlign;
8080
uint32_t IndexBitWidth;
81-
81+
/// Pointers in this address space don't have a well-defined bitwise
82+
/// representation (e.g. may be relocated by a copying garbage collector).
83+
/// Additionally, they may also be non-integral (i.e. containing additional
84+
/// metadata such as bounds information/permissions).
85+
bool IsNonIntegral;
8286
bool operator==(const PointerSpec &Other) const;
8387
};
8488

@@ -133,10 +137,6 @@ class DataLayout {
133137
// The StructType -> StructLayout map.
134138
mutable void *LayoutMap = nullptr;
135139

136-
/// Pointers in these address spaces are non-integral, and don't have a
137-
/// well-defined bitwise representation.
138-
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
139-
140140
/// Sets or updates the specification for the given primitive type.
141141
void setPrimitiveSpec(char Specifier, uint32_t BitWidth, Align ABIAlign,
142142
Align PrefAlign);
@@ -147,7 +147,8 @@ class DataLayout {
147147

148148
/// Sets or updates the specification for pointer in the given address space.
149149
void setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign,
150-
Align PrefAlign, uint32_t IndexBitWidth);
150+
Align PrefAlign, uint32_t IndexBitWidth,
151+
bool IsNonIntegral);
151152

152153
/// Internal helper to get alignment for integer of given bitwidth.
153154
Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
@@ -165,7 +166,8 @@ class DataLayout {
165166
Error parsePointerSpec(StringRef Spec);
166167

167168
/// Attempts to parse a single specification.
168-
Error parseSpecification(StringRef Spec);
169+
Error parseSpecification(StringRef Spec,
170+
SmallVectorImpl<unsigned> &NonIntegralAddressSpaces);
169171

170172
/// Attempts to parse a data layout string.
171173
Error parseLayoutString(StringRef LayoutString);
@@ -337,13 +339,17 @@ class DataLayout {
337339

338340
/// Return the address spaces containing non-integral pointers. Pointers in
339341
/// this address space don't have a well-defined bitwise representation.
340-
ArrayRef<unsigned> getNonIntegralAddressSpaces() const {
341-
return NonIntegralAddressSpaces;
342+
SmallVector<unsigned, 8> getNonIntegralAddressSpaces() const {
343+
SmallVector<unsigned, 8> AddrSpaces;
344+
for (const PointerSpec &PS : PointerSpecs) {
345+
if (PS.IsNonIntegral)
346+
AddrSpaces.push_back(PS.AddrSpace);
347+
}
348+
return AddrSpaces;
342349
}
343350

344351
bool isNonIntegralAddressSpace(unsigned AddrSpace) const {
345-
ArrayRef<unsigned> NonIntegralSpaces = getNonIntegralAddressSpaces();
346-
return is_contained(NonIntegralSpaces, AddrSpace);
352+
return getPointerSpec(AddrSpace).IsNonIntegral;
347353
}
348354

349355
bool isNonIntegralPointerType(PointerType *PT) const {

llvm/lib/IR/DataLayout.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ bool DataLayout::PrimitiveSpec::operator==(const PrimitiveSpec &Other) const {
151151
bool DataLayout::PointerSpec::operator==(const PointerSpec &Other) const {
152152
return AddrSpace == Other.AddrSpace && BitWidth == Other.BitWidth &&
153153
ABIAlign == Other.ABIAlign && PrefAlign == Other.PrefAlign &&
154-
IndexBitWidth == Other.IndexBitWidth;
154+
IndexBitWidth == Other.IndexBitWidth &&
155+
IsNonIntegral == Other.IsNonIntegral;
155156
}
156157

157158
namespace {
@@ -206,7 +207,8 @@ constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = {
206207

207208
// Default pointer type specifications.
208209
constexpr DataLayout::PointerSpec DefaultPointerSpecs[] = {
209-
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64} // p0:64:64:64:64
210+
// p0:64:64:64:64
211+
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false},
210212
};
211213

212214
DataLayout::DataLayout()
@@ -239,13 +241,11 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
239241
PointerSpecs = Other.PointerSpecs;
240242
StructABIAlignment = Other.StructABIAlignment;
241243
StructPrefAlignment = Other.StructPrefAlignment;
242-
NonIntegralAddressSpaces = Other.NonIntegralAddressSpaces;
243244
return *this;
244245
}
245246

246247
bool DataLayout::operator==(const DataLayout &Other) const {
247248
// NOTE: StringRepresentation might differ, it is not canonicalized.
248-
// FIXME: NonIntegralAddressSpaces isn't compared.
249249
return BigEndian == Other.BigEndian &&
250250
AllocaAddrSpace == Other.AllocaAddrSpace &&
251251
ProgramAddrSpace == Other.ProgramAddrSpace &&
@@ -454,11 +454,13 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
454454
return createStringError(
455455
"index size cannot be larger than the pointer size");
456456

457-
setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth);
457+
setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth,
458+
false);
458459
return Error::success();
459460
}
460461

461-
Error DataLayout::parseSpecification(StringRef Spec) {
462+
Error DataLayout::parseSpecification(
463+
StringRef Spec, SmallVectorImpl<unsigned> &NonIntegralAddressSpaces) {
462464
// The "ni" specifier is the only two-character specifier. Handle it first.
463465
if (Spec.starts_with("ni")) {
464466
// ni:<address space>[:<address space>]...
@@ -614,12 +616,23 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
614616

615617
// Split the data layout string into specifications separated by '-' and
616618
// parse each specification individually, updating internal data structures.
619+
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
617620
for (StringRef Spec : split(LayoutString, '-')) {
618621
if (Spec.empty())
619622
return createStringError("empty specification is not allowed");
620-
if (Error Err = parseSpecification(Spec))
623+
if (Error Err = parseSpecification(Spec, NonIntegralAddressSpaces))
621624
return Err;
622625
}
626+
// Mark all address spaces that were qualified as non-integral now. This has
627+
// to be done later since the non-integral property is not part of the data
628+
// layout pointer specification.
629+
for (unsigned AS : NonIntegralAddressSpaces) {
630+
// If there is no special spec for a given AS, getPointerSpec(AS) returns
631+
// the spec for AS0, and we then update that to mark it non-integral.
632+
const PointerSpec &PS = getPointerSpec(AS);
633+
setPointerSpec(AS, PS.BitWidth, PS.ABIAlign, PS.PrefAlign, PS.IndexBitWidth,
634+
true);
635+
}
623636

624637
return Error::success();
625638
}
@@ -666,16 +679,17 @@ DataLayout::getPointerSpec(uint32_t AddrSpace) const {
666679

667680
void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth,
668681
Align ABIAlign, Align PrefAlign,
669-
uint32_t IndexBitWidth) {
682+
uint32_t IndexBitWidth, bool IsNonIntegral) {
670683
auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
671684
if (I == PointerSpecs.end() || I->AddrSpace != AddrSpace) {
672685
PointerSpecs.insert(I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign,
673-
IndexBitWidth});
686+
IndexBitWidth, IsNonIntegral});
674687
} else {
675688
I->BitWidth = BitWidth;
676689
I->ABIAlign = ABIAlign;
677690
I->PrefAlign = PrefAlign;
678691
I->IndexBitWidth = IndexBitWidth;
692+
I->IsNonIntegral = IsNonIntegral;
679693
}
680694
}
681695

0 commit comments

Comments
 (0)