Skip to content

Commit e7dd596

Browse files
authored
[BOLT] Use deterministic xxh3 for computing BF/BB hashes (#72542)
std::hash and ADT/Hashing::hash_value are non-deterministic functions whose results might vary across implementation/process/execution. Using xxh3 instead for computing hashes of BinaryFunctions and BinaryBasicBlock for stale profile matching. (A possible alternative is to use ADT/StableHashing.h based on FNV hashing but xxh3 seems to be more popular in LLVM) This is to address #65241.
1 parent 488d900 commit e7dd596

File tree

6 files changed

+50
-29
lines changed

6 files changed

+50
-29
lines changed

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "llvm/Support/Regex.h"
4141
#include "llvm/Support/Timer.h"
4242
#include "llvm/Support/raw_ostream.h"
43+
#include "llvm/Support/xxhash.h"
4344
#include <functional>
4445
#include <limits>
4546
#include <numeric>
@@ -3636,7 +3637,7 @@ size_t BinaryFunction::computeHash(bool UseDFS,
36363637
for (const BinaryBasicBlock *BB : Order)
36373638
HashString.append(hashBlock(BC, *BB, OperandHashFunc));
36383639

3639-
return Hash = std::hash<std::string>{}(HashString);
3640+
return Hash = llvm::xxh3_64bits(HashString);
36403641
}
36413642

36423643
void BinaryFunction::insertBasicBlocks(

bolt/lib/Core/HashUtilities.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,6 @@
1818
namespace llvm {
1919
namespace bolt {
2020

21-
/// Hashing a 64-bit integer to a 16-bit one.
22-
uint16_t hash_64_to_16(const uint64_t Hash) {
23-
uint16_t Res = (uint16_t)(Hash & 0xFFFF);
24-
Res ^= (uint16_t)((Hash >> 16) & 0xFFFF);
25-
Res ^= (uint16_t)((Hash >> 32) & 0xFFFF);
26-
Res ^= (uint16_t)((Hash >> 48) & 0xFFFF);
27-
return Res;
28-
}
29-
3021
std::string hashInteger(uint64_t Value) {
3122
std::string HashString;
3223
if (Value == 0)

bolt/lib/Profile/StaleProfileMatching.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/ADT/Bitfields.h"
3131
#include "llvm/ADT/Hashing.h"
3232
#include "llvm/Support/CommandLine.h"
33+
#include "llvm/Support/xxhash.h"
3334
#include "llvm/Transforms/Utils/SampleProfileInference.h"
3435

3536
#include <queue>
@@ -240,12 +241,12 @@ void BinaryFunction::computeBlockHashes() const {
240241
// Hashing complete instructions.
241242
std::string InstrHashStr = hashBlock(
242243
BC, *BB, [&](const MCOperand &Op) { return hashInstOperand(BC, Op); });
243-
uint64_t InstrHash = std::hash<std::string>{}(InstrHashStr);
244-
BlendedHashes[I].InstrHash = (uint16_t)hash_value(InstrHash);
244+
uint64_t InstrHash = llvm::xxh3_64bits(InstrHashStr);
245+
BlendedHashes[I].InstrHash = (uint16_t)InstrHash;
245246
// Hashing opcodes.
246247
std::string OpcodeHashStr = hashBlockLoose(BC, *BB);
247-
OpcodeHashes[I] = std::hash<std::string>{}(OpcodeHashStr);
248-
BlendedHashes[I].OpcodeHash = (uint16_t)hash_value(OpcodeHashes[I]);
248+
OpcodeHashes[I] = llvm::xxh3_64bits(OpcodeHashStr);
249+
BlendedHashes[I].OpcodeHash = (uint16_t)OpcodeHashes[I];
249250
}
250251

251252
// Initialize neighbor hash.
@@ -257,15 +258,15 @@ void BinaryFunction::computeBlockHashes() const {
257258
uint64_t SuccHash = OpcodeHashes[SuccBB->getIndex()];
258259
Hash = hashing::detail::hash_16_bytes(Hash, SuccHash);
259260
}
260-
BlendedHashes[I].SuccHash = (uint8_t)hash_value(Hash);
261+
BlendedHashes[I].SuccHash = (uint8_t)Hash;
261262

262263
// Append hashes of predecessors.
263264
Hash = 0;
264265
for (BinaryBasicBlock *PredBB : BB->predecessors()) {
265266
uint64_t PredHash = OpcodeHashes[PredBB->getIndex()];
266267
Hash = hashing::detail::hash_16_bytes(Hash, PredHash);
267268
}
268-
BlendedHashes[I].PredHash = (uint8_t)hash_value(Hash);
269+
BlendedHashes[I].PredHash = (uint8_t)Hash;
269270
}
270271

271272
// Assign hashes.
@@ -405,6 +406,8 @@ void matchWeightsByHashes(BinaryContext &BC,
405406
++BC.Stats.NumMatchedBlocks;
406407
BC.Stats.MatchedSampleCount += YamlBB.ExecCount;
407408
LLVM_DEBUG(dbgs() << " exact match\n");
409+
} else {
410+
LLVM_DEBUG(dbgs() << " loose match\n");
408411
}
409412
} else {
410413
LLVM_DEBUG(

bolt/test/X86/Inputs/blarge_profile_stale.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,33 @@ header:
1010
functions:
1111
- name: SolveCubic
1212
fid: 6
13-
hash: 0xC6E9098E973BBE19
13+
hash: 0x0000000000000000
1414
exec: 151
1515
nblocks: 18
1616
blocks:
1717
- bid: 0
1818
insns: 43
19-
hash: 0xed4db287e71c0000
19+
hash: 0x4600940a609c0000
2020
exec: 151
2121
succ: [ { bid: 1, cnt: 151, mis: 2 }, { bid: 7, cnt: 0 } ]
2222
- bid: 1
2323
insns: 7
24-
hash: 0x39330000e4560088
24+
hash: 0x167a1f084f130088
2525
succ: [ { bid: 13, cnt: 151 }, { bid: 2, cnt: 0 } ]
2626
- bid: 13
2727
insns: 26
28-
hash: 0xa9700000fe202a7
28+
hash: 0xa8d50000f81902a7
2929
succ: [ { bid: 3, cnt: 89 }, { bid: 2, cnt: 10 } ]
3030
- bid: 3
3131
insns: 9
32-
hash: 0x62391dad18a700a0
32+
hash: 0xc516000073dc00a0
3333
succ: [ { bid: 5, cnt: 151 } ]
3434
- bid: 5
3535
insns: 9
36-
hash: 0x4d906d19ecec0111
36+
hash: 0x6446e1ea500111
3737
- name: usqrt
3838
fid: 7
39-
hash: 0x8B62B1F9AD81EA35
39+
hash: 0x0000000000000000
4040
exec: 20
4141
nblocks: 6
4242
blocks:
@@ -47,10 +47,10 @@ functions:
4747
succ: [ { bid: 1, cnt: 0 } ]
4848
- bid: 1
4949
insns: 9
50-
hash: 0x27e43a5e10cd0010
50+
hash: 0xd70d7a64320e0010
5151
succ: [ { bid: 3, cnt: 320, mis: 171 }, { bid: 2, cnt: 0 } ]
5252
- bid: 3
5353
insns: 2
54-
hash: 0x4db935b6471e0039
54+
hash: 0x5c06705524800039
5555
succ: [ { bid: 1, cnt: 300, mis: 33 }, { bid: 4, cnt: 20 } ]
5656
...

bolt/test/X86/pre-aggregated-perf.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ PERF2BOLT: 1 usqrt a 1 usqrt 10 0 22
4646

4747
NEWFORMAT: - name: 'frame_dummy/1'
4848
NEWFORMAT: fid: 3
49-
NEWFORMAT: hash: 0x24496F7F9594E89F
49+
NEWFORMAT: hash: 0x28C72085C0BD8D37
5050
NEWFORMAT: exec: 1
5151

5252
NEWFORMAT: - name: usqrt

bolt/test/X86/reader-stale-yaml.test

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
11
# This script checks that YamlProfileReader in llvm-bolt is reading data
22
# correctly and stale data is corrected by profile inference.
33

4+
REQUIRES: asserts
45
RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
56
# Testing "usqrt"
67
RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \
78
RUN: --print-cfg --print-only=usqrt --infer-stale-profile=1 \
8-
RUN: --profile-ignore-hash=1 --profile-use-dfs=0 2>&1 | FileCheck %s -check-prefix=CHECK1
9+
RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK1
910
# Testing "SolveCubic"
1011
RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \
1112
RUN: --print-cfg --print-only=SolveCubic --infer-stale-profile=1 \
12-
RUN: --profile-ignore-hash=1 --profile-use-dfs=0 2>&1 | FileCheck %s -check-prefix=CHECK2
13+
RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK2
1314

1415
# Function "usqrt" has stale profile, since the number of blocks in the profile
1516
# (nblocks=6) does not match the size of the CFG in the binary. The entry
1617
# block (bid=0) has an incorrect (missing) count, which should be inferred by
1718
# the algorithm.
1819

19-
# Verify that yaml reader works as expected.
20+
# Verify inference details.
2021
CHECK1: pre-processing profile using YAML profile reader
22+
CHECK1: applying profile inference for "usqrt"
23+
CHECK1: Matched yaml block (bid = 0) with hash 1111111111111111 to BB (index = 0) with hash 36007ba1d80c0000
24+
CHECK1-NEXT: loose match
25+
CHECK1: Matched yaml block (bid = 1) with hash d70d7a64320e0010 to BB (index = 1) with hash d70d7a64320e0010
26+
CHECK1-NEXT: exact match
27+
CHECK1: Matched yaml block (bid = 3) with hash 5c06705524800039 to BB (index = 3) with hash 5c06705524800039
28+
CHECK1-NEXT: exact match
29+
30+
# Verify that yaml reader works as expected.
2131
CHECK1: Binary Function "usqrt" after building cfg {
2232
CHECK1: State : CFG constructed
2333
CHECK1: Address : 0x401170
@@ -28,6 +38,7 @@ CHECK1: BB Count : 5
2838
CHECK1: Exec Count : 20
2939
CHECK1: Branch Count: 640
3040
CHECK1: }
41+
3142
# Verify block counts.
3243
CHECK1: .LBB01 (4 instructions, align : 1)
3344
CHECK1: Successors: .Ltmp[[#BB13:]] (mispreds: 0, count: 20)
@@ -48,7 +59,21 @@ CHECK1: inferred profile for 2 (100.00% of profiled, 100.00% of stale) function
4859
# verifies that the inference is able to match two blocks (bid=1 and bid=13)
4960
# using "loose" hashes and then correctly propagate the counts.
5061

62+
# Verify inference details.
5163
CHECK2: pre-processing profile using YAML profile reader
64+
CHECK2: applying profile inference for "SolveCubic"
65+
CHECK2: Matched yaml block (bid = 0) with hash 4600940a609c0000 to BB (index = 0) with hash 4600940a609c0000
66+
CHECK2-NEXT: exact match
67+
CHECK2: Matched yaml block (bid = 1) with hash 167a1f084f130088 to BB (index = 1) with hash 167a1f084f130088
68+
CHECK2-NEXT: exact match
69+
CHECK2: Matched yaml block (bid = 13) with hash a8d50000f81902a7 to BB (index = 13) with hash a8d5aa43f81902a7
70+
CHECK2-NEXT: loose match
71+
CHECK2: Matched yaml block (bid = 3) with hash c516000073dc00a0 to BB (index = 3) with hash c516b1c973dc00a0
72+
CHECK2-NEXT: loose match
73+
CHECK2: Matched yaml block (bid = 5) with hash 6446e1ea500111 to BB (index = 5) with hash 6446e1ea500111
74+
CHECK2-NEXT: exact match
75+
76+
# Verify that yaml reader works as expected.
5277
CHECK2: Binary Function "SolveCubic" after building cfg {
5378
CHECK2: State : CFG constructed
5479
CHECK2: Address : 0x400e00
@@ -58,6 +83,7 @@ CHECK2: IsSimple : 1
5883
CHECK2: BB Count : 18
5984
CHECK2: Exec Count : 151
6085
CHECK2: Branch Count: 552
86+
6187
# Verify block counts.
6288
CHECK2: .LBB00 (43 instructions, align : 1)
6389
CHECK2: Successors: .Ltmp[[#BB7:]] (mispreds: 0, count: 0), .LFT[[#BB1:]] (mispreds: 0, count: 151)

0 commit comments

Comments
 (0)