summaryrefslogtreecommitdiff
path: root/llvm/include/llvm/Support/Alignment.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/Support/Alignment.h')
-rw-r--r--llvm/include/llvm/Support/Alignment.h166
1 files changed, 69 insertions, 97 deletions
diff --git a/llvm/include/llvm/Support/Alignment.h b/llvm/include/llvm/Support/Alignment.h
index 72fad87dd0d4d..667434e8a407f 100644
--- a/llvm/include/llvm/Support/Alignment.h
+++ b/llvm/include/llvm/Support/Alignment.h
@@ -22,17 +22,16 @@
#define LLVM_SUPPORT_ALIGNMENT_H_
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
-#include <limits>
+#ifndef NDEBUG
+#include <string>
+#endif // NDEBUG
namespace llvm {
#define ALIGN_CHECK_ISPOSITIVE(decl) \
assert(decl > 0 && (#decl " should be defined"))
-#define ALIGN_CHECK_ISSET(decl) \
- assert(decl.hasValue() && (#decl " should be defined"))
/// This struct is a compact representation of a valid (non-zero power of two)
/// alignment.
@@ -86,11 +85,14 @@ public:
uint64_t value() const { return uint64_t(1) << ShiftValue; }
/// Returns a default constructed Align which corresponds to no alignment.
- /// This is useful to test for unalignment as it conveys clear semantic.
- /// `if (A != Align::None())`
- /// would be better than
- /// `if (A > Align(1))`
- constexpr static const Align None() { return Align(); }
+ /// It was decided to deprecate Align::None because it's too close to
+ /// llvm::None which can be used to initialize `MaybeAlign`.
+ /// MaybeAlign = llvm::None means unspecified alignment,
+ /// Align = Align::None() means alignment of one byte.
+ LLVM_ATTRIBUTE_DEPRECATED(constexpr static const Align None(),
+ "Use Align() or Align(1) instead") {
+ return Align();
+ }
/// Allow constructions of constexpr Align.
template <size_t kValue> constexpr static LogValue Constant() {
@@ -147,13 +149,6 @@ inline bool isAligned(Align Lhs, uint64_t SizeInBytes) {
return SizeInBytes % Lhs.value() == 0;
}
-/// Checks that SizeInBytes is a multiple of the alignment.
-/// Returns false if the alignment is undefined.
-inline bool isAligned(MaybeAlign Lhs, uint64_t SizeInBytes) {
- ALIGN_CHECK_ISSET(Lhs);
- return SizeInBytes % (*Lhs).value() == 0;
-}
-
/// Checks that Addr is a multiple of the alignment.
inline bool isAddrAligned(Align Lhs, const void *Addr) {
return isAligned(Lhs, reinterpret_cast<uintptr_t>(Addr));
@@ -161,17 +156,34 @@ inline bool isAddrAligned(Align Lhs, const void *Addr) {
/// Returns a multiple of A needed to store `Size` bytes.
inline uint64_t alignTo(uint64_t Size, Align A) {
- const uint64_t value = A.value();
- // The following line is equivalent to `(Size + value - 1) / value * value`.
+ const uint64_t Value = A.value();
+ // The following line is equivalent to `(Size + Value - 1) / Value * Value`.
// The division followed by a multiplication can be thought of as a right
// shift followed by a left shift which zeros out the extra bits produced in
- // the bump; `~(value - 1)` is a mask where all those bits being zeroed out
+ // the bump; `~(Value - 1)` is a mask where all those bits being zeroed out
// are just zero.
// Most compilers can generate this code but the pattern may be missed when
// multiple functions gets inlined.
- return (Size + value - 1) & ~(value - 1);
+ return (Size + Value - 1) & ~(Value - 1U);
+}
+
+/// If non-zero \p Skew is specified, the return value will be a minimal integer
+/// that is greater than or equal to \p Size and equal to \p A * N + \p Skew for
+/// some integer N. If \p Skew is larger than \p A, its value is adjusted to '\p
+/// Skew mod \p A'.
+///
+/// Examples:
+/// \code
+/// alignTo(5, Align(8), 7) = 7
+/// alignTo(17, Align(8), 1) = 17
+/// alignTo(~0LL, Align(8), 3) = 3
+/// \endcode
+inline uint64_t alignTo(uint64_t Size, Align A, uint64_t Skew) {
+ const uint64_t Value = A.value();
+ Skew %= Value;
+ return ((Size + Value - 1 - Skew) & ~(Value - 1U)) + Skew;
}
/// Returns a multiple of A needed to store `Size` bytes.
@@ -184,7 +196,8 @@ inline uint64_t alignTo(uint64_t Size, MaybeAlign A) {
inline uintptr_t alignAddr(const void *Addr, Align Alignment) {
uintptr_t ArithAddr = reinterpret_cast<uintptr_t>(Addr);
assert(static_cast<uintptr_t>(ArithAddr + Alignment.value() - 1) >=
- ArithAddr && "Overflow");
+ ArithAddr &&
+ "Overflow");
return alignTo(ArithAddr, Alignment);
}
@@ -203,13 +216,6 @@ inline uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment) {
/// Returns the log2 of the alignment.
inline unsigned Log2(Align A) { return A.ShiftValue; }
-/// Returns the log2 of the alignment.
-/// \pre A must be defined.
-inline unsigned Log2(MaybeAlign A) {
- ALIGN_CHECK_ISSET(A);
- return Log2(A.getValue());
-}
-
/// Returns the alignment that satisfies both alignments.
/// Same semantic as MinAlign.
inline Align commonAlignment(Align A, Align B) { return std::min(A, B); }
@@ -281,26 +287,6 @@ inline bool operator==(MaybeAlign Lhs, uint64_t Rhs) {
inline bool operator!=(MaybeAlign Lhs, uint64_t Rhs) {
return Lhs ? (*Lhs).value() != Rhs : Rhs != 0;
}
-inline bool operator<=(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() <= Rhs;
-}
-inline bool operator>=(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() >= Rhs;
-}
-inline bool operator<(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() < Rhs;
-}
-inline bool operator>(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() > Rhs;
-}
/// Comparisons operators between Align.
inline bool operator==(Align Lhs, Align Rhs) {
@@ -322,56 +308,30 @@ inline bool operator>(Align Lhs, Align Rhs) {
return Lhs.ShiftValue > Rhs.ShiftValue;
}
-/// Comparisons operators between Align and MaybeAlign.
-inline bool operator==(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() == (*Rhs).value();
-}
-inline bool operator!=(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() != (*Rhs).value();
-}
-inline bool operator<=(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() <= (*Rhs).value();
-}
-inline bool operator>=(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() >= (*Rhs).value();
-}
-inline bool operator<(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() < (*Rhs).value();
-}
-inline bool operator>(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() > (*Rhs).value();
-}
+// Don't allow relational comparisons with MaybeAlign.
+bool operator<=(Align Lhs, MaybeAlign Rhs) = delete;
+bool operator>=(Align Lhs, MaybeAlign Rhs) = delete;
+bool operator<(Align Lhs, MaybeAlign Rhs) = delete;
+bool operator>(Align Lhs, MaybeAlign Rhs) = delete;
-/// Comparisons operators between MaybeAlign and Align.
-inline bool operator==(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() == Rhs.value();
-}
-inline bool operator!=(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() != Rhs.value();
-}
-inline bool operator<=(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() <= Rhs.value();
-}
-inline bool operator>=(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() >= Rhs.value();
-}
-inline bool operator<(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() < Rhs.value();
+bool operator<=(MaybeAlign Lhs, Align Rhs) = delete;
+bool operator>=(MaybeAlign Lhs, Align Rhs) = delete;
+bool operator<(MaybeAlign Lhs, Align Rhs) = delete;
+bool operator>(MaybeAlign Lhs, Align Rhs) = delete;
+
+bool operator<=(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+bool operator>=(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+bool operator<(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+bool operator>(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+
+inline Align operator*(Align Lhs, uint64_t Rhs) {
+ assert(Rhs > 0 && "Rhs must be positive");
+ return Align(Lhs.value() * Rhs);
}
-inline bool operator>(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() > Rhs.value();
+
+inline MaybeAlign operator*(MaybeAlign Lhs, uint64_t Rhs) {
+ assert(Rhs > 0 && "Rhs must be positive");
+ return Lhs ? Lhs.getValue() * Rhs : MaybeAlign();
}
inline Align operator/(Align Lhs, uint64_t Divisor) {
@@ -395,8 +355,20 @@ inline Align max(Align Lhs, MaybeAlign Rhs) {
return Rhs && *Rhs > Lhs ? *Rhs : Lhs;
}
+#ifndef NDEBUG
+// For usage in LLVM_DEBUG macros.
+inline std::string DebugStr(const Align &A) {
+ return std::to_string(A.value());
+}
+// For usage in LLVM_DEBUG macros.
+inline std::string DebugStr(const MaybeAlign &MA) {
+ if (MA)
+ return std::to_string(MA->value());
+ return "None";
+}
+#endif // NDEBUG
+
#undef ALIGN_CHECK_ISPOSITIVE
-#undef ALIGN_CHECK_ISSET
} // namespace llvm