Skip to content

Commit 072af72

Browse files
committed
Merge pull request #2941 from gottesmm/build-system-improvements-for-lto
Build system improvements for lto
2 parents 73c3711 + 2e7d88e commit 072af72

File tree

8 files changed

+218
-79
lines changed

8 files changed

+218
-79
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ set(SWIFT_NATIVE_CLANG_TOOLS_PATH "" CACHE STRING
140140
set(SWIFT_NATIVE_SWIFT_TOOLS_PATH "" CACHE STRING
141141
"Path to the directory that contains Swift tools that are executable on the build machine")
142142

143-
option(SWIFT_ENABLE_LTO
143+
option(SWIFT_TOOLS_ENABLE_LTO
144144
"If set to true, build the swift compiler with link time optimization enabled" FALSE)
145145

146146
# The following only works with the Ninja generator in CMake >= 3.0.
@@ -743,7 +743,7 @@ endif()
743743
message(STATUS "Building host Swift tools for ${SWIFT_HOST_VARIANT_SDK} ${SWIFT_HOST_VARIANT_ARCH}")
744744
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
745745
message(STATUS " Assertions: ${LLVM_ENABLE_ASSERTIONS}")
746-
message(STATUS " LTO: ${SWIFT_ENABLE_LTO}")
746+
message(STATUS " LTO: ${SWIFT_TOOLS_ENABLE_LTO}")
747747
message(STATUS "")
748748

749749
message(STATUS "Building Swift standard library and SDK overlays for SDKs: ${SWIFT_SDKS}")

cmake/modules/AddSwift.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ function(_add_variant_c_compile_flags)
131131
ARCH "${CFLAGS_ARCH}"
132132
BUILD_TYPE "${CFLAGS_BUILD_TYPE}"
133133
ENABLE_ASSERTIONS "${CFLAGS_ENABLE_ASSERTIONS}"
134-
ENABLE_LTO "${SWIFT_ENABLE_LTO}"
134+
ENABLE_LTO "${SWIFT_TOOLS_ENABLE_LTO}"
135135
ANALYZE_CODE_COVERAGE FALSE
136136
DEPLOYMENT_VERSION_IOS "${CFLAGS_DEPLOYMENT_VERSION_IOS}"
137137
RESULT_VAR_NAME result)
@@ -150,7 +150,7 @@ function(_add_variant_c_compile_flags)
150150

151151
is_build_type_with_debuginfo("${CFLAGS_BUILD_TYPE}" debuginfo)
152152
if(debuginfo)
153-
if(SWIFT_ENABLE_LTO)
153+
if(SWIFT_TOOLS_ENABLE_LTO)
154154
list(APPEND result "-gline-tables-only")
155155
else()
156156
list(APPEND result "-g")
@@ -236,7 +236,7 @@ function(_add_variant_link_flags)
236236
ARCH "${LFLAGS_ARCH}"
237237
BUILD_TYPE "${LFLAGS_BUILD_TYPE}"
238238
ENABLE_ASSERTIONS "${LFLAGS_ENABLE_ASSERTIONS}"
239-
ENABLE_LTO "${SWIFT_ENABLE_LTO}"
239+
ENABLE_LTO "${SWIFT_TOOLS_ENABLE_LTO}"
240240
ANALYZE_CODE_COVERAGE "${LFLAGS_ANALYZE_CODE_COVERAGE}"
241241
DEPLOYMENT_VERSION_IOS "${LFLAGS_DEPLOYMENT_VERSION_IOS}"
242242
RESULT_VAR_NAME result)

test/lit.site.cfg.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ if "@SWIFT_ASAN_BUILD@" == "TRUE":
2626
else:
2727
config.available_features.add('no_asan')
2828

29-
if '@SWIFT_ENABLE_LTO@' == 'TRUE':
29+
if '@SWIFT_TOOLS_ENABLE_LTO@' == 'TRUE':
3030
config.available_features.add('lto')
3131
else:
3232
config.available_features.add('no_lto')

utils/build-presets.ini

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,15 @@ test-optimized=0
182182
mixin-preset=
183183
mixin_buildbot_tools_RA_stdlib_RDA
184184

185+
lto
186+
185187
dash-dash
186188

187189
# Don't run host tests for iOS, tvOS and watchOS platforms to make the build
188190
# faster.
189191
skip-test-ios-host
190192
skip-test-tvos-host
191193
skip-test-watchos-host
192-
swift-enable-lto
193-
llvm-enable-lto
194194

195195
#===------------------------------------------------------------------------===#
196196
# Incremental buildbots for Darwin OSes
@@ -415,9 +415,9 @@ skip-build-benchmarks
415415
mixin-preset=buildbot_incremental,tools=RA,stdlib=RD,smoketest=macosx
416416
build-subdir=buildbot_incremental
417417

418-
dash-dash
418+
lto
419419

420-
swift-enable-lto
420+
dash-dash
421421

422422
[preset: buildbot_incremental,tools=RA,llvm-only]
423423
build-subdir=buildbot_incremental_llvmonly

utils/build-script

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support'))
3737
# E402 means module level import not at top of file
3838
from swift_build_support import arguments # noqa (E402)
3939
from swift_build_support import diagnostics # noqa (E402)
40+
from swift_build_support import host # noqa (E402)
4041
from swift_build_support.toolchain import host_toolchain # noqa (E402)
4142
import swift_build_support.debug # noqa (E402)
4243
from swift_build_support import migration # noqa (E402)
@@ -976,6 +977,31 @@ details of the setups of other systems or automated environments.""")
976977
default=False,
977978
const=True)
978979

980+
parser.add_argument(
981+
"--lto",
982+
help="use lto optimization on llvm/swift tools. This does not "
983+
"imply using lto on the swift standard library or runtime",
984+
metavar="BOOL",
985+
nargs='?',
986+
type=arguments.type.bool,
987+
default=False,
988+
const=True)
989+
990+
default_max_lto_link_job_counts = host.max_lto_link_job_counts()
991+
parser.add_argument(
992+
"--llvm-max-parallel-lto-link-jobs",
993+
help="the maximum number of parallel link jobs to use when compiling "
994+
"llvm",
995+
metavar="COUNT",
996+
default=default_max_lto_link_job_counts['llvm'])
997+
998+
parser.add_argument(
999+
"--swift-tools-max-parallel-lto-link-jobs",
1000+
help="the maximum number of parallel link jobs to use when compiling "
1001+
"swift tools.",
1002+
metavar="COUNT",
1003+
default=default_max_lto_link_job_counts['swift'])
1004+
9791005
parser.add_argument(
9801006
# Explicitly unavailable options here.
9811007
"--build-jobs",
@@ -1442,6 +1468,22 @@ details of the setups of other systems or automated environments.""")
14421468
pipes.quote(opt) for opt in args.extra_cmake_options)
14431469
]
14441470

1471+
if args.lto:
1472+
build_script_impl_args += [
1473+
"--llvm-enable-lto",
1474+
"--swift-tools-enable-lto"
1475+
]
1476+
if args.llvm_max_parallel_lto_link_jobs is not None:
1477+
build_script_impl_args += [
1478+
"--llvm-num-parallel-lto-link-jobs=%s" %
1479+
min(args.llvm_max_parallel_lto_link_jobs, args.build_jobs)
1480+
]
1481+
if args.swift_tools_max_parallel_lto_link_jobs is not None:
1482+
build_script_impl_args += [
1483+
"--swift-tools-num-parallel-lto-link-jobs=%s" %
1484+
min(args.swift_tools_max_parallel_lto_link_jobs,
1485+
args.build_jobs)
1486+
]
14451487
build_script_impl_args += args.build_script_impl_args
14461488

14471489
if args.dry_run:

utils/build-script-impl

Lines changed: 16 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ KNOWN_SETTINGS=(
7474
swift-build-type "Debug" "the CMake build variant for Swift"
7575
swift-enable-assertions "1" "enable assertions in Swift"
7676
swift-analyze-code-coverage "not-merged" "Code coverage analysis mode for Swift (false, not-merged, merged). Defaults to false if the argument is not present, and not-merged if the argument is present without a modifier."
77-
swift-enable-lto "0" "enable LTO compilation of just Swift."
77+
swift-tools-enable-lto "0" "enable LTO compilation of Swift tools. *NOTE* This does not include the swift standard library and runtime."
7878
llvm-enable-lto "0" "enable LTO compilation of LLVM/Clang."
79+
swift-tools-num-parallel-lto-link-jobs "" "The number of parallel link jobs to use when compiling swift tools"
80+
llvm-num-parallel-lto-link-jobs "" "The number of parallel link jobs to use when compiling llvm"
7981
swift-stdlib-build-type "Debug" "the CMake build variant for Swift"
8082
swift-stdlib-enable-assertions "1" "enable assertions in Swift"
8183
swift-stdlib-enable-resilience "0" "build the Swift stdlib and overlays with resilience enabled"
@@ -287,28 +289,6 @@ function set_lldb_build_mode() {
287289
LLDB_BUILD_MODE="CustomSwift-${LLDB_BUILD_TYPE}"
288290
}
289291

290-
function system_memory_in_bytes() {
291-
case "$(uname -s -m)" in
292-
Darwin\ x86_64)
293-
sysctl hw.memsize | cut -f 2 -d " "
294-
;;
295-
*)
296-
echo "Unknown operating system"
297-
exit 1
298-
;;
299-
esac
300-
}
301-
302-
function float_min() {
303-
local LHS=$1
304-
local RHS=$2
305-
if (( $(echo "${LHS} < ${RHS}" | bc -l) )); then
306-
echo ${LHS}
307-
else
308-
echo ${RHS}
309-
fi
310-
}
311-
312292
# Support for performing isolated actions.
313293
#
314294
# This is part of refactoring more work to be done or controllable via
@@ -354,48 +334,6 @@ function should_execute_host_actions_for_phase() {
354334
fi
355335
}
356336

