[clang] [clang][bytecode][NFC] Switch BitcastBuffer to SmallVector (PR #114677)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 2 09:18:25 PDT 2024
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/114677
>From 9583cf5edac75e25c47f7ad2cb52a3b3bb95442b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sat, 2 Nov 2024 16:59:41 +0100
Subject: [PATCH] [clang][bytecode][NFC] Switch BitcastBuffer to SmallVector
This is a little easier to work with since we are guaranteed that the
item type of the vector is byte sized and not something else.
---
.../lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 43 +++++++++----------
clang/test/AST/ByteCode/builtin-bit-cast.cpp | 11 +++++
2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
index fde2c6d9b11ac8..1acd49de307b96 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
@@ -83,39 +83,33 @@ static void swapBytes(std::byte *M, size_t N) {
/// have indeterminate value.
/// All offsets are in bits.
struct BitcastBuffer {
- llvm::BitVector Data;
+ size_t SizeInBits = 0;
+ llvm::SmallVector<std::byte> Data;
BitcastBuffer() = default;
- size_t size() const { return Data.size(); }
+ size_t size() const { return SizeInBits; }
- const std::byte *data() const {
- unsigned NBytes = Data.size() / 8;
- unsigned BitVectorWordSize = sizeof(uintptr_t);
- bool FullWord = (NBytes % BitVectorWordSize == 0);
-
- // llvm::BitVector uses 64-bit fields internally, so when we have
- // fewer bytes than that, we need to compensate for that on
- // big endian hosts.
- unsigned DataPlus;
- if (llvm::sys::IsBigEndianHost)
- DataPlus = BitVectorWordSize - (NBytes % BitVectorWordSize);
- else
- DataPlus = 0;
-
- return reinterpret_cast<const std::byte *>(Data.getData().data()) +
- (FullWord ? 0 : DataPlus);
- }
+ const std::byte *data() const { return Data.data(); }
bool allInitialized() const {
// FIXME: Implement.
return true;
}
+ bool atByteBoundary() const { return (Data.size() * 8) == SizeInBits; }
+
+ void pushBit(bool Value) {
+ if (atByteBoundary())
+ Data.push_back(std::byte{0});
+
+ if (Value)
+ Data.back() |= (std::byte{1} << (SizeInBits % 8));
+ ++SizeInBits;
+ }
+
void pushData(const std::byte *data, size_t BitOffset, size_t BitWidth,
bool BigEndianTarget) {
- Data.reserve(BitOffset + BitWidth);
-
bool OnlyFullBytes = BitWidth % 8 == 0;
unsigned NBytes = BitWidth / 8;
@@ -125,7 +119,7 @@ struct BitcastBuffer {
std::byte B =
BigEndianTarget ? data[NBytes - OnlyFullBytes - I] : data[I];
for (unsigned X = 0; X != 8; ++X) {
- Data.push_back(bitof(B, X));
+ pushBit(bitof(B, X));
++BitsHandled;
}
}
@@ -137,7 +131,7 @@ struct BitcastBuffer {
assert((BitWidth - BitsHandled) < 8);
std::byte B = BigEndianTarget ? data[0] : data[NBytes];
for (size_t I = 0, E = (BitWidth - BitsHandled); I != E; ++I) {
- Data.push_back(bitof(B, I));
+ pushBit(bitof(B, I));
++BitsHandled;
}
@@ -363,5 +357,8 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
HasIndeterminateBits = !Buffer.allInitialized();
std::memcpy(Buff, Buffer.data(), BuffSize);
+ if (llvm::sys::IsBigEndianHost)
+ swapBytes(Buff, BuffSize);
+
return Success;
}
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index 0e86da9133b33d..c5380647c94aee 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -74,6 +74,17 @@ constexpr bool operator==(const struct bits<N, T, P>& lhs, const struct bits<N,
#ifdef __SIZEOF_INT128__
static_assert(check_round_trip<__int128_t>((__int128_t)34));
static_assert(check_round_trip<__int128_t>((__int128_t)-34));
+
+constexpr unsigned char OneBit[] = {
+ 0x1, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+};
+constexpr __int128_t One = 1;
+constexpr __int128_t Expected = One << 120;
+static_assert(__builtin_bit_cast(__int128_t, OneBit) == (LITTLE_END ? 1 : Expected));
+
#endif
More information about the cfe-commits
mailing list