3 include(ExternalProject)
5 set(LLVM_LINK_COMPONENTS Support)
7 #==============================================================================
8 # Build Google Benchmark
9 #==============================================================================
10 set(GOOGLE_BENCHMARK_TARGET_FLAGS ${BENCHMARK_DIALECT_FLAG})
11 if (LIBCXX_BENCHMARK_GCC_TOOLCHAIN)
12 set(GOOGLE_BENCHMARK_TARGET_FLAGS
13 --gcc-toolchain=${LIBCXX_BENCHMARK_GCC_TOOLCHAIN})
15 string(REPLACE ";" " " GOOGLE_BENCHMARK_TARGET_FLAGS "${GOOGLE_BENCHMARK_TARGET_FLAGS}")
17 ExternalProject_Add(google-benchmark
19 PREFIX google-benchmark
20 SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark
21 INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/google-benchmark
23 -DBUILD_SHARED_LIBS:BOOL=OFF
24 -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
25 -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
26 -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
27 -DCMAKE_CXX_FLAGS:STRING=${GOOGLE_BENCHMARK_TARGET_FLAGS}
28 -DCMAKE_CXX_STANDARD:STRING=14
29 -DCMAKE_BUILD_TYPE:STRING=RELEASE
30 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
31 -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)
33 set(GOOGLE_BENCHMARK_LIBC_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/google-benchmark)
34 set(GOOGLE_BENCHMARK_LINK_FLAGS -L${GOOGLE_BENCHMARK_LIBC_INSTALL}/lib/)
36 #==============================================================================
37 # Add Unit Testing Support
38 #==============================================================================
40 function(add_libc_benchmark_unittest target_name)
41 if(NOT LLVM_INCLUDE_TESTS)
45 cmake_parse_arguments(
46 "LIBC_BENCHMARKS_UNITTEST"
47 "" # No optional arguments
48 "SUITE" # Single value arguments
49 "SRCS;DEPENDS" # Multi-value arguments
53 add_executable(${target_name}
55 ${LIBC_BENCHMARKS_UNITTEST_SRCS}
57 target_link_libraries(${target_name}
61 ${LIBC_BENCHMARKS_UNITTEST_DEPENDS}
67 COMMAND $<TARGET_FILE:${target_name}>
69 add_dependencies(libc-benchmark-util-tests ${target_name})
72 #==============================================================================
73 # Build Google Benchmark for libc
74 #==============================================================================
76 add_custom_target(libc-benchmark-util-tests)
78 function(fix_rtti target)
79 # TODO: Make this portable and inline with rtti mode from llvm/
80 target_compile_options(${target} PUBLIC -fno-rtti)
84 add_library(libc-benchmark
90 add_dependencies(libc-benchmark google-benchmark)
91 target_include_directories(libc-benchmark
93 "${GOOGLE_BENCHMARK_LIBC_INSTALL}/include"
95 target_link_libraries(libc-benchmark
97 "${GOOGLE_BENCHMARK_LINK_FLAGS}" # FIXME: Move to `target_link_options`
98 -lbenchmark # FIXME: Move to `target_link_options`
102 fix_rtti(libc-benchmark)
104 add_libc_benchmark_unittest(libc-benchmark-test
105 SRCS LibcBenchmarkTest.cpp
106 DEPENDS libc-benchmark
109 # libc-memory-benchmark
110 add_library(libc-memory-benchmark
113 LibcMemoryBenchmark.cpp
114 LibcMemoryBenchmark.h
115 LibcFunctionPrototypes.h
116 MemorySizeDistributions.cpp
117 MemorySizeDistributions.h
119 target_include_directories(libc-memory-benchmark
121 ${CMAKE_CURRENT_SOURCE_DIR}
123 target_link_libraries(libc-memory-benchmark
127 fix_rtti(libc-memory-benchmark)
129 add_libc_benchmark_unittest(libc-memory-benchmark-test
130 SRCS LibcMemoryBenchmarkTest.cpp
131 DEPENDS libc-memory-benchmark
141 target_link_libraries(json PUBLIC libc-memory-benchmark)
144 add_libc_benchmark_unittest(json-test
149 #==============================================================================
151 #==============================================================================
153 # Benchmark all implementations that can run on the target CPU.
154 function(add_libc_multi_impl_benchmark name)
155 get_property(fq_implementations GLOBAL PROPERTY ${name}_implementations)
156 foreach(fq_config_name IN LISTS fq_implementations)
157 get_target_property(required_cpu_features ${fq_config_name} REQUIRE_CPU_FEATURES)
158 cpu_supports(can_run "${required_cpu_features}")
160 set(benchmark_name ${fq_config_name}_benchmark)
161 add_executable(${benchmark_name}
163 LibcMemoryBenchmarkMain.cpp
165 get_target_property(entrypoint_object_file ${fq_config_name} "OBJECT_FILE_RAW")
166 target_link_libraries(${benchmark_name} PUBLIC json ${entrypoint_object_file})
167 string(TOUPPER ${name} name_upper)
168 target_compile_definitions(${benchmark_name} PRIVATE "-DLIBC_BENCHMARK_FUNCTION_${name_upper}=__llvm_libc::${name}" "-DLIBC_BENCHMARK_FUNCTION_NAME=\"${fq_config_name}\"")
170 message(STATUS "Skipping benchmark for '${fq_config_name}' insufficient host cpu features '${required_cpu_features}'")
175 add_libc_multi_impl_benchmark(bcmp)
176 add_libc_multi_impl_benchmark(bzero)
177 add_libc_multi_impl_benchmark(memcmp)
178 add_libc_multi_impl_benchmark(memcpy)
179 add_libc_multi_impl_benchmark(memmove)
180 add_libc_multi_impl_benchmark(memset)
182 #==============================================================================
183 # Google Benchmarking tool
184 #==============================================================================
186 # This target uses the Google Benchmark facility to report throughput for llvm
187 # libc memory functions compiled for the host machine. This is useful to
188 # continuously monitor the performance of the memory functions.
189 add_executable(libc.benchmarks.memory_functions.opt_host
191 LibcMemoryGoogleBenchmarkMain.cpp
192 LibcDefaultImplementations.cpp
195 target_link_libraries(libc.benchmarks.memory_functions.opt_host
197 libc-memory-benchmark
198 libc.src.string.memcmp_opt_host
199 libc.src.string.bcmp_opt_host
200 libc.src.string.memcpy_opt_host
201 libc.src.string.memset_opt_host
202 libc.src.string.bzero_opt_host
203 libc.src.string.memmove_opt_host
207 add_subdirectory(automemcpy)