From 088818bf44b7649d233bb8be22cbb820b2d5926c Mon Sep 17 00:00:00 2001 From: nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com> Date: Thu, 30 Jun 2022 19:14:34 -0700 Subject: [PATCH] [benchmark] add gbenchmark (#2780) Co-authored-by: Nicole Mazzuca Co-authored-by: Stephan T. Lavavej Co-authored-by: Casey Carter --- .gitignore | 1 + .gitmodules | 3 + .vscode/settings.json | 6 +- CMakeLists.txt | 48 +++------ NOTICE.txt | 10 ++ README.md | 44 ++++++++- azure-devops/checkout-sources.yml | 27 +++++ azure-devops/cmake-configure-build.yml | 4 + azure-devops/cross-build.yml | 4 + azure-pipelines.yml | 1 + benchmarks/CMakeLists.txt | 77 +++++++++++++++ benchmarks/google-benchmark | 1 + benchmarks/inc/udt.hpp | 26 +++++ benchmarks/inc/utility.hpp | 23 +++++ benchmarks/inc/xoshiro.hpp | 41 ++++++++ benchmarks/src/std_copy.cpp | 124 +++++++++++++++++++++++ stl/CMakeLists.txt | 131 ++++++++++++++++++------- tests/libcxx/lit.site.cfg.in | 4 +- tests/std/lit.site.cfg.in | 4 +- tests/tr1/lit.site.cfg.in | 4 +- tools/format/CMakeLists.txt | 7 ++ tools/validate/validate.cpp | 1 + 22 files changed, 512 insertions(+), 79 deletions(-) create mode 100644 benchmarks/CMakeLists.txt create mode 160000 benchmarks/google-benchmark create mode 100644 benchmarks/inc/udt.hpp create mode 100644 benchmarks/inc/utility.hpp create mode 100644 benchmarks/inc/xoshiro.hpp create mode 100644 benchmarks/src/std_copy.cpp diff --git a/.gitignore b/.gitignore index 693d320cc7..692a1918b2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ __pycache__/ /out/ /tools/out/ /CMakeLists.txt.user +/*.log diff --git a/.gitmodules b/.gitmodules index d9ff8484bf..f1618b17f5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "boost-math"] path = boost-math url = https://github.com/boostorg/math.git +[submodule "benchmarks/google-benchmark"] + path = benchmarks/google-benchmark + url = https://github.com/google/benchmark.git diff --git a/.vscode/settings.json b/.vscode/settings.json index ed78450048..4c357e6002 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception { "C_Cpp.autoAddFileAssociations": false, - "editor.formatOnSave": true, + "editor.formatOnSave": false, + "[cpp]": { + "editor.formatOnSave": true + }, "files.associations": { ".clang-format": "yaml", "header-units.json": "jsonc", @@ -10,6 +13,7 @@ }, "files.eol": "\r\n", "files.exclude": { + "benchmarks/google-benchmark": true, "llvm-project": true, "stl/msbuild": true, "boost-math": true diff --git a/CMakeLists.txt b/CMakeLists.txt index 08aa354d00..c91d5b02d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,17 +42,11 @@ if(TARGET run-validate) endif() option(BUILD_TESTING "Enable testing" ON) +option(STL_BUILD_BENCHMARKING "Enable benchmarking" OFF) set(VCLIBS_SUFFIX "_oss" CACHE STRING "suffix for built DLL names to avoid conflicts with distributed DLLs") option(STL_USE_ANALYZE "Pass the /analyze flag to MSVC" OFF) -set(CMAKE_CXX_FLAGS "") -set(CMAKE_CXX_FLAGS_DEBUG "") -set(CMAKE_CXX_FLAGS_RELEASE "") -set(CMAKE_CXX_STANDARD_LIBRARIES "kernel32.lib") -set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "kernel32.lib") -set(CMAKE_MSVC_RUNTIME_LIBRARY "") - if("${VCLIBS_TARGET_ARCHITECTURE}" MATCHES "^x86$") set(VCLIBS_TARGET_ARCHITECTURE "x86") set(VCLIBS_I386_OR_AMD64 "i386") @@ -72,27 +66,27 @@ elseif(VCLIBS_TARGET_ARCHITECTURE MATCHES "^armv7$") set(VCLIBS_I386_OR_AMD64 "arm") set(VCLIBS_X86_OR_X64 "arm") add_compile_definitions(_ARM_ _VCRT_WIN32_WINNT=0x0602 _STL_WIN32_WINNT=0x0602) - string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " Synchronization.lib") elseif(VCLIBS_TARGET_ARCHITECTURE MATCHES "^arm64$") set(VCLIBS_TARGET_ARCHITECTURE "arm64") set(VCLIBS_I386_OR_AMD64 "arm64") set(VCLIBS_X86_OR_X64 "arm64") add_compile_definitions(_ARM64_ _VCRT_WIN32_WINNT=0x0A00 _STL_WIN32_WINNT=0x0A00) - string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " Synchronization.lib") else() message(FATAL_ERROR "Could not determine target architecture: VCLIBS_TARGET_ARCHITECTURE: ${VCLIBS_TARGET_ARCHITECTURE}") endif() +get_filename_component(TOOLSET_BINARIES_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) # Example: $\VC\Tools\MSVC\14.23.27931\bin\Hostx86\x86 +get_filename_component(TOOLSET_ROOT_DIR "${TOOLSET_BINARIES_DIR}" DIRECTORY) # $\VC\Tools\MSVC\14.23.27931\bin\Hostx86 +get_filename_component(TOOLSET_ROOT_DIR "${TOOLSET_ROOT_DIR}" DIRECTORY) # $\VC\Tools\MSVC\14.23.27931\bin +get_filename_component(TOOLSET_ROOT_DIR "${TOOLSET_ROOT_DIR}" DIRECTORY) # $\VC\Tools\MSVC\14.23.27931 +set(TOOLSET_LIB "${TOOLSET_ROOT_DIR}/lib/${VCLIBS_X86_OR_X64}") +set(STL_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out/lib/${VCLIBS_I386_OR_AMD64}") +set(STL_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out/lib/${VCLIBS_I386_OR_AMD64}") +set(STL_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out/bin/${VCLIBS_I386_OR_AMD64}") add_compile_definitions( _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH WIN32_LEAN_AND_MEAN STRICT _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS _CRT_DECLARE_NONSTDC_NAMES=1 _WIN32_WINNT=0x0A00 NTDDI_VERSION=NTDDI_WIN10_CO) -add_compile_options(/WX /Gy - "$<$:/diagnostics:caret;/W4;/w14265;/w15038;/fastfail;/guard:cf;/Z7;/Zp8;/std:c++latest;/permissive-;/Zc:threadSafeInit-;/Zl>" - - # note that /Zi generates debug info inside the object file, it's the same as /Z7 for msvc - "$<$:/Zi;/W3;/nologo>") - if(STL_USE_ANALYZE) # TRANSITION OS-40109504: Windows SDK: incorrect SAL annotations on functions the STL uses # warning C6553: The annotation for function 'LCMapStringEx' on _Param_(9) @@ -114,24 +108,6 @@ set(VCLIBS_DEBUG_OPTIONS "$<$:/Od>") # See GH-2108 for more info. set(VCLIBS_RELEASE_OPTIONS "$<$:/O2;/Os>") -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out/lib/${VCLIBS_I386_OR_AMD64}") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out/lib/${VCLIBS_I386_OR_AMD64}") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/out/bin/${VCLIBS_I386_OR_AMD64}") - -set(CMAKE_STATIC_LINKER_FLAGS "/WX") -set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "") -set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "") -set(CMAKE_SHARED_LINKER_FLAGS "/DEBUG:FULL /WX /RELEASE /SUBSYSTEM:Console /NODEFAULTLIB /INCREMENTAL:NO /MANIFEST:NO /DLL /profile /guard:cf /DEBUGTYPE:cv,fixup /LARGEADDRESSAWARE") -set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "") -set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "") - -get_filename_component(TOOLSET_BINARIES_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) # Example: $\VC\Tools\MSVC\14.23.27931\bin\Hostx86\x86 -get_filename_component(TOOLSET_ROOT_DIR "${TOOLSET_BINARIES_DIR}" DIRECTORY) # $\VC\Tools\MSVC\14.23.27931\bin\Hostx86 -get_filename_component(TOOLSET_ROOT_DIR "${TOOLSET_ROOT_DIR}" DIRECTORY) # $\VC\Tools\MSVC\14.23.27931\bin -get_filename_component(TOOLSET_ROOT_DIR "${TOOLSET_ROOT_DIR}" DIRECTORY) # $\VC\Tools\MSVC\14.23.27931 - -set(TOOLSET_LIB "${TOOLSET_ROOT_DIR}/lib/${VCLIBS_X86_OR_X64}") - add_subdirectory(boost-math) add_subdirectory(stl) @@ -139,3 +115,9 @@ if(BUILD_TESTING) enable_testing() add_subdirectory(tests) endif() +if(STL_BUILD_BENCHMARKING) + if(VCLIBS_TARGET_ARCHITECTURE STREQUAL "arm") + message(WARNING "google benchmark does not build on arm32 - this build will likely fail.") + endif() + add_subdirectory(benchmarks) +endif() diff --git a/NOTICE.txt b/NOTICE.txt index 8c846a8667..4a81a50be0 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -216,3 +216,13 @@ In addition, certain files include the notices provided below. // shall not be used in advertising or otherwise to promote the sale, // use or other dealings in these Data Files or Software without prior // written authorization of the copyright holder. + +---------------------- + +/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) + +To the extent possible under law, the author has dedicated all copyright +and related and neighboring rights to this software to the public domain +worldwide. This software is distributed without any warranty. + +See . */ diff --git a/README.md b/README.md index 65f8f8339f..0a87ab04a2 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ Just try to follow these rules, so we can spend more time fixing bugs and implem 2. Open Visual Studio, and choose the "Clone or check out code" option. Enter the URL of this repository, `https://github.com/microsoft/STL`. 3. Open a terminal in the IDE with `` Ctrl + ` `` (by default) or press on "View" in the top bar, and then "Terminal". -4. In the terminal, invoke `git submodule update --init --progress llvm-project boost-math` +4. In the terminal, invoke `git submodule update --init --progress` 5. Choose the architecture you wish to build in the IDE, and build as you would any other project. All necessary CMake settings are set by `CMakeSettings.json`. @@ -398,6 +398,46 @@ build folder to your path: set PATH=C:\STL\out\build\x64\out\bin\amd64;%PATH% ``` +# Benchmarking + +For performance-sensitive code – containers, algorithms, and the like – +you may wish to write and/or run benchmarks, and the STL team will likely +run any benchmarks we do have in our PR process. Additionally, +if you are writing a "performance improvement" PR, please add and run benchmarks +to show that the PR does, in fact, improve performance. + +The benchmarking code is located in `benchmarks`. Adding a new benchmark is as easy as adding a new file +to `benchmarks/src`, and then adding `add_benchmark( )` +to `benchmarks/CMakeLists.txt`. +You may also modify an existing benchmark file. We use Google's [Benchmark][gbenchmark] library, +so you may find [their documentation][gbenchmark:docs] helpful, and you can also read the existing code +for how _we_ use it. + +To run benchmarks, you'll need to configure the STL with the `-DSTL_BUILD_BENCHMARKING=ON` option: + +```cmd +cmake -B out\bench -S . -G Ninja -DSTL_BUILD_BENCHMARKING=ON +cmake --build out\bench +``` + +You can then run your benchmark with: + +```cmd +out\bench\benchmarks\benchmark- --benchmark_out= --benchmark_out_format=csv +``` + +And then you can copy this csv file into Excel, or another spreadsheet program. For example: + +```cmd +out\bench\benchmarks\benchmark-std_copy --benchmark_out=benchmark-std_copy-results.csv --benchmark_out_format=csv +``` + +If you want to see all the other flags you can pass, run: + +```cmd +out\bench\benchmarks\benchmark- --help +``` + # Editing And Testing The Debugger Visualizer ### Modify The Visualizer @@ -500,6 +540,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception [bug tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3Abug [cxx20 tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3Acxx20 [enhancement tag]: https://github.com/microsoft/STL/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement +[gbenchmark]: https://github.com/google/benchmark +[gbenchmark:docs]: https://github.com/google/benchmark/blob/main/docs/user_guide.md [hub]: https://support.microsoft.com/en-us/help/4021566/windows-10-send-feedback-to-microsoft-with-feedback-hub-app [libcxx]: https://libcxx.llvm.org [lit]: https://llvm.org/docs/CommandGuide/lit.html diff --git a/azure-devops/checkout-sources.yml b/azure-devops/checkout-sources.yml index 9deeed7c91..76c9214700 100644 --- a/azure-devops/checkout-sources.yml +++ b/azure-devops/checkout-sources.yml @@ -8,6 +8,9 @@ parameters: - name: boostMathSHAVar type: string default: boostMathSHA +- name: googleBenchmarkSHAVar + type: string + default: googleBenchmarkSHA steps: - checkout: self clean: true @@ -28,6 +31,9 @@ steps: Write-Host "##vso[task.setvariable variable=${{ parameters.llvmSHAVar }};]$llvmSHA" $boostMathSHA = git submodule status --cached boost-math | %{$_ -replace $regexSubmoduleSHA, '$1'} Write-Host "##vso[task.setvariable variable=${{ parameters.boostMathSHAVar }};]$boostMathSHA" + $googleBenchmarkSHA = git submodule status --cached benchmarks/google-benchmark ` + | %{$_ -replace $regexSubmoduleSHA, '$1'} + Write-Host "##vso[task.setvariable variable=${{ parameters.googleBenchmarkSHAVar }};]$googleBenchmarkSHA" - script: | cd $(Build.SourcesDirectory) if not exist "llvm-project" ( @@ -71,3 +77,24 @@ steps: git reset --quiet --hard FETCH_HEAD git clean --quiet -x -d -f -f displayName: "Checkout boost-math source" +- script: | + cd $(Build.SourcesDirectory)/benchmarks + if not exist "google-benchmark" ( + mkdir google-benchmark + ) + cd google-benchmark + + if not exist ".git" ( + del /S /Q * + git init + ) + + git remote get-url googlebenchmark + if errorlevel 1 ( + git remote add googlebenchmark https://github.com/google/benchmark.git + ) + + git fetch --filter=tree:0 --depth=1 googlebenchmark $(${{ parameters.googleBenchmarkSHAVar }}) + git reset --quiet --hard FETCH_HEAD + git clean --quiet -x -d -f -f + displayName: "Checkout google benchmark source" diff --git a/azure-devops/cmake-configure-build.yml b/azure-devops/cmake-configure-build.yml index d43ac81247..b9449ee821 100644 --- a/azure-devops/cmake-configure-build.yml +++ b/azure-devops/cmake-configure-build.yml @@ -11,6 +11,9 @@ parameters: - name: buildOutputLocationVar type: string default: buildOutputLocation +- name: buildBenchmarking + type: string + default: 'ON' - name: cmakeAdditionalFlags type: string default: '' @@ -32,6 +35,7 @@ steps: cmake ${{ parameters.cmakeAdditionalFlags}} -G Ninja ^ -DCMAKE_CXX_COMPILER=cl ^ -DCMAKE_BUILD_TYPE=Release ^ + -DSTL_BUILD_BENCHMARKING=${{ parameters.buildBenchmarking }} ^ -DLIT_FLAGS=$(litFlags) ^ -DSTL_USE_ANALYZE=ON ^ -S $(Build.SourcesDirectory) -B $(${{ parameters.buildOutputLocationVar }}) diff --git a/azure-devops/cross-build.yml b/azure-devops/cross-build.yml index 0f802cacc3..8f159d7cb7 100644 --- a/azure-devops/cross-build.yml +++ b/azure-devops/cross-build.yml @@ -15,6 +15,9 @@ parameters: - name: numShards type: number default: 8 +- name: buildBenchmarking + type: string + default: 'ON' jobs: - job: '${{ parameters.targetPlatform }}' variables: @@ -38,6 +41,7 @@ jobs: targetPlatform: ${{ parameters.targetPlatform }} hostArch: ${{ parameters.hostArch }} targetArch: ${{ parameters.vsDevCmdArch }} + buildBenchmarking: ${{ parameters.buildBenchmarking }} cmakeAdditionalFlags: '-DTESTS_BUILD_ONLY=ON' - template: run-tests.yml parameters: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b339093de8..377d6c63ce 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -86,6 +86,7 @@ stages: parameters: targetPlatform: arm vsDevCmdArch: arm + buildBenchmarking: 'OFF' - stage: Build_ARM64 dependsOn: Build_And_Test_x64 diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt new file mode 100644 index 0000000000..4c68444508 --- /dev/null +++ b/benchmarks/CMakeLists.txt @@ -0,0 +1,77 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set(STL_BENCHMARK_MSVC_RUNTIME_LIBRARY + MultiThreaded + CACHE STRING "The flavor of the standard library to use; see https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html for more information.") +set_property(CACHE STL_BENCHMARK_MSVC_RUNTIME_LIBRARY + PROPERTY STRINGS + "MultiThreaded;MultiThreadedDLL;MultiThreadedDebug;MultiThreadedDebugDLL" +) +set(CMAKE_MSVC_RUNTIME_LIBRARY "${STL_BENCHMARK_MSVC_RUNTIME_LIBRARY}") + +set(STL_BENCHMARK_ITERATOR_DEBUG_LEVEL + default + CACHE STRING "What level of iterator debugging to use." +) +set_property(CACHE STL_BENCHMARK_ITERATOR_DEBUG_LEVEL + PROPERTY STRINGS + "default;0;1;2" +) + +if(NOT STL_BENCHMARK_ITERATOR_DEBUG_LEVEL STREQUAL "default") + add_compile_definitions("_ITERATOR_DEBUG_LEVEL=${STL_BENCHMARK_ITERATOR_DEBUG_LEVEL}") +endif() + +set(CMAKE_BUILD_TYPE RelWithDebInfo) + +if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/google-benchmark/.git") + message(FATAL_ERROR "google-benchmark is not checked out; make sure to run\n git submodule update --init benchmarks/google-benchmark") +endif() + +set(BENCHMARK_ENABLE_DOXYGEN OFF) +set(BENCHMARK_ENABLE_INSTALL OFF) +set(BENCHMARK_ENABLE_TESTING OFF) +set(BUILD_SHARED_LIBS OFF) + +# TRANSITION, GH-2816: on some machines, librt is found, despite it being a unix-only library +set(HAVE_LIB_RT OFF) + +include_directories(BEFORE "${CMAKE_BINARY_DIR}/out/inc") +link_directories(BEFORE "${STL_LIBRARY_OUTPUT_DIRECTORY}") + +add_subdirectory(google-benchmark EXCLUDE_FROM_ALL) + +set(benchmark_headers + "inc/udt.hpp" + "inc/utility.hpp" + "inc/xoshiro.hpp" +) + +function(add_benchmark name) + cmake_parse_arguments(PARSE_ARGV 1 "arg" "" "CXX_STANDARD" "") + + if(NOT DEFINED arg_CXX_STANDARD) + set(arg_CXX_STANDARD 23) + elseif(NOT arg_CXX_STANDARD MATCHES "^[0-9][0-9]$") + message(FATAL_ERROR "Unexpected value for CXX_STANDARD: ${arg_CXX_STANDARD}") + endif() + + if(NOT DEFINED arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "benchmark ${name} does not have any source files") + endif() + + add_executable(benchmark-${name} + ${benchmark_headers} + ${arg_UNPARSED_ARGUMENTS} + ) + + target_compile_features(benchmark-${name} PRIVATE cxx_std_${arg_CXX_STANDARD}) + target_include_directories(benchmark-${name} PRIVATE inc) + target_link_libraries(benchmark-${name} PRIVATE benchmark::benchmark) +endfunction() + +add_benchmark(std_copy + src/std_copy.cpp + CXX_STANDARD 23 +) diff --git a/benchmarks/google-benchmark b/benchmarks/google-benchmark new file mode 160000 index 0000000000..0d98dba29d --- /dev/null +++ b/benchmarks/google-benchmark @@ -0,0 +1 @@ +Subproject commit 0d98dba29d66e93259db7daa53a9327df767a415 diff --git a/benchmarks/inc/udt.hpp b/benchmarks/inc/udt.hpp new file mode 100644 index 0000000000..b47c58c2c9 --- /dev/null +++ b/benchmarks/inc/udt.hpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#pragma once + +template +struct aggregate { + Contained c; + + friend bool operator==(const aggregate&, const aggregate&) = default; +}; + +template +struct non_trivial { + Contained c; + non_trivial() : c() {} + non_trivial(const Contained& src) : c(src) {} + non_trivial(const non_trivial& other) : c(other.c) {} + non_trivial& operator=(const non_trivial& other) { + c = other.c; + return *this; + } + ~non_trivial() {} + + friend bool operator==(const non_trivial&, const non_trivial&) = default; +}; diff --git a/benchmarks/inc/utility.hpp b/benchmarks/inc/utility.hpp new file mode 100644 index 0000000000..a27e1bacea --- /dev/null +++ b/benchmarks/inc/utility.hpp @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#pragma once + +#include +#include +#include +#include +#include + +#include + +template +std::vector random_vector(size_t n) { + std::random_device rd; + std::uniform_int_distribution id64; + xoshiro256ss prng{id64(rd), id64(rd), id64(rd), id64(rd)}; + + std::vector res(n); + std::generate(res.begin(), res.end(), [&prng] { return static_cast(prng.next()); }); + return res; +} diff --git a/benchmarks/inc/xoshiro.hpp b/benchmarks/inc/xoshiro.hpp new file mode 100644 index 0000000000..82d4856ef5 --- /dev/null +++ b/benchmarks/inc/xoshiro.hpp @@ -0,0 +1,41 @@ +/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) + +To the extent possible under law, the author has dedicated all copyright +and related and neighboring rights to this software to the public domain +worldwide. This software is distributed without any warranty. + +See . +SPDX-License-Identifier: CC0-1.0 */ + +#pragma once + +#include +#include + +struct xoshiro256ss { + xoshiro256ss() = delete; + xoshiro256ss(uint64_t s0, uint64_t s1, uint64_t s2, uint64_t s3) : s0_(s0), s1_(s1), s2_(s2), s3_(s3) {} + + uint64_t next() { + auto result = std::rotl(s1_ * 5, 7) * 9; + + const uint64_t t = s1_ << 17; + + s2_ ^= s0_; + s3_ ^= s1_; + s1_ ^= s2_; + s0_ ^= s3_; + + s2_ ^= t; + + s3_ = std::rotl(s3_, 45); + + return result; + } + +private: + uint64_t s0_; + uint64_t s1_; + uint64_t s2_; + uint64_t s3_; +}; diff --git a/benchmarks/src/std_copy.cpp b/benchmarks/src/std_copy.cpp new file mode 100644 index 0000000000..a84d58d19d --- /dev/null +++ b/benchmarks/src/std_copy.cpp @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace { + + template + void handwritten_loop(benchmark::State& state) { + const size_t r0 = static_cast(state.range(0)); + const auto in_buffer = random_vector(r0); + std::vector out_buffer(r0); + for ([[maybe_unused]] auto _ : state) { + benchmark::DoNotOptimize(in_buffer.data()); + const Contained* in_ptr = in_buffer.data(); + const Contained* const in_ptr_end = in_ptr + r0; + Contained* out_ptr = out_buffer.data(); + while (in_ptr != in_ptr_end) { + *out_ptr++ = *in_ptr++; + } + + benchmark::DoNotOptimize(out_buffer.data()); + } + } + + template + void handwritten_loop_n(benchmark::State& state) { + const size_t r0 = static_cast(state.range(0)); + const auto in_buffer = random_vector(r0); + std::vector out_buffer(r0); + for ([[maybe_unused]] auto _ : state) { + benchmark::DoNotOptimize(in_buffer.data()); + const Contained* const in_ptr = in_buffer.data(); + Contained* const out_ptr = out_buffer.data(); + for (size_t idx = 0; idx < r0; ++idx) { + out_ptr[idx] = in_ptr[idx]; + } + + benchmark::DoNotOptimize(out_buffer.data()); + } + } + + template + void memcpy_call(benchmark::State& state) { + static_assert( + std::is_trivially_copyable_v, "memcpy must only be called on trivially copyable types"); + const size_t r0 = static_cast(state.range(0)); + const auto in_buffer = random_vector(r0); + std::vector out_buffer(r0); + for ([[maybe_unused]] auto _ : state) { + benchmark::DoNotOptimize(in_buffer.data()); + memcpy(out_buffer.data(), in_buffer.data(), r0 * sizeof(Contained)); + benchmark::DoNotOptimize(out_buffer.data()); + } + } + + template + void std_copy_call(benchmark::State& state) { + const size_t r0 = static_cast(state.range(0)); + const auto in_buffer = random_vector(r0); + std::vector out_buffer(r0); + for ([[maybe_unused]] auto _ : state) { + benchmark::DoNotOptimize(in_buffer.data()); + std::copy(in_buffer.begin(), in_buffer.end(), out_buffer.begin()); + benchmark::DoNotOptimize(out_buffer.data()); + } + } + + template + void std_copy_n_call(benchmark::State& state) { + const size_t r0 = static_cast(state.range(0)); + const auto in_buffer = random_vector(r0); + std::vector out_buffer(r0); + for ([[maybe_unused]] auto _ : state) { + benchmark::DoNotOptimize(in_buffer.data()); + std::copy_n(in_buffer.begin(), r0, out_buffer.begin()); + benchmark::DoNotOptimize(out_buffer.data()); + } + } +} // namespace + +BENCHMARK_TEMPLATE1(handwritten_loop, char)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(handwritten_loop_n, char)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(memcpy_call, char)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(std_copy_call, char)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(std_copy_n_call, char)->Range(0, 1 << 18); + +BENCHMARK_TEMPLATE1(handwritten_loop, aggregate)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(handwritten_loop_n, aggregate)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(memcpy_call, aggregate)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(std_copy_call, aggregate)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(std_copy_n_call, aggregate)->Range(0, 1 << 18); + +BENCHMARK_TEMPLATE1(handwritten_loop, non_trivial)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(handwritten_loop_n, non_trivial)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(std_copy_call, non_trivial)->Range(0, 1 << 18); +BENCHMARK_TEMPLATE1(std_copy_n_call, non_trivial)->Range(0, 1 << 18); + +BENCHMARK_TEMPLATE1(handwritten_loop, int)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(handwritten_loop_n, int)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(memcpy_call, int)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(std_copy_call, int)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(std_copy_n_call, int)->Range(0, 1 << 15); + +BENCHMARK_TEMPLATE1(handwritten_loop, aggregate)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(handwritten_loop_n, aggregate)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(memcpy_call, aggregate)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(std_copy_call, aggregate)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(std_copy_n_call, aggregate)->Range(0, 1 << 15); + +BENCHMARK_TEMPLATE1(handwritten_loop, non_trivial)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(handwritten_loop_n, non_trivial)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(std_copy_call, non_trivial)->Range(0, 1 << 15); +BENCHMARK_TEMPLATE1(std_copy_n_call, non_trivial)->Range(0, 1 << 15); + +BENCHMARK_MAIN(); diff --git a/stl/CMakeLists.txt b/stl/CMakeLists.txt index 3a18357bc3..643066112a 100644 --- a/stl/CMakeLists.txt +++ b/stl/CMakeLists.txt @@ -444,10 +444,28 @@ set(STATIC_SOURCES # Objs that exist in all satellite DLLs set(SATELLITE_DLL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/dllmain_satellite.cpp - ) +) add_compile_definitions(_CRTBLD _VCRT_ALLOW_INTERNALS _HAS_OLD_IOSTREAMS_MEMBERS=1 _STL_CONCRT_SUPPORT) +set(CMAKE_CXX_FLAGS "") +set(CMAKE_CXX_FLAGS_DEBUG "") +set(CMAKE_CXX_FLAGS_RELEASE "") +set(CMAKE_CXX_STANDARD_LIBRARIES "kernel32.lib") +set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "kernel32.lib") +set(CMAKE_MSVC_RUNTIME_LIBRARY "") + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${STL_ARCHIVE_OUTPUT_DIRECTORY}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${STL_LIBRARY_OUTPUT_DIRECTORY}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${STL_RUNTIME_OUTPUT_DIRECTORY}") + +set(CMAKE_STATIC_LINKER_FLAGS "/WX") +set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "") +set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "") +set(CMAKE_SHARED_LINKER_FLAGS "/DEBUG:FULL /WX /RELEASE /SUBSYSTEM:Console /NODEFAULTLIB /INCREMENTAL:NO /MANIFEST:NO /DLL /profile /guard:cf /DEBUGTYPE:cv,fixup /LARGEADDRESSAWARE") +set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "") +set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "") + include_directories(BEFORE "${CMAKE_CURRENT_LIST_DIR}/inc" "${TOOLSET_ROOT_DIR}/crt/src/vcruntime" @@ -457,67 +475,101 @@ if(VCLIBS_TARGET_ARCHITECTURE MATCHES "^(x86|x64)$") add_library(stl_alias_objects OBJECT ${ALIAS_SOURCES_X86_X64}) else() add_library(stl_alias_objects INTERFACE) + + # on ARM64 and ARM, we can unconditionally expect Synchronization.lib to exist + string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " Synchronization.lib") endif() -function(add_stl_dlls D_SUFFIX THIS_CONFIG_DEFINITIONS THIS_CONFIG_COMPILE_OPTIONS GL_FLAG THIS_CONFIG_LINK_OPTIONS) +add_compile_options(/WX /Gy + "$<$:/diagnostics:caret;/W4;/w14265;/w15038;/fastfail;/guard:cf;/Z7;/Zp8;/std:c++latest;/permissive-;/Zc:threadSafeInit-;/Zl>" + # note that /Zi generates debug info inside the object file, it's the same as /Z7 for msvc + "$<$:/Zi;/W3;/nologo>" +) + +function(target_stl_compile_options tgt rel_or_dbg) + if(rel_or_dbg STREQUAL "Release") + target_compile_options(${tgt} PRIVATE ${VCLIBS_RELEASE_OPTIONS}) + elseif(rel_or_dbg STREQUAL "Debug") + target_compile_options(${tgt} PRIVATE ${VCLIBS_DEBUG_OPTIONS}) + target_compile_definitions(${tgt} PRIVATE "_DEBUG") + else() + message(FATAL_ERROR "INTERNAL ERROR: unexpected value for rel_or_dbg: '${rel_or_dbg}'") + endif() +endfunction() + +function(add_stl_dlls D_SUFFIX REL_OR_DBG) + set(link_options_Release "/LTCG;/opt:ref,icf") + set(link_options_Debug "/opt:ref,noicf") + + set(gl_flag_Release "/GL") + set(gl_flag_Debug "") + # msvcp140.dll add_library(msvcp${D_SUFFIX}_objects OBJECT ${DLL_SOURCES} ${SOURCES}) - target_compile_definitions(msvcp${D_SUFFIX}_objects PRIVATE "CRTDLL2;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp${D_SUFFIX}_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHsc") + target_compile_definitions(msvcp${D_SUFFIX}_objects PRIVATE CRTDLL2 _DLL) + target_compile_options(msvcp${D_SUFFIX}_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_objects ${REL_OR_DBG}) add_library(msvcp${D_SUFFIX}_init_objects OBJECT ${INITIALIZER_SOURCES}) - target_compile_definitions(msvcp${D_SUFFIX}_init_objects PRIVATE "CRTDLL2;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp${D_SUFFIX}_init_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};/EHsc") + target_compile_definitions(msvcp${D_SUFFIX}_init_objects PRIVATE CRTDLL2 _DLL) + target_compile_options(msvcp${D_SUFFIX}_init_objects PRIVATE /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_init_objects ${REL_OR_DBG}) add_library(msvcp${D_SUFFIX}_eha_objects OBJECT ${EHA_SOURCES}) - target_compile_definitions(msvcp${D_SUFFIX}_eha_objects PRIVATE "CRTDLL2;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp${D_SUFFIX}_eha_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHa") + target_compile_definitions(msvcp${D_SUFFIX}_eha_objects PRIVATE CRTDLL2 _DLL) + target_compile_options(msvcp${D_SUFFIX}_eha_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHa) + target_stl_compile_options(msvcp${D_SUFFIX}_eha_objects ${REL_OR_DBG}) add_library(msvcp${D_SUFFIX} SHARED) target_link_libraries(msvcp${D_SUFFIX} PRIVATE msvcp${D_SUFFIX}_eha_objects msvcp${D_SUFFIX}_objects msvcp${D_SUFFIX}_init_objects "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib" "ole32.lib") set_target_properties(msvcp${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_base${D_SUFFIX}${VCLIBS_SUFFIX}") set_target_properties(msvcp${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") set_target_properties(msvcp${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140${D_SUFFIX}${VCLIBS_SUFFIX}") - target_link_options(msvcp${D_SUFFIX} PRIVATE "${THIS_CONFIG_LINK_OPTIONS}") + target_link_options(msvcp${D_SUFFIX} PRIVATE ${link_options_${REL_OR_DBG}}) # import library 'statics' add_library(msvcp${D_SUFFIX}_implib_objects OBJECT ${IMPLIB_SOURCES}) - target_compile_definitions(msvcp${D_SUFFIX}_implib_objects PRIVATE "_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp${D_SUFFIX}_implib_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};$<$:/EHsc>") # No /GL! + target_compile_definitions(msvcp${D_SUFFIX}_implib_objects PRIVATE _DLL) + target_compile_options(msvcp${D_SUFFIX}_implib_objects PRIVATE /EHsc) # No /GL! + target_stl_compile_options(msvcp${D_SUFFIX}_implib_objects ${REL_OR_DBG}) add_library(msvcp${D_SUFFIX}_satellite_objects OBJECT ${SATELLITE_DLL_SOURCES}) - target_compile_options(msvcp${D_SUFFIX}_satellite_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHsc") - target_compile_definitions(msvcp${D_SUFFIX}_satellite_objects PRIVATE "_DLL;${THIS_CONFIG_DEFINITIONS}") + target_compile_definitions(msvcp${D_SUFFIX}_satellite_objects PRIVATE _DLL) + target_compile_options(msvcp${D_SUFFIX}_satellite_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_satellite_objects ${REL_OR_DBG}) # msvcp140_1.dll (the memory_resource satellite) add_library(msvcp_1${D_SUFFIX}_objects OBJECT ${SOURCES_SATELLITE_1}) - target_compile_definitions(msvcp_1${D_SUFFIX}_objects PRIVATE "_BUILDING_SATELLITE_1;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp_1${D_SUFFIX}_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHsc") + target_compile_definitions(msvcp_1${D_SUFFIX}_objects PRIVATE _BUILDING_SATELLITE_1 _DLL) + target_compile_options(msvcp_1${D_SUFFIX}_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp_1${D_SUFFIX}_objects ${REL_OR_DBG}) add_library(msvcp_1${D_SUFFIX} SHARED) target_link_libraries(msvcp_1${D_SUFFIX} PRIVATE msvcp_1${D_SUFFIX}_objects msvcp${D_SUFFIX}_satellite_objects "msvcp${D_SUFFIX}" "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") set_target_properties(msvcp_1${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_1${D_SUFFIX}${VCLIBS_SUFFIX}") set_target_properties(msvcp_1${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") set_target_properties(msvcp_1${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140_1${D_SUFFIX}${VCLIBS_SUFFIX}") - target_link_options(msvcp_1${D_SUFFIX} PRIVATE "${THIS_CONFIG_LINK_OPTIONS}") + target_link_options(msvcp_1${D_SUFFIX} PRIVATE ${link_options_${REL_OR_DBG}}) # msvcp140_2.dll (the special math satellite) add_library(msvcp_2${D_SUFFIX}_objects OBJECT ${SOURCES_SATELLITE_2}) - target_compile_definitions(msvcp_2${D_SUFFIX}_objects PRIVATE "_BUILDING_SATELLITE_2;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp_2${D_SUFFIX}_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHsc") + target_compile_definitions(msvcp_2${D_SUFFIX}_objects PRIVATE _BUILDING_SATELLITE_2 _DLL) + target_compile_options(msvcp_2${D_SUFFIX}_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) target_link_libraries(msvcp_2${D_SUFFIX}_objects PRIVATE Boost::math) + target_stl_compile_options(msvcp_2${D_SUFFIX}_objects ${REL_OR_DBG}) add_library(msvcp_2${D_SUFFIX} SHARED) - target_link_libraries(msvcp_2${D_SUFFIX} PRIVATE msvcp_2${D_SUFFIX}_objects msvcp${D_SUFFIX}_satellite_objects msvcp${D_SUFFIX}_implib_objects "msvcp${D_SUFFIX}" "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") + target_link_libraries(msvcp_2${D_SUFFIX} PRIVATE msvcp_2${D_SUFFIX}_objects msvcp${D_SUFFIX}_satellite_objects msvcp${D_SUFFIX}_implib_objects msvcp${D_SUFFIX} "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") set_target_properties(msvcp_2${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_2${D_SUFFIX}${VCLIBS_SUFFIX}") set_target_properties(msvcp_2${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") set_target_properties(msvcp_2${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140_2${D_SUFFIX}${VCLIBS_SUFFIX}") - target_link_options(msvcp_2${D_SUFFIX} PRIVATE "${THIS_CONFIG_LINK_OPTIONS}") + target_link_options(msvcp_2${D_SUFFIX} PRIVATE ${link_options_${REL_OR_DBG}}) # msvcp140_atomic_wait.dll (the atomic wait satellite) add_library(msvcp${D_SUFFIX}_atomic_wait_objects OBJECT ${SOURCES_SATELLITE_ATOMIC_WAIT}) - target_compile_definitions(msvcp${D_SUFFIX}_atomic_wait_objects PRIVATE "_BUILDING_SATELLITE_ATOMIC_WAIT;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp${D_SUFFIX}_atomic_wait_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHsc") + target_compile_definitions(msvcp${D_SUFFIX}_atomic_wait_objects PRIVATE _BUILDING_SATELLITE_ATOMIC_WAIT _DLL) + target_compile_options(msvcp${D_SUFFIX}_atomic_wait_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_atomic_wait_objects ${REL_OR_DBG}) # generate the .def for msvcp140_atomic_wait.dll set(_ATOMIC_WAIT_OUTPUT_NAME "msvcp140${D_SUFFIX}_atomic_wait${VCLIBS_SUFFIX}") @@ -534,19 +586,20 @@ function(add_stl_dlls D_SUFFIX THIS_CONFIG_DEFINITIONS THIS_CONFIG_COMPILE_OPTIO set_target_properties(msvcp${D_SUFFIX}_atomic_wait PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_atomic_wait${D_SUFFIX}${VCLIBS_SUFFIX}") set_target_properties(msvcp${D_SUFFIX}_atomic_wait PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") set_target_properties(msvcp${D_SUFFIX}_atomic_wait PROPERTIES OUTPUT_NAME "${_ATOMIC_WAIT_OUTPUT_NAME}") - target_link_options(msvcp${D_SUFFIX}_atomic_wait PRIVATE "${THIS_CONFIG_LINK_OPTIONS}") + target_link_options(msvcp${D_SUFFIX}_atomic_wait PRIVATE ${link_options_${REL_OR_DBG}}) # msvcp140_codecvt_ids.dll add_library(msvcp${D_SUFFIX}_codecvt_ids_objects OBJECT ${SOURCES_SATELLITE_CODECVT_IDS}) - target_compile_definitions(msvcp${D_SUFFIX}_codecvt_ids_objects PRIVATE "_BUILDING_SATELLITE_CODECVT_IDS;_DLL;${THIS_CONFIG_DEFINITIONS}") - target_compile_options(msvcp${D_SUFFIX}_codecvt_ids_objects PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};${GL_FLAG};/EHsc") + target_compile_definitions(msvcp${D_SUFFIX}_codecvt_ids_objects PRIVATE _BUILDING_SATELLITE_CODECVT_IDS _DLL) + target_compile_options(msvcp${D_SUFFIX}_codecvt_ids_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_codecvt_ids_objects ${REL_OR_DBG}) add_library(msvcp${D_SUFFIX}_codecvt_ids SHARED) target_link_libraries(msvcp${D_SUFFIX}_codecvt_ids PRIVATE msvcp${D_SUFFIX}_codecvt_ids_objects msvcp${D_SUFFIX}_satellite_objects "msvcp${D_SUFFIX}" "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") set_target_properties(msvcp${D_SUFFIX}_codecvt_ids PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_codecvt_ids${D_SUFFIX}${VCLIBS_SUFFIX}") set_target_properties(msvcp${D_SUFFIX}_codecvt_ids PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") set_target_properties(msvcp${D_SUFFIX}_codecvt_ids PROPERTIES OUTPUT_NAME "msvcp140${D_SUFFIX}_codecvt_ids${VCLIBS_SUFFIX}") - target_link_options(msvcp${D_SUFFIX}_codecvt_ids PRIVATE "${THIS_CONFIG_LINK_OPTIONS}") + target_link_options(msvcp${D_SUFFIX}_codecvt_ids PRIVATE ${link_options_${REL_OR_DBG}}) # import library add_library(msvcp${D_SUFFIX}_implib STATIC ${HEADERS}) @@ -556,25 +609,27 @@ function(add_stl_dlls D_SUFFIX THIS_CONFIG_DEFINITIONS THIS_CONFIG_COMPILE_OPTIO set_target_properties(msvcp${D_SUFFIX}_implib PROPERTIES ARCHIVE_OUTPUT_NAME "msvcprt${D_SUFFIX}") endfunction() -add_stl_dlls("" "" "${VCLIBS_RELEASE_OPTIONS}" "/GL" "/LTCG;/opt:ref,icf") -add_stl_dlls("d" "_DEBUG" "${VCLIBS_DEBUG_OPTIONS}" "" "/opt:ref,noicf") +add_stl_dlls("" Release) +add_stl_dlls("d" Debug) -function(add_stl_statics FLAVOR_SUFFIX THIS_CONFIG_DEFINITIONS THIS_CONFIG_COMPILE_OPTIONS) +function(add_stl_statics FLAVOR_SUFFIX REL_OR_DBG IDL_VALUE) add_library(libcpmt${FLAVOR_SUFFIX}_eha OBJECT ${EHA_SOURCES}) - target_compile_definitions(libcpmt${FLAVOR_SUFFIX}_eha PRIVATE "${THIS_CONFIG_DEFINITIONS};_ANNOTATE_VECTOR;_ANNOTATE_STRING") - target_compile_options(libcpmt${FLAVOR_SUFFIX}_eha PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};/EHa") + target_compile_definitions(libcpmt${FLAVOR_SUFFIX}_eha PRIVATE _ANNOTATE_VECTOR _ANNOTATE_STRING "_ITERATOR_DEBUG_LEVEL=${IDL_VALUE}") + target_compile_options(libcpmt${FLAVOR_SUFFIX}_eha PRIVATE /EHa) + target_stl_compile_options(libcpmt${FLAVOR_SUFFIX}_eha ${REL_OR_DBG}) add_library(libcpmt${FLAVOR_SUFFIX} STATIC ${HEADERS} ${IMPLIB_SOURCES} ${SOURCES} ${INITIALIZER_SOURCES} ${STATIC_SOURCES}) - target_compile_definitions(libcpmt${FLAVOR_SUFFIX} PRIVATE "${THIS_CONFIG_DEFINITIONS};_ANNOTATE_VECTOR;_ANNOTATE_STRING") - target_compile_options(libcpmt${FLAVOR_SUFFIX} PRIVATE "${THIS_CONFIG_COMPILE_OPTIONS};$<$:/EHsc>") + target_compile_definitions(libcpmt${FLAVOR_SUFFIX} PRIVATE _ANNOTATE_VECTOR _ANNOTATE_STRING "_ITERATOR_DEBUG_LEVEL=${IDL_VALUE}") + target_compile_options(libcpmt${FLAVOR_SUFFIX} PRIVATE "$<$:/EHsc>") target_link_libraries(libcpmt${FLAVOR_SUFFIX} PRIVATE Boost::math stl_alias_objects libcpmt${FLAVOR_SUFFIX}_eha) + target_stl_compile_options(libcpmt${FLAVOR_SUFFIX} ${REL_OR_DBG}) endfunction() -add_stl_statics("" "_ITERATOR_DEBUG_LEVEL=0" "${VCLIBS_RELEASE_OPTIONS}") -add_stl_statics("1" "_ITERATOR_DEBUG_LEVEL=1" "${VCLIBS_RELEASE_OPTIONS}") -add_stl_statics("d" "_DEBUG;_ITERATOR_DEBUG_LEVEL=2" "${VCLIBS_DEBUG_OPTIONS}") -add_stl_statics("d1" "_DEBUG;_ITERATOR_DEBUG_LEVEL=1" "${VCLIBS_DEBUG_OPTIONS}") -add_stl_statics("d0" "_DEBUG;_ITERATOR_DEBUG_LEVEL=0" "${VCLIBS_DEBUG_OPTIONS}") +add_stl_statics("" Release 0) +add_stl_statics("1" Release 1) +add_stl_statics("d" Debug 2) +add_stl_statics("d1" Debug 1) +add_stl_statics("d0" Debug 0) add_library(stl_asan STATIC ${ASAN_SOURCES}) diff --git a/tests/libcxx/lit.site.cfg.in b/tests/libcxx/lit.site.cfg.in index 0557736b46..edbd6a04f9 100644 --- a/tests/libcxx/lit.site.cfg.in +++ b/tests/libcxx/lit.site.cfg.in @@ -25,10 +25,10 @@ lit_config.test_subdirs = getattr(lit_config, 'test_subdirs', dict()) lit_config.expected_results[config.name] = stl.test.file_parsing.parse_result_file('@LIBCXX_EXPECTED_RESULTS@') lit_config.include_dirs[config.name] = ['@STL_TESTED_HEADERS_DIR@', '@LIBCXX_SOURCE_DIR@/test/support'] -lit_config.library_dirs[config.name] = ['@CMAKE_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@'] +lit_config.library_dirs[config.name] = ['@STL_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@'] lit_config.test_subdirs[config.name] = ['@LIBCXX_SOURCE_DIR@/test/std'] -lit_config.cxx_runtime = '@CMAKE_RUNTIME_OUTPUT_DIRECTORY@' +lit_config.cxx_runtime = '@STL_RUNTIME_OUTPUT_DIRECTORY@' lit_config.target_arch = '@VCLIBS_TARGET_ARCHITECTURE@' lit_config.build_only = '@TESTS_BUILD_ONLY@'.lower() in ['1', 'true', 'on'] diff --git a/tests/std/lit.site.cfg.in b/tests/std/lit.site.cfg.in index 653f76d16a..06680843d1 100644 --- a/tests/std/lit.site.cfg.in +++ b/tests/std/lit.site.cfg.in @@ -24,11 +24,11 @@ lit_config.test_subdirs = getattr(lit_config, 'test_subdirs', dict()) lit_config.expected_results[config.name] = stl.test.file_parsing.parse_result_file('@STD_EXPECTED_RESULTS@') lit_config.include_dirs[config.name] = \ ['@STL_TESTED_HEADERS_DIR@', '@LIBCXX_SOURCE_DIR@/test/support', '@STL_SOURCE_DIR@/tests/std/include'] -lit_config.library_dirs[config.name] = ['@CMAKE_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@'] +lit_config.library_dirs[config.name] = ['@STL_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@'] lit_config.test_subdirs[config.name] = ['@CMAKE_CURRENT_SOURCE_DIR@/tests'] lit_config.cxx_headers = '@STL_TESTED_HEADERS_DIR@' -lit_config.cxx_runtime = '@CMAKE_RUNTIME_OUTPUT_DIRECTORY@' +lit_config.cxx_runtime = '@STL_RUNTIME_OUTPUT_DIRECTORY@' lit_config.target_arch = '@VCLIBS_TARGET_ARCHITECTURE@' lit_config.build_only = '@TESTS_BUILD_ONLY@'.lower() in ['1', 'true', 'on'] diff --git a/tests/tr1/lit.site.cfg.in b/tests/tr1/lit.site.cfg.in index a0d226bca8..aaddf346ee 100644 --- a/tests/tr1/lit.site.cfg.in +++ b/tests/tr1/lit.site.cfg.in @@ -24,10 +24,10 @@ lit_config.test_subdirs = getattr(lit_config, 'test_subdirs', dict()) lit_config.expected_results[config.name] = stl.test.file_parsing.parse_result_file('@TR1_EXPECTED_RESULTS@') lit_config.include_dirs[config.name] = \ ['@STL_TESTED_HEADERS_DIR@', '@STL_SOURCE_DIR@/tests/tr1/include', '@STL_SOURCE_DIR@/tests/std/include'] -lit_config.library_dirs[config.name] = ['@CMAKE_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@'] +lit_config.library_dirs[config.name] = ['@STL_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@'] lit_config.test_subdirs[config.name] = ['@CMAKE_CURRENT_SOURCE_DIR@/tests'] -lit_config.cxx_runtime = '@CMAKE_RUNTIME_OUTPUT_DIRECTORY@' +lit_config.cxx_runtime = '@STL_RUNTIME_OUTPUT_DIRECTORY@' lit_config.target_arch = '@VCLIBS_TARGET_ARCHITECTURE@' lit_config.build_only = '@TESTS_BUILD_ONLY@'.lower() in ['1', 'true', 'on'] diff --git a/tools/format/CMakeLists.txt b/tools/format/CMakeLists.txt index e737a18f10..37c109b220 100644 --- a/tools/format/CMakeLists.txt +++ b/tools/format/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.23) project(msvc_standard_libraries_format NONE) set(did_search OFF) + if(NOT DEFINED CLANG_FORMAT) message(STATUS "Searching for VS clang-format") set(did_search ON) @@ -26,21 +27,26 @@ find_program(CLANG_FORMAT NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH ) + if(CLANG_FORMAT) if(did_search) message(STATUS "Searching for VS clang-format - found") endif() file(GLOB_RECURSE maybe_clang_format_files + "../../benchmarks/inc/*" + "../../benchmarks/src/*" "../../stl/inc/*" "../../stl/src/*" "../../tests/*" "../../tools/*" ) set(clang_format_files "") + foreach(maybe_file IN LISTS maybe_clang_format_files) cmake_path(GET maybe_file FILENAME filename) cmake_path(GET maybe_file EXTENSION LAST_ONLY extension) + if(extension MATCHES [[^(|\.cpp|\.h|\.hpp)$]] AND NOT filename MATCHES [[^\.]]) list(APPEND clang_format_files "${maybe_file}") endif() @@ -51,6 +57,7 @@ if(CLANG_FORMAT) endif() add_custom_target(run-format) + foreach(file IN LISTS clang_format_files) cmake_path(RELATIVE_PATH file BASE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../.." diff --git a/tools/validate/validate.cpp b/tools/validate/validate.cpp index c590c7dd9e..9870cb6c0a 100644 --- a/tools/validate/validate.cpp +++ b/tools/validate/validate.cpp @@ -208,6 +208,7 @@ int main() { L"__pycache__"sv, L"boost-math"sv, L"build"sv, + L"google-benchmark"sv, L"llvm-project"sv, L"out"sv, };