Skip to content

Commit 14a60d8

Browse files
committed
refactor: Implement AVX2 runtime detection instead of using blake3's
1 parent 20923df commit 14a60d8

13 files changed

+109
-45
lines changed

ci/build

+6-1
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ else
3535
;;
3636
esac
3737

38+
if [ -x ccache ]; then
39+
./ccache --version
40+
elif command -v wine >/dev/null && [ -f ccache.exe ]; then
41+
wine ccache.exe --version
42+
fi
43+
3844
case "${RUN_TESTS:-all}" in
3945
all)
4046
CC="${TEST_CC}" ctest --output-on-failure -j"${JOBS}" "$@"
4147
;;
4248
unittest-in-wine)
43-
wine ccache.exe --version
4449
wine unittest/unittest.exe
4550
;;
4651
none)

cmake/GenerateConfigurationFile.cmake

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
include(CheckIncludeFile)
22
set(include_files
3+
cpuid.h
34
dirent.h
45
linux/fs.h
56
pwd.h
@@ -70,8 +71,8 @@ include(CheckCXXSourceCompiles)
7071
check_cxx_source_compiles(
7172
[=[
7273
#include <immintrin.h>
73-
#ifndef _MSC_VER // MSVC does not need explicit enabling of AVX2.
74-
void func() __attribute__((target("avx2")));
74+
#ifndef _MSC_VER
75+
__attribute__((target("avx2")))
7576
#endif
7677
void func() { _mm256_abs_epi8(_mm256_set1_epi32(42)); }
7778
int main()

cmake/config.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969

7070
// === Header files ===
7171

72+
// Define if you have the <cpuid.h> header file.
73+
#cmakedefine HAVE_CPUID_H
74+
7275
// Define if you have the <dirent.h> header file.
7376
#cmakedefine HAVE_DIRENT_H
7477

src/ccache/core/mainoptions.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <ccache/util/UmaskScope.hpp>
4545
#include <ccache/util/XXH3_128.hpp>
4646
#include <ccache/util/assertions.hpp>
47+
#include <ccache/util/cpu.hpp>
4748
#include <ccache/util/environment.hpp>
4849
#include <ccache/util/expected.hpp>
4950
#include <ccache/util/file.hpp>
@@ -417,8 +418,13 @@ parse_compression_level(std::string_view level)
417418
static std::string
418419
get_version_text(const std::string_view ccache_name)
419420
{
421+
auto features = storage::get_features();
422+
if (util::cpu_supports_avx2()) {
423+
features.emplace_back("avx2");
424+
}
425+
std::sort(features.begin(), features.end());
420426
return FMT(
421-
VERSION_TEXT, ccache_name, CCACHE_VERSION, storage::get_features());
427+
VERSION_TEXT, ccache_name, CCACHE_VERSION, util::join(features, " "));
422428
}
423429

424430
std::string

src/ccache/hashutil.cpp

+5-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <ccache/execute.hpp>
2626
#include <ccache/macroskip.hpp>
2727
#include <ccache/util/DirEntry.hpp>
28+
#include <ccache/util/cpu.hpp>
2829
#include <ccache/util/file.hpp>
2930
#include <ccache/util/format.hpp>
3031
#include <ccache/util/logging.hpp>
@@ -36,8 +37,6 @@
3637
# include "InodeCache.hpp"
3738
#endif
3839

39-
#include <blake3_cpu_supports_avx2.h>
40-
4140
#ifdef HAVE_UNISTD_H
4241
# include <unistd.h>
4342
#endif
@@ -112,14 +111,12 @@ check_for_temporal_macros_bmh(std::string_view str, size_t start = 0)
112111
}
113112

114113
#ifdef HAVE_AVX2
115-
# ifndef _MSC_VER // MSVC does not need explicit enabling of AVX2.
116-
HashSourceCodeResult check_for_temporal_macros_avx2(std::string_view str)
117-
__attribute__((target("avx2")));
118-
# endif
119-
120114
// The following algorithm, which uses AVX2 instructions to find __DATE__,
121115
// __TIME__ and __TIMESTAMP__, is heavily inspired by
122116
// <http://0x80.pl/articles/simd-strfind.html>.
117+
# ifndef _MSC_VER
118+
__attribute__((target("avx2")))
119+
# endif
123120
HashSourceCodeResult
124121
check_for_temporal_macros_avx2(std::string_view str)
125122
{
@@ -222,7 +219,7 @@ HashSourceCodeResult
222219
check_for_temporal_macros(std::string_view str)
223220
{
224221
#ifdef HAVE_AVX2
225-
if (blake3_cpu_supports_avx2()) {
222+
if (util::cpu_supports_avx2()) {
226223
return check_for_temporal_macros_avx2(str);
227224
}
228225
#endif

src/ccache/storage/Storage.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const std::unordered_map<std::string /*scheme*/,
6060
#endif
6161
};
6262

63-
std::string
63+
std::vector<std::string>
6464
get_features()
6565
{
6666
std::vector<std::string> features;
@@ -69,8 +69,7 @@ get_features()
6969
k_remote_storage_implementations.end(),
7070
std::back_inserter(features),
7171
[](auto& entry) { return FMT("{}-storage", entry.first); });
72-
std::sort(features.begin(), features.end());
73-
return util::join(features, " ");
72+
return features;
7473
}
7574

7675
// Representation of one shard configuration.

src/ccache/storage/Storage.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace storage {
3737

3838
constexpr auto k_redacted_password = "********";
3939

40-
std::string get_features();
40+
std::vector<std::string> get_features();
4141

4242
struct RemoteStorageBackendEntry;
4343
struct RemoteStorageEntry;

src/ccache/util/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(
1212
Tokenizer.cpp
1313
UmaskScope.cpp
1414
assertions.cpp
15+
cpu.cpp
1516
environment.cpp
1617
error.cpp
1718
file.cpp

src/ccache/util/cpu.cpp

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (C) 2024 Joel Rosdahl and other contributors
2+
//
3+
// See doc/AUTHORS.adoc for a complete list of contributors.
4+
//
5+
// This program is free software; you can redistribute it and/or modify it
6+
// under the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3 of the License, or (at your option)
8+
// any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful, but WITHOUT
11+
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13+
// more details.
14+
//
15+
// You should have received a copy of the GNU General Public License along with
16+
// this program; if not, write to the Free Software Foundation, Inc., 51
17+
// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
#include "cpu.hpp"
20+
21+
#ifdef _MSC_VER
22+
# include <intrin.h>
23+
#endif
24+
25+
#ifdef HAVE_CPUID_H
26+
# include <cpuid.h>
27+
#endif
28+
29+
namespace util {
30+
31+
bool
32+
cpu_supports_avx2()
33+
{
34+
// CPUID with EAX=7 ECX=0 returns AVX2 support in bit 5 of EBX.
35+
int registers[4]; // EAX, EBX, ECX, EDX
36+
#if defined(_MSC_VER) && defined(_M_X64)
37+
__cpuidex(registers, 7, 0);
38+
#elif defined(HAVE_CPUID_H)
39+
__cpuid_count(7, 0, registers[0], registers[1], registers[2], registers[3]);
40+
#elif __x86_64__
41+
__asm__ __volatile__("cpuid"
42+
: "=a"(registers[0]),
43+
"=b"(registers[1]),
44+
"=c"(registers[2]),
45+
"=d"(registers[3])
46+
: "a"(7), "c"(0));
47+
#else
48+
registers[1] = 0;
49+
#endif
50+
return registers[1] & (1 << 5);
51+
}
52+
53+
} // namespace util

src/ccache/util/cpu.hpp

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (C) 2024 Joel Rosdahl and other contributors
2+
//
3+
// See doc/AUTHORS.adoc for a complete list of contributors.
4+
//
5+
// This program is free software; you can redistribute it and/or modify it
6+
// under the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3 of the License, or (at your option)
8+
// any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful, but WITHOUT
11+
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13+
// more details.
14+
//
15+
// You should have received a copy of the GNU General Public License along with
16+
// this program; if not, write to the Free Software Foundation, Inc., 51
17+
// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
#pragma once
20+
21+
namespace util {
22+
23+
// --- Interface ---
24+
25+
bool cpu_supports_avx2();
26+
27+
} // namespace util

src/third_party/blake3/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
add_library(dep_blake3 STATIC blake3.c blake3_dispatch_ccache.c blake3_portable.c)
1+
add_library(dep_blake3 STATIC blake3.c blake3_dispatch.c blake3_portable.c)
22

33
target_include_directories(dep_blake3 INTERFACE "${CMAKE_SOURCE_DIR}/src/third_party/blake3")
44
target_link_libraries(dep_blake3 PRIVATE standard_settings)

src/third_party/blake3/blake3_cpu_supports_avx2.h

-18
This file was deleted.

src/third_party/blake3/blake3_dispatch_ccache.c

-10
This file was deleted.

0 commit comments

Comments
 (0)