Skip to content

Commit e573a6b

Browse files
committed
tc-build: Introduce '--muilticall'
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
1 parent aaec068 commit e573a6b

File tree

3 files changed

+42
-16
lines changed

3 files changed

+42
-16
lines changed

build-llvm.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@
236236
'''),
237237
type=str,
238238
choices=['thin', 'full'])
239+
parser.add_argument('-m',
240+
'--multicall',
241+
help=textwrap.dedent('''\
242+
Build LLVM as a multicall binary via the LLVM_TOOL_LLVM_DRIVER_BUILD CMake option.
243+
This results in a much smaller installation on disk.
244+
245+
'''),
246+
action='store_true')
239247
parser.add_argument('-n',
240248
'--no-update',
241249
help=textwrap.dedent('''\
@@ -536,6 +544,8 @@
536544
if args.vendor_string:
537545
common_cmake_defines['CLANG_VENDOR'] = args.vendor_string
538546
common_cmake_defines['LLD_VENDOR'] = args.vendor_string
547+
if args.multicall:
548+
common_cmake_defines['LLVM_TOOL_LLVM_DRIVER_BUILD'] = 'ON'
539549
if args.defines:
540550
defines = dict(define.split('=', 1) for define in args.defines)
541551
common_cmake_defines.update(defines)

tc_build/kernel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ def __init__(self, arch):
3838

3939
def build(self):
4040
bin_folder = Path(self.toolchain_prefix, 'bin')
41-
if self.bolt_instrumentation:
42-
self.make_variables['CC'] = Path(bin_folder, 'clang.inst')
41+
if self.bolt_instrumentation and (clang_inst := Path(bin_folder, 'clang.inst')).exists():
42+
self.make_variables['CC'] = clang_inst
4343
# The user may have configured clang without the host target, in which
4444
# case we need to use GCC for compiling the host utilities.
4545
if self.can_use_clang_as_hostcc():

tc_build/llvm.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,26 +74,27 @@ def bolt_clang(self):
7474

7575
tc_build.utils.print_header(f"Performing BOLT with {mode}")
7676

77-
# clang-#: original binary
78-
# clang.bolt: BOLT optimized binary
77+
# real_binary: clang-# or llvm (if multicall is enabled)
78+
# bolt_binary: clang.bolt or llvm.bolt
7979
# .bolt will become original binary after optimization
80-
clang = Path(self.folders.build, 'bin/clang').resolve()
81-
clang_bolt = clang.with_name('clang.bolt')
80+
real_binary = Path(self.folders.build, 'bin/clang').resolve()
81+
binary_prefix = 'llvm' if self.multicall_is_enabled() else 'clang'
82+
bolt_binary = real_binary.with_name(f"{binary_prefix}.bolt")
8283

83-
bolt_profile = Path(self.folders.build, 'clang.fdata')
84+
bolt_profile = Path(self.folders.build, f"{binary_prefix}.fdata")
8485

8586
if mode == 'instrumentation':
86-
# clang.inst: instrumented binary, will be removed after generating profiles
87-
clang_inst = clang.with_name('clang.inst')
87+
# clang.inst / llvm.inst: instrumented binary, will be removed after generating profiles
88+
inst_binary = real_binary.with_name(f"{binary_prefix}.inst")
8889

8990
clang_inst_cmd = [
9091
self.tools.llvm_bolt,
9192
'--instrument',
9293
f"--instrumentation-file={bolt_profile}",
9394
'--instrumentation-file-append-pid',
9495
'-o',
95-
clang_inst,
96-
clang,
96+
inst_binary,
97+
real_binary,
9798
]
9899
# When running an instrumented binary on certain platforms (namely
99100
# Apple Silicon), there may be hangs due to instrumentation in
@@ -106,6 +107,13 @@ def bolt_clang(self):
106107

107108
self.bolt_builder.bolt_instrumentation = True
108109

110+
# To avoid messing with all existing symlinks, move llvm to
111+
# llvm.orig and llvm.inst to llvm
112+
if binary_prefix == 'llvm':
113+
orig_binary = real_binary.with_name('llvm.orig')
114+
real_binary.replace(orig_binary)
115+
inst_binary.replace(real_binary)
116+
109117
if mode == 'sampling':
110118
self.bolt_builder.bolt_sampling_output = Path(self.folders.build, 'perf.data')
111119

@@ -115,6 +123,11 @@ def bolt_clang(self):
115123
# With instrumentation, we need to combine the profiles we generated,
116124
# as they are separated by PID
117125
if mode == 'instrumentation':
126+
# Undo shuffle from above
127+
if binary_prefix == 'llvm':
128+
real_binary.replace(inst_binary)
129+
orig_binary.replace(real_binary)
130+
118131
fdata_files = bolt_profile.parent.glob(f"{bolt_profile.name}.*.fdata")
119132

120133
# merge-fdata will print one line for each .fdata it merges.
@@ -139,7 +152,7 @@ def bolt_clang(self):
139152
self.bolt_builder.bolt_sampling_output,
140153
'-o',
141154
bolt_profile,
142-
clang,
155+
real_binary,
143156
]
144157
self.run_cmd(perf2bolt_cmd)
145158
self.bolt_builder.bolt_sampling_output.unlink()
@@ -166,18 +179,18 @@ def bolt_clang(self):
166179
'--dyno-stats',
167180
f"--icf={icf_val}",
168181
'-o',
169-
clang_bolt,
182+
bolt_binary,
170183
f"--reorder-blocks={'cache+' if use_cache_plus else 'ext-tsp'}",
171184
f"--reorder-functions={reorder_funcs_val}",
172185
'--split-all-cold',
173186
f"--split-functions{'=3' if use_sf_val else ''}",
174187
'--use-gnu-stack',
175-
clang,
188+
real_binary,
176189
]
177190
self.run_cmd(clang_opt_cmd)
178-
clang_bolt.replace(clang)
191+
bolt_binary.replace(real_binary)
179192
if mode == 'instrumentation':
180-
clang_inst.unlink()
193+
inst_binary.unlink()
181194

182195
def build(self):
183196
if not self.folders.build:
@@ -388,6 +401,9 @@ def host_target(self):
388401
def host_target_is_enabled(self):
389402
return 'all' in self.targets or self.host_target() in self.targets
390403

404+
def multicall_is_enabled(self):
405+
return self.cmake_defines.get('LLVM_TOOL_LLVM_DRIVER_BUILD', 'OFF') == 'ON'
406+
391407
def project_is_enabled(self, project):
392408
return 'all' in self.projects or project in self.projects
393409

0 commit comments

Comments
 (0)