From bcfaad06b1325c1b15e6bffe52af340071e6494c Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 12 Jul 2024 19:30:02 +0900 Subject: [PATCH 1/6] Add LTO build of wasi-libc --- cmake/wasi-sdk-sysroot.cmake | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cmake/wasi-sdk-sysroot.cmake b/cmake/wasi-sdk-sysroot.cmake index 7e7345b0f..c2df2426d 100644 --- a/cmake/wasi-sdk-sysroot.cmake +++ b/cmake/wasi-sdk-sysroot.cmake @@ -102,10 +102,13 @@ function(define_wasi_libc target) if(${target} MATCHES threads) set(extra_make_flags THREAD_MODEL=posix) + set(extra_make_flags_lto LTO=full THREAD_MODEL=posix) elseif(${target} MATCHES p2) set(extra_make_flags WASI_SNAPSHOT=p2 default libc_so) + set(extra_make_flags_lto LTO=full WASI_SNAPSHOT=p2 default) else() set(extra_make_flags default libc_so) + set(extra_make_flags_lto LTO=full default) endif() string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER) @@ -129,8 +132,17 @@ function(define_wasi_libc target) NM=${CMAKE_NM} SYSROOT=${wasi_sysroot} EXTRA_CFLAGS=${extra_cflags} - TARGET_TRIPLE=${target} + TARGET_TRIPLE=${target} ${extra_make_flags} + COMMAND + ${MAKE} -j8 -C ${build_dir} + CC=${CMAKE_C_COMPILER} + AR=${CMAKE_AR} + NM=${CMAKE_NM} + SYSROOT=${wasi_sysroot} + EXTRA_CFLAGS=${extra_cflags} + TARGET_TRIPLE=${target} + ${extra_make_flags_lto} INSTALL_COMMAND "" DEPENDS compiler-rt EXCLUDE_FROM_ALL ON From afe909d8f32336e9737c8096b0eb254572b07bcf Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 12 Jul 2024 20:38:59 +0900 Subject: [PATCH 2/6] Add LTO build of libc++ --- cmake/wasi-sdk-sysroot.cmake | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/cmake/wasi-sdk-sysroot.cmake b/cmake/wasi-sdk-sysroot.cmake index c2df2426d..b05ae1b97 100644 --- a/cmake/wasi-sdk-sysroot.cmake +++ b/cmake/wasi-sdk-sysroot.cmake @@ -160,7 +160,12 @@ endforeach() # libcxx build logic # ============================================================================= -function(define_libcxx target) +execute_process( + COMMAND ${CMAKE_C_COMPILER} -dumpversion + OUTPUT_VARIABLE llvm_version + OUTPUT_STRIP_TRAILING_WHITESPACE) + +function(define_libcxx_sub target target_suffix extra_target_flags extra_libdir_suffix) if(${target} MATCHES threads) set(threads ON) set(pic OFF) @@ -170,6 +175,10 @@ function(define_libcxx target) set(pic ON) set(target_flags "") endif() + if(${target_suffix} MATCHES lto) + set(pic OFF) + endif() + list(APPEND target_flags ${extra_target_flags}) set(runtimes "libcxx;libcxxabi") @@ -188,7 +197,7 @@ function(define_libcxx target) set(extra_cxxflags_list ${CMAKE_CXX_FLAGS} ${extra_flags}) list(JOIN extra_cxxflags_list " " extra_cxxflags) - ExternalProject_Add(libcxx-${target}-build + ExternalProject_Add(libcxx-${target}${target_suffix}-build SOURCE_DIR ${llvm_proj_dir}/runtimes CMAKE_ARGS ${default_cmake_args} @@ -226,8 +235,8 @@ function(define_libcxx target) -DUNIX:BOOL=ON -DCMAKE_C_FLAGS=${extra_cflags} -DCMAKE_CXX_FLAGS=${extra_cxxflags} - -DLIBCXX_LIBDIR_SUFFIX=/${target} - -DLIBCXXABI_LIBDIR_SUFFIX=/${target} + -DLIBCXX_LIBDIR_SUFFIX=/${target}${extra_libdir_suffix} + -DLIBCXXABI_LIBDIR_SUFFIX=/${target}${extra_libdir_suffix} # See https://www.scivision.dev/cmake-externalproject-list-arguments/ for # why this is in `CMAKE_CACHE_ARGS` instead of above @@ -241,6 +250,11 @@ function(define_libcxx target) USES_TERMINAL_BUILD ON USES_TERMINAL_INSTALL ON ) +endfunction() + +function(define_libcxx target) + define_libcxx_sub(${target} "" "" "") + define_libcxx_sub(${target} "-lto" "-flto=full" "/llvm-lto/${llvm_version}") # As of this writing, `clang++` will ignore the target-specific include dirs # unless this one also exists: @@ -248,7 +262,7 @@ function(define_libcxx target) COMMAND ${CMAKE_COMMAND} -E make_directory ${wasi_sysroot}/include/c++/v1 COMMENT "creating libcxx-specific header file folder") add_custom_target(libcxx-${target} - DEPENDS libcxx-${target}-build libcxx-${target}-extra-dir) + DEPENDS libcxx-${target}-build libcxx-${target}-lto-build libcxx-${target}-extra-dir) endfunction() foreach(target IN LISTS WASI_SDK_TARGETS) From 252deae54d55f73514918b4328a397301d65e1d0 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sat, 13 Jul 2024 12:21:32 +0900 Subject: [PATCH 3/6] Update wasi-libc (to include the LTO support) --- src/wasi-libc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wasi-libc b/src/wasi-libc index 3f43ea9ab..b9e15a8af 160000 --- a/src/wasi-libc +++ b/src/wasi-libc @@ -1 +1 @@ -Subproject commit 3f43ea9abb24ed8d24d760989e1d87ea385f8eaa +Subproject commit b9e15a8af930603183eb13af62e193de0f9f9ee3 From 343292513493ff0f56debc25c6d0150c813f5026 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 16 Jul 2024 08:05:03 +0900 Subject: [PATCH 4/6] Add a comment about /llvm-lto/${llvm_version} convention --- cmake/wasi-sdk-sysroot.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/wasi-sdk-sysroot.cmake b/cmake/wasi-sdk-sysroot.cmake index b05ae1b97..aae0d3487 100644 --- a/cmake/wasi-sdk-sysroot.cmake +++ b/cmake/wasi-sdk-sysroot.cmake @@ -254,6 +254,8 @@ endfunction() function(define_libcxx target) define_libcxx_sub(${target} "" "" "") + # Note: clang knows this /llvm-lto/${llvm_version} convention. + # https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/clang/lib/Driver/ToolChains/WebAssembly.cpp#L204-L210 define_libcxx_sub(${target} "-lto" "-flto=full" "/llvm-lto/${llvm_version}") # As of this writing, `clang++` will ignore the target-specific include dirs From 6ab86ef756f2559c198b9655287f29e98eb44755 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 16 Jul 2024 09:22:08 +0900 Subject: [PATCH 5/6] Use separate targets for wasi-libc with and without lto A downside: this makes four more copies of wasi-libc source tree. --- cmake/wasi-sdk-sysroot.cmake | 44 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/cmake/wasi-sdk-sysroot.cmake b/cmake/wasi-sdk-sysroot.cmake index aae0d3487..6e0c38ddd 100644 --- a/cmake/wasi-sdk-sysroot.cmake +++ b/cmake/wasi-sdk-sysroot.cmake @@ -97,18 +97,27 @@ add_custom_target(compiler-rt DEPENDS compiler-rt-build compiler-rt-post-build) # wasi-libc build logic # ============================================================================= -function(define_wasi_libc target) - set(build_dir ${CMAKE_CURRENT_BINARY_DIR}/wasi-libc-${target}) +function(define_wasi_libc_sub target target_suffix lto) + set(build_dir ${CMAKE_CURRENT_BINARY_DIR}/wasi-libc-${target}${target_suffix}) if(${target} MATCHES threads) - set(extra_make_flags THREAD_MODEL=posix) - set(extra_make_flags_lto LTO=full THREAD_MODEL=posix) + if(lto) + set(extra_make_flags LTO=full THREAD_MODEL=posix) + else() + set(extra_make_flags THREAD_MODEL=posix) + endif() elseif(${target} MATCHES p2) - set(extra_make_flags WASI_SNAPSHOT=p2 default libc_so) - set(extra_make_flags_lto LTO=full WASI_SNAPSHOT=p2 default) + if(lto) + set(extra_make_flags LTO=full WASI_SNAPSHOT=p2 default) + else() + set(extra_make_flags WASI_SNAPSHOT=p2 default libc_so) + endif() else() - set(extra_make_flags default libc_so) - set(extra_make_flags_lto LTO=full default) + if(lto) + set(extra_make_flags LTO=full default) + else() + set(extra_make_flags default libc_so) + endif() endif() string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER) @@ -117,7 +126,7 @@ function(define_wasi_libc target) "${CMAKE_C_FLAGS} ${directory_cflags} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}") list(JOIN extra_cflags_list " " extra_cflags) - ExternalProject_Add(wasi-libc-${target} + ExternalProject_Add(wasi-libc-${target}${target_suffix}-build # Currently wasi-libc doesn't support out-of-tree builds so feigh a # "download command" which copies the source tree to a different location # so out-of-tree builds are supported. @@ -134,15 +143,6 @@ function(define_wasi_libc target) EXTRA_CFLAGS=${extra_cflags} TARGET_TRIPLE=${target} ${extra_make_flags} - COMMAND - ${MAKE} -j8 -C ${build_dir} - CC=${CMAKE_C_COMPILER} - AR=${CMAKE_AR} - NM=${CMAKE_NM} - SYSROOT=${wasi_sysroot} - EXTRA_CFLAGS=${extra_cflags} - TARGET_TRIPLE=${target} - ${extra_make_flags_lto} INSTALL_COMMAND "" DEPENDS compiler-rt EXCLUDE_FROM_ALL ON @@ -152,6 +152,14 @@ function(define_wasi_libc target) ) endfunction() +function(define_wasi_libc target) + define_wasi_libc_sub (${target} "" OFF) + define_wasi_libc_sub (${target} "-lto" ON) + + add_custom_target(wasi-libc-${target} + DEPENDS wasi-libc-${target}-build wasi-libc-${target}-lto-build) +endfunction() + foreach(target IN LISTS WASI_SDK_TARGETS) define_wasi_libc(${target}) endforeach() From e7ceecb22a813064f27688408dbe881e4be1790d Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 16 Jul 2024 10:45:25 +0900 Subject: [PATCH 6/6] Make LTO build optional --- cmake/wasi-sdk-sysroot.cmake | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cmake/wasi-sdk-sysroot.cmake b/cmake/wasi-sdk-sysroot.cmake index 6e0c38ddd..6bed7d37d 100644 --- a/cmake/wasi-sdk-sysroot.cmake +++ b/cmake/wasi-sdk-sysroot.cmake @@ -10,6 +10,7 @@ find_program(MAKE make REQUIRED) option(WASI_SDK_DEBUG_PREFIX_MAP "Pass `-fdebug-prefix-map` for built artifacts" ON) option(WASI_SDK_INCLUDE_TESTS "Whether or not to build tests by default" OFF) option(WASI_SDK_INSTALL_TO_CLANG_RESOURCE_DIR "Whether or not to modify the compiler's resource directory" OFF) +option(WASI_SDK_LTO "Whether or not to build LTO assets" ON) set(wasi_tmp_install ${CMAKE_CURRENT_BINARY_DIR}/install) set(wasi_sysroot ${wasi_tmp_install}/share/wasi-sysroot) @@ -154,10 +155,12 @@ endfunction() function(define_wasi_libc target) define_wasi_libc_sub (${target} "" OFF) - define_wasi_libc_sub (${target} "-lto" ON) + if(WASI_SDK_LTO) + define_wasi_libc_sub (${target} "-lto" ON) + endif() add_custom_target(wasi-libc-${target} - DEPENDS wasi-libc-${target}-build wasi-libc-${target}-lto-build) + DEPENDS wasi-libc-${target}-build $<$:wasi-libc-${target}-lto-build>) endfunction() foreach(target IN LISTS WASI_SDK_TARGETS) @@ -262,9 +265,11 @@ endfunction() function(define_libcxx target) define_libcxx_sub(${target} "" "" "") - # Note: clang knows this /llvm-lto/${llvm_version} convention. - # https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/clang/lib/Driver/ToolChains/WebAssembly.cpp#L204-L210 - define_libcxx_sub(${target} "-lto" "-flto=full" "/llvm-lto/${llvm_version}") + if(WASI_SDK_LTO) + # Note: clang knows this /llvm-lto/${llvm_version} convention. + # https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/clang/lib/Driver/ToolChains/WebAssembly.cpp#L204-L210 + define_libcxx_sub(${target} "-lto" "-flto=full" "/llvm-lto/${llvm_version}") + endif() # As of this writing, `clang++` will ignore the target-specific include dirs # unless this one also exists: @@ -272,7 +277,7 @@ function(define_libcxx target) COMMAND ${CMAKE_COMMAND} -E make_directory ${wasi_sysroot}/include/c++/v1 COMMENT "creating libcxx-specific header file folder") add_custom_target(libcxx-${target} - DEPENDS libcxx-${target}-build libcxx-${target}-lto-build libcxx-${target}-extra-dir) + DEPENDS libcxx-${target}-build $<$:libcxx-${target}-lto-build> libcxx-${target}-extra-dir) endfunction() foreach(target IN LISTS WASI_SDK_TARGETS)