Skip to content

Commit 110540d

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
1 parent 17f0aaa commit 110540d

File tree

3 files changed

+64
-16
lines changed

3 files changed

+64
-16
lines changed

llvm/docs/LangRef.rst

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,16 +3134,25 @@ as follows:
31343134
``A<address space>``
31353135
Specifies the address space of objects created by '``alloca``'.
31363136
Defaults to the default address space of 0.
3137-
``p[n]:<size>:<abi>[:<pref>][:<idx>]``
3137+
``p[n]:<size>:<abi>[:<pref>][:<idx>][:<addr>]``
31383138
This specifies the *size* of a pointer and its ``<abi>`` and
31393139
``<pref>``\erred alignments for address space ``n``. ``<pref>`` is optional
3140-
and defaults to ``<abi>``. The fourth parameter ``<idx>`` is the size of the
3141-
index that used for address calculation, which must be less than or equal
3142-
to the pointer size. If not
3143-
specified, the default index size is equal to the pointer size. All sizes
3144-
are in bits. The address space, ``n``, is optional, and if not specified,
3140+
and defaults to ``<abi>``.
3141+
The fourth parameter ``<idx>`` is the size of the index that used for
3142+
address calculations such as :ref:`getelementptr <i_getelementptr>`.
3143+
It must be less than or equal to the pointer size. If not specified, the
3144+
default index size is equal to the pointer size.
3145+
The fifth parameter ``<addr>`` specifies the width of addresses in this
3146+
address space. If not specified, the default address size is equal to the
3147+
index size. The address size may be wider than either the index or pointer
3148+
size as it could be a value relative to a base address. For example AMDGPU
3149+
buffer fat pointers use a 48-bit address range, but only allow for 32 bits
3150+
of indexing.
3151+
All sizes are in bits.
3152+
The address space, ``n``, is optional, and if not specified,
31453153
denotes the default address space 0. The value of ``n`` must be
31463154
in the range [1,2^24).
3155+
31473156
``i<size>:<abi>[:<pref>]``
31483157
This specifies the alignment for an integer type of a given bit
31493158
``<size>``. The value of ``<size>`` must be in the range [1,2^24).
@@ -12996,9 +13005,9 @@ This instruction requires several arguments:
1299613005
- Caller and callee both have the calling convention ``fastcc`` or ``tailcc``.
1299713006
- The call is in tail position (ret immediately follows call and ret
1299813007
uses value of call or is void).
12999-
- Option ``-tailcallopt`` is enabled, ``llvm::GuaranteedTailCallOpt`` is
13008+
- Option ``-tailcallopt`` is enabled, ``llvm::GuaranteedTailCallOpt`` is
1300013009
``true``, or the calling convention is ``tailcc``.
13001-
- `Platform-specific constraints are met.
13010+
- `Platform-specific constraints are met.
1300213011
<CodeGenerator.html#tail-call-optimization>`_
1300313012

1300413013
#. The optional ``notail`` marker indicates that the optimizers should not add

llvm/include/llvm/IR/DataLayout.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class DataLayout {
7878
Align ABIAlign;
7979
Align PrefAlign;
8080
uint32_t IndexBitWidth;
81+
uint32_t AddressBitWidth;
8182
/// Pointers in this address space don't have a well-defined bitwise
8283
/// representation (e.g. may be relocated by a copying garbage collector).
8384
/// Additionally, they may also be non-integral (i.e. containing additional
@@ -148,7 +149,7 @@ class DataLayout {
148149
/// Sets or updates the specification for pointer in the given address space.
149150
void setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign,
150151
Align PrefAlign, uint32_t IndexBitWidth,
151-
bool IsNonIntegral);
152+
uint32_t AddressBitWidth, bool IsNonIntegral);
152153

