blob: f62ec62e1c84f570276c87ab5535439de6e98e44 [file] [log] [blame]
# 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",
]
}