Bug 1568026 - move LTO/PGO configure bits to a new file; r=dmajor

To do properly checks on LLVM version correspondence between `clang` and
`rustc`, we need information about both of those compilers to be
available.  The current placement of the LTO/PGO checks is after we know
something about `clang`, but before we know something about `rustc`.
Therefore we need to move those checks after we've gathered information
about `rustc`.

The PGO bits come along for this bug because the LTO bits depend on
them, and we're going to need the Rust information for cross-language
PGO checks in a different bug.  So we might as well move everything all
at once.

Differential Revision: https://phabricator.services.mozilla.com/D39390

--HG--
rename : build/moz.configure/toolchain.configure => build/moz.configure/lto-pgo.configure
extra : moz-landing-system : lando
This commit is contained in:
Nathan Froyd 2019-07-30 16:38:39 +00:00
Родитель 748c1f7ff0
Коммит f51898d9da
3 изменённых файлов: 197 добавлений и 191 удалений

Просмотреть файл

@ -0,0 +1,195 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# PGO
# ==============================================================
@depends(c_compiler, check_build_environment, target)
@imports('multiprocessing')
@imports(_from='__builtin__', _import='min')
def pgo_flags(compiler, build_env, target):
topobjdir = build_env.topobjdir
if topobjdir.endswith('/js/src'):
topobjdir = topobjdir[:-7]
if compiler.type == 'gcc':
return namespace(
gen_cflags=['-fprofile-generate'],
gen_ldflags=['-fprofile-generate'],
use_cflags=['-fprofile-use', '-fprofile-correction',
'-Wcoverage-mismatch'],
use_ldflags=['-fprofile-use'],
)
if compiler.type in ('clang-cl', 'clang'):
profdata = os.path.join(topobjdir, 'merged.profdata')
prefix = ''
if compiler.type == 'clang-cl':
prefix = '/clang:'
if target.cpu == 'x86_64':
gen_ldflags = ['clang_rt.profile-x86_64.lib']
elif target.cpu == 'x86':
gen_ldflags = ['clang_rt.profile-i386.lib']
else:
gen_ldflags = None
else:
gen_ldflags = ['-fprofile-generate']
return namespace(
gen_cflags=[prefix + '-fprofile-generate'],
gen_ldflags=gen_ldflags,
use_cflags=[prefix + '-fprofile-use=%s' % profdata,
# Some error messages about mismatched profile data
# come in via -Wbackend-plugin, so disable those too.
'-Wno-error=backend-plugin'],
use_ldflags=[],
)
set_config('PROFILE_GEN_CFLAGS', pgo_flags.gen_cflags)
set_config('PROFILE_GEN_LDFLAGS', pgo_flags.gen_ldflags)
set_config('PROFILE_USE_CFLAGS', pgo_flags.use_cflags)
set_config('PROFILE_USE_LDFLAGS', pgo_flags.use_ldflags)
llvm_profdata = check_prog('LLVM_PROFDATA', ['llvm-profdata'],
allow_missing=True,
paths=toolchain_search_path)
js_option('--enable-profile-generate',
help='Build a PGO instrumented binary')
imply_option('MOZ_PGO',
depends_if('--enable-profile-generate')(lambda _: True))
set_config('MOZ_PROFILE_GENERATE',
depends_if('--enable-profile-generate')(lambda _: True))
set_define('MOZ_PROFILE_GENERATE',
depends_if('--enable-profile-generate')(lambda _: True))
js_option('--enable-profile-use',
help='Use a generated profile during the build')
js_option('--with-pgo-profile-path',
help='Path to the directory with unmerged profile data to use during the build',
nargs=1)
imply_option('MOZ_PGO',
depends_if('--enable-profile-use')(lambda _: True))
set_config('MOZ_PROFILE_USE',
depends_if('--enable-profile-use')(lambda _: True))
@depends('--with-pgo-profile-path', '--enable-profile-use', llvm_profdata)
@imports('os')
def pgo_profile_path(path, pgo_use, profdata):
if not path:
return
if path and not pgo_use:
die('Pass --enable-profile-use to use --with-pgo-profile-path.')
if path and not profdata:
die('LLVM_PROFDATA must be set to process the pgo profile.')
if not os.path.isdir(path[0]):
die('Argument to --with-pgo-profile-path must be a directory.')
if not os.path.isabs(path[0]):
die('Argument to --with-pgo-profile-path must be an absolute path.')
return path[0]
set_config('PGO_PROFILE_PATH', pgo_profile_path)
option('--with-pgo-jarlog',
help='Use the provided jarlog file when packaging during a profile-use '
'build',
nargs=1)
set_config('PGO_JARLOG_PATH', depends_if('--with-pgo-jarlog')(lambda p: p))
# LTO
# ==============================================================
js_option('--enable-lto',
env='MOZ_LTO',
nargs='?',
choices=('full', 'thin', 'cross'),
help='Enable LTO')
js_option(env='MOZ_LD64_KNOWN_GOOD',
nargs=1,
help='Indicate that ld64 is free of symbol aliasing bugs.')
imply_option('MOZ_LD64_KNOWN_GOOD', depends_if('MOZ_AUTOMATION')(lambda _: True))
@depends('--enable-lto', 'MOZ_PGO', '--enable-profile-generate', c_compiler,
'MOZ_LD64_KNOWN_GOOD', target)
@imports('multiprocessing')
def lto(value, pgo, profile_generate, c_compiler, ld64_known_good, target):
cflags = []
ldflags = []
enabled = None
rust_lto = False
# MSVC's implementation of PGO implies LTO. Make clang-cl match this.
if c_compiler.type == 'clang-cl' and pgo and not profile_generate and value.origin == 'default':
value = ['cross']
if value:
enabled = True
# `cross` implies `thin`, but with Rust code participating in LTO
# as well. Make that a little more explicit.
if len(value) and value[0].lower() == 'cross':
if c_compiler.type == 'gcc':
die('Cross-language LTO is not supported with GCC.')
rust_lto = True
value = ['thin']
if target.kernel == 'Darwin' and target.os == 'OSX' \
and value[0].lower() == 'cross' and not ld64_known_good:
die('The Mac linker is known to have a bug that affects cross-language '
'LTO. If you know that your linker is free from this bug, please '
'set the environment variable `MOZ_LD64_KNOWN_GOOD=1` and re-run '
'configure.')
if c_compiler.type == 'clang':
if len(value) and value[0].lower() == 'full':
cflags.append("-flto")
ldflags.append("-flto")
else:
cflags.append("-flto=thin")
ldflags.append("-flto=thin")
elif c_compiler.type == 'clang-cl':
if len(value) and value[0].lower() == 'full':
cflags.append("-flto")
else:
cflags.append("-flto=thin")
# With clang-cl, -flto can only be used with -c or -fuse-ld=lld.
# AC_TRY_LINKs during configure don't have -c, so pass -fuse-ld=lld.
cflags.append("-fuse-ld=lld");
else:
num_cores = multiprocessing.cpu_count()
cflags.append("-flto")
cflags.append("-flifetime-dse=1")
ldflags.append("-flto=%s" % num_cores)
ldflags.append("-flifetime-dse=1")
return namespace(
enabled=enabled,
cflags=cflags,
ldflags=ldflags,
rust_lto=rust_lto,
)
add_old_configure_assignment('MOZ_LTO', lto.enabled)
set_config('MOZ_LTO', lto.enabled)
set_define('MOZ_LTO', lto.enabled)
set_config('MOZ_LTO_CFLAGS', lto.cflags)
set_config('MOZ_LTO_LDFLAGS', lto.ldflags)
set_config('MOZ_LTO_RUST', lto.rust_lto)
add_old_configure_assignment('MOZ_LTO_CFLAGS', lto.cflags)
add_old_configure_assignment('MOZ_LTO_LDFLAGS', lto.ldflags)

Просмотреть файл

@ -1411,54 +1411,6 @@ set_config('_DEPEND_CFLAGS', depend_cflags(c_compiler))
set_config('_HOST_DEPEND_CFLAGS', depend_cflags(host_c_compiler))
@depends(c_compiler, check_build_environment, target)
@imports('multiprocessing')
@imports(_from='__builtin__', _import='min')
def pgo_flags(compiler, build_env, target):
topobjdir = build_env.topobjdir
if topobjdir.endswith('/js/src'):
topobjdir = topobjdir[:-7]
if compiler.type == 'gcc':
return namespace(
gen_cflags=['-fprofile-generate'],
gen_ldflags=['-fprofile-generate'],
use_cflags=['-fprofile-use', '-fprofile-correction',
'-Wcoverage-mismatch'],
use_ldflags=['-fprofile-use'],
)
if compiler.type in ('clang-cl', 'clang'):
profdata = os.path.join(topobjdir, 'merged.profdata')
prefix = ''
if compiler.type == 'clang-cl':
prefix = '/clang:'
if target.cpu == 'x86_64':
gen_ldflags = ['clang_rt.profile-x86_64.lib']
elif target.cpu == 'x86':
gen_ldflags = ['clang_rt.profile-i386.lib']
else:
gen_ldflags = None
else:
gen_ldflags = ['-fprofile-generate']
return namespace(
gen_cflags=[prefix + '-fprofile-generate'],
gen_ldflags=gen_ldflags,
use_cflags=[prefix + '-fprofile-use=%s' % profdata,
# Some error messages about mismatched profile data
# come in via -Wbackend-plugin, so disable those too.
'-Wno-error=backend-plugin'],
use_ldflags=[],
)
set_config('PROFILE_GEN_CFLAGS', pgo_flags.gen_cflags)
set_config('PROFILE_GEN_LDFLAGS', pgo_flags.gen_ldflags)
set_config('PROFILE_USE_CFLAGS', pgo_flags.use_cflags)
set_config('PROFILE_USE_LDFLAGS', pgo_flags.use_ldflags)
@depends(c_compiler)
def preprocess_option(compiler):
# The uses of PREPROCESS_OPTION depend on the spacing for -o/-Fi.
@ -1482,149 +1434,6 @@ def is_windows(target, host):
include('windows.configure', when=is_windows)
# PGO
# ==============================================================
llvm_profdata = check_prog('LLVM_PROFDATA', ['llvm-profdata'],
allow_missing=True,
paths=toolchain_search_path)
js_option('--enable-profile-generate',
help='Build a PGO instrumented binary')
imply_option('MOZ_PGO',
depends_if('--enable-profile-generate')(lambda _: True))
set_config('MOZ_PROFILE_GENERATE',
depends_if('--enable-profile-generate')(lambda _: True))
set_define('MOZ_PROFILE_GENERATE',
depends_if('--enable-profile-generate')(lambda _: True))
js_option('--enable-profile-use',
help='Use a generated profile during the build')
js_option('--with-pgo-profile-path',
help='Path to the directory with unmerged profile data to use during the build',
nargs=1)
imply_option('MOZ_PGO',
depends_if('--enable-profile-use')(lambda _: True))
set_config('MOZ_PROFILE_USE',
depends_if('--enable-profile-use')(lambda _: True))
@depends('--with-pgo-profile-path', '--enable-profile-use', llvm_profdata)
@imports('os')
def pgo_profile_path(path, pgo_use, profdata):
if not path:
return
if path and not pgo_use:
die('Pass --enable-profile-use to use --with-pgo-profile-path.')
if path and not profdata:
die('LLVM_PROFDATA must be set to process the pgo profile.')
if not os.path.isdir(path[0]):
die('Argument to --with-pgo-profile-path must be a directory.')
if not os.path.isabs(path[0]):
die('Argument to --with-pgo-profile-path must be an absolute path.')
return path[0]
set_config('PGO_PROFILE_PATH', pgo_profile_path)
option('--with-pgo-jarlog',
help='Use the provided jarlog file when packaging during a profile-use '
'build',
nargs=1)
set_config('PGO_JARLOG_PATH', depends_if('--with-pgo-jarlog')(lambda p: p))
# LTO
# ==============================================================
js_option('--enable-lto',
env='MOZ_LTO',
nargs='?',
choices=('full', 'thin', 'cross'),
help='Enable LTO')
js_option(env='MOZ_LD64_KNOWN_GOOD',
nargs=1,
help='Indicate that ld64 is free of symbol aliasing bugs.')
imply_option('MOZ_LD64_KNOWN_GOOD', depends_if('MOZ_AUTOMATION')(lambda _: True))
@depends('--enable-lto', 'MOZ_PGO', '--enable-profile-generate', c_compiler,
'MOZ_LD64_KNOWN_GOOD', target)
@imports('multiprocessing')
def lto(value, pgo, profile_generate, c_compiler, ld64_known_good, target):
cflags = []
ldflags = []
enabled = None
rust_lto = False
# MSVC's implementation of PGO implies LTO. Make clang-cl match this.
if c_compiler.type == 'clang-cl' and pgo and not profile_generate and value.origin == 'default':
value = ['cross']
if value:
enabled = True
# `cross` implies `thin`, but with Rust code participating in LTO
# as well. Make that a little more explicit.
if len(value) and value[0].lower() == 'cross':
if c_compiler.type == 'gcc':
die('Cross-language LTO is not supported with GCC.')
rust_lto = True
value = ['thin']
if target.kernel == 'Darwin' and target.os == 'OSX' \
and value[0].lower() == 'cross' and not ld64_known_good:
die('The Mac linker is known to have a bug that affects cross-language '
'LTO. If you know that your linker is free from this bug, please '
'set the environment variable `MOZ_LD64_KNOWN_GOOD=1` and re-run '
'configure.')
if c_compiler.type == 'clang':
if len(value) and value[0].lower() == 'full':
cflags.append("-flto")
ldflags.append("-flto")
else:
cflags.append("-flto=thin")
ldflags.append("-flto=thin")
elif c_compiler.type == 'clang-cl':
if len(value) and value[0].lower() == 'full':
cflags.append("-flto")
else:
cflags.append("-flto=thin")
# With clang-cl, -flto can only be used with -c or -fuse-ld=lld.
# AC_TRY_LINKs during configure don't have -c, so pass -fuse-ld=lld.
cflags.append("-fuse-ld=lld");
else:
num_cores = multiprocessing.cpu_count()
cflags.append("-flto")
cflags.append("-flifetime-dse=1")
ldflags.append("-flto=%s" % num_cores)
ldflags.append("-flifetime-dse=1")
return namespace(
enabled=enabled,
cflags=cflags,
ldflags=ldflags,
rust_lto=rust_lto,
)
add_old_configure_assignment('MOZ_LTO', lto.enabled)
set_config('MOZ_LTO', lto.enabled)
set_define('MOZ_LTO', lto.enabled)
set_config('MOZ_LTO_CFLAGS', lto.cflags)
set_config('MOZ_LTO_LDFLAGS', lto.ldflags)
set_config('MOZ_LTO_RUST', lto.rust_lto)
add_old_configure_assignment('MOZ_LTO_CFLAGS', lto.cflags)
add_old_configure_assignment('MOZ_LTO_LDFLAGS', lto.ldflags)
# ASAN
# ==============================================================

Просмотреть файл

@ -22,6 +22,8 @@ include('../build/moz.configure/rust.configure',
when='--enable-compile-environment')
include('../build/moz.configure/bindgen.configure',
when='--enable-compile-environment')
include('../build/moz.configure/lto-pgo.configure',
when='--enable-compile-environment')
@depends('JS_STANDALONE')
def js_standalone(value):