Add thinlto support. Closes #7493.

pull/7913/head
Jussi Pakkanen 4 years ago
parent b6dc4d5e5c
commit 3e6fbde94c
  1. 27
      docs/markdown/snippets/thinlto.md
  2. 16
      mesonbuild/compilers/compilers.py
  3. 7
      mesonbuild/compilers/mixins/clang.py
  4. 4
      mesonbuild/compilers/mixins/gnu.py
  5. 2
      mesonbuild/compilers/mixins/islinker.py
  6. 6
      mesonbuild/linkers.py
  7. 2
      test cases/common/41 options/meson.build

@ -0,0 +1,27 @@
## Add support for thin LTO
The `b_lto` option has been updated and now can be set to the value
`thin`. This enables [thin
LTO](https://clang.llvm.org/docs/ThinLTO.html) on all compilers where
it is supported. At the time of writing this means only Clang.
This change is potentially backwards incompatible. If you have
examined the value of `b_lto` in your build file, note that its type
has changed from a boolean to a string. Thus comparisons like this:
```meson
if get_option('b_lto')
...
endif
```
need to be changed to something like this instead:
```meson
if get_option('b_lto') == 'true'
...
endif
```
This should not affect any comman line invocations as configuring LTO
with `-Db_lto=true` still works and behaves the same way as before.

@ -266,7 +266,9 @@ clike_debug_args = {False: [],
True: ['-g']} # type: T.Dict[bool, T.List[str]] True: ['-g']} # type: T.Dict[bool, T.List[str]]
base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True), base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True),
'b_lto': coredata.UserBooleanOption('Use link time optimization', False), 'b_lto': coredata.UserComboOption('Use link time optimization',
['false', 'true', 'thin'],
'false'),
'b_sanitize': coredata.UserComboOption('Code sanitizer to use', 'b_sanitize': coredata.UserComboOption('Code sanitizer to use',
['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'], ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'],
'none'), 'none'),
@ -307,8 +309,7 @@ def option_enabled(boptions: T.List[str], options: 'OptionDictType',
def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.List[str]: def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.List[str]:
args = [] # type T.List[str] args = [] # type T.List[str]
try: try:
if options['b_lto'].value: args.extend(compiler.get_lto_compile_args(options['b_lto'].value))
args.extend(compiler.get_lto_compile_args())
except KeyError: except KeyError:
pass pass
try: try:
@ -357,8 +358,7 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
is_shared_module: bool) -> T.List[str]: is_shared_module: bool) -> T.List[str]:
args = [] # type: T.List[str] args = [] # type: T.List[str]
try: try:
if options['b_lto'].value: args.extend(linker.get_lto_link_args(options['b_lto'].value))
args.extend(linker.get_lto_link_args())
except KeyError: except KeyError:
pass pass
try: try:
@ -940,11 +940,11 @@ class Compiler(metaclass=abc.ABCMeta):
ret.append(arg) ret.append(arg)
return ret return ret
def get_lto_compile_args(self) -> T.List[str]: def get_lto_compile_args(self, lto_type: str) -> T.List[str]:
return [] return []
def get_lto_link_args(self) -> T.List[str]: def get_lto_link_args(self, lto_type: str) -> T.List[str]:
return self.linker.get_lto_args() return self.linker.get_lto_args(lto_type)
def sanitizer_compile_args(self, value: str) -> T.List[str]: def sanitizer_compile_args(self, value: str) -> T.List[str]:
return [] return []

@ -77,6 +77,13 @@ class ClangCompiler(GnuLikeCompiler):
# so it might change semantics at any time. # so it might change semantics at any time.
return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))] return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))]
def get_lto_compile_args(self, lto_type: str) -> T.List[str]:
if lto_type == 'thin':
return ['-flto=thin']
if lto_type == 'true':
return ['-flto']
return []
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
myargs = [] # type: T.List[str] myargs = [] # type: T.List[str]
if mode is CompileCheckMode.COMPILE: if mode is CompileCheckMode.COMPILE:

@ -295,8 +295,10 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
return self._split_fetch_real_dirs(line.split('=', 1)[1]) return self._split_fetch_real_dirs(line.split('=', 1)[1])
return [] return []
def get_lto_compile_args(self) -> T.List[str]: def get_lto_compile_args(self, lto_type: str) -> T.List[str]:
if lto_type != 'false':
return ['-flto'] return ['-flto']
return []
def sanitizer_compile_args(self, value: str) -> T.List[str]: def sanitizer_compile_args(self, value: str) -> T.List[str]:
if value == 'none': if value == 'none':

@ -48,7 +48,7 @@ class BasicLinkerIsCompilerMixin(Compiler):
def sanitizer_link_args(self, value: str) -> T.List[str]: def sanitizer_link_args(self, value: str) -> T.List[str]:
return [] return []
def get_lto_link_args(self) -> T.List[str]: def get_lto_link_args(self, lto_type: str) -> T.List[str]:
return [] return []
def can_linker_accept_rsp(self) -> bool: def can_linker_accept_rsp(self) -> bool:

@ -411,7 +411,7 @@ class DynamicLinker(LinkerEnvVarsMixin, metaclass=abc.ABCMeta):
m = 'Linker {} does not support position-independent executable' m = 'Linker {} does not support position-independent executable'
raise mesonlib.EnvironmentException(m.format(self.id)) raise mesonlib.EnvironmentException(m.format(self.id))
def get_lto_args(self) -> T.List[str]: def get_lto_args(self, lto_type: str) -> T.List[str]:
return [] return []
def sanitizer_args(self, value: str) -> T.List[str]: def sanitizer_args(self, value: str) -> T.List[str]:
@ -550,8 +550,10 @@ class GnuLikeDynamicLinkerMixin:
def get_allow_undefined_args(self) -> T.List[str]: def get_allow_undefined_args(self) -> T.List[str]:
return self._apply_prefix('--allow-shlib-undefined') return self._apply_prefix('--allow-shlib-undefined')
def get_lto_args(self) -> T.List[str]: def get_lto_args(self, lto_type: str) -> T.List[str]:
if lto_type != 'false':
return ['-flto'] return ['-flto']
return []
def sanitizer_args(self, value: str) -> T.List[str]: def sanitizer_args(self, value: str) -> T.List[str]:
if value == 'none': if value == 'none':

@ -18,7 +18,7 @@ if get_option('array_opt') != ['one', 'two']
endif endif
# If the default changes, update test cases/unit/13 reconfigure # If the default changes, update test cases/unit/13 reconfigure
if get_option('b_lto') != false if get_option('b_lto') != 'false'
error('Incorrect value in base option.') error('Incorrect value in base option.')
endif endif

Loading…
Cancel
Save