357-
function num_llvm_parallel_lto_link_jobs() {
358-
case "$(uname -s -m)" in
359-
Darwin\ x86_64)
360-
# *WARNING! HEURISTIC!*
361-
#
362-
# Use the formula (GB Memory - 3)/6.0GB to get the number of
363-
# parallel link threads we can support. This gives the OS 3 GB of
364-
# room to work with.
365-
#
366-
# This is a bit conservative, but I have found that this number
367-
# prevents me from swapping on my test machine.
368-
local NUM_MEMORY_THREADS=$(echo \( $(system_memory_in_bytes)/1000000000.0 - 3.0 \) / 6.0 | bc)
369-
echo $(float_min "${NUM_MEMORY_THREADS}" "${BUILD_JOBS}")
370-
;;
371-
*)
372-
echo "Unknown operating system"
373-
exit 1
374-
;;
375-
esac
376-
}
377-
378-
function num_swift_parallel_lto_link_jobs() {
379-
case "$(uname -s -m)" in
380-
Darwin\ x86_64)
381-
# *WARNING! HEURISTIC!*
382-
#
383-
# Use the formula (GB Memory - 3)/8.0GB to get the number of
384-
# parallel link threads we can support. This gives the OS 3 GB of
385-
# room to work with.
386-
#
387-
# This is a bit conservative, but I have found that this number
388-
# prevents me from swapping on my test machine.
389-
local NUM_MEMORY_THREADS=$(echo \( $(system_memory_in_bytes)/1000000000 - 3.0 \) / 8.0 | bc)
390-
echo $(float_min "${NUM_MEMORY_THREADS}" "${BUILD_JOBS}")
391-
;;
392-
*)
393-
echo "Unknown operating system"
394-
exit 1
395-
;;
396-
esac
397-
}
398-
399337
function set_build_options_for_host() {
400338
llvm_cmake_options=()
401339
swift_cmake_options=()
@@ -638,19 +576,28 @@ function set_build_options_for_host() {
638576
fi
639577

640578
llvm_cmake_options+=(
641-
"-DLLVM_PARALLEL_LINK_JOBS=$(num_llvm_parallel_lto_link_jobs)"
579+
"-DLLVM_PARALLEL_LINK_JOBS=${LLVM_NUM_PARALLEL_LTO_LINK_JOBS}"
642580
)
643581
fi
644582

645-
if [[ $(true_false "${SWIFT_ENABLE_LTO}") = "TRUE" ]]; then
583+
if [[ $(true_false "${SWIFT_TOOLS_ENABLE_LTO}") = "TRUE" ]]; then
646584
if [[ $(cmake_needs_to_specify_standard_computed_defaults) = "TRUE" ]]; then
647585
swift_cmake_options+=(
648586
"-DCMAKE_C_STANDARD_COMPUTED_DEFAULT=AppleClang"
649587
"-DCMAKE_CXX_STANDARD_COMPUTED_DEFAULT=AppleClang"
650588
)
651589
fi
590+
591+
# We need to also pass in this flag so that parts of LLVM's
592+
# build system that we use (for instance when compiling
593+
# unittests) do not use too many threads when we are using lto.
594+
if [[ $(true_false "${LLVM_ENABLE_LTO}") == "TRUE" ]]; then
595+
swift_cmake_options+=(
596+
"-DLLVM_PARALLEL_LINK_JOBS=${LLVM_NUM_PARALLEL_LTO_LINK_JOBS}"
597+
)
598+
fi
652599
swift_cmake_options+=(
653-
"-DSWIFT_PARALLEL_LINK_JOBS=$(num_swift_parallel_lto_link_jobs)"
600+
"-DSWIFT_PARALLEL_LINK_JOBS=${SWIFT_TOOLS_NUM_PARALLEL_LTO_LINK_JOBS}"
654601
)
655602
fi
656603

@@ -1891,7 +1838,7 @@ for host in "${ALL_HOSTS[@]}"; do
18911838
-DSWIFT_INCLUDE_TESTS:BOOL=$(true_false "${build_tests_this_time}")
18921839
-DSWIFT_INSTALL_COMPONENTS:STRING="${SWIFT_INSTALL_COMPONENTS}"
18931840
-DSWIFT_EMBED_BITCODE_SECTION:BOOL=$(true_false "${EMBED_BITCODE_SECTION}")
1894-
-DSWIFT_ENABLE_LTO:BOOL=$(true_false "${SWIFT_ENABLE_LTO}")
1841+
-DSWIFT_TOOLS_ENABLE_LTO:BOOL=$(true_false "${SWIFT_TOOLS_ENABLE_LTO}")
18951842
-DSWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER:BOOL=$(true_false "${BUILD_RUNTIME_WITH_HOST_COMPILER}")
18961843
"${swift_cmake_options[@]}"
18971844
)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# swift_build_support/host.py ----------- Migrating build-script -*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# -----------------------------------------------------------------------------
12+
#
13+
# This file contains routines for determining information about the host for
14+
# use in utils/build-script.
15+
#
16+
# -----------------------------------------------------------------------------
17+
18+
from __future__ import absolute_import
19+
20+
import platform
21+
22+
from . import shell
23+
24+
25+
# Utilities
26+
def _return_none_fun():
27+
return None
28+
29+
30+
def _return_none_fun_pair():
31+
return (_return_none_fun, _return_none_fun)
32+
33+
34+
def _compute_system_key():
35+
return (platform.system(), platform.machine())
36+
37+
38+
# System Memory
39+
def _darwin_system_memory():
40+
# Output looks like "hw.memsize: \d+\n"
41+
return int(shell.capture(["sysctl", "hw.memsize"],
42+
dry_run=False, echo=False,
43+
optional=False).strip().split(" ")[1])
44+
45+
_PER_PLATFORM_SYSTEM_MEMORY = {
46+
('Darwin', 'x86_64'): _darwin_system_memory
47+
}
48+
49+
50+
def system_memory():
51+
return _PER_PLATFORM_SYSTEM_MEMORY.get(_compute_system_key(),
52+
_return_none_fun)()
53+
54+
55+
# Max Num CPU Threads for use with LTO
56+
def _darwin_max_num_llvm_parallel_lto_link_jobs():
57+
# *WARNING! HEURISTIC!*
58+
#
59+
# Use the formula (GB Memory - 3)/6.0GB to get the number of
60+
# parallel link threads we can support. This gives the OS 3 GB of
61+
# room to work with.
62+
#
63+
# This is a bit conservative, but I have found that this number
64+
# prevents me from swapping on my test machine.
65+
return int((_darwin_system_memory()/1000000000.0 - 3.0)/6.0)
66+
67+
68+
def _darwin_max_num_swift_parallel_lto_link_jobs():
69+
# *WARNING! HEURISTIC!*
70+
#
71+
# Use the formula (GB Memory - 3)/8.0GB to get the number of
72+
# parallel link threads we can support. This gives the OS 3 GB of
73+
# room to work with.
74+
#
75+
# This is a bit conservative, but I have found that this number
76+
# prevents me from swapping on my test machine.
77+
return int((_darwin_system_memory()/1000000000.0 - 3.0)/8.0)
78+
79+
_PER_PLATFORM_MAX_PARALLEL_LTO_JOBS = {
80+
('Darwin', 'x86_64'): (_darwin_max_num_llvm_parallel_lto_link_jobs,
81+
_darwin_max_num_swift_parallel_lto_link_jobs)
82+
}
83+
84+
85+
def max_lto_link_job_counts():
86+
key = _compute_system_key()
87+
info = _PER_PLATFORM_MAX_PARALLEL_LTO_JOBS.get(key,
88+
_return_none_fun_pair())
89+
return {'llvm': info[0](), 'swift': info[1]()}

0 commit comments

Comments
 (0)