Skip to content

Commit 6390412

Browse files
committed
[Clang][CMake] Add CSSPGO support to LLVM_BUILD_INSTRUMENTED
Build on Clang-BOLT infrastructure to collect sample profiles for CSSPGO. Add clang/cmake/caches/CSSPGO.cmake to automate CSSPGO Clang build. Differential Revision: https://reviews.llvm.org/D155419
1 parent dd0356d commit 6390412

File tree

8 files changed

+124
-14
lines changed

8 files changed

+124
-14
lines changed

clang/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,11 +741,21 @@ if (CLANG_ENABLE_BOOTSTRAP)
741741
if(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED)
742742
add_dependencies(clang-bootstrap-deps llvm-profdata)
743743
set(PGO_OPT -DLLVM_PROFDATA=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-profdata)
744+
string(TOUPPER "${BOOTSTRAP_LLVM_BUILD_INSTRUMENTED}" BOOTSTRAP_LLVM_BUILD_INSTRUMENTED)
745+
if (BOOTSTRAP_LLVM_BUILD_INSTRUMENTED STREQUAL "CSSPGO")
746+
add_dependencies(clang-bootstrap-deps llvm-profgen)
747+
list(APPEND PGO_OPT -DLLVM_PROFGEN=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-profgen)
748+
endif()
744749
endif()
745750

746751
if(LLVM_BUILD_INSTRUMENTED)
752+
string(TOUPPER "${LLVM_BUILD_INSTRUMENTED}" LLVM_BUILD_INSTRUMENTED)
747753
add_dependencies(clang-bootstrap-deps generate-profdata)
748-
set(PGO_OPT -DLLVM_PROFDATA_FILE=${CMAKE_CURRENT_BINARY_DIR}/utils/perf-training/clang.profdata)
754+
if (LLVM_BUILD_INSTRUMENTED STREQUAL "CSSPGO")
755+
set(PGO_OPT -DLLVM_SPROFDATA_FILE=${CMAKE_CURRENT_BINARY_DIR}/utils/perf-training/clang.profdata)
756+
else()
757+
set(PGO_OPT -DLLVM_PROFDATA_FILE=${CMAKE_CURRENT_BINARY_DIR}/utils/perf-training/clang.profdata)
758+
endif()
749759
# Use the current tools for LTO instead of the instrumented ones
750760
list(APPEND _BOOTSTRAP_DEFAULT_PASSTHROUGH
751761
CMAKE_CXX_COMPILER

clang/cmake/caches/CSSPGO.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
2+
set(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED "CSSPGO" CACHE STRING "")
3+
include(${CMAKE_CURRENT_LIST_DIR}/PGO.cmake)

clang/utils/perf-training/CMakeLists.txt

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,33 @@ if(LLVM_BUILD_INSTRUMENTED)
1818
DEPENDS clang clear-profraw ${CLANG_PGO_TRAINING_DEPS}
1919
)
2020

21+
add_custom_target(generate-profdata-deps)
22+
string(TOUPPER "${LLVM_BUILD_INSTRUMENTED}" uppercase_LLVM_BUILD_INSTRUMENTED)
23+
if (uppercase_LLVM_BUILD_INSTRUMENTED STREQUAL "CSSPGO")
24+
set(PROFDATA_SAMPLE "--sample")
25+
if(NOT LLVM_PROFGEN)
26+
find_program(LLVM_PROFGEN llvm-profgen)
27+
endif()
28+
29+
if(NOT LLVM_PROFGEN)
30+
message(STATUS "To enable converting CSSPGO samples LLVM_PROFGEN has to point to llvm-profgen")
31+
endif()
32+
33+
# Convert perf profiles into profraw
34+
add_custom_target(convert-perf-profraw
35+
COMMAND "${Python3_EXECUTABLE}"
36+
${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py perf2prof ${LLVM_PROFGEN}
37+
$<TARGET_FILE:clang> ${CMAKE_CURRENT_BINARY_DIR}
38+
COMMENT "Converting perf profiles into profraw"
39+
DEPENDS generate-profraw)
40+
add_dependencies(generate-profdata-deps convert-perf-profraw)
41+
else()
42+
add_dependencies(generate-profdata-deps generate-profraw)
43+
endif()
44+
2145
add_custom_target(clear-profraw
2246
COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/profiles/ profraw
47+
COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} perf.data
2348
COMMENT "Clearing old profraw data")
2449

2550
if(NOT LLVM_PROFDATA)
@@ -30,9 +55,12 @@ if(LLVM_BUILD_INSTRUMENTED)
3055
message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to llvm-profdata")
3156
else()
3257
add_custom_target(generate-profdata
33-
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/
58+
COMMAND "${Python3_EXECUTABLE}"
59+
${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA}
60+
${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
61+
${CMAKE_BINARY_DIR}/profiles/ ${PROFDATA_SAMPLE}
3462
COMMENT "Merging profdata"
35-
DEPENDS generate-profraw)
63+
DEPENDS generate-profdata-deps)
3664
if (CLANG_PGO_TRAINING_DATA_SOURCE_DIR)
3765
llvm_ExternalProject_Add(generate-profraw-external ${CLANG_PGO_TRAINING_DATA_SOURCE_DIR}
3866
USE_TOOLCHAIN EXLUDE_FROM_ALL NO_INSTALL DEPENDS generate-profraw)

