[llvm] [BOLT] Use deterministic xxh3 for computing BF/BB hashes (PR #72542)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 27 13:35:06 PST 2023
https://github.com/spupyrev updated https://github.com/llvm/llvm-project/pull/72542
>From c0b454ff41740f126eb1ddb4c0ad004b35da8330 Mon Sep 17 00:00:00 2001
From: spupyrev <spupyrev at fb.com>
Date: Thu, 16 Nov 2023 06:42:36 -0800
Subject: [PATCH 1/2] [BOLT] Use deterministic xxh3 for computing BF/BB hashes
---
bolt/lib/Core/BinaryFunction.cpp | 3 +-
bolt/lib/Core/HashUtilities.cpp | 9 ------
bolt/lib/Profile/StaleProfileMatching.cpp | 15 +++++----
.../test/X86/Inputs/blarge_profile_stale.yaml | 18 +++++------
bolt/test/X86/pre-aggregated-perf.test | 2 +-
bolt/test/X86/reader-stale-yaml.test | 31 +++++++++++++++++--
6 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 30c34a82c32d720..3b0a2314dc1d252 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -40,6 +40,7 @@
#include "llvm/Support/Regex.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/xxhash.h"
#include <functional>
#include <limits>
#include <numeric>
@@ -3636,7 +3637,7 @@ size_t BinaryFunction::computeHash(bool UseDFS,
for (const BinaryBasicBlock *BB : Order)
HashString.append(hashBlock(BC, *BB, OperandHashFunc));
- return Hash = std::hash<std::string>{}(HashString);
+ return Hash = llvm::xxh3_64bits(HashString);
}
void BinaryFunction::insertBasicBlocks(
diff --git a/bolt/lib/Core/HashUtilities.cpp b/bolt/lib/Core/HashUtilities.cpp
index 6c7570dcc44e87b..d40159b2e216d90 100644
--- a/bolt/lib/Core/HashUtilities.cpp
+++ b/bolt/lib/Core/HashUtilities.cpp
@@ -18,15 +18,6 @@
namespace llvm {
namespace bolt {
-/// Hashing a 64-bit integer to a 16-bit one.
-uint16_t hash_64_to_16(const uint64_t Hash) {
- uint16_t Res = (uint16_t)(Hash & 0xFFFF);
- Res ^= (uint16_t)((Hash >> 16) & 0xFFFF);
- Res ^= (uint16_t)((Hash >> 32) & 0xFFFF);
- Res ^= (uint16_t)((Hash >> 48) & 0xFFFF);
- return Res;
-}
-
std::string hashInteger(uint64_t Value) {
std::string HashString;
if (Value == 0)
diff --git a/bolt/lib/Profile/StaleProfileMatching.cpp b/bolt/lib/Profile/StaleProfileMatching.cpp
index d00bf87ffc8ad87..6fb6f380f71eecd 100644
--- a/bolt/lib/Profile/StaleProfileMatching.cpp
+++ b/bolt/lib/Profile/StaleProfileMatching.cpp
@@ -30,6 +30,7 @@
#include "llvm/ADT/Bitfields.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/xxhash.h"
#include "llvm/Transforms/Utils/SampleProfileInference.h"
#include <queue>
@@ -240,12 +241,12 @@ void BinaryFunction::computeBlockHashes() const {
// Hashing complete instructions.
std::string InstrHashStr = hashBlock(
BC, *BB, [&](const MCOperand &Op) { return hashInstOperand(BC, Op); });
- uint64_t InstrHash = std::hash<std::string>{}(InstrHashStr);
- BlendedHashes[I].InstrHash = (uint16_t)hash_value(InstrHash);
+ uint64_t InstrHash = llvm::xxh3_64bits(InstrHashStr);
+ BlendedHashes[I].InstrHash = (uint16_t)InstrHash;
// Hashing opcodes.
std::string OpcodeHashStr = hashBlockLoose(BC, *BB);
- OpcodeHashes[I] = std::hash<std::string>{}(OpcodeHashStr);
- BlendedHashes[I].OpcodeHash = (uint16_t)hash_value(OpcodeHashes[I]);
+ OpcodeHashes[I] = llvm::xxh3_64bits(OpcodeHashStr);
+ BlendedHashes[I].OpcodeHash = (uint16_t)OpcodeHashes[I];
}
// Initialize neighbor hash.
@@ -257,7 +258,7 @@ void BinaryFunction::computeBlockHashes() const {
uint64_t SuccHash = OpcodeHashes[SuccBB->getIndex()];
Hash = hashing::detail::hash_16_bytes(Hash, SuccHash);
}
- BlendedHashes[I].SuccHash = (uint8_t)hash_value(Hash);
+ BlendedHashes[I].SuccHash = (uint8_t)Hash;
// Append hashes of predecessors.
Hash = 0;
@@ -265,7 +266,7 @@ void BinaryFunction::computeBlockHashes() const {
uint64_t PredHash = OpcodeHashes[PredBB->getIndex()];
Hash = hashing::detail::hash_16_bytes(Hash, PredHash);
}
- BlendedHashes[I].PredHash = (uint8_t)hash_value(Hash);
+ BlendedHashes[I].PredHash = (uint8_t)Hash;
}
// Assign hashes.
@@ -405,6 +406,8 @@ void matchWeightsByHashes(BinaryContext &BC,
++BC.Stats.NumMatchedBlocks;
BC.Stats.MatchedSampleCount += YamlBB.ExecCount;
LLVM_DEBUG(dbgs() << " exact match\n");
+ } else {
+ LLVM_DEBUG(dbgs() << " loose match\n");
}
} else {
LLVM_DEBUG(
diff --git a/bolt/test/X86/Inputs/blarge_profile_stale.yaml b/bolt/test/X86/Inputs/blarge_profile_stale.yaml
index f5abaed3da39412..43b75c99656f188 100644
--- a/bolt/test/X86/Inputs/blarge_profile_stale.yaml
+++ b/bolt/test/X86/Inputs/blarge_profile_stale.yaml
@@ -10,33 +10,33 @@ header:
functions:
- name: SolveCubic
fid: 6
- hash: 0xC6E9098E973BBE19
+ hash: 0x0000000000000000
exec: 151
nblocks: 18
blocks:
- bid: 0
insns: 43
- hash: 0xed4db287e71c0000
+ hash: 0x4600940a609c0000
exec: 151
succ: [ { bid: 1, cnt: 151, mis: 2 }, { bid: 7, cnt: 0 } ]
- bid: 1
insns: 7
- hash: 0x39330000e4560088
+ hash: 0x167a1f084f130088
succ: [ { bid: 13, cnt: 151 }, { bid: 2, cnt: 0 } ]
- bid: 13
insns: 26
- hash: 0xa9700000fe202a7
+ hash: 0xa8d50000f81902a7
succ: [ { bid: 3, cnt: 89 }, { bid: 2, cnt: 10 } ]
- bid: 3
insns: 9
- hash: 0x62391dad18a700a0
+ hash: 0xc516000073dc00a0
succ: [ { bid: 5, cnt: 151 } ]
- bid: 5
insns: 9
- hash: 0x4d906d19ecec0111
+ hash: 0x6446e1ea500111
- name: usqrt
fid: 7
- hash: 0x8B62B1F9AD81EA35
+ hash: 0x0000000000000000
exec: 20
nblocks: 6
blocks:
@@ -47,10 +47,10 @@ functions:
succ: [ { bid: 1, cnt: 0 } ]
- bid: 1
insns: 9
- hash: 0x27e43a5e10cd0010
+ hash: 0xd70d7a64320e0010
succ: [ { bid: 3, cnt: 320, mis: 171 }, { bid: 2, cnt: 0 } ]
- bid: 3
insns: 2
- hash: 0x4db935b6471e0039
+ hash: 0x5c06705524800039
succ: [ { bid: 1, cnt: 300, mis: 33 }, { bid: 4, cnt: 20 } ]
...
diff --git a/bolt/test/X86/pre-aggregated-perf.test b/bolt/test/X86/pre-aggregated-perf.test
index 720d179d1c6b809..e8c3f64239a27dd 100644
--- a/bolt/test/X86/pre-aggregated-perf.test
+++ b/bolt/test/X86/pre-aggregated-perf.test
@@ -46,7 +46,7 @@ PERF2BOLT: 1 usqrt a 1 usqrt 10 0 22
NEWFORMAT: - name: 'frame_dummy/1'
NEWFORMAT: fid: 3
-NEWFORMAT: hash: 0x24496F7F9594E89F
+NEWFORMAT: hash: 0x28C72085C0BD8D37
NEWFORMAT: exec: 1
NEWFORMAT: - name: usqrt
diff --git a/bolt/test/X86/reader-stale-yaml.test b/bolt/test/X86/reader-stale-yaml.test
index 4127e92b59d3f97..b9715f0cabe33bf 100644
--- a/bolt/test/X86/reader-stale-yaml.test
+++ b/bolt/test/X86/reader-stale-yaml.test
@@ -5,19 +5,28 @@ RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
# Testing "usqrt"
RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \
RUN: --print-cfg --print-only=usqrt --infer-stale-profile=1 \
-RUN: --profile-ignore-hash=1 --profile-use-dfs=0 2>&1 | FileCheck %s -check-prefix=CHECK1
+RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK1
# Testing "SolveCubic"
RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \
RUN: --print-cfg --print-only=SolveCubic --infer-stale-profile=1 \
-RUN: --profile-ignore-hash=1 --profile-use-dfs=0 2>&1 | FileCheck %s -check-prefix=CHECK2
+RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK2
# Function "usqrt" has stale profile, since the number of blocks in the profile
# (nblocks=6) does not match the size of the CFG in the binary. The entry
# block (bid=0) has an incorrect (missing) count, which should be inferred by
# the algorithm.
-# Verify that yaml reader works as expected.
+# Verify inference details.
CHECK1: pre-processing profile using YAML profile reader
+CHECK1: applying profile inference for "usqrt"
+CHECK1: Matched yaml block (bid = 0) with hash 1111111111111111 to BB (index = 0) with hash 36007ba1d80c0000
+CHECK1-NEXT: loose match
+CHECK1: Matched yaml block (bid = 1) with hash d70d7a64320e0010 to BB (index = 1) with hash d70d7a64320e0010
+CHECK1-NEXT: exact match
+CHECK1: Matched yaml block (bid = 3) with hash 5c06705524800039 to BB (index = 3) with hash 5c06705524800039
+CHECK1-NEXT: exact match
+
+# Verify that yaml reader works as expected.
CHECK1: Binary Function "usqrt" after building cfg {
CHECK1: State : CFG constructed
CHECK1: Address : 0x401170
@@ -28,6 +37,7 @@ CHECK1: BB Count : 5
CHECK1: Exec Count : 20
CHECK1: Branch Count: 640
CHECK1: }
+
# Verify block counts.
CHECK1: .LBB01 (4 instructions, align : 1)
CHECK1: Successors: .Ltmp[[#BB13:]] (mispreds: 0, count: 20)
@@ -48,7 +58,21 @@ CHECK1: inferred profile for 2 (100.00% of profiled, 100.00% of stale) function
# verifies that the inference is able to match two blocks (bid=1 and bid=13)
# using "loose" hashes and then correctly propagate the counts.
+# Verify inference details.
CHECK2: pre-processing profile using YAML profile reader
+CHECK2: applying profile inference for "SolveCubic"
+CHECK2: Matched yaml block (bid = 0) with hash 4600940a609c0000 to BB (index = 0) with hash 4600940a609c0000
+CHECK2-NEXT: exact match
+CHECK2: Matched yaml block (bid = 1) with hash 167a1f084f130088 to BB (index = 1) with hash 167a1f084f130088
+CHECK2-NEXT: exact match
+CHECK2: Matched yaml block (bid = 13) with hash a8d50000f81902a7 to BB (index = 13) with hash a8d5aa43f81902a7
+CHECK2-NEXT: loose match
+CHECK2: Matched yaml block (bid = 3) with hash c516000073dc00a0 to BB (index = 3) with hash c516b1c973dc00a0
+CHECK2-NEXT: loose match
+CHECK2: Matched yaml block (bid = 5) with hash 6446e1ea500111 to BB (index = 5) with hash 6446e1ea500111
+CHECK2-NEXT: exact match
+
+# Verify that yaml reader works as expected.
CHECK2: Binary Function "SolveCubic" after building cfg {
CHECK2: State : CFG constructed
CHECK2: Address : 0x400e00
@@ -58,6 +82,7 @@ CHECK2: IsSimple : 1
CHECK2: BB Count : 18
CHECK2: Exec Count : 151
CHECK2: Branch Count: 552
+
# Verify block counts.
CHECK2: .LBB00 (43 instructions, align : 1)
CHECK2: Successors: .Ltmp[[#BB7:]] (mispreds: 0, count: 0), .LFT[[#BB1:]] (mispreds: 0, count: 151)
>From 5cb1a1de8414d55ab8220864a182da464e56a0b6 Mon Sep 17 00:00:00 2001
From: spupyrev <spupyrev at fb.com>
Date: Mon, 27 Nov 2023 11:31:29 -0800
Subject: [PATCH 2/2] added REQUIRES: asserts
---
bolt/test/X86/reader-stale-yaml.test | 1 +
1 file changed, 1 insertion(+)
diff --git a/bolt/test/X86/reader-stale-yaml.test b/bolt/test/X86/reader-stale-yaml.test
index b9715f0cabe33bf..ad0945b1493407c 100644
--- a/bolt/test/X86/reader-stale-yaml.test
+++ b/bolt/test/X86/reader-stale-yaml.test
@@ -1,6 +1,7 @@
# This script checks that YamlProfileReader in llvm-bolt is reading data
# correctly and stale data is corrected by profile inference.
+REQUIRES: asserts
RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
# Testing "usqrt"
RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \
More information about the llvm-commits
mailing list