[clang] Remove type-punning in LazyOffsetPtr. (PR #112806)
Jessica Clarke via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 18 05:56:13 PDT 2024
================
@@ -321,50 +322,87 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// external AST source itself.
template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
struct LazyOffsetPtr {
- /// Either a pointer to an AST node or the offset within the
- /// external AST source where the AST node can be found.
- ///
- /// If the low bit is clear, a pointer to the AST node. If the low
- /// bit is set, the upper 63 bits are the offset.
- mutable uint64_t Ptr = 0;
+ /// Storage for a pointer or an offset, for the case where pointers are 64
+ /// bits wide. The least-significant bit is used as the discriminator. If the
+ /// bit is clear, a pointer to the AST node. If the bit is set, the upper 63
+ /// bits are the offset.
+ union StorageType64 {
+ StorageType64(uint64_t Offset) : ShiftedOffset((Offset << 1) | 1) {
+ assert(isOffset());
+ }
+ StorageType64(T *Ptr) : Pointer(Ptr) { assert(!isOffset()); }
+
+ bool isOffset() { return llvm::bit_cast<uint64_t>(*this) & 1; }
+ uint64_t offset() { return ShiftedOffset >> 1; }
+ T *&pointer() { return Pointer; }
+
+ uint64_t ShiftedOffset;
+ T *Pointer;
+ };
+
+ /// Storage for a pointer or an offset, for the case where pointers are not 64
+ /// bits wide.
+ union StorageType32 {
+ StorageType32(uint64_t Off) : Offset{true, Off} {}
+ StorageType32(T *Ptr) : Pointer{false, Ptr} {}
+
+ bool isOffset() { return Offset.IsOffset; }
+ uint64_t offset() { return Offset.Offset; }
+ T *&pointer() { return Pointer.Pointer; }
+
+ struct OffsetType {
+ uint64_t IsOffset : 1;
+ uint64_t Offset : 63;
+ } Offset;
+ struct PointerType {
+ uint64_t IsOffset : 1;
+ T *Pointer;
+ } Pointer;
+ };
+
+ mutable std::conditional_t<sizeof(uint64_t) == sizeof(T *), StorageType64,
+ StorageType32>
----------------
jrtc27 wrote:
Well, CHERI is such a system. LLVM isn't ported to it today, but I'd rather not see the problem get worse if it can be avoided. And whilst, yes, more memory is needed, quadrupling the size of a structure when the pointer size doubles makes the problem far worse.
https://github.com/llvm/llvm-project/pull/112806
More information about the cfe-commits
mailing list