Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 3a04627

Browse files
committed
Add xxhash to llvm.
It will be used for fast fingerprinting in lld at least. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282493 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent e9029b1 commit 3a04627

File tree

5 files changed

+203
-0
lines changed

5 files changed

+203
-0
lines changed

include/llvm/Support/xxhash.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
xxHash - Extremely Fast Hash algorithm
3+
Header File
4+
Copyright (C) 2012-2016, Yann Collet.
5+
6+
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7+
8+
Redistribution and use in source and binary forms, with or without
9+
modification, are permitted provided that the following conditions are
10+
met:
11+
12+
* Redistributions of source code must retain the above copyright
13+
notice, this list of conditions and the following disclaimer.
14+
* Redistributions in binary form must reproduce the above
15+
copyright notice, this list of conditions and the following disclaimer
16+
in the documentation and/or other materials provided with the
17+
distribution.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
You can contact the author at :
32+
- xxHash source repository : https://github.com/Cyan4973/xxHash
33+
*/
34+
35+
/* based on revision d2df04efcbef7d7f6886d345861e5dfda4edacc1 Removed
36+
* everything but a simple interface for computing XXh64. */
37+
38+
#ifndef LLVM_SUPPORT_XXHASH_H
39+
#define LLVM_SUPPORT_XXHASH_H
40+
41+
#include "llvm/ADT/StringRef.h"
42+
43+
namespace llvm {
44+
uint64_t xxHash64(llvm::StringRef Data);
45+
}
46+
47+
#endif

lib/Support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ add_llvm_library(LLVMSupport
106106
regexec.c
107107
regfree.c
108108
regstrlcpy.c
109+
xxhash.cpp
109110

110111
# System
111112
Atomic.cpp

lib/Support/xxhash.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* xxHash - Fast Hash algorithm
3+
* Copyright (C) 2012-2016, Yann Collet
4+
*
5+
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are
9+
* met:
10+
*
11+
* * Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
* * Redistributions in binary form must reproduce the above
14+
* copyright notice, this list of conditions and the following disclaimer
15+
* in the documentation and/or other materials provided with the
16+
* distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*
30+
* You can contact the author at :
31+
* - xxHash homepage: http://www.xxhash.com
32+
* - xxHash source repository : https://github.com/Cyan4973/xxHash
33+
*/
34+
35+
/* based on revision d2df04efcbef7d7f6886d345861e5dfda4edacc1 Removed
36+
* everything but a simple interface for computing XXh64. */
37+
38+
#include "llvm/Support/xxhash.h"
39+
#include "llvm/Support/Endian.h"
40+
41+
#include <stdlib.h>
42+
#include <string.h>
43+
44+
using namespace llvm;
45+
using namespace support;
46+
47+
static uint64_t rotl64(uint64_t X, size_t R) {
48+
return (X << R) | (X >> (64 - R));
49+
}
50+
51+
static const uint64_t PRIME64_1 = 11400714785074694791ULL;
52+
static const uint64_t PRIME64_2 = 14029467366897019727ULL;
53+
static const uint64_t PRIME64_3 = 1609587929392839161ULL;
54+
static const uint64_t PRIME64_4 = 9650029242287828579ULL;
55+
static const uint64_t PRIME64_5 = 2870177450012600261ULL;
56+
57+
static uint64_t round(uint64_t Acc, uint64_t Input) {
58+
Acc += Input * PRIME64_2;
59+
Acc = rotl64(Acc, 31);
60+
Acc *= PRIME64_1;
61+
return Acc;
62+
}
63+
64+
static uint64_t mergeRound(uint64_t Acc, uint64_t Val) {
65+
Val = round(0, Val);
66+
Acc ^= Val;
67+
Acc = Acc * PRIME64_1 + PRIME64_4;
68+
return Acc;
69+
}
70+
71+
uint64_t llvm::xxHash64(StringRef Data) {
72+
size_t Len = Data.size();
73+
uint64_t Seed = 0;
74+
const char *P = Data.data();
75+
const char *const BEnd = P + Len;
76+
uint64_t H64;
77+
78+
if (Len >= 32) {
79+
const char *const Limit = BEnd - 32;
80+
uint64_t V1 = Seed + PRIME64_1 + PRIME64_2;
81+
uint64_t V2 = Seed + PRIME64_2;
82+
uint64_t V3 = Seed + 0;
83+
uint64_t V4 = Seed - PRIME64_1;
84+
85+
do {
86+
V1 = round(V1, endian::read64le(P));
87+
P += 8;
88+
V2 = round(V2, endian::read64le(P));
89+
P += 8;
90+
V3 = round(V3, endian::read64le(P));
91+
P += 8;
92+
V4 = round(V4, endian::read64le(P));
93+
P += 8;
94+
} while (P <= Limit);
95+
96+
H64 = rotl64(V1, 1) + rotl64(V2, 7) + rotl64(V3, 12) + rotl64(V4, 18);
97+
H64 = mergeRound(H64, V1);
98+
H64 = mergeRound(H64, V2);
99+
H64 = mergeRound(H64, V3);
100+
H64 = mergeRound(H64, V4);
101+
102+
} else {
103+
H64 = Seed + PRIME64_5;
104+
}
105+
106+
H64 += (uint64_t)Len;
107+
108+
while (P + 8 <= BEnd) {
109+
uint64_t const K1 = round(0, endian::read64le(P));
110+
H64 ^= K1;
111+
H64 = rotl64(H64, 27) * PRIME64_1 + PRIME64_4;
112+
P += 8;
113+
}
114+
115+
if (P + 4 <= BEnd) {
116+
H64 ^= (uint64_t)(endian::read32le(P)) * PRIME64_1;
117+
H64 = rotl64(H64, 23) * PRIME64_2 + PRIME64_3;
118+
P += 4;
119+
}
120+
121+
while (P < BEnd) {
122+
H64 ^= (*P) * PRIME64_5;
123+
H64 = rotl64(H64, 11) * PRIME64_1;
124+
P++;
125+
}
126+
127+
H64 ^= H64 >> 33;
128+
H64 *= PRIME64_2;
129+
H64 ^= H64 >> 29;
130+
H64 *= PRIME64_3;
131+
H64 ^= H64 >> 32;
132+
133+
return H64;
134+
}

unittests/Support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ add_llvm_unittest(SupportTests
5252
raw_ostream_test.cpp
5353
raw_pwrite_stream_test.cpp
5454
raw_sha1_ostream_test.cpp
55+
xxhashTest.cpp
5556
)
5657

5758
# ManagedStatic.cpp uses <pthread>.

unittests/Support/xxhashTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===- llvm/unittest/Support/xxhashTest.cpp -------------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "llvm/Support/xxhash.h"
11+
#include "gtest/gtest.h"
12+
13+
using namespace llvm;
14+
15+
TEST(xxhashTest, Basic) {
16+
EXPECT_EQ(0x33bf00a859c4ba3fU, xxHash64("foo"));
17+
EXPECT_EQ(0x48a37c90ad27a659U, xxHash64("bar"));
18+
EXPECT_EQ(0x69196c1b3af0bff9U,
19+
xxHash64("0123456789abcdefghijklmnopqrstuvwxyz"));
20+
}

0 commit comments

Comments
 (0)