Optimize SwissTable slot lifecycle and resize transfers with restrict qualifiers. In raw_hash_set, constructing, destroying, or transferring slots writes subobjects (such as moved-from SSO string tags, vector end pointers, map values, or control bytes) through one pointer while reading from another, preventing the compiler from proving non-aliasing across slot-lifecycle operations and table growth. Add __restrict qualifiers to the slot pointer parameters of the slot-lifecycle helpers (construct, destroy, transfer) and type-erased slot callbacks (transfer_n_slots_fn, destroy_slot_fn_impl, and transfer_unprobed_elements_to_next_capacity_fn, along with CommonFields& __restrict common) in raw_hash_set.h. PiperOrigin-RevId: 996076967
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index ce8a1e4..2cd1784 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -3593,17 +3593,17 @@ }; template <typename... Args> - void construct(slot_type* slot, Args&&... args) { + void construct(slot_type* __restrict slot, Args&&... args) { ReentranceGuard guard(common()); allocator_type alloc(char_alloc_ref()); PolicyTraits::construct(&alloc, slot, std::forward<Args>(args)...); } - void destroy(slot_type* slot) { + void destroy(slot_type* __restrict slot) { ReentranceGuard guard(common()); allocator_type alloc(char_alloc_ref()); PolicyTraits::destroy(&alloc, slot); } - void transfer(slot_type* to, slot_type* from) { + void transfer(slot_type* __restrict to, slot_type* __restrict from) { ReentranceGuard guard(common()); allocator_type alloc(char_alloc_ref()); PolicyTraits::transfer(&alloc, to, from); @@ -4170,8 +4170,8 @@ kSeedShift>(); } - static void transfer_n_slots_fn(void* set, void* dst, void* src, - size_t count) { + static void transfer_n_slots_fn(void* set, void* __restrict dst, + void* __restrict src, size_t count) { auto* src_slot = to_slot(src); auto* dst_slot = to_slot(dst); @@ -4189,7 +4189,7 @@ PolicyTraits::element(static_cast<slot_type*>(const_cast<void*>(src)))); } - static void destroy_slot_fn_impl(void* set, void* slot) { + static void destroy_slot_fn_impl(void* set, void* __restrict slot) { auto* h = static_cast<raw_hash_set*>(set); h->destroy(to_slot(slot)); } @@ -4203,8 +4203,8 @@ // by GetKey + Hash for memcpyable types. // TODO(b/382423690): Try to type erase for big slots: sizeof(slot_type) > 16. static void transfer_unprobed_elements_to_next_capacity_fn( - CommonFields& common, const ctrl_t* old_ctrl, void* probed_storage, - void* old_slots, size_t old_capacity, + CommonFields& __restrict common, const ctrl_t* old_ctrl, + void* probed_storage, void* __restrict old_slots, size_t old_capacity, void (*encode_probed_element)(void* probed_storage, size_t hash, size_t source_offset)) { ABSL_ASSUME(old_capacity + 1 >= Group::kWidth);