Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
Hashing.hpp
Go to the documentation of this file.
1#ifndef PROTEUS_HASHING_HPP
2#define PROTEUS_HASHING_HPP
3
7
8#include <llvm/ADT/ArrayRef.h>
9#if LLVM_VERSION_MAJOR >= 18
10#include <llvm/ADT/StableHashing.h>
11#else
12#include <llvm/CodeGen/StableHashing.h>
13#endif
14
15#include <string>
16
17namespace proteus {
18
19using namespace llvm;
20
21class HashT {
22private:
23 stable_hash Value;
24
25public:
26 inline HashT(const stable_hash HashValue) { Value = HashValue; }
27 inline HashT(const StringRef &S) { S.getAsInteger(0, Value); }
28 inline stable_hash getValue() const { return Value; }
29 inline std::string toString() const { return std::to_string(Value); }
30 inline bool operator==(const HashT &Other) const {
31 return Value == Other.Value;
32 }
33
34 inline bool operator<(const HashT &Other) const {
35 return Value < Other.Value;
36 }
37};
38
39inline HashT hashValue(const HashT &H) { return H; }
40
41// Function that abstracts interface differences in stable hashing across LLVM.
42inline HashT hashValue(const StringRef &S) {
43#if LLVM_VERSION_MAJOR >= 20
44 ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(S.data()),
45 S.size());
46 return xxh3_64bits(Bytes);
47#else
49#endif
50}
51
52inline HashT hashValue(const std::string &S) { return hashValue(StringRef{S}); }
53
54template <typename T>
55inline std::enable_if_t<std::is_scalar<T>::value, HashT> hashValue(const T &V) {
56 return hashValue(StringRef{reinterpret_cast<const char *>(&V), sizeof(T)});
57}
58
59template <typename T>
61 if (RC.ArrInfo.NumElts <= 0)
62 reportFatalError("Invalid number of elements in array: " +
63 std::to_string(RC.ArrInfo.NumElts));
64
65 if (!RC.ArrInfo.Blob)
66 reportFatalError("Expected non-null Blob");
67
68 return hashValue(
69 StringRef{reinterpret_cast<const char *>(RC.ArrInfo.Blob.get()),
70 sizeof(T) * RC.ArrInfo.NumElts});
71}
72
74 if (RC.ObjInfo.Size <= 0)
75 reportFatalError("Invalid object size <= 0");
76
77 if (!RC.ObjInfo.Blob)
78 reportFatalError("Expected non-null Blob");
79
80 return hashValue(
81 StringRef{reinterpret_cast<const char *>(RC.ObjInfo.Blob.get()),
82 static_cast<size_t>(RC.ObjInfo.Size)});
83}
84
86 if (RC.Type == RuntimeConstantType::ARRAY ||
89 switch (RC.ArrInfo.EltType) {
102 default:
103 reportFatalError("Unsupported array element type: " +
104 toString(RC.ArrInfo.EltType));
105 }
106 } else if (RC.Type == RuntimeConstantType::OBJECT) {
108 } else if (isScalarRuntimeConstantType(RC.Type)) {
109 return hashValue(
110 StringRef{reinterpret_cast<const char *>(&RC.Value), sizeof(RC.Value)});
111 }
112
113 reportFatalError("Unsupported type " + toString(RC.Type));
114}
115
117 if (Arr.empty())
118 return 0;
119
120 HashT HashValue = hashArrayRefElement(Arr[0]);
121 for (int I = 1, E = Arr.size(); I < E; ++I)
122 HashValue = stable_hash_combine(HashValue.getValue(),
124
125 return HashValue;
126}
127
129 return stable_hash_combine(A.getValue(), B.getValue());
130}
131
132template <typename FirstT, typename... RestTs>
133inline HashT hash(FirstT &&First, RestTs &&...Rest) {
135 HashT HashValue = hashValue(First);
136
137 ((HashValue = hashCombine(HashValue, hashValue(Rest))), ...);
138
139 return HashValue;
140}
141
142template <typename T> inline HashT hash(T &&Data) {
143 HashT HashValue = hashValue(Data);
144 return HashValue;
145}
146
147} // namespace proteus
148
149namespace std {
150template <> struct hash<proteus::HashT> {
151 std::size_t operator()(const proteus::HashT &Key) const {
152 return Key.getValue();
153 }
154};
155
156} // namespace std
157#endif
#define TIMESCOPE(x)
Definition TimeTracing.hpp:59
Definition Hashing.hpp:21
std::string toString() const
Definition Hashing.hpp:29
bool operator==(const HashT &Other) const
Definition Hashing.hpp:30
stable_hash getValue() const
Definition Hashing.hpp:28
bool operator<(const HashT &Other) const
Definition Hashing.hpp:34
HashT(const stable_hash HashValue)
Definition Hashing.hpp:26
HashT(const StringRef &S)
Definition Hashing.hpp:27
Definition Helpers.h:141
Definition ObjectCacheChain.cpp:26
HashT hashValue(const HashT &H)
Definition Hashing.hpp:39
@ ARRAY
Definition CompilerInterfaceTypes.h:33
@ VECTOR
Definition CompilerInterfaceTypes.h:32
@ INT32
Definition CompilerInterfaceTypes.h:25
@ INT64
Definition CompilerInterfaceTypes.h:26
@ FLOAT
Definition CompilerInterfaceTypes.h:27
@ STATIC_ARRAY
Definition CompilerInterfaceTypes.h:31
@ INT8
Definition CompilerInterfaceTypes.h:24
@ BOOL
Definition CompilerInterfaceTypes.h:23
@ OBJECT
Definition CompilerInterfaceTypes.h:34
@ DOUBLE
Definition CompilerInterfaceTypes.h:28
HashT hash(FirstT &&First, RestTs &&...Rest)
Definition Hashing.hpp:133
void reportFatalError(const llvm::Twine &Reason, const char *FILE, unsigned Line)
Definition Error.cpp:14
T getRuntimeConstantValue(void *Arg)
Definition CompilerInterfaceRuntimeConstantInfo.h:113
HashT hashArrayRefElement(const RuntimeConstant &RC)
Definition Hashing.hpp:85
HashT hashCombine(HashT A, HashT B)
Definition Hashing.hpp:128
std::string toString(CodegenOption Option)
Definition Config.hpp:26
HashT hashRuntimeConstantObject(const RuntimeConstant &RC)
Definition Hashing.hpp:73
bool isScalarRuntimeConstantType(RuntimeConstantType RCType)
Definition RuntimeConstantTypeHelpers.h:148
HashT hashRuntimeConstantArray(const RuntimeConstant &RC)
Definition Hashing.hpp:60
Definition Hashing.hpp:149
Definition CompilerInterfaceTypes.h:72
std::size_t operator()(const proteus::HashT &Key) const
Definition Hashing.hpp:151