1find_package(Threads) 2 3include(ExternalProject) 4 5set(LLVM_LINK_COMPONENTS Support) 6 7#============================================================================== 8# Build Google Benchmark 9#============================================================================== 10set(GOOGLE_BENCHMARK_TARGET_FLAGS ${BENCHMARK_DIALECT_FLAG}) 11if (LIBCXX_BENCHMARK_GCC_TOOLCHAIN) 12 set(GOOGLE_BENCHMARK_TARGET_FLAGS 13 -gcc-toolchain ${LIBCXX_BENCHMARK_GCC_TOOLCHAIN}) 14endif() 15string(REPLACE ";" " " GOOGLE_BENCHMARK_TARGET_FLAGS "${GOOGLE_BENCHMARK_TARGET_FLAGS}") 16 17ExternalProject_Add(google-benchmark 18 EXCLUDE_FROM_ALL ON 19 PREFIX google-benchmark 20 SOURCE_DIR ${LIBC_SOURCE_DIR}/../llvm/utils/benchmark 21 INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/google-benchmark 22 CMAKE_CACHE_ARGS 23 -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON 24 -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} 25 -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} 26 -DCMAKE_CXX_FLAGS:STRING=${GOOGLE_BENCHMARK_TARGET_FLAGS} 27 -DCMAKE_CXX_STANDARD:STRING=14 28 -DCMAKE_BUILD_TYPE:STRING=RELEASE 29 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> 30 -DBENCHMARK_ENABLE_TESTING:BOOL=OFF) 31 32set(GOOGLE_BENCHMARK_LIBC_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/google-benchmark) 33set(GOOGLE_BENCHMARK_LINK_FLAGS -L${GOOGLE_BENCHMARK_LIBC_INSTALL}/lib/) 34 35#============================================================================== 36# Add Unit Testing Support 37#============================================================================== 38 39function(add_libc_benchmark_unittest target_name) 40 if(NOT LLVM_INCLUDE_TESTS) 41 return() 42 endif() 43 44 cmake_parse_arguments( 45 "LIBC_BENCHMARKS_UNITTEST" 46 "" # No optional arguments 47 "SUITE" # Single value arguments 48 "SRCS;DEPENDS" # Multi-value arguments 49 ${ARGN} 50 ) 51 52 add_executable(${target_name} 53 EXCLUDE_FROM_ALL 54 ${LIBC_BENCHMARKS_UNITTEST_SRCS} 55 ) 56 target_link_libraries(${target_name} 57 PRIVATE 58 gtest_main 59 gtest 60 ${LIBC_BENCHMARKS_UNITTEST_DEPENDS} 61 ) 62 63 add_custom_command( 64 TARGET ${target_name} 65 POST_BUILD 66 COMMAND $<TARGET_FILE:${target_name}> 67 ) 68 add_dependencies(libc-benchmark-util-tests ${target_name}) 69endfunction() 70 71#============================================================================== 72# Build Google Benchmark for libc 73#============================================================================== 74 75add_custom_target(libc-benchmark-util-tests) 76 77function(fix_rtti target) 78 # TODO: Make this portable and inline with rtti mode from llvm/ 79 target_compile_options(${target} PUBLIC -fno-rtti) 80endfunction() 81 82# libc-benchmark 83add_library(libc-benchmark 84 STATIC 85 EXCLUDE_FROM_ALL 86 LibcBenchmark.cpp 87 LibcBenchmark.h 88) 89add_dependencies(libc-benchmark google-benchmark) 90target_include_directories(libc-benchmark 91 SYSTEM PUBLIC 92 "${GOOGLE_BENCHMARK_LIBC_INSTALL}/include" 93) 94target_link_libraries(libc-benchmark 95 PUBLIC 96 "${GOOGLE_BENCHMARK_LINK_FLAGS}" # FIXME: Move to `target_link_options` 97 -lbenchmark # FIXME: Move to `target_link_options` 98 LLVMSupport 99 Threads::Threads 100) 101fix_rtti(libc-benchmark) 102 103add_libc_benchmark_unittest(libc-benchmark-test 104 SRCS LibcBenchmarkTest.cpp 105 DEPENDS libc-benchmark 106) 107 108# libc-memory-benchmark 109add_library(libc-memory-benchmark 110 STATIC 111 EXCLUDE_FROM_ALL 112 LibcMemoryBenchmark.cpp 113 LibcMemoryBenchmark.h 114 MemorySizeDistributions.cpp 115 MemorySizeDistributions.h 116) 117target_link_libraries(libc-memory-benchmark PUBLIC libc-benchmark) 118fix_rtti(libc-memory-benchmark) 119 120add_libc_benchmark_unittest(libc-memory-benchmark-test 121 SRCS LibcMemoryBenchmarkTest.cpp 122 DEPENDS libc-memory-benchmark 123) 124 125# json 126add_library(json 127 STATIC 128 EXCLUDE_FROM_ALL 129 JSON.cpp 130 JSON.h 131) 132target_link_libraries(json PUBLIC libc-memory-benchmark) 133fix_rtti(json) 134 135add_libc_benchmark_unittest(json-test 136 SRCS JSONTest.cpp 137 DEPENDS json 138) 139 140#============================================================================== 141# Benchmark tests configuration 142#============================================================================== 143 144function(add_libc_benchmark_analysis conf_target run_target) 145 set(png_file "/tmp/last-${conf_target}.png") 146 set(render_target render-${conf_target}) 147 add_custom_target(${render_target} 148 COMMAND python3 render.py3 ${json_file} --headless --output=${png_file} 149 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 150 COMMENT "render ${libc_target} to ${png_file}" 151 ) 152 add_dependencies(${render_target} ${run_target}) 153 154 set(display_target display-${conf_target}) 155 add_custom_target(${display_target} 156 COMMAND python3 render.py3 ${json_file} 157 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 158 COMMENT "display ${libc_target}" 159 ) 160 add_dependencies(${display_target} ${run_target}) 161endfunction() 162 163function(add_libc_benchmark_configuration target configuration) 164 set(conf_target ${target}-${configuration}) 165 set(json_file "/tmp/last-${conf_target}.json") 166 set(run_target run-${conf_target}) 167 add_custom_target(${run_target} 168 COMMAND ${libc_target} --conf=configuration_${configuration}.json -o ${json_file} 169 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 170 ) 171 add_libc_benchmark_analysis(${conf_target} ${run_target}) 172endfunction() 173 174function(add_libc_benchmark name file entrypoint_target) 175 set(libc_target libc-${name}-benchmark) 176 add_executable(${libc_target} 177 EXCLUDE_FROM_ALL 178 ${file} 179 LibcMemoryBenchmarkMain.h 180 LibcMemoryBenchmarkMain.cpp 181 ) 182 183 get_target_property(entrypoint_object_file ${entrypoint_target} "OBJECT_FILE_RAW") 184 target_link_libraries(${libc_target} PUBLIC json ${entrypoint_object_file}) 185 foreach(configuration "small" "big") 186 add_libc_benchmark_configuration(${libc_target} ${configuration}) 187 endforeach() 188endfunction() 189 190add_libc_benchmark(memcpy Memcpy.cpp libc.src.string.memcpy) 191add_libc_benchmark(memset Memset.cpp libc.src.string.memset) 192