[llvm] [clang] [CMake][PGO] Build Sema.cpp to generate profdata for PGO builds (PR #77347)
Tom Stellard via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 11 22:09:43 PST 2024
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 <tstellar at redhat.com>
Date: Sat, 6 Jan 2024 07:46:01 +0000
Subject: [PATCH 1/6] [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 <tstellar at redhat.com>
Date: Mon, 8 Jan 2024 18:07:31 +0000
Subject: [PATCH 2/6] 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 <tstellar at redhat.com>
Date: Thu, 11 Jan 2024 23:37:19 +0000
Subject: [PATCH 3/6] 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 <tstellar at redhat.com>
Date: Thu, 11 Jan 2024 23:57:51 +0000
Subject: [PATCH 4/6] 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 <tstellar at redhat.com>
Date: Fri, 12 Jan 2024 00:42:10 +0000
Subject: [PATCH 5/6] 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
>From 8b8837acc9fa2a4bac2595b612e018bc5d0fa3f8 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 12 Jan 2024 06:06:45 +0000
Subject: [PATCH 6/6] Fix documentation
---
llvm/docs/AdvancedBuilds.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/docs/AdvancedBuilds.rst b/llvm/docs/AdvancedBuilds.rst
index bfe3455a9a26c2..4da2171b1f33c8 100644
--- a/llvm/docs/AdvancedBuilds.rst
+++ b/llvm/docs/AdvancedBuilds.rst
@@ -162,7 +162,7 @@ profile data you would use the following command:
-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
+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
More information about the cfe-commits
mailing list