https://github.com/tstellar updated https://github.com/llvm/llvm-project/pull/77347
>From 127e2ae83f33843cfb9c5cca314afa2fc9844239 Mon Sep 17 00:00:00 2001 From: Tom Stellard <tstel...@redhat.com> Date: Sat, 6 Jan 2024 07:46:01 +0000 Subject: [PATCH 1/5] [CMake][PGO] Use check-clang target to generate profdata for PGO builds When doing a multi-stage PGO build of clang, run the check-clang and check-llvm targets using the instrumented clang and use that profile data for building the final stage2 clang. This is what is recommended by our official documentation: https://llvm.org/docs/HowToBuildWithPGO.html#building-clang-with-pgo I benchmarked this change by compiling the SemaChecking.cpp file from clang. Using check-clang/check-llvm to generate the profile data gives a 25% speedup in the PGO+LTO stage2 clang when compared to the stage1 clang (no-LTO). Prior to this change, I was only seeing ~5% speedup when comparing the stage2 and stage1 builds. --- clang/utils/perf-training/CMakeLists.txt | 6 +++--- clang/utils/perf-training/perf-helper.py | 16 +++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/clang/utils/perf-training/CMakeLists.txt b/clang/utils/perf-training/CMakeLists.txt index c6d51863fb1b5c..95ff8115aa538b 100644 --- a/clang/utils/perf-training/CMakeLists.txt +++ b/clang/utils/perf-training/CMakeLists.txt @@ -15,7 +15,7 @@ if(LLVM_BUILD_INSTRUMENTED) ) add_custom_target(clear-profraw - COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} profraw + COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/profiles/ profraw COMMENT "Clearing old profraw data") if(NOT LLVM_PROFDATA) @@ -26,9 +26,9 @@ if(LLVM_BUILD_INSTRUMENTED) message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to llvm-profdata") else() add_custom_target(generate-profdata - COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR} + COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/profiles/ COMMENT "Merging profdata" - DEPENDS generate-profraw) + DEPENDS generate-profraw check-clang check-llvm) endif() endif() diff --git a/clang/utils/perf-training/perf-helper.py b/clang/utils/perf-training/perf-helper.py index 99d6a3333b6ef0..bd8f74c9c2e129 100644 --- a/clang/utils/perf-training/perf-helper.py +++ b/clang/utils/perf-training/perf-helper.py @@ -30,26 +30,28 @@ def findFilesWithExtension(path, extension): def clean(args): - if len(args) != 2: + if len(args) < 2: print( - "Usage: %s clean <path> <extension>\n" % __file__ + "Usage: %s clean <paths> <extension>\n" % __file__ + "\tRemoves all files with extension from <path>." ) return 1 - for filename in findFilesWithExtension(args[0], args[1]): - os.remove(filename) + for path in args[1:-1]: + for filename in findFilesWithExtension(path, args[-1]): + os.remove(filename) return 0 def merge(args): - if len(args) != 3: + if len(args) < 3: print( - "Usage: %s merge <llvm-profdata> <output> <path>\n" % __file__ + "Usage: %s merge <llvm-profdata> <output> <paths>\n" % __file__ + "\tMerges all profraw files from path into output." ) return 1 cmd = [args[0], "merge", "-o", args[1]] - cmd.extend(findFilesWithExtension(args[2], "profraw")) + for i in range(2, len(args)): + cmd.extend(findFilesWithExtension(args[i], "profraw")) subprocess.check_call(cmd) return 0 >From 4f7734584af3aa9a18bde17349ceccbef3658c53 Mon Sep 17 00:00:00 2001 From: Tom Stellard <tstel...@redhat.com> Date: Mon, 8 Jan 2024 18:07:31 +0000 Subject: [PATCH 2/5] Fix python formatting --- clang/utils/perf-training/perf-helper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/utils/perf-training/perf-helper.py b/clang/utils/perf-training/perf-helper.py index bd8f74c9c2e129..844aa274f049aa 100644 --- a/clang/utils/perf-training/perf-helper.py +++ b/clang/utils/perf-training/perf-helper.py @@ -37,8 +37,8 @@ def clean(args): ) return 1 for path in args[1:-1]: - for filename in findFilesWithExtension(path, args[-1]): - os.remove(filename) + for filename in findFilesWithExtension(path, args[-1]): + os.remove(filename) return 0 @@ -51,7 +51,7 @@ def merge(args): return 1 cmd = [args[0], "merge", "-o", args[1]] for i in range(2, len(args)): - cmd.extend(findFilesWithExtension(args[i], "profraw")) + cmd.extend(findFilesWithExtension(args[i], "profraw")) subprocess.check_call(cmd) return 0 >From d330bfffc47c23b1e02602591b7ff02cd5a31c2d Mon Sep 17 00:00:00 2001 From: Tom Stellard <tstel...@redhat.com> Date: Thu, 11 Jan 2024 23:37:19 +0000 Subject: [PATCH 3/5] Build Sema.cpp to generate profile data instead of using check-clang and check-llvm Also add an option to supply a cmake project to use to generate profile data. --- clang/utils/perf-training/CMakeLists.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/clang/utils/perf-training/CMakeLists.txt b/clang/utils/perf-training/CMakeLists.txt index 95ff8115aa538b..75e6278191c2c2 100644 --- a/clang/utils/perf-training/CMakeLists.txt +++ b/clang/utils/perf-training/CMakeLists.txt @@ -1,6 +1,10 @@ +include(LLVMExternalProjectUtils) + set(CLANG_PGO_TRAINING_DATA "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "The path to a lit testsuite containing samples for PGO and order file generation" ) +set(CLANG_PGO_TRAINING_DATA_SOURCE_DIR OFF CACHE STRING "Path to source directory containing cmake project with source files to use for generating pgo data") +set(CLANG_PERF_TRAINING_DEPS "" CACHE STRING "Extra dependencies needed to build the PGO training data.") if(LLVM_BUILD_INSTRUMENTED) configure_lit_site_cfg( @@ -28,7 +32,21 @@ if(LLVM_BUILD_INSTRUMENTED) add_custom_target(generate-profdata COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/profiles/ COMMENT "Merging profdata" - DEPENDS generate-profraw check-clang check-llvm) + DEPENDS generate-profraw) + if (CLANG_PGO_TRAINING_DATA_SOURCE_DIR) + llvm_ExternalProject_Add(generate-profraw-external ${CLANG_PGO_TRAINING_DATA_SOURCE_DIR} + USE_TOOLCHAIN EXLUDE_FROM_ALL NO_INSTALL DEPENDS generate-profraw) + add_dependencies(generate-profdata generate-profraw-external) + else() + # Default to compiling a file from clang. This also builds all the + # dependencies needed to build this file, like TableGen. + set(generate_profraw_clang_sema tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/Sema.cpp.o) + llvm_ExternalProject_Add(generate-profraw-clang ${CMAKE_CURRENT_SOURCE_DIR}/../../../llvm + USE_TOOLCHAIN EXLUDE_FROM_ALL NO_INSTALL DEPENDS generate-profraw + EXTRA_TARGETS generate_profraw_clang_sema + CMAKE_ARGS -DLLVM_ENABLE_PROJECTS=clang) + add_dependencies(generate-profdata generate_profraw_clang_sema) + endif() endif() endif() >From 9b6543de1af17ec4c2ac1c540f2361e3d193363d Mon Sep 17 00:00:00 2001 From: Tom Stellard <tstel...@redhat.com> Date: Thu, 11 Jan 2024 23:57:51 +0000 Subject: [PATCH 4/5] Update documentatin --- llvm/docs/AdvancedBuilds.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/llvm/docs/AdvancedBuilds.rst b/llvm/docs/AdvancedBuilds.rst index 960b19fa5317f3..7d8a8718f6867c 100644 --- a/llvm/docs/AdvancedBuilds.rst +++ b/llvm/docs/AdvancedBuilds.rst @@ -145,6 +145,28 @@ that also enables ThinTLO, use the following command: -DPGO_INSTRUMENT_LTO=Thin \ <path to source>/llvm +By default, clang will generate profile data by compiling the Sema.cpp +file (and all its dependencies, e.g. TableGen). However, you can also +tell clang use an external project for generating profile data that may +be a better fit for your use case. The project you specify must either +be a lit test suite (use the CLANG_PGO_TRAINING_DATA option) or a CMake +project (use the CLANG_PERF_TRAINING_DATA_SOURCE_DIR option). + +For example, If you wanted to use the +`LLVM Test Suite <https://github.com/llvm/llvm-test-suite/>`_ to generate +profile data you would use the following command: + +.. code-block:: console + $ cmake -G Ninja -C <path to source>/clang/cmake/caches/PGO.cmake \ + -DBOOTSTRAP_CLANG_PGO_TRAINING_DATA_SOURCE_DIR=/home/fedora/llvm-test-suite/ \ + -DBOOTSTRAP_CLANG_PERF_TRAINING_DEPS=runtimes + +The BOOTSTRAP_ prefixes tells CMake to pass the variables on to the instrumented +stage two build. And the CLANG_PERF_TRAINING_DEPS option let's you specify +additional build targets to build before building the external project. The +LLVM Test Suite requires compiler-rt to build, so we need to add the +`runtimes` target as a dependency. + After configuration, building the stage2-instrumented-generate-profdata target will automatically build the stage1 compiler, build the instrumented compiler with the stage1 compiler, and then run the instrumented compiler against the >From adcbfc043d7a1ca24b008e79c834193ad776ff2a Mon Sep 17 00:00:00 2001 From: Tom Stellard <tstel...@redhat.com> Date: Fri, 12 Jan 2024 00:42:10 +0000 Subject: [PATCH 5/5] Fix documentation build --- llvm/docs/AdvancedBuilds.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/docs/AdvancedBuilds.rst b/llvm/docs/AdvancedBuilds.rst index 7d8a8718f6867c..bfe3455a9a26c2 100644 --- a/llvm/docs/AdvancedBuilds.rst +++ b/llvm/docs/AdvancedBuilds.rst @@ -157,6 +157,7 @@ For example, If you wanted to use the profile data you would use the following command: .. code-block:: console + $ cmake -G Ninja -C <path to source>/clang/cmake/caches/PGO.cmake \ -DBOOTSTRAP_CLANG_PGO_TRAINING_DATA_SOURCE_DIR=/home/fedora/llvm-test-suite/ \ -DBOOTSTRAP_CLANG_PERF_TRAINING_DEPS=runtimes _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits