| # Copyright 2017 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/lto/config.gni") |
| import("//build/toolchain/variant.gni") |
| |
| config("lto-clang") { |
| cflags = [ "-flto" ] |
| |
| if (!is_fuchsia || is_kernel) { |
| configs = [ ":lto-whole-program-devirtualization" ] |
| } |
| |
| ldflags = cflags |
| |
| # TODO(https://fxbug.dev/42061844): Temporarily disable branch funneling on lto. Branch |
| # funneling likely generates bad code involving return values not propagated |
| # correctly to other functions. Once this is resolved, come back and remove this. |
| if (is_fuchsia) { |
| disable_branch_funneling = "-wholeprogramdevirt-branch-funnel-threshold=0" |
| cflags += [ |
| "-mllvm", |
| "$disable_branch_funneling", |
| ] |
| ldflags += [ "-Wl,-mllvm,$disable_branch_funneling" ] |
| |
| # TODO(https://fxbug.dev/42086180): The linker flags below are required to avoid code |
| # generation bugs during LTO. They can be removed once LTO properly handles |
| # target features |
| if (target_cpu == "riscv64") { |
| ldflags += [ |
| "-Wl,-mllvm,-mattr=+c", |
| "-Wl,-mllvm,-mattr=+relax", |
| ] |
| } |
| } |
| } |
| |
| # This enables whole program devirtualization when LTO is enabled. Individual |
| # binaries can opt-in to using this for LTO builds. This can be turned on safely |
| # for self-contained binaries that do not expose the C++ ABI (such as the |
| # kernel or fdio). This should only be used for LTO builds. |
| # |
| # Users should be careful when using this because this can lead to virtual |
| # function calls unexpectedly being devirtualized if the compiler determines |
| # that a virtual call can resolve to a function from only one vtable. |
| # https://fxbug.dev/42075686 contains an example of this. For these cases, if |
| # the C++ ABI is expected to be exposed from a shared library, then adding |
| # [[clang::lto_visibility_public]] to the public/exported class will tell the |
| # compiler that other subclasses may exist outside this LTO unit. See |
| # https://clang.llvm.org/docs/LTOVisibility.html for more information on the |
| # annotation. |
| config("lto-whole-program-devirtualization") { |
| cflags = [ |
| # Opt-in for whole-program devirtualization and virtual constant propagation. |
| "-fwhole-program-vtables", |
| ] |
| ldflags = cflags |
| } |
| |
| config("lto-rust") { |
| rustflags = [ |
| "-Clto=fat", |
| "-Zdylib-lto", |
| "-Clinker-plugin-lto", |
| "-Zsplit-lto-unit", |
| ] |
| } |
| |
| # This can be appended with: |
| # ``` |
| # configs += [ "//build/config/lto:no-lto" ] |
| # ``` |
| # in any particular target to disable LTO. |
| config("no-lto") { |
| cflags = [ "-fno-lto" ] |
| |
| if (!is_fuchsia) { |
| cflags += [ "-fno-whole-program-vtables" ] |
| } |
| |
| ldflags = cflags |
| |
| rustflags = [ "-Clto=off" ] |
| } |
| |
| variant("lto") { |
| configs = [ |
| ":lto-clang", |
| ":lto-rust", |
| ] |
| } |
| |
| config("thinlto-clang") { |
| cflags = [ "-flto=thin" ] |
| ldflags = cflags |
| |
| # These switches have the same meaning but different spellings for |
| # lld-link vs ld.lld. |
| if (current_os == "win") { |
| _jobs = "/opt:lldltojobs=" |
| _cache_dir = "/lldltocache:" |
| } else { |
| _jobs = "--thinlto-jobs=" |
| _cache_dir = "--thinlto-cache-dir=" |
| } |
| |
| ldflags += [ |
| # The ThinLTO driver launches a number of threads in parallel whose |
| # number is by default equivalent to the number of cores. We need |
| # to limit the parallelism to avoid aggressive competition between |
| # different linker jobs. |
| "-Wl,${_jobs}$thinlto_jobs", |
| |
| # Set the ThinLTO cache directory which is used to cache native |
| # object files for ThinLTO incremental builds. This directory is |
| # not managed by Ninja and has to be cleaned manually, but it is |
| # periodically garbage-collected by the ThinLTO driver. |
| "-Wl,${_cache_dir}$thinlto_cache_dir", |
| ] |
| |
| # TODO(https://fxbug.dev/42086180): The linker flags below are required to avoid code |
| # generation bugs during LTO. They can be removed once LTO properly handles |
| # target features |
| if (target_cpu == "riscv64") { |
| ldflags += [ |
| "-Wl,-mllvm,-mattr=+c", |
| "-Wl,-mllvm,-mattr=+relax", |
| ] |
| } |
| } |
| |
| config("thinlto-rust") { |
| rustflags = [ |
| "-Clto=thin", |
| "-Zdylib-lto", |
| ] |
| |
| # These switches have the same meaning but different spellings for |
| # lld-link vs ld.lld. |
| if (current_os == "win") { |
| _cache_dir = "/lldltocache:" |
| } else { |
| _cache_dir = "--thinlto-cache-dir=" |
| } |
| |
| if (is_fuchsia) { |
| # On fuchsia, rustc directly calls lld. |
| rust_linkarg = "-Clink-args" |
| } else { |
| # On all other platforms, rustc calls clang, which calls lld. |
| rust_linkarg = "-Clink-args=-Wl" |
| } |
| |
| rustflags += [ "${rust_linkarg}=${_cache_dir}$thinlto_cache_dir" ] |
| } |
| |
| variant("thinlto") { |
| configs = [ |
| ":thinlto-clang", |
| ":thinlto-rust", |
| ] |
| } |