forked from OSchip/llvm-project
[Alignment][NFC] Allow constexpr Align
Summary: This is patch is part of a series to introduce an Alignment type. See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html See this patch for the introduction of the type: https://reviews.llvm.org/D64790 Reviewers: courbet Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68329 llvm-svn: 373580
This commit is contained in:
parent
abc35f1bd8
commit
b3af236fb5
|
@ -58,10 +58,10 @@ public:
|
|||
constexpr Align() = default;
|
||||
/// Do not perform checks in case of copy/move construct/assign, because the
|
||||
/// checks have been performed when building `Other`.
|
||||
Align(const Align &Other) = default;
|
||||
Align &operator=(const Align &Other) = default;
|
||||
Align(Align &&Other) = default;
|
||||
Align &operator=(Align &&Other) = default;
|
||||
constexpr Align(const Align &Other) = default;
|
||||
constexpr Align &operator=(const Align &Other) = default;
|
||||
constexpr Align(Align &&Other) = default;
|
||||
constexpr Align &operator=(Align &&Other) = default;
|
||||
|
||||
explicit Align(uint64_t Value) {
|
||||
assert(Value > 0 && "Value must not be 0");
|
||||
|
@ -80,6 +80,24 @@ public:
|
|||
/// would be better than
|
||||
/// `if (A > Align(1))`
|
||||
constexpr static const Align None() { return Align(); }
|
||||
|
||||
/// This function is useful when initializing constexpr Align constants.
|
||||
/// e.g. static constexpr Align kAlign16 = Align::Constant<16>();
|
||||
/// Most compilers (clang, gcc, icc) will be able to compute `ShiftValue`
|
||||
/// at compile time with `Align::Align(uint64_t Value)` but to be
|
||||
/// able to use Align as a constexpr constant use this method.
|
||||
/// FIXME: When LLVM is C++17 ready `Align::Align(uint64_t Value)`
|
||||
/// can be constexpr and we can dispatch between runtime (Log2_64) vs
|
||||
/// compile time (CTLog2) versions using constexpr-if. Then this
|
||||
/// function is no more necessary and we can add user defined literals
|
||||
/// for convenience.
|
||||
template <uint64_t kValue> constexpr static Align Constant() {
|
||||
static_assert(kValue > 0 && llvm::isPowerOf2_64(kValue),
|
||||
"Not a valid alignment");
|
||||
Align A;
|
||||
A.ShiftValue = CTLog2<kValue>();
|
||||
return A;
|
||||
}
|
||||
};
|
||||
|
||||
/// Treats the value 0 as a 1, so Align is always at least 1.
|
||||
|
|
|
@ -532,6 +532,15 @@ inline double Log2(double Value) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/// Return the compile time log base 2 of the specified Value.
|
||||
/// `kValue` has to be a power of two.
|
||||
template <uint64_t kValue> static constexpr inline uint8_t CTLog2() {
|
||||
static_assert(kValue > 0 && llvm::isPowerOf2_64(kValue),
|
||||
"Value is not a valid power of 2");
|
||||
return 1 + CTLog2<kValue / 2>();
|
||||
}
|
||||
template <> constexpr inline uint8_t CTLog2<1>() { return 0; }
|
||||
|
||||
/// Return the floor log base 2 of the specified value, -1 if the value is zero.
|
||||
/// (32 bit edition.)
|
||||
/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
|
||||
|
|
|
@ -62,7 +62,7 @@ static cl::opt<bool> ClMergeInit(
|
|||
static cl::opt<unsigned> ClScanLimit("stack-tagging-merge-init-scan-limit",
|
||||
cl::init(40), cl::Hidden);
|
||||
|
||||
static const Align kTagGranuleSize = Align(16);
|
||||
static constexpr Align kTagGranuleSize = Align::Constant<16>();
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
|
@ -44,6 +44,16 @@ TEST(AlignmentTest, ValidCTors) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(AlignmentTest, CompileTimeConstant) {
|
||||
EXPECT_EQ(Align::Constant<1>(), Align(1));
|
||||
EXPECT_EQ(Align::Constant<2>(), Align(2));
|
||||
EXPECT_EQ(Align::Constant<4>(), Align(4));
|
||||
EXPECT_EQ(Align::Constant<8>(), Align(8));
|
||||
EXPECT_EQ(Align::Constant<16>(), Align(16));
|
||||
EXPECT_EQ(Align::Constant<32>(), Align(32));
|
||||
EXPECT_EQ(Align::Constant<64>(), Align(64));
|
||||
}
|
||||
|
||||
TEST(AlignmentTest, CheckMaybeAlignHasValue) {
|
||||
EXPECT_TRUE(MaybeAlign(1));
|
||||
EXPECT_TRUE(MaybeAlign(1).hasValue());
|
||||
|
|
|
@ -203,6 +203,25 @@ TEST(MathExtras, PowerOf2Floor) {
|
|||
EXPECT_EQ(4U, PowerOf2Floor(7U));
|
||||
}
|
||||
|
||||
TEST(MathExtras, CTLog2) {
|
||||
EXPECT_EQ(CTLog2<1ULL << 0>(), 0);
|
||||
EXPECT_EQ(CTLog2<1ULL << 1>(), 1);
|
||||
EXPECT_EQ(CTLog2<1ULL << 2>(), 2);
|
||||
EXPECT_EQ(CTLog2<1ULL << 3>(), 3);
|
||||
EXPECT_EQ(CTLog2<1ULL << 4>(), 4);
|
||||
EXPECT_EQ(CTLog2<1ULL << 5>(), 5);
|
||||
EXPECT_EQ(CTLog2<1ULL << 6>(), 6);
|
||||
EXPECT_EQ(CTLog2<1ULL << 7>(), 7);
|
||||
EXPECT_EQ(CTLog2<1ULL << 8>(), 8);
|
||||
EXPECT_EQ(CTLog2<1ULL << 9>(), 9);
|
||||
EXPECT_EQ(CTLog2<1ULL << 10>(), 10);
|
||||
EXPECT_EQ(CTLog2<1ULL << 11>(), 11);
|
||||
EXPECT_EQ(CTLog2<1ULL << 12>(), 12);
|
||||
EXPECT_EQ(CTLog2<1ULL << 13>(), 13);
|
||||
EXPECT_EQ(CTLog2<1ULL << 14>(), 14);
|
||||
EXPECT_EQ(CTLog2<1ULL << 15>(), 15);
|
||||
}
|
||||
|
||||
TEST(MathExtras, ByteSwap_32) {
|
||||
EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344));
|
||||
EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD));
|
||||
|
|
Loading…
Reference in New Issue