Skip to content

Commit

Permalink
Blake3 build (ccache#781)
Browse files Browse the repository at this point in the history
* Build the blake3 asm files to determine if they are supported

Building the files doesn't take long and gives a better result than just
checking that the assembler accepts a flag.

See also ccache#768.

* Remove no longer used cmake function

* Update BLAKE3 to 3a8204f5f (0.3.7 + minor fixes) and include all MSVC asm files

* Try to improve blake3 on MSVC by using asm version
  • Loading branch information
erijo authored Jan 19, 2021
1 parent 3ea726f commit bcd08a3
Show file tree
Hide file tree
Showing 10 changed files with 6,648 additions and 96 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
cmake_minimum_required(VERSION 3.4.3)

project(ccache LANGUAGES C CXX ASM)
project(ccache LANGUAGES C CXX)
if(MSVC)
enable_language(ASM_MASM)
else()
enable_language(ASM)
endif()
set(CMAKE_PROJECT_DESCRIPTION "a fast C/C++ compiler cache")

if(NOT "${CMAKE_CXX_STANDARD}")
Expand Down
62 changes: 0 additions & 62 deletions cmake/CheckAsmCompilerFlag.cmake

This file was deleted.

104 changes: 75 additions & 29 deletions src/third_party/blake3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,63 @@ add_library(blake3 STATIC blake3.c blake3_dispatch_ccache.c blake3_portable.c)

target_link_libraries(blake3 PRIVATE standard_settings)

if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SIZEOF_VOID_P EQUAL 8
AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
set(blake_source_type asm)
set(blake_suffix "_x86-64_unix.S")
else()
set(blake_source_type c)
set(blake_suffix ".c")
if(MSVC)
# No object file is created if masm is passed the compile options from standard_settings,
# so don't pass any flags at all to assembler (as no flags are needed anyway).
string(REPLACE "<FLAGS> " "" CMAKE_ASM_MASM_COMPILE_OBJECT "${CMAKE_ASM_MASM_COMPILE_OBJECT}")
endif()

include(CheckAsmCompilerFlag)
include(CheckCSourceCompiles)

function(add_source_if_enabled feature compile_flags intrinsic)
string(TOUPPER "have_${blake_source_type}_${feature}" have_feature)

# AVX512 support fails to compile with old Apple Clang versions even though
# the compiler accepts the -m flags.
if(${feature} STREQUAL "avx512"
AND CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
message(STATUS "Detected unsupported compiler for ${have_feature} - disabled")
set(${have_feature} FALSE)
elseif(${blake_source_type} STREQUAL "asm")
check_asm_compiler_flag(${compile_flags} ${have_feature})
function(add_source_if_enabled feature msvc_flags others_flags intrinsic)
if(MSVC)
set(compile_flags "${msvc_flags}")
else()
set(compile_flags "${others_flags}")
endif()

# First check if it's possible to use the assembler variant for the feature.
string(TOUPPER "have_asm_${feature}" have_feature)
if(NOT DEFINED "${have_feature}" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
if(MSVC)
set(suffix "_x86-64_windows_msvc.asm")
elseif(WIN32)
set(suffix "_x86-64_windows_gnu.S")
else()
set(suffix "_x86-64_unix.S")
endif()

if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${have_feature}")
endif()

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# Must set CMAKE_ASM_MASM_CREATE_STATIC_LIBRARY explicitly otherwise try_compile
# fails, see https://discourse.cmake.org/t/building-lib-file-from-asm-cmake-bug/1959
try_compile(
${have_feature}
${CMAKE_CURRENT_BINARY_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/blake3_${feature}${suffix}"
CMAKE_FLAGS -DCMAKE_ASM_MASM_CREATE_STATIC_LIBRARY=${CMAKE_C_CREATE_STATIC_LIBRARY}
COMPILE_DEFINITIONS ${compile_flags})

unset(CMAKE_TRY_COMPILE_TARGET_TYPE)

if(NOT CMAKE_REQUIRED_QUIET)
if (${${have_feature}})
message(STATUS "Performing Test ${have_feature} - Success")
else()
message(STATUS "Performing Test ${have_feature} - Failed")
endif()
endif()
endif()

# If the assembler variant didn't work, try the c variant.
if(NOT ${have_feature})
string(TOUPPER "have_c_${feature}" have_feature)
set(suffix ".c")

set(CMAKE_REQUIRED_FLAGS ${compile_flags})
check_c_source_compiles(
[=[
Expand All @@ -39,21 +70,36 @@ function(add_source_if_enabled feature compile_flags intrinsic)
endif()

if(${have_feature})
target_sources(blake3 PRIVATE blake3_${feature}${blake_suffix})
set_property(
SOURCE blake3_${feature}${blake_suffix}
APPEND PROPERTY COMPILE_FLAGS ${compile_flags})
target_sources(blake3 PRIVATE blake3_${feature}${suffix})
if(suffix STREQUAL ".c")
if(MINGW AND feature STREQUAL "avx512")
# Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65782.
# Taken from blake3's build.rs.
set(compile_flags "${compile_flags} -fno-asynchronous-unwind-tables")
endif()
set_property(
SOURCE blake3_${feature}${suffix}
APPEND PROPERTY COMPILE_FLAGS ${compile_flags})
elseif(NOT MSVC)
set_property(
SOURCE blake3_${feature}${suffix}
PROPERTY COMPILE_FLAGS ${compile_flags})
endif()
else()
string(TOUPPER "blake3_no_${feature}" no_feature)
target_compile_definitions(blake3 PRIVATE ${no_feature})
endif()
endfunction()

# https://software.intel.com/sites/landingpage/IntrinsicsGuide/
add_source_if_enabled(sse2 "-msse2" "_mm_set1_epi32(42)")
add_source_if_enabled(sse41 "-msse4.1" "_mm_test_all_ones(_mm_set1_epi32(42))")
add_source_if_enabled(avx2 "-mavx2" "_mm256_abs_epi8(_mm256_set1_epi32(42))")
add_source_if_enabled(avx512 "-mavx512f -mavx512vl" "_mm256_abs_epi64(_mm256_set1_epi32(42))")
add_source_if_enabled(sse2 "" "-msse2"
"_mm_set1_epi32(42)")
add_source_if_enabled(sse41 "" "-msse4.1"
"_mm_test_all_ones(_mm_set1_epi32(42))")
add_source_if_enabled(avx2 "/arch:AVX2" "-mavx2"
"_mm256_abs_epi8(_mm256_set1_epi32(42))")
add_source_if_enabled(avx512 "/arch:AVX512" "-mavx512f -mavx512vl"
"_mm256_abs_epi64(_mm256_set1_epi32(42))")

# Neon is always available on AArch64
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
Expand Down
4 changes: 4 additions & 0 deletions src/third_party/blake3/blake3.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include "blake3.h"
#include "blake3_impl.h"

const char * blake3_version(void) {
return BLAKE3_VERSION_STRING;
}

INLINE void chunk_state_init(blake3_chunk_state *self, const uint32_t key[8],
uint8_t flags) {
memcpy(self->cv, key, BLAKE3_KEY_LEN);
Expand Down
2 changes: 2 additions & 0 deletions src/third_party/blake3/blake3.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
extern "C" {
#endif

#define BLAKE3_VERSION_STRING "0.3.7"
#define BLAKE3_KEY_LEN 32
#define BLAKE3_OUT_LEN 32
#define BLAKE3_BLOCK_LEN 64
Expand Down Expand Up @@ -38,6 +39,7 @@ typedef struct {
uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
} blake3_hasher;

const char * blake3_version(void);
void blake3_hasher_init(blake3_hasher *self);
void blake3_hasher_init_keyed(blake3_hasher *self,
const uint8_t key[BLAKE3_KEY_LEN]);
Expand Down
Loading

0 comments on commit bcd08a3

Please sign in to comment.