clang/utils/perf-training/lit.cfg

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ config.name = 'Clang Perf Training'
2828
config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap', '.test']
2929

3030
cc1_wrapper = '%s %s/perf-helper.py cc1' % (config.python_exe, config.perf_helper_dir)
31+
if config.llvm_build_instrumented.upper() == "CSSPGO":
32+
perf_wrapper = "%s %s/perf-helper.py perf --lbr --call-graph --event=br_inst_retired.near_taken:uppp -- " % (
33+
config.python_exe,
34+
config.perf_helper_dir,
35+
)
36+
cc1_wrapper = perf_wrapper
3137

3238
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
3339
config.test_format = lit.formats.ShTest(use_lit_shell == "0")

clang/utils/perf-training/lit.site.cfg.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
88
config.test_source_root = "@CLANG_PGO_TRAINING_DATA@"
99
config.target_triple = "@LLVM_TARGET_TRIPLE@"
1010
config.python_exe = "@Python3_EXECUTABLE@"
11+
config.llvm_build_instrumented = "@LLVM_BUILD_INSTRUMENTED@"
1112

1213
# Let the main config do the real work.
1314
lit_config.load_config(config, "@CLANG_SOURCE_DIR@/utils/perf-training/lit.cfg")

clang/utils/perf-training/perf-helper.py

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,21 @@ def clean(args):
4343

4444

4545
def merge(args):
46-
if len(args) < 3:
47-
print(
48-
"Usage: %s merge <llvm-profdata> <output> <paths>\n" % __file__
49-
+ "\tMerges all profraw files from path into output."
50-
)
51-
return 1
52-
cmd = [args[0], "merge", "-o", args[1]]
53-
for path in args[2:]:
46+
parser = argparse.ArgumentParser(
47+
prog="perf-helper merge",
48+
description="Merges all profraw files from path(s) into output"
49+
)
50+
parser.add_argument("profdata", help="Path to llvm-profdata tool")
51+
parser.add_argument("output", help="Output filename")
52+
parser.add_argument("paths", nargs='+',
53+
help="Folder(s) containing input profraw files")
54+
parser.add_argument("--sample", action="store_true", help="Sample profile")
55+
opts = parser.parse_args(args)
56+
57+
cmd = [opts.profdata, "merge", "-o", opts.output]
58+
if opts.sample:
59+
cmd += ["--sample"]
60+
for path in opts.paths:
5461
cmd.extend(findFilesWithExtension(path, "profraw"))
5562
subprocess.check_call(cmd)
5663
return 0
@@ -71,11 +78,19 @@ def merge_fdata(args):
7178

7279
def perf(args):
7380
parser = argparse.ArgumentParser(
74-
prog="perf-helper perf", description="perf wrapper for BOLT profile collection"
81+
prog="perf-helper perf",
82+
description="perf wrapper for BOLT/CSSPGO profile collection"
7583
)
7684
parser.add_argument(
7785
"--lbr", action="store_true", help="Use perf with branch stacks"
7886
)
87+
parser.add_argument(
88+
"--call-graph", action="store_true", help="Collect call graph"
89+
)
90+
parser.add_argument(
91+
"--event", help="PMU event name, defaults to cycles:u",
92+
default="cycles:u"
93+
)
7994
parser.add_argument("cmd", nargs=argparse.REMAINDER, help="")
8095

8196
opts = parser.parse_args(args)
@@ -84,12 +99,14 @@ def perf(args):
8499
perf_args = [
85100
"perf",
86101
"record",
87-
"--event=cycles:u",
102+
f"--event={opts.event}",
88103
"--freq=max",
89104
"--output=%d.perf.data" % os.getpid(),
90105
]
91106
if opts.lbr:
92107
perf_args += ["--branch-filter=any,u"]
108+
if opts.call_graph:
109+
perf_args += ["-g", "--call-graph=fp"]
93110
perf_args.extend(cmd)
94111

95112
start_time = time.time()
@@ -125,6 +142,23 @@ def perf2bolt(args):
125142
return 0
126143

127144

145+
def perf2prof(args):
146+
parser = argparse.ArgumentParser(
147+
prog="perf-helper perf2prof",
148+
description="perf to CSSPGO prof conversion wrapper",
149+
)
150+
parser.add_argument("profgen", help="Path to llvm-profgen binary")
151+
parser.add_argument("binary", help="Input binary")
152+
parser.add_argument("path", help="Path containing perf.data files")
153+
opts = parser.parse_args(args)
154+
155+
profgen_args = [opts.profgen, f"--binary={opts.binary}"]
156+
for filename in findFilesWithExtension(opts.path, "perf.data"):
157+
subprocess.check_call(profgen_args + [f"--perfdata={filename}",
158+
f"--output={filename}.profraw"])
159+
return 0
160+
161+
128162
def dtrace(args):
129163
parser = argparse.ArgumentParser(
130164
prog="perf-helper dtrace",
@@ -567,6 +601,7 @@ def genOrderFile(args):
567601
"merge-fdata": merge_fdata,
568602
"perf": perf,
569603
"perf2bolt": perf2bolt,
604+
"perf2prof": perf2prof,
570605
}
571606

572607

llvm/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,9 @@ set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_defa
879879
set(LLVM_PROFDATA_FILE "" CACHE FILEPATH
880880
"Profiling data file to use when compiling in order to improve runtime performance.")
881881

882+
set(LLVM_SPROFDATA_FILE "" CACHE FILEPATH
883+
"Sampling profiling data file to use when compiling in order to improve runtime performance.")
884+
882885
if(LLVM_INCLUDE_TESTS)
883886
# Lit test suite requires at least python 3.6
884887
set(LLVM_MINIMUM_PYTHON_VERSION 3.6)

llvm/cmake/modules/HandleLLVMOptions.cmake

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ endif()
11161116
option(LLVM_ENABLE_IR_PGO "Build LLVM and tools with IR PGO instrumentation (deprecated)" Off)
11171117
mark_as_advanced(LLVM_ENABLE_IR_PGO)
11181118

1119-
set(LLVM_BUILD_INSTRUMENTED OFF CACHE STRING "Build LLVM and tools with PGO instrumentation. May be specified as IR or Frontend")
1119+
set(LLVM_BUILD_INSTRUMENTED OFF CACHE STRING "Build LLVM and tools with PGO instrumentation. May be specified as IR, Frontend, CSIR, CSSPGO")
11201120
set(LLVM_VP_COUNTERS_PER_SITE "1.5" CACHE STRING "Value profile counters to use per site for IR PGO with Clang")
11211121
mark_as_advanced(LLVM_BUILD_INSTRUMENTED LLVM_VP_COUNTERS_PER_SITE)
11221122
string(TOUPPER "${LLVM_BUILD_INSTRUMENTED}" uppercase_LLVM_BUILD_INSTRUMENTED)
@@ -1149,6 +1149,15 @@ if (LLVM_BUILD_INSTRUMENTED)
11491149
CMAKE_EXE_LINKER_FLAGS
11501150
CMAKE_SHARED_LINKER_FLAGS)
11511151
endif()
1152+
elseif(uppercase_LLVM_BUILD_INSTRUMENTED STREQUAL "CSSPGO")
1153+
append("-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-optimize-sibling-calls -fpseudo-probe-for-profiling"
1154+
CMAKE_CXX_FLAGS
1155+
CMAKE_C_FLAGS)
1156+
if(NOT LINKER_IS_LLD_LINK)
1157+
append("-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-optimize-sibling-calls -fpseudo-probe-for-profiling"
1158+
CMAKE_EXE_LINKER_FLAGS
1159+
CMAKE_SHARED_LINKER_FLAGS)
1160+
endif()
11521161
else()
11531162
append("-fprofile-instr-generate=\"${LLVM_PROFILE_FILE_PATTERN}\""
11541163
CMAKE_CXX_FLAGS
@@ -1199,6 +1208,21 @@ if(LLVM_PROFDATA_FILE AND EXISTS ${LLVM_PROFDATA_FILE})
11991208
endif()
12001209
endif()
12011210

1211+
if(LLVM_SPROFDATA_FILE AND EXISTS ${LLVM_SPROFDATA_FILE})
1212+
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
1213+
append("-fpseudo-probe-for-profiling -fprofile-sample-use=\"${LLVM_SPROFDATA_FILE}\""
1214+
CMAKE_CXX_FLAGS
1215+
CMAKE_C_FLAGS)
1216+
if(NOT LINKER_IS_LLD_LINK)
1217+
append("-fpseudo-probe-for-profiling -fprofile-sample-use=\"${LLVM_SPROFDATA_FILE}\""
1218+
CMAKE_EXE_LINKER_FLAGS
1219+
CMAKE_SHARED_LINKER_FLAGS)
1220+
endif()
1221+
else()
1222+
message(FATAL_ERROR "LLVM_SPROFDATA_FILE can only be specified when compiling with clang")
1223+
endif()
1224+
endif()
1225+
12021226
option(LLVM_BUILD_INSTRUMENTED_COVERAGE "Build LLVM and tools with Code Coverage instrumentation" Off)
12031227
option(LLVM_INDIVIDUAL_TEST_COVERAGE "Emit individual coverage file for each test case." OFF)
12041228
mark_as_advanced(LLVM_BUILD_INSTRUMENTED_COVERAGE)

0 commit comments

Comments
 (0)