153154
/// Internal helper to get alignment for integer of given bitwidth.
154155
Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
@@ -324,12 +325,26 @@ class DataLayout {
324325
/// the backends/clients are updated.
325326
Align getPointerPrefAlignment(unsigned AS = 0) const;
326327

327-
/// Layout pointer size in bytes, rounded up to a whole
328-
/// number of bytes.
328+
/// Layout pointer size in bytes, rounded up to a whole number of bytes. The
329+
/// difference between this function and getPointerAddressSize() is this one
330+
/// returns the size of the entire pointer type (this includes metadata bits
331+
/// for fat pointers) and the latter only returns the number of address bits.
332+
/// \sa DataLayout::getPointerAddressSizeInBits
329333
/// FIXME: The defaults need to be removed once all of
330334
/// the backends/clients are updated.
331335
unsigned getPointerSize(unsigned AS = 0) const;
332336

337+
/// Returns the integral size of a pointer in a given address space in bytes.
338+
/// For targets that store bits in pointers that are not part of the address,
339+
/// this returns the number of bits that can be manipulated using operations
340+
/// that change the address (e.g. addition/subtraction).
341+
/// For example, a 64-bit CHERI-enabled target has 128-bit pointers of which
342+
/// only 64 are used to represent the address and the remaining ones are used
343+
/// for metadata such as bounds and access permissions. In this case
344+
/// getPointerSize() returns 16, but getPointerAddressSize() returns 8.
345+
/// \sa DataLayout::getPointerSize
346+
unsigned getPointerAddressSize(unsigned AS) const;
347+
333348
// Index size in bytes used for address calculation,
334349
/// rounded up to a whole number of bytes.
335350
unsigned getIndexSize(unsigned AS) const;
@@ -365,6 +380,14 @@ class DataLayout {
365380
return getPointerSpec(AS).BitWidth;
366381
}
367382

383+
unsigned getPointerAddressSizeInBits(unsigned AS) const {
384+
// Currently, this returns the same value as getIndexSizeInBits() as this
385+
// is correct for all currently known LLVM targets. If another target is
386+
// added that has pointer size != pointer range != GEP index width, we can
387+
// add a new datalayout field for pointer integral range.
388+
return getPointerSpec(AS).AddressBitWidth;
389+
}
390+
368391
/// Size in bits of index used for address calculation in getelementptr.
369392
unsigned getIndexSizeInBits(unsigned AS) const {
370393
return getPointerSpec(AS).IndexBitWidth;

llvm/lib/IR/DataLayout.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = {
208208
// Default pointer type specifications.
209209
constexpr DataLayout::PointerSpec DefaultPointerSpecs[] = {
210210
// p0:64:64:64:64
211-
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false},
211+
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, 64, false},
212212
};
213213

214214
DataLayout::DataLayout()
@@ -454,8 +454,17 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
454454
return createStringError(
455455
"index size cannot be larger than the pointer size");
456456

457+
unsigned AddressBitWidth = BitWidth;
458+
if (Components.size() > 4)
459+
if (Error Err = parseSize(Components[4], AddressBitWidth, "address size"))
460+
return Err;
461+
462+
if (AddressBitWidth > BitWidth)
463+
return createStringError(
464+
"address size cannot be larger than the pointer size");
465+
457466
setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth,
458-
false);
467+
AddressBitWidth, false);
459468
return Error::success();
460469
}
461470

@@ -631,7 +640,7 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) {
631640
// the spec for AS0, and we then update that to mark it non-integral.
632641
const PointerSpec &PS = getPointerSpec(AS);
633642
setPointerSpec(AS, PS.BitWidth, PS.ABIAlign, PS.PrefAlign, PS.IndexBitWidth,
634-
true);
643+
PS.AddressBitWidth, true);
635644
}
636645

637646
return Error::success();
@@ -679,16 +688,19 @@ DataLayout::getPointerSpec(uint32_t AddrSpace) const {
679688

680689
void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth,
681690
Align ABIAlign, Align PrefAlign,
682-
uint32_t IndexBitWidth, bool IsNonIntegral) {
691+
uint32_t IndexBitWidth,
692+
uint32_t AddressBitWidth, bool IsNonIntegral) {
683693
auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
684694
if (I == PointerSpecs.end() || I->AddrSpace != AddrSpace) {
685695
PointerSpecs.insert(I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign,
686-
IndexBitWidth, IsNonIntegral});
696+
IndexBitWidth, AddressBitWidth,
697+
IsNonIntegral});
687698
} else {
688699
I->BitWidth = BitWidth;
689700
I->ABIAlign = ABIAlign;
690701
I->PrefAlign = PrefAlign;
691702
I->IndexBitWidth = IndexBitWidth;
703+
I->AddressBitWidth = AddressBitWidth;
692704
I->IsNonIntegral = IsNonIntegral;
693705
}
694706
}
@@ -728,6 +740,10 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
728740
return L;
729741
}
730742

743+
unsigned DataLayout::getPointerAddressSize(unsigned AS) const {
744+
return divideCeil(getPointerAddressSizeInBits(AS), 8);
745+
}
746+
731747
Align DataLayout::getPointerABIAlignment(unsigned AS) const {
732748
return getPointerSpec(AS).ABIAlign;
733749
}

0 commit comments

Comments
 (0)