Enable whole-program virtual function optimization in LTO mode.

Also move LTO config out of sanitizer config, and enable function
sections on all architectures (not just ARM) as it improves
the linker's ability to do ICF.

BUG=580389

Review URL: https://codereview.chromium.org/1809273002

Cr-Original-Commit-Position: refs/heads/master@{#385630}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 5f4ec37b6548c11b0b470ce824a3d28f7f54fcd1
This commit is contained in:
pcc 2016-04-06 19:32:39 -07:00 коммит произвёл Commit bot
Родитель fa8f205cc8
Коммит 545f95b0b0
7 изменённых файлов: 100 добавлений и 69 удалений

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

@ -6149,6 +6149,11 @@
['_toolset=="target"', {
'ldflags': [
'-Wl,--plugin-opt,O1',
# Allows the linker to apply ICF to the LTO object file. Also, when
# targeting ARM, wWithout this flag, LTO produces a .text section
# that is larger than the maximum call displacement, preventing the
# linker from relocating calls (http://llvm.org/PR22999).
'-Wl,--plugin-opt,-function-sections',
],
}],
['_toolset=="target" and _type!="static_library"', {
@ -6168,20 +6173,6 @@
},
},
}],
['use_lto==1 and clang==1 and target_arch=="arm"', {
'target_defaults': {
'target_conditions': [
['_toolset=="target"', {
# Without this flag, LTO produces a .text section that is larger
# than the maximum call displacement, preventing the linker from
# relocating calls (http://llvm.org/PR22999).
'ldflags': [
'-Wl,-plugin-opt,-function-sections',
],
}],
],
},
}],
['(use_lto==1 or use_lto_o2==1) and clang==0', {
'target_defaults': {
'target_conditions': [
@ -6327,6 +6318,24 @@
],
},
}],
# TODO(pcc): Make these flags work correctly with CFI.
['use_lto!=0 and cfi_vptr==0', {
'target_defaults': {
'target_conditions': [
['_toolset=="target"', {
'cflags': [
'-fwhole-program-vtables',
# TODO(pcc): Remove this flag once the upstream interface change
# (http://reviews.llvm.org/D18635) lands.
'-fwhole-program-vtables-blacklist=<(cfi_blacklist)',
],
'ldflags': [
'-fwhole-program-vtables',
],
}],
],
},
}],
],
'xcode_settings': {
# DON'T ADD ANYTHING NEW TO THIS BLOCK UNLESS YOU REALLY REALLY NEED IT!

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

@ -7,6 +7,7 @@ import("//build/config/chrome_build.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/nacl/config.gni")
import("//build/toolchain/cc_wrapper.gni")
import("//build/toolchain/toolchain.gni")
if (current_cpu == "arm") {
import("//build/config/arm.gni")
@ -378,6 +379,52 @@ config("compiler") {
}
}
# Add flags for link-time optimization. These flags enable
# optimizations/transformations that require whole-program visibility at link
# time, so they need to be applied to all translation units, and we may end up
# with miscompiles if only part of the program is compiled with LTO flags. For
# that reason, we cannot allow targets to enable or disable these flags, for
# example by disabling the optimize configuration.
# TODO(pcc): Make this conditional on is_official_build rather than on gn
# flags for specific features.
if (!is_debug && (allow_posix_link_time_opt || is_cfi) && !is_nacl) {
cflags += [ "-flto" ]
ldflags += [ "-flto" ]
# Apply a lower LTO optimization level as the default is too slow.
if (is_linux) {
ldflags += [ "-Wl,-plugin-opt,O1" ]
} else if (is_mac) {
ldflags += [ "-Wl,-mllvm,-O1" ]
}
# Work-around for http://openradar.appspot.com/20356002
if (is_mac) {
ldflags += [ "-Wl,-all_load" ]
}
# Allows the linker to apply ICF to the LTO object file. Also, when
# targeting ARM, without this flag, LTO produces a .text section that is
# larger than the maximum call displacement, preventing the linker from
# relocating calls (http://llvm.org/PR22999).
if (is_linux) {
ldflags += [ "-Wl,-plugin-opt,-function-sections" ]
}
# TODO(pcc): Make these flags work correctly with CFI.
if (!is_cfi) {
cflags += [
"-fwhole-program-vtables",
# TODO(pcc): Remove this flag once the upstream interface change
# (http://reviews.llvm.org/D18635) lands.
"-fwhole-program-vtables-blacklist=" +
rebase_path("//tools/cfi/blacklist.txt", root_build_dir),
]
ldflags += [ "-fwhole-program-vtables" ]
}
}
# Pass the same C/C++ flags to the objective C/C++ compiler.
cflags_objc += cflags_c
cflags_objcc += cflags_cc

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

@ -94,36 +94,13 @@ config("default_sanitizer_ldflags") {
if (is_ubsan_vptr) {
ldflags += [ "-fsanitize=vptr" ]
}
if (is_lto && !is_nacl) {
ldflags += [ "-flto" ]
# Apply a lower LTO optimization level as the default is too slow.
if (is_linux) {
ldflags += [ "-Wl,-plugin-opt,O1" ]
} else if (is_mac) {
ldflags += [ "-Wl,-mllvm,-O1" ]
}
# Work-around for http://openradar.appspot.com/20356002
if (is_mac) {
ldflags += [ "-Wl,-all_load" ]
}
# Without this flag, LTO produces a .text section that is larger
# than the maximum call displacement, preventing the linker from
# relocating calls (http://llvm.org/PR22999).
if (current_cpu == "arm") {
ldflags += [ "-Wl,-plugin-opt,-function-sections" ]
}
if (is_cfi) {
ldflags += [
"-fsanitize=cfi-vcall",
"-fsanitize=cfi-derived-cast",
"-fsanitize=cfi-unrelated-cast",
]
}
if (is_cfi && !is_nacl) {
ldflags += [
"-fsanitize=cfi-vcall",
"-fsanitize=cfi-derived-cast",
"-fsanitize=cfi-unrelated-cast",
]
if (use_cfi_diag) {
ldflags += [
"-fno-sanitize-trap=cfi",
@ -156,7 +133,7 @@ config("default_sanitizer_flags") {
# Common options for AddressSanitizer, LeakSanitizer, ThreadSanitizer,
# MemorySanitizer and non-official CFI builds.
if (using_sanitizer || (is_lto && !is_official_build)) {
if (using_sanitizer || (is_cfi && !is_official_build)) {
if (is_posix) {
cflags += [ "-fno-omit-frame-pointer" ]
} else {
@ -282,19 +259,15 @@ config("default_sanitizer_flags") {
"-fsanitize-blacklist=$ubsan_blacklist_path",
]
}
if (is_lto && !is_nacl) {
cflags += [ "-flto" ]
if (is_cfi) {
cfi_blacklist_path =
rebase_path("//tools/cfi/blacklist.txt", root_build_dir)
cflags += [
"-fsanitize=cfi-vcall",
"-fsanitize=cfi-derived-cast",
"-fsanitize=cfi-unrelated-cast",
"-fsanitize-blacklist=$cfi_blacklist_path",
]
}
if (is_cfi && !is_nacl) {
cfi_blacklist_path =
rebase_path("//tools/cfi/blacklist.txt", root_build_dir)
cflags += [
"-fsanitize=cfi-vcall",
"-fsanitize=cfi-derived-cast",
"-fsanitize=cfi-unrelated-cast",
"-fsanitize-blacklist=$cfi_blacklist_path",
]
if (use_cfi_diag) {
cflags += [

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

@ -39,6 +39,8 @@ declare_args() {
# Compile with Control Flow Integrity to protect virtual calls and casts.
# See http://clang.llvm.org/docs/ControlFlowIntegrity.html
#
# TODO(pcc): Remove this flag if/when CFI is enabled in official builds.
is_cfi = false
# By default, Control Flow Integrity will crash the program if it detects a
@ -72,10 +74,6 @@ declare_args() {
use_custom_libcxx = (is_asan && is_linux) || is_tsan || is_msan || is_ubsan ||
is_ubsan_security || use_libfuzzer
# Enable Link Time Optimization (output programs runs faster,
# but linking is up to 5-20x slower.
is_lto = is_cfi
use_sanitizer_coverage = use_libfuzzer
}

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

@ -9,7 +9,7 @@ import("//build/toolchain/goma.gni")
import("//build/toolchain/toolchain.gni")
# This value will be inherited in the toolchain below.
if (is_lto) {
if (allow_posix_link_time_opt || is_cfi) {
concurrent_links =
exec_script("get_concurrent_links.py", [ "--lto" ], "value")
} else {
@ -217,7 +217,8 @@ template("gcc_toolchain") {
tool("alink") {
rspfile = "{{output}}.rsp"
arflags = ""
if (is_lto && invoker.toolchain_os != "nacl") {
if ((allow_posix_link_time_opt || is_cfi) &&
invoker.toolchain_os != "nacl") {
gold_plugin_path = rebase_path(
"//third_party/llvm-build/Release+Asserts/lib/LLVMgold.so",
root_build_dir)

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

@ -5,6 +5,14 @@
# Toolchain-related configuration that may be needed outside the context of the
# toolchain() rules themselves.
declare_args() {
# Enable Link Time Optimization in optimized builds (output programs run
# faster, but linking is up to 5-20x slower).
#
# TODO(pcc): Remove this flag if/when LTO is enabled in official builds.
allow_posix_link_time_opt = false
}
# Subdirectory within root_out_dir for shared library files.
# TODO(agrieve): GYP sets this to "lib" for Linux & Android, but this won't work
# in GN until support for loadable_module() is added.

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

@ -25,12 +25,7 @@ if (use_goma) {
}
# This value will be inherited in the toolchain below.
if (is_lto) {
concurrent_links =
exec_script("../get_concurrent_links.py", [ "--lto" ], "value")
} else {
concurrent_links = exec_script("../get_concurrent_links.py", [], "value")
}
concurrent_links = exec_script("../get_concurrent_links.py", [], "value")
# Copy the VS runtime DLL for the default toolchain to the root build directory
# so things will run.