| # Copyright 2016 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/chrome_build.gni") |
| import("//build/config/clang/clang.gni") |
| import("//build/config/compiler/compiler.gni") |
| import("//build/config/compiler/pgo/pgo.gni") |
| import("//build/config/features.gni") |
| import("//build/toolchain/toolchain.gni") |
| |
| # Configuration that enables PGO instrumentation. |
| config("pgo_instrumentation_flags") { |
| visibility = [ |
| ":default_pgo_flags", |
| ":renderer_pgo_flags", |
| ] |
| |
| # Only add flags when chrome_pgo_phase == 1, so that variables we would use |
| # are not required to be defined when we're not actually using PGO. |
| if (chrome_pgo_phase == 1 && is_clang && is_a_target_toolchain) { |
| cflags = [ "-fprofile-generate" ] |
| if (temporal_pgo_profile) { |
| cflags += [ |
| "-mllvm", |
| "-pgo-temporal-instrumentation", |
| ] |
| } |
| |
| # Increase the value profiling counter limit on macOS to capture more |
| # indirect call targets (e.g., C++ virtual calls). Apple Silicon’s massive |
| # instruction cache (icache) and 8-wide execution width make a 'chain of |
| # comparisons' significantly faster than a standard indirect call. While |
| # this increases the Chromium Framework binary size by 0.6%, it yields a |
| # measurable improvement in runtime benchmarks. |
| if (is_mac && current_cpu == "arm64") { |
| cflags += [ |
| "-mllvm", |
| "-vp-counters-per-site=6", |
| ] |
| } |
| |
| if (!is_win) { |
| # Windows directly calls link.exe instead of the compiler driver when |
| # linking, and embeds the path to the profile runtime library as |
| # dependent library into each object file. |
| ldflags = [ "-fprofile-generate" ] |
| } |
| } |
| } |
| |
| # Configuration that enables optimization using profile data. |
| config("pgo_optimization_flags") { |
| visibility = [ |
| ":default_pgo_flags", |
| ":pgo_renderer_optimization_flags", |
| ] |
| |
| # Only add flags when chrome_pgo_phase == 2, so that variables we would use |
| # are not required to be defined when we're not actually using PGO. |
| if (chrome_pgo_phase == 2 && is_clang && is_a_target_toolchain) { |
| _pgo_target = "" |
| |
| # There are txt files used by //tools/update_pgo_profiles.py to decide which |
| # profiles to use, adding them as inputs so that analyzer recognizes the |
| # dependencies. |
| inputs = [] |
| |
| if (is_win) { |
| if (target_cpu == "arm64") { |
| _pgo_target = "win-arm64" |
| } else if (target_cpu == "x64") { |
| _pgo_target = "win64" |
| } else { |
| _pgo_target = "win32" |
| } |
| } else if (is_mac) { |
| if (target_cpu == "arm64") { |
| _pgo_target = "mac-arm" |
| } else { |
| _pgo_target = "mac" |
| } |
| } else if (is_linux) { |
| _pgo_target = "linux" |
| } else if (is_android) { |
| # Use |current_cpu| and not |target_cpu|; for Android we may built both. |
| if (is_desktop_android && current_cpu == "x64") { |
| _pgo_target = "android-desktop-x64" |
| } else if (current_cpu == "arm64") { |
| _pgo_target = "android-arm64" |
| } else { |
| _pgo_target = "android-arm32" |
| } |
| } else if (is_fuchsia) { |
| if (target_cpu == "arm64") { |
| _pgo_target = "mac-arm" |
| } else { |
| _pgo_target = "mac" |
| } |
| } else if (is_ios && use_blink) { |
| if (target_cpu == "arm64") { |
| _pgo_target = "mac-arm" |
| } else { |
| _pgo_target = "mac" |
| } |
| } |
| |
| if (_pgo_target == "win-arm64") { |
| inputs = [ "//chrome/build/win-arm64.pgo.txt" ] |
| } else if (_pgo_target == "win64") { |
| inputs = [ "//chrome/build/win64.pgo.txt" ] |
| } else if (_pgo_target == "win32") { |
| inputs = [ "//chrome/build/win32.pgo.txt" ] |
| } else if (_pgo_target == "mac-arm") { |
| inputs = [ "//chrome/build/mac-arm.pgo.txt" ] |
| } else if (_pgo_target == "mac") { |
| inputs = [ "//chrome/build/mac.pgo.txt" ] |
| } else if (_pgo_target == "linux") { |
| inputs = [ "//chrome/build/linux.pgo.txt" ] |
| } else if (_pgo_target == "android-arm32") { |
| inputs = [ "//chrome/build/android-arm32.pgo.txt" ] |
| } else if (_pgo_target == "android-desktop-x64") { |
| inputs = [ "//chrome/build/android-desktop-x64.pgo.txt" ] |
| } |
| |
| if (_pgo_target != "" && pgo_data_path == "") { |
| common_args = [ |
| "--target", |
| _pgo_target, |
| ] |
| if (pgo_override_filename != "") { |
| common_args += [ |
| "--override-filename", |
| pgo_override_filename, |
| ] |
| |
| # This is slow but it is only expected to be run on the orderfile bots |
| # that require this special step. |
| exec_script("//tools/update_pgo_profiles.py", |
| common_args + [ |
| "update", |
| "--gs-url-base=$pgo_gs_bucket/$pgo_gs_bucket_path", |
| ]) |
| } |
| pgo_data_path = exec_script("//tools/update_pgo_profiles.py", |
| common_args + [ "get_profile_path" ], |
| "value") |
| } |
| assert(pgo_data_path != "", |
| "Please set pgo_data_path to point at the profile data") |
| |
| # Ensure that the actual PGO profile that is used in the build is also |
| # listed in inputs in addition to any sha1 .txt files. This way the object |
| # files are rebuilt whenever the .txt files change or whenever the actual |
| # profile changes. |
| inputs += [ pgo_data_path ] |
| |
| cflags = [ |
| "-fprofile-use=" + rebase_path(pgo_data_path, root_build_dir), |
| |
| # It's possible to have some profile data legitimately missing, |
| # and at least some profile data always ends up being considered |
| # out of date, so make sure we don't error for those cases. |
| "-Wno-profile-instr-unprofiled", |
| "-Wno-profile-instr-out-of-date", |
| |
| # Some hashing conflict results in a lot of warning like this when doing |
| # a PGO build: |
| # warning: foo.cc: Function control flow change detected (hash mismatch) |
| # [-Wbackend-plugin] |
| # See https://crbug.com/978401 |
| "-Wno-backend-plugin", |
| ] |
| |
| # TODO(crbug.com/383537825): Try enabling on all platforms. |
| if (is_android || is_fuchsia) { |
| cflags += [ |
| "-mllvm", |
| "-pgo-cold-func-opt=minsize", |
| ] |
| } |
| |
| # Enable basic block layout based on the extended TSP problem. This aims to |
| # improve icache utilization and reduce the binary size. |
| if (use_thin_lto) { |
| if (is_win) { |
| ldflags = [ "-mllvm:-enable-ext-tsp-block-placement=1" ] |
| } else { |
| ldflags = [ "-Wl,-mllvm,-enable-ext-tsp-block-placement=1" ] |
| } |
| } else { |
| cflags += [ |
| "-mllvm", |
| "-enable-ext-tsp-block-placement=1", |
| ] |
| } |
| } |
| } |
| |
| # Applies flags necessary when profile-guided optimization is used. |
| # Flags are only added if PGO is enabled, so that this config is safe to |
| # include by default. |
| config("default_pgo_flags") { |
| if (chrome_pgo_phase == 0) { |
| # Nothing. This config should be a no-op when chrome_pgo_phase == 0. |
| } else if (chrome_pgo_phase == 1) { |
| configs = [ ":pgo_instrumentation_flags" ] |
| } else if (chrome_pgo_phase == 2) { |
| configs = [ ":pgo_optimization_flags" ] |
| } |
| } |
| |
| # Configuration that enables optimization using renderer profile data. |
| config("pgo_renderer_optimization_flags") { |
| visibility = [ ":renderer_pgo_flags" ] |
| |
| if (enable_separate_pgo && chrome_pgo_phase == 2 && is_clang && |
| is_a_target_toolchain) { |
| configs = [ ":pgo_optimization_flags" ] |
| |
| _pgo_target = "" |
| |
| if (is_win) { |
| if (target_cpu == "arm64") { |
| _pgo_target = "win-arm64" |
| } else if (target_cpu == "x64") { |
| _pgo_target = "win64" |
| } else { |
| _pgo_target = "win32" |
| } |
| } else if (is_mac) { |
| if (target_cpu == "arm64") { |
| _pgo_target = "mac-arm" |
| } else { |
| _pgo_target = "mac" |
| } |
| } else if (is_linux) { |
| _pgo_target = "linux" |
| } |
| |
| _renderer_pgo_path = pgo_data_path |
| if (_renderer_pgo_path == "" && _pgo_target != "") { |
| common_args = [ |
| "--target", |
| _pgo_target, |
| "--profile-type", |
| "renderer", |
| ] |
| if (pgo_override_filename != "") { |
| common_args += [ |
| "--override-filename", |
| pgo_override_filename, |
| ] |
| } |
| _renderer_pgo_path = exec_script("//tools/update_pgo_profiles.py", |
| common_args + [ "get_profile_path" ], |
| "value") |
| } else { |
| _renderer_pgo_path = |
| string_replace(_renderer_pgo_path, ".profdata", "_renderer.profdata") |
| } |
| |
| inputs = [ _renderer_pgo_path ] |
| cflags = |
| [ "-fprofile-use=" + rebase_path(_renderer_pgo_path, root_build_dir) ] |
| } |
| } |
| |
| # Applies target-specific flags for renderer profile-guided optimization. |
| config("renderer_pgo_flags") { |
| if (!enable_separate_pgo) { |
| configs = [ ":default_pgo_flags" ] |
| } else if (chrome_pgo_phase == 0) { |
| # Nothing. This config should be a no-op when chrome_pgo_phase == 0. |
| } else if (chrome_pgo_phase == 1) { |
| configs = [ ":pgo_instrumentation_flags" ] |
| } else if (chrome_pgo_phase == 2) { |
| configs = [ ":pgo_renderer_optimization_flags" ] |
| } |
| } |