diff --git a/CMakeLists.txt b/CMakeLists.txt index d847dd4f..43e482b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ cmake_minimum_required(VERSION 3.28.0) # Enable CMAKE_MSVC_RUNTIME_LIBRARY cmake_policy(SET CMP0091 NEW) -project(dwarfs) +project(dwarfs LANGUAGES CXX C) include(ExternalProject) include(CheckCXXSourceCompiles) diff --git a/cmake/libdwarfs_tool.cmake b/cmake/libdwarfs_tool.cmake index 4d56d452..99ba7eec 100644 --- a/cmake/libdwarfs_tool.cmake +++ b/cmake/libdwarfs_tool.cmake @@ -29,6 +29,15 @@ add_library( tools/src/tool/tool.cpp ) +# TODO: Try enabling folly memcpy also for ARM if we figure out how that works :-) +if(STATIC_BUILD_DO_NOT_USE AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + enable_language(ASM) + target_sources(dwarfs_tool PRIVATE folly/folly/memcpy.S) + set_property(SOURCE folly/folly/memcpy.S APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp" "-D__AVX2__") + target_link_options(dwarfs_tool PUBLIC -Wl,--wrap=memcpy) + target_compile_definitions(dwarfs_tool PRIVATE -DDWARFS_USE_FOLLY_MEMCPY) +endif() + if(WITH_MAN_OPTION) target_sources(dwarfs_tool PRIVATE tools/src/tool/pager.cpp diff --git a/tools/include/dwarfs/tool/main_adapter.h b/tools/include/dwarfs/tool/main_adapter.h index 472a1763..3cab7f17 100644 --- a/tools/include/dwarfs/tool/main_adapter.h +++ b/tools/include/dwarfs/tool/main_adapter.h @@ -42,8 +42,7 @@ class main_adapter { public: using main_fn_type = int (*)(int, sys_char**, iolayer const&); - explicit main_adapter(main_fn_type main_fn) - : main_fn_(main_fn) {} + explicit main_adapter(main_fn_type main_fn); int operator()(int argc, sys_char** argv) const; int operator()(std::span args, iolayer const& iol) const; diff --git a/tools/src/tool/main_adapter.cpp b/tools/src/tool/main_adapter.cpp index 2e4e09c1..4d93d9f6 100644 --- a/tools/src/tool/main_adapter.cpp +++ b/tools/src/tool/main_adapter.cpp @@ -26,12 +26,48 @@ * SPDX-License-Identifier: MIT */ +#include #include +#include + #include #include #include +#ifdef DWARFS_USE_FOLLY_MEMCPY + +extern "C" { + +extern void* __real_memcpy(void* dest, void const* src, size_t size); +extern void* __folly_memcpy(void* dest, void const* src, size_t size); +} + +namespace { + +static void* (*the_memcpy)(void*, void const*, size_t) = &__real_memcpy; + +void select_memcpy() { + bool const debug = dwarfs::getenv_is_enabled("DWARFS_DEBUG_MEMCPY"); + if (__builtin_cpu_supports("avx2")) { + the_memcpy = &__folly_memcpy; + if (debug) { + std::cerr << "Using AVX2 memcpy\n"; + } + } else if (debug) { + std::cerr << "Using default memcpy\n"; + } +} + +} // namespace + +extern "C" void* +__wrap_memcpy(void* __restrict dest, void const* __restrict src, size_t size) { + return the_memcpy(dest, src, size); +} + +#endif // DWARFS_USE_FOLLY_MEMCPY + namespace dwarfs::tool { namespace { @@ -52,6 +88,13 @@ int call_sys_main_iolayer(std::span args, iolayer const& iol, } // namespace +main_adapter::main_adapter(main_fn_type main_fn) + : main_fn_(main_fn) { +#ifdef DWARFS_USE_FOLLY_MEMCPY + select_memcpy(); +#endif +} + int main_adapter::operator()(int argc, sys_char** argv) const { return main_fn_(argc, argv, iolayer::system_default()); }