1//===-- llvm/Support/Alignment.h - Useful alignment functions ---*- C++ -*-===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file contains types to represent alignments. 10// They are instrumented to guarantee some invariants are preserved and prevent 11// invalid manipulations. 13// - Align represents an alignment in bytes, it is always set and always a valid 14// power of two, its minimum value is 1 which means no alignment requirements. 16// - MaybeAlign is an optional type, it may be undefined or set. When it's set 17// you can get the underlying Align type by using the value() method. 19//===----------------------------------------------------------------------===// 21#ifndef LLVM_SUPPORT_ALIGNMENT_H_ 22#define LLVM_SUPPORT_ALIGNMENT_H_ 33#define ALIGN_CHECK_ISPOSITIVE(decl) \ 34 assert(decl > 0 && (#decl " should be defined"))
36/// This struct is a compact representation of a valid (non-zero power of two) 38/// It is suitable for use as static global constants. 41uint8_t ShiftValue = 0;
/// The log2 of the required alignment. 42 /// ShiftValue is less than 64 by construction. 55 /// A trivial type to allow construction of constexpr Align. 56 /// This is currently needed to workaround a bug in GCC 5.3 which prevents 57 /// definition of constexpr assign operators. 58 /// https://stackoverflow.com/questions/46756288/explicitly-defaulted-function-cannot-be-declared-as-constexpr-because-the-implic 59 /// FIXME: Remove this, make all assign operators constexpr and introduce user 60 /// defined literals when we don't have to support GCC 5.3 anymore. 61 /// https://llvm.org/docs/GettingStarted.html#getting-a-modern-host-c-toolchain 67 /// Default is byte-aligned. 69 /// Do not perform checks in case of copy/move construct/assign, because the 70 /// checks have been performed when building `Other`. 80assert(ShiftValue < 64 &&
"Broken invariant");
83 /// This is a hole in the type system and should not be abused. 84 /// Needed to interact with C for instance. 87// Returns the previous alignment. 89assert(ShiftValue != 0 &&
"Undefined operation");
91 Out.ShiftValue = ShiftValue - 1;
95 /// Allow constructions of constexpr Align. 97return LogValue{
static_cast<uint8_t>(CTLog2<kValue>())};
100 /// Allow constructions of constexpr Align from types. 101 /// Compile time equivalent to Align(alignof(T)). 102template <
typename T>
constexprstaticAlignOf() {
106 /// Constexpr constructor from LogValue type. 107constexprAlign(LogValue CA) : ShiftValue(CA.Log) {}
110/// Treats the value 0 as a 1, so Align is always at least 1. 115/// This struct is a compact representation of a valid (power of two) or 116/// undefined (0) alignment. 119usingUP = std::optional<Align>;
122 /// Default is undefined. 124 /// Do not perform checks in case of copy/move construct/assign, because the 125 /// checks have been performed when building `Other`. 135"Alignment is neither 0 nor a power of 2");
140 /// For convenience, returns a valid alignment or 1 if undefined. 144/// Checks that SizeInBytes is a multiple of the alignment. 146return SizeInBytes % Lhs.
value() == 0;
149/// Checks that Addr is a multiple of the alignment. 154/// Returns a multiple of A needed to store `Size` bytes. 157// The following line is equivalent to `(Size + Value - 1) / Value * Value`. 159// The division followed by a multiplication can be thought of as a right 160// shift followed by a left shift which zeros out the extra bits produced in 161// the bump; `~(Value - 1)` is a mask where all those bits being zeroed out 164// Most compilers can generate this code but the pattern may be missed when 165// multiple functions gets inlined. 169/// If non-zero \p Skew is specified, the return value will be a minimal integer 170/// that is greater than or equal to \p Size and equal to \p A * N + \p Skew for 171/// some integer N. If \p Skew is larger than \p A, its value is adjusted to '\p 176/// alignTo(5, Align(8), 7) = 7 177/// alignTo(17, Align(8), 1) = 17 178/// alignTo(~0LL, Align(8), 3) = 3 186/// Aligns `Addr` to `Alignment` bytes, rounding up. 188 uintptr_t ArithAddr =
reinterpret_cast<uintptr_t
>(
Addr);
189assert(
static_cast<uintptr_t
>(ArithAddr + Alignment.
value() - 1) >=
192returnalignTo(ArithAddr, Alignment);
195/// Returns the offset to the next integer (mod 2**64) that is greater than 196/// or equal to \p Value and is a multiple of \p Align. 201/// Returns the necessary adjustment for aligning `Addr` to `Alignment` 202/// bytes, rounding up. 207/// Returns the log2 of the alignment. 210/// Returns the alignment that satisfies both alignments. 211/// Same semantic as MinAlign. 216/// Returns a representation of the alignment that encodes undefined as 0. 219/// Dual operation of the encode function above. 224 Out.ShiftValue =
Value - 1;
228/// Returns a representation of the alignment, the encoded value is positive by 232/// Comparisons between Align and scalars. Rhs must be positive. 235return Lhs.
value() == Rhs;
239return Lhs.
value() != Rhs;
243return Lhs.
value() <= Rhs;
247return Lhs.
value() >= Rhs;
251return Lhs.
value() < Rhs;
255return Lhs.
value() > Rhs;
258/// Comparisons operators between Align. 260return Lhs.ShiftValue == Rhs.ShiftValue;
263return Lhs.ShiftValue != Rhs.ShiftValue;
266return Lhs.ShiftValue <= Rhs.ShiftValue;
269return Lhs.ShiftValue >= Rhs.ShiftValue;
272return Lhs.ShiftValue < Rhs.ShiftValue;
275return Lhs.ShiftValue > Rhs.ShiftValue;
278// Don't allow relational comparisons with MaybeAlign. 294// Allow equality comparisons between Align and MaybeAlign. 299// Allow equality comparisons with MaybeAlign. 301return (Lhs && Rhs && (*Lhs == *Rhs)) || (!Lhs && !Rhs);
304// Allow equality comparisons with std::nullopt. 311// For usage in LLVM_DEBUG macros. 313return std::to_string(
A.value());
315// For usage in LLVM_DEBUG macros. 318return std::to_string(MA->value());
323#undef ALIGN_CHECK_ISPOSITIVE 327#endif// LLVM_SUPPORT_ALIGNMENT_H_ #define ALIGN_CHECK_ISPOSITIVE(decl)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static TripleVec::iterator emplace(TripleVec &Container, Triple &&T)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This is an important base class in LLVM.
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool operator!=(uint64_t V1, const APInt &V2)
bool operator>=(int64_t V1, const APSInt &V2)
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
bool operator>(int64_t V1, const APSInt &V2)
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
MaybeAlign decodeMaybeAlign(unsigned Value)
Dual operation of the encode function above.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
unsigned Log2(Align A)
Returns the log2 of the alignment.
bool operator<=(int64_t V1, const APSInt &V2)
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
This struct is a compact representation of a valid (non-zero power of two) alignment.
friend unsigned encode(struct MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
friend bool operator>=(Align Lhs, Align Rhs)
constexpr Align(LogValue CA)
Constexpr constructor from LogValue type.
static constexpr Align Of()
Allow constructions of constexpr Align from types.
friend struct MaybeAlign decodeMaybeAlign(unsigned Value)
Dual operation of the encode function above.
Align & operator=(Align &&Other)=default
uint64_t value() const
This is a hole in the type system and should not be abused.
constexpr Align(Align &&Other)=default
friend bool operator<(Align Lhs, Align Rhs)
static constexpr Align Constant()
Allow constructions of constexpr Align.
Align & operator=(const Align &Other)=default
friend bool operator==(Align Lhs, Align Rhs)
Comparisons operators between Align.
friend bool operator<=(Align Lhs, Align Rhs)
constexpr Align()=default
Default is byte-aligned.
friend bool operator!=(Align Lhs, Align Rhs)
friend unsigned Log2(Align)
Returns the log2 of the alignment.
constexpr Align(const Align &Other)=default
Do not perform checks in case of copy/move construct/assign, because the checks have been performed w...
friend bool operator>(Align Lhs, Align Rhs)
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
MaybeAlign(MaybeAlign &&Other)=default
constexpr MaybeAlign(Align Value)
constexpr MaybeAlign(std::nullopt_t None)
MaybeAlign(const MaybeAlign &Other)=default
Do not perform checks in case of copy/move construct/assign, because the checks have been performed w...
MaybeAlign(uint64_t Value)
MaybeAlign()=default
Default is undefined.
MaybeAlign & operator=(MaybeAlign &&Other)=default
MaybeAlign & operator=(const MaybeAlign &Other)=default