From b58916bb7ca2ef4087107c630ed5118d1bf91dea Mon Sep 17 00:00:00 2001 From: David Rubin Date: Sun, 15 Dec 2024 03:40:20 -0800 Subject: [PATCH 1/2] correct the hint in `XxHash3` --- lib/std/hash/xxhash.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/std/hash/xxhash.zig b/lib/std/hash/xxhash.zig index eb3d4ea2b916..28b5ceaa3d63 100644 --- a/lib/std/hash/xxhash.zig +++ b/lib/std/hash/xxhash.zig @@ -593,7 +593,7 @@ pub const XxHash3 = struct { } fn hash3(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 { - @branchHint(.cold); + @branchHint(.unlikely); std.debug.assert(input.len > 0 and input.len < 4); const flip: [2]u32 = @bitCast(secret[0..8].*); @@ -625,7 +625,7 @@ pub const XxHash3 = struct { } fn hash16(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 { - @branchHint(.cold); + @branchHint(.unlikely); std.debug.assert(input.len > 8 and input.len <= 16); const flip: [4]u64 = @bitCast(secret[24..56].*); @@ -641,7 +641,7 @@ pub const XxHash3 = struct { } fn hash128(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 { - @branchHint(.cold); + @branchHint(.unlikely); std.debug.assert(input.len > 16 and input.len <= 128); var acc = XxHash64.prime_1 *% @as(u64, input.len); @@ -657,7 +657,7 @@ pub const XxHash3 = struct { } fn hash240(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 { - @branchHint(.cold); + @branchHint(.unlikely); std.debug.assert(input.len > 128 and input.len <= 240); var acc = XxHash64.prime_1 *% @as(u64, input.len); @@ -676,7 +676,7 @@ pub const XxHash3 = struct { } noinline fn hashLong(seed: u64, input: []const u8) u64 { - @branchHint(.cold); + @branchHint(.unlikely); std.debug.assert(input.len >= 240); const block_count = ((input.len - 1) / @sizeOf(Block)) * @sizeOf(Block); From 0fe17ea12a5bc389d8cb0c87027a112a552e9cbc Mon Sep 17 00:00:00 2001 From: David Rubin Date: Sun, 15 Dec 2024 03:41:56 -0800 Subject: [PATCH 2/2] hashmap: remove `inline` from `getIndex` now that we have `@branchHint` --- lib/std/hash_map.zig | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index e6f51dc6481d..2218ff1c5da9 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -1187,17 +1187,13 @@ pub fn HashMapUnmanaged( } /// Find the index containing the data for the given key. - /// Whether this function returns null is almost always - /// branched on after this function returns, and this function - /// returns null/not null from separate code paths. We - /// want the optimizer to remove that branch and instead directly - /// fuse the basic blocks after the branch to the basic blocks - /// from this function. To encourage that, this function is - /// marked as inline. - inline fn getIndex(self: Self, key: anytype, ctx: anytype) ?usize { + fn getIndex(self: Self, key: anytype, ctx: anytype) ?usize { comptime verifyContext(@TypeOf(ctx), @TypeOf(key), K, Hash, false); if (self.size == 0) { + // We use cold instead of unlikely to force a jump to this case, + // no matter the weight of the opposing side. + @branchHint(.cold); return null; }