[llvm] [ADT] Decouple xxhash.h from ADT. NFC (PR #196774)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat May 9 20:20:38 PDT 2026
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/196774
Move xxHash64, xxh3_64bits, and xxh3_128bits ArrayRef/StringRef
overloads from llvm/Support/xxhash.h to inline overloads in
llvm/ADT/ArrayRef.h and llvm/ADT/StringRef.h, so xxhash.h has no ADT
dependencies.
This is prerequisite for using xxh3 as the combine_bytes backend in
llvm/ADT/Hashing.h (#194567), which would otherwise reintroduce a header
dependency cycle.
FoldingSet.h and StableHashing.h adjust to call the new
pointer-and-length entry point.
>From 2cc3af248083de9422de5d27234445918b7eba0e Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 9 May 2026 20:13:53 -0700
Subject: [PATCH] [ADT] Decouple xxhash.h from ADT. NFC
Move xxHash64, xxh3_64bits, and xxh3_128bits ArrayRef/StringRef
overloads from llvm/Support/xxhash.h to inline overloads in
llvm/ADT/ArrayRef.h and llvm/ADT/StringRef.h, so xxhash.h has no ADT
dependencies.
This is prerequisite for using xxh3 as the combine_bytes backend in
llvm/ADT/Hashing.h (#194567), which would otherwise reintroduce a header
dependency cycle.
FoldingSet.h and StableHashing.h adjust to call the new
pointer-and-length entry point.
---
llvm/benchmarks/xxhash.cpp | 1 +
llvm/include/llvm/ADT/ArrayRef.h | 14 ++++++++++++++
llvm/include/llvm/ADT/FoldingSet.h | 4 ++--
llvm/include/llvm/ADT/StableHashing.h | 5 ++---
llvm/include/llvm/ADT/StringRef.h | 12 ++++++++++++
llvm/include/llvm/Support/xxhash.h | 20 ++++++++++----------
llvm/lib/Support/xxhash.cpp | 19 ++++---------------
7 files changed, 45 insertions(+), 30 deletions(-)
diff --git a/llvm/benchmarks/xxhash.cpp b/llvm/benchmarks/xxhash.cpp
index 429cbc0fa87d4..ab72ebd649293 100644
--- a/llvm/benchmarks/xxhash.cpp
+++ b/llvm/benchmarks/xxhash.cpp
@@ -1,5 +1,6 @@
#include "llvm/Support/xxhash.h"
#include "benchmark/benchmark.h"
+#include "llvm/ADT/ArrayRef.h"
#include <memory>
diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h
index 86d4a6ec0e907..366233fdefd02 100644
--- a/llvm/include/llvm/ADT/ArrayRef.h
+++ b/llvm/include/llvm/ADT/ArrayRef.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <array>
#include <cassert>
@@ -551,6 +552,19 @@ template <typename T> hash_code hash_value(ArrayRef<T> S) {
return hash_combine_range(S);
}
+/// Inline ArrayRef overloads of the xxhash entry points declared
+/// out-of-line in llvm/Support/xxhash.h. They live here so xxhash.h can stay
+/// free of ADT dependencies.
+inline uint64_t xxHash64(ArrayRef<uint8_t> data) {
+ return xxHash64(data.data(), data.size());
+}
+inline uint64_t xxh3_64bits(ArrayRef<uint8_t> data) {
+ return xxh3_64bits(data.data(), data.size());
+}
+inline XXH128_hash_t xxh3_128bits(ArrayRef<uint8_t> data) {
+ return xxh3_128bits(data.data(), data.size());
+}
+
// Provide DenseMapInfo for ArrayRefs.
template <typename T> struct DenseMapInfo<ArrayRef<T>, void> {
static inline ArrayRef<T> getEmptyKey() {
diff --git a/llvm/include/llvm/ADT/FoldingSet.h b/llvm/include/llvm/ADT/FoldingSet.h
index ab501ad172be6..cde22fe35e390 100644
--- a/llvm/include/llvm/ADT/FoldingSet.h
+++ b/llvm/include/llvm/ADT/FoldingSet.h
@@ -185,8 +185,8 @@ class FoldingSetNodeIDRef {
// Compute a deterministic hash value across processes that is suitable for
// on-disk serialization.
unsigned computeStableHash() const {
- return static_cast<unsigned>(xxh3_64bits(ArrayRef(
- reinterpret_cast<const uint8_t *>(Data), sizeof(unsigned) * Size)));
+ return static_cast<unsigned>(xxh3_64bits(
+ reinterpret_cast<const uint8_t *>(Data), sizeof(unsigned) * Size));
}
LLVM_ABI bool operator==(FoldingSetNodeIDRef) const;
diff --git a/llvm/include/llvm/ADT/StableHashing.h b/llvm/include/llvm/ADT/StableHashing.h
index 0dd83be639424..1beb5b85c9967 100644
--- a/llvm/include/llvm/ADT/StableHashing.h
+++ b/llvm/include/llvm/ADT/StableHashing.h
@@ -30,9 +30,8 @@ namespace llvm {
using stable_hash = uint64_t;
inline stable_hash stable_hash_combine(ArrayRef<stable_hash> Buffer) {
- const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(Buffer.data());
- size_t Size = Buffer.size() * sizeof(stable_hash);
- return xxh3_64bits(ArrayRef<uint8_t>(Ptr, Size));
+ return xxh3_64bits(reinterpret_cast<const uint8_t *>(Buffer.data()),
+ Buffer.size() * sizeof(stable_hash));
}
inline stable_hash stable_hash_combine(stable_hash A, stable_hash B) {
diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h
index 71aa7157dfd98..7ed0d6efdbeb3 100644
--- a/llvm/include/llvm/ADT/StringRef.h
+++ b/llvm/include/llvm/ADT/StringRef.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -940,6 +941,17 @@ inline std::string &operator+=(std::string &buffer, StringRef string) {
/// Compute a hash_code for a StringRef.
[[nodiscard]] LLVM_ABI hash_code hash_value(StringRef S);
+/// Inline StringRef overloads of the xxhash entry points declared out-of-line
+/// in llvm/Support/xxhash.h. They live here so xxhash.h can stay free of ADT
+/// dependencies.
+inline uint64_t xxHash64(StringRef data) {
+ return xxHash64(reinterpret_cast<const uint8_t *>(data.data()), data.size());
+}
+inline uint64_t xxh3_64bits(StringRef data) {
+ return xxh3_64bits(reinterpret_cast<const uint8_t *>(data.data()),
+ data.size());
+}
+
// Provide DenseMapInfo for StringRefs.
template <> struct DenseMapInfo<StringRef, void> {
static inline StringRef getEmptyKey() {
diff --git a/llvm/include/llvm/Support/xxhash.h b/llvm/include/llvm/Support/xxhash.h
index b521adbef3456..15c4f1bfd4563 100644
--- a/llvm/include/llvm/Support/xxhash.h
+++ b/llvm/include/llvm/Support/xxhash.h
@@ -38,19 +38,18 @@
#ifndef LLVM_SUPPORT_XXHASH_H
#define LLVM_SUPPORT_XXHASH_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
+#include <cstddef>
+#include <cstdint>
namespace llvm {
-LLVM_ABI uint64_t xxHash64(llvm::StringRef Data);
-LLVM_ABI uint64_t xxHash64(llvm::ArrayRef<uint8_t> Data);
+// Deprecated pre-xxh3 64-bit hash.
+LLVM_ABI uint64_t xxHash64(const uint8_t *data, size_t len);
-LLVM_ABI uint64_t xxh3_64bits(ArrayRef<uint8_t> data);
-inline uint64_t xxh3_64bits(StringRef data) {
- return xxh3_64bits(ArrayRef(data.bytes_begin(), data.size()));
-}
+/// XXH3's 64-bit variant. Inline ArrayRef and StringRef overloads live in
+/// llvm/ADT/ArrayRef.h and llvm/ADT/StringRef.h.
+LLVM_ABI uint64_t xxh3_64bits(const uint8_t *data, size_t len);
/*-**********************************************************************
* XXH3 128-bit variant
@@ -72,8 +71,9 @@ struct XXH128_hash_t {
}
};
-/// XXH3's 128-bit variant.
-LLVM_ABI XXH128_hash_t xxh3_128bits(ArrayRef<uint8_t> data);
+/// XXH3's 128-bit variant. Inline ArrayRef overload lives in
+/// llvm/ADT/ArrayRef.h.
+LLVM_ABI XXH128_hash_t xxh3_128bits(const uint8_t *data, size_t len);
} // namespace llvm
diff --git a/llvm/lib/Support/xxhash.cpp b/llvm/lib/Support/xxhash.cpp
index cdb76d57e2c1d..6997fed7e8336 100644
--- a/llvm/lib/Support/xxhash.cpp
+++ b/llvm/lib/Support/xxhash.cpp
@@ -100,11 +100,9 @@ static uint64_t XXH64_avalanche(uint64_t hash) {
return hash;
}
-uint64_t llvm::xxHash64(StringRef Data) {
- size_t Len = Data.size();
+uint64_t llvm::xxHash64(const uint8_t *P, size_t Len) {
uint64_t Seed = 0;
- const unsigned char *P = Data.bytes_begin();
- const unsigned char *const BEnd = Data.bytes_end();
+ const uint8_t *const BEnd = P + Len;
uint64_t H64;
if (Len >= 32) {
@@ -160,10 +158,6 @@ uint64_t llvm::xxHash64(StringRef Data) {
return XXH64_avalanche(H64);
}
-uint64_t llvm::xxHash64(ArrayRef<uint8_t> Data) {
- return xxHash64({(const char *)Data.data(), Data.size()});
-}
-
constexpr size_t XXH3_SECRETSIZE_MIN = 136;
constexpr size_t XXH_SECRET_DEFAULT_SIZE = 192;
@@ -550,9 +544,7 @@ static uint64_t XXH3_hashLong_64b(const uint8_t *input, size_t len,
(uint64_t)len * PRIME64_1);
}
-uint64_t llvm::xxh3_64bits(ArrayRef<uint8_t> data) {
- auto *in = data.data();
- size_t len = data.size();
+uint64_t llvm::xxh3_64bits(const uint8_t *in, size_t len) {
if (len <= 16)
return XXH3_len_0to16_64b(in, len, kSecret, 0);
if (len <= 128)
@@ -1020,10 +1012,7 @@ XXH3_hashLong_128b(const uint8_t *input, size_t len, const uint8_t *secret,
return h128;
}
-llvm::XXH128_hash_t llvm::xxh3_128bits(ArrayRef<uint8_t> data) {
- size_t len = data.size();
- const uint8_t *input = data.data();
-
+llvm::XXH128_hash_t llvm::xxh3_128bits(const uint8_t *input, size_t len) {
/*
* If an action is to be taken if `secret` conditions are not respected,
* it should be done here.
More information about the llvm-commits
mailing list