Go to the documentation of this file.
15 #ifndef LLVM_SUPPORT_HASHBUILDER_H
16 #define LLVM_SUPPORT_HASHBUILDER_H
30 namespace hashbuilder_detail {
35 : std::integral_constant<bool, is_integral_or_enum<U>::value> {};
42 template <
typename HasherT_ = HasherT>
77 template <
typename... ArgTypes>
80 Hasher(*OptionalHasher) {}
92 template <
typename HasherT, support::endianness Endianness>
95 "HashBuilder should canonicalize endianness");
100 template <
typename... ArgTypes>
105 template <
typename T>
106 std::enable_if_t<hashbuilder_detail::IsHashableData<T>::value,
135 Value.size() *
sizeof(
T)));
137 for (
auto &V :
Value)
167 template <
typename T>
169 decltype(addHash(std::declval<HashBuilderImpl &>(), std::declval<T &>()));
253 template <
typename T>
254 std::enable_if_t<is_detected<HasAddHashT, T>::value &&
258 addHash(*
this,
Value);
262 template <
typename T1,
typename T2>
270 return addTupleHelper(
Arg,
typename std::index_sequence_for<Ts...>());
283 template <
typename T,
typename... Ts>
291 template <
typename ForwardIteratorT>
301 template <
typename ForwardIteratorT>
303 ForwardIteratorT Last) {
304 return addRangeElementsImpl(
306 typename std::iterator_traits<ForwardIteratorT>::iterator_category());
309 template <
typename RangeT>
314 template <
typename T>
318 template <
typename T>
319 std::enable_if_t<is_detected<HasByteSwapT, T>::value,
HashBuilderImpl &>
323 sizeof(SwappedValue)));
328 template <
typename... Ts, std::size_t... Indices>
330 std::index_sequence<Indices...>) {
331 add(std::get<Indices>(
Arg)...);
337 template <
typename ForwardIteratorT>
339 ForwardIteratorT Last,
340 std::forward_iterator_tag) {
341 for (
auto It = First; It != Last; ++It)
346 template <
typename T>
347 std::enable_if_t<hashbuilder_detail::IsHashableData<T>::value &&
350 addRangeElementsImpl(T *First, T *Last, std::forward_iterator_tag) {
352 (Last - First) *
sizeof(T)));
407 template <
class HasherT, support::endianness Endianness>
413 namespace hashbuilder_detail {
430 template <
typename T>
441 #endif // LLVM_SUPPORT_HASHBUILDER_H
HashBuilderImpl & addRangeElements(ForwardIteratorT First, ForwardIteratorT Last)
void update(ArrayRef< uint8_t > Data)
Forward to HasherT::update(ArrayRef<uint8_t>).
HashBuilderImpl & add(const std::pair< T1, T2 > &Value)
HashBuilderBase(ArgTypes &&...Args)
HashBuilderImpl(ArgTypes &&...Args)
This is an optimization pass for GlobalISel generic memory operations.
constexpr support::endianness Endianness
The endianness of all multi-byte encoded values in MessagePack.
Declares the hasher member, and functions forwarding directly to the hasher.
decltype(std::declval< HasherT_ & >().final()) HashResultTy
hash_code hash_value(const APFloat &Arg)
See friend declarations above.
std::enable_if_t< is_detected< HasByteSwapT, T >::value, HashBuilderImpl & > adjustForEndiannessAndAdd(const T &Value)
Adjust Value for the target endianness and add it to the hash.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
HashBuilderImpl & add(const std::tuple< Ts... > &Arg)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
decltype(auto) adl_end(ContainerTy &&container)
void update(ArrayRef< uint8_t > Data)
into llvm powi allowing the code generator to produce balanced multiplication trees First
HashResultTy< HasherT_ > result()
Forward to HasherT::result() if available.
std::enable_if_t< hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > add(T Value)
Implement hashing for hashable data types, e.g. integral or enum values.
HashBuilderImpl & add(ArrayRef< T > Value)
Support hashing ArrayRef.
HashBuilderImpl(HasherT &Hasher)
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
HashBuilderBase(HasherT &Hasher)
std::enable_if<(sizeof...(Ts) >=1), HashBuilderImpl & >::type add(const T &FirstArg, const Ts &...Args)
A convenenience variadic helper.
HashBuilderImpl< HasherT,(Endianness==support::endianness::native ? support::endian::system_endianness() :Endianness)> HashBuilder
Interface to help hash various types through a hasher type.
constexpr in_place_t in_place
HashBuilderImpl & addRangeElements(const RangeT &Range)
Implementation of the HashBuilder interface.
HashBuilderImpl & add(StringRef Value)
Support hashing StringRef.
StringRef - Represent a constant reference to a string, i.e.
decltype(support::endian::byte_swap(std::declval< T & >(), support::endianness::little)) HasByteSwapT
decltype(auto) adl_begin(ContainerTy &&container)
value_type byte_swap(value_type value, endianness endian)
constexpr endianness system_endianness()
decltype(addHash(std::declval< HashBuilderImpl & >(), std::declval< T & >())) HasAddHashT
HashBuilderImpl & addRange(ForwardIteratorT First, ForwardIteratorT Last)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
HashBuilderImpl & addRange(const RangeT &Range)
std::enable_if_t< is_detected< HasAddHashT, T >::value &&!hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > add(const T &Value)
Implement hashing for user-defined structs.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Trait to indicate whether a type's bits can be hashed directly (after endianness correction).
LLVM Value Representation.
void update(StringRef Data)
Forward to HasherT::update(ArrayRef<uint8_t>).
An opaque object representing a hash code.