Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
Hashing.h
Go to the documentation of this file.
1#ifndef PROTEUS_HASHING_H
2#define PROTEUS_HASHING_H
3
8
9#include <llvm/ADT/ArrayRef.h>
10#if LLVM_VERSION_MAJOR >= 18
11#include <llvm/ADT/StableHashing.h>
12#else
13#include <llvm/CodeGen/StableHashing.h>
14#endif
15
16#include <string>
17
18namespace proteus {
19
20using namespace llvm;
21
22class HashT {
23private:
24 stable_hash Value;
25
26public:
27 inline HashT(const stable_hash HashValue) { Value = HashValue; }
28 inline HashT(const StringRef &S) { S.getAsInteger(0, Value); }
29 inline stable_hash getValue() const { return Value; }
30 inline std::string toString() const { return std::to_string(Value); }
31 // Returns a suffix for mangled JIT function names. CUDA uses "$" delimiters
32 // because "." generates invalid PTX. HIP/Host use "." for demangle-ability.
33 inline std::string toMangledSuffix() const {
34#if PROTEUS_ENABLE_CUDA
35 return "$jit$" + toString() + "$";
36#else
37 return ".jit." + toString();
38#endif
39 }
40 inline bool operator==(const HashT &Other) const {
41 return Value == Other.Value;
42 }
43
44 inline bool operator<(const HashT &Other) const {
45 return Value < Other.Value;
46 }
47};
48
49inline HashT hashValue(const HashT &H) { return H; }
50
51// Function that abstracts interface differences in stable hashing across LLVM.
52inline HashT hashValue(const StringRef &S) {
53#if LLVM_VERSION_MAJOR >= 20
54 ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(S.data()),
55 S.size());
56 return xxh3_64bits(Bytes);
57#else
58 return stable_hash_combine_string(S);
59#endif
60}
61
62inline HashT hashValue(const std::string &S) { return hashValue(StringRef{S}); }
63
64template <typename T>
65inline std::enable_if_t<std::is_scalar<T>::value, HashT> hashValue(const T &V) {
66 return hashValue(StringRef{reinterpret_cast<const char *>(&V), sizeof(T)});
67}
68
69template <typename T>
71 if (RC.ArrInfo.NumElts <= 0)
72 reportFatalError("Invalid number of elements in array: " +
73 std::to_string(RC.ArrInfo.NumElts));
74
75 if (!RC.ArrInfo.Blob)
76 reportFatalError("Expected non-null Blob");
77
78 return hashValue(
79 StringRef{reinterpret_cast<const char *>(RC.ArrInfo.Blob.get()),
80 sizeof(T) * RC.ArrInfo.NumElts});
81}
82
84 if (RC.ObjInfo.Size <= 0)
85 reportFatalError("Invalid object size <= 0");
86
87 if (!RC.ObjInfo.Blob)
88 reportFatalError("Expected non-null Blob");
89
90 return hashValue(
91 StringRef{reinterpret_cast<const char *>(RC.ObjInfo.Blob.get()),
92 static_cast<size_t>(RC.ObjInfo.Size)});
93}
94
99 switch (RC.ArrInfo.EltType) {
101 return hashRuntimeConstantArray<bool>(RC);
103 return hashRuntimeConstantArray<int8_t>(RC);
105 return hashRuntimeConstantArray<int32_t>(RC);
107 return hashRuntimeConstantArray<int64_t>(RC);
109 return hashRuntimeConstantArray<float>(RC);
111 return hashRuntimeConstantArray<double>(RC);
112 default:
113 reportFatalError("Unsupported array element type: " +
115 }
116 } else if (RC.Type == RuntimeConstantType::OBJECT) {
117 return hashRuntimeConstantObject(RC);
118 } else if (isScalarRuntimeConstantType(RC.Type)) {
119 return hashValue(
120 StringRef{reinterpret_cast<const char *>(&RC.Value), sizeof(RC.Value)});
121 }
122
123 reportFatalError("Unsupported type " + toString(RC.Type));
124}
125
126inline HashT hashValue(ArrayRef<RuntimeConstant> Arr) {
127 if (Arr.empty())
128 return 0;
129
130 HashT HashValue = hashArrayRefElement(Arr[0]);
131 for (int I = 1, E = Arr.size(); I < E; ++I)
132 HashValue = stable_hash_combine(HashValue.getValue(),
133 hashArrayRefElement(Arr[I]).getValue());
134
135 return HashValue;
136}
137
139 return stable_hash_combine(A.getValue(), B.getValue());
140}
141
143 HashT H = hashValue(static_cast<int>(CGConfig.codeGenOption()));
144 H = hashCombine(H, hashValue(CGConfig.optLevel()));
145 H = hashCombine(H, hashValue(CGConfig.codeGenOptLevel()));
146 if (auto Pipeline = CGConfig.optPipeline())
147 H = hashCombine(H, hashValue(Pipeline.value()));
148 return H;
149}
150
151inline HashT
153 HashT H = hashValue(CGConfig.specializeArgs());
154 H = hashCombine(H, hashValue(CGConfig.specializeDims()));
155 H = hashCombine(H, hashValue(CGConfig.specializeDimsRange()));
156 H = hashCombine(H, hashValue(CGConfig.specializeLaunchBounds()));
157 return H;
158}
159
160// The generic CodeGenerationConfig hash is codegen-only so frontend module
161// caches do not depend on runtime specialization policy. Runtime JIT cache keys
162// add hashRuntimeSpecializationConfig explicitly where those flags apply.
163inline HashT hashValue(const CodeGenerationConfig &CGConfig) {
164 return hashCodeGenConfig(CGConfig);
165}
166
167template <typename FirstT, typename... RestTs>
168inline HashT hash(FirstT &&First, RestTs &&...Rest) {
169 TIMESCOPE("proteus::hash");
170 HashT HashValue = hashValue(First);
171
172 ((HashValue = hashCombine(HashValue, hashValue(Rest))), ...);
173
174 return HashValue;
175}
176
177template <typename T> inline HashT hash(T &&Data) {
178 HashT HashValue = hashValue(Data);
179 return HashValue;
180}
181
182} // namespace proteus
183
184namespace std {
185template <> struct hash<proteus::HashT> {
186 std::size_t operator()(const proteus::HashT &Key) const {
187 return Key.getValue();
188 }
189};
190
191} // namespace std
192#endif
#define TIMESCOPE(...)
Definition TimeTracing.h:66
Definition Config.h:164
bool specializeArgs() const
Definition Config.h:260
bool specializeDimsRange() const
Definition Config.h:262
bool specializeLaunchBounds() const
Definition Config.h:263
std::optional< const std::string > optPipeline() const
Definition Config.h:266
bool specializeDims() const
Definition Config.h:261
char optLevel() const
Definition Config.h:264
CodegenOption codeGenOption() const
Definition Config.h:259
int codeGenOptLevel() const
Definition Config.h:265
Definition Hashing.h:22
std::string toString() const
Definition Hashing.h:30
bool operator==(const HashT &Other) const
Definition Hashing.h:40
stable_hash getValue() const
Definition Hashing.h:29
bool operator<(const HashT &Other) const
Definition Hashing.h:44
HashT(const stable_hash HashValue)
Definition Hashing.h:27
HashT(const StringRef &S)
Definition Hashing.h:28
std::string toMangledSuffix() const
Definition Hashing.h:33
Definition CompiledLibrary.h:7
Definition MemoryCache.h:27
HashT hashValue(const HashT &H)
Definition Hashing.h:49
@ 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.h:168
void reportFatalError(const llvm::Twine &Reason, const char *FILE, unsigned Line)
Definition Error.cpp:14
HashT hashRuntimeSpecializationConfig(const CodeGenerationConfig &CGConfig)
Definition Hashing.h:152
HashT hashCodeGenConfig(const CodeGenerationConfig &CGConfig)
Definition Hashing.h:142
HashT hashArrayRefElement(const RuntimeConstant &RC)
Definition Hashing.h:95
HashT hashCombine(HashT A, HashT B)
Definition Hashing.h:138
std::string toString(CodegenOption Option)
Definition Config.h:28
HashT hashRuntimeConstantObject(const RuntimeConstant &RC)
Definition Hashing.h:83
bool isScalarRuntimeConstantType(RuntimeConstantType RCType)
Definition RuntimeConstantTypeHelpers.h:148
HashT hashRuntimeConstantArray(const RuntimeConstant &RC)
Definition Hashing.h:70
Definition Hashing.h:184
int32_t NumElts
Definition CompilerInterfaceTypes.h:42
RuntimeConstantType EltType
Definition CompilerInterfaceTypes.h:43
std::shared_ptr< unsigned char[]> Blob
Definition CompilerInterfaceTypes.h:44
std::shared_ptr< unsigned char[]> Blob
Definition CompilerInterfaceTypes.h:53
int32_t Size
Definition CompilerInterfaceTypes.h:51
Definition CompilerInterfaceTypes.h:72
ArrayInfo ArrInfo
Definition CompilerInterfaceTypes.h:78
RuntimeConstantValue Value
Definition CompilerInterfaceTypes.h:73
RuntimeConstantType Type
Definition CompilerInterfaceTypes.h:74
ObjectInfo ObjInfo
Definition CompilerInterfaceTypes.h:79
std::size_t operator()(const proteus::HashT &Key) const
Definition Hashing.h:186