1# Copyright 2016 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import("//build/config/chromeos/ui_mode.gni") 6import("//build/config/clang/clang.gni") 7import("//build/config/compiler/compiler.gni") 8import("//build/config/compiler/pgo/pgo.gni") 9import("//build/config/features.gni") 10import("//build/toolchain/toolchain.gni") 11 12# Configuration that enables PGO instrumentation. 13config("pgo_instrumentation_flags") { 14 visibility = [ ":default_pgo_flags" ] 15 16 # Only add flags when chrome_pgo_phase == 1, so that variables we would use 17 # are not required to be defined when we're not actually using PGO. 18 if (chrome_pgo_phase == 1 && is_clang && !is_nacl && is_a_target_toolchain) { 19 cflags = [ "-fprofile-generate" ] 20 if (temporal_pgo_profile) { 21 cflags += [ 22 "-mllvm", 23 "-pgo-temporal-instrumentation", 24 ] 25 } 26 if (!is_win) { 27 # Windows directly calls link.exe instead of the compiler driver when 28 # linking, and embeds the path to the profile runtime library as 29 # dependent library into each object file. 30 ldflags = [ "-fprofile-generate" ] 31 } 32 } 33} 34 35# Configuration that enables optimization using profile data. 36config("pgo_optimization_flags") { 37 visibility = [ ":default_pgo_flags" ] 38 39 # Only add flags when chrome_pgo_phase == 2, so that variables we would use 40 # are not required to be defined when we're not actually using PGO. 41 if (chrome_pgo_phase == 2 && is_clang && !is_nacl && is_a_target_toolchain) { 42 _pgo_target = "" 43 44 # There are txt files used by //tools/update_pgo_profiles.py to decide which 45 # profiles to use, adding them as inputs so that analyzer recognizes the 46 # dependencies. 47 inputs = [] 48 49 if (is_win) { 50 if (target_cpu == "arm64") { 51 _pgo_target = "win-arm64" 52 } else if (target_cpu == "x64") { 53 _pgo_target = "win64" 54 } else { 55 _pgo_target = "win32" 56 } 57 } else if (is_mac) { 58 if (target_cpu == "arm64") { 59 _pgo_target = "mac-arm" 60 } else { 61 _pgo_target = "mac" 62 } 63 } else if (is_linux) { 64 _pgo_target = "linux" 65 } else if (is_chromeos_lacros) { 66 if (target_cpu == "arm") { 67 # We don't have the arm device to train arm pgo data. So Lacros arm 68 # would use arm64 profile. 69 _pgo_target = "lacros-arm64" 70 } else if (target_cpu == "arm64") { 71 _pgo_target = "lacros-arm64" 72 } else { 73 _pgo_target = "lacros64" 74 } 75 } else if (is_android) { 76 # Use |current_cpu| and not |target_cpu|; for Android we may built both. 77 if (current_cpu == "arm64") { 78 _pgo_target = "android-arm64" 79 } else { 80 _pgo_target = "android-arm32" 81 } 82 } else if (is_fuchsia) { 83 if (target_cpu == "arm64") { 84 _pgo_target = "mac-arm" 85 } else { 86 _pgo_target = "mac" 87 } 88 } else if (is_ios && use_blink) { 89 if (target_cpu == "arm64") { 90 _pgo_target = "mac-arm" 91 } else { 92 _pgo_target = "mac" 93 } 94 } 95 96 if (_pgo_target == "win-arm64") { 97 inputs = [ "//chrome/build/win-arm64.pgo.txt" ] 98 } else if (_pgo_target == "win64") { 99 inputs = [ "//chrome/build/win64.pgo.txt" ] 100 } else if (_pgo_target == "win32") { 101 inputs = [ "//chrome/build/win32.pgo.txt" ] 102 } else if (_pgo_target == "mac-arm") { 103 inputs = [ "//chrome/build/mac-arm.pgo.txt" ] 104 } else if (_pgo_target == "mac") { 105 inputs = [ "//chrome/build/mac.pgo.txt" ] 106 } else if (_pgo_target == "linux") { 107 inputs = [ "//chrome/build/linux.pgo.txt" ] 108 } else if (_pgo_target == "lacros64") { 109 inputs = [ "//chrome/build/lacros64.pgo.txt" ] 110 } else if (_pgo_target == "lacros-arm") { 111 inputs = [ "//chrome/build/lacros-arm.pgo.txt" ] 112 } else if (_pgo_target == "lacros-arm64") { 113 inputs = [ "//chrome/build/lacros-arm64.pgo.txt" ] 114 } else if (_pgo_target == "android-arm32") { 115 inputs = [ "//chrome/build/android-arm32.pgo.txt" ] 116 } else if (_pgo_target == "android-arm64") { 117 inputs = [ "//chrome/build/android-arm64.pgo.txt" ] 118 } 119 120 if (_pgo_target != "" && pgo_data_path == "") { 121 pgo_data_path = exec_script("//tools/update_pgo_profiles.py", 122 [ 123 "--target", 124 _pgo_target, 125 "get_profile_path", 126 ], 127 "value") 128 } 129 assert(pgo_data_path != "", 130 "Please set pgo_data_path to point at the profile data") 131 cflags = [ 132 "-fprofile-use=" + rebase_path(pgo_data_path, root_build_dir), 133 134 # It's possible to have some profile data legitimately missing, 135 # and at least some profile data always ends up being considered 136 # out of date, so make sure we don't error for those cases. 137 "-Wno-profile-instr-unprofiled", 138 "-Wno-profile-instr-out-of-date", 139 140 # Some hashing conflict results in a lot of warning like this when doing 141 # a PGO build: 142 # warning: foo.cc: Function control flow change detected (hash mismatch) 143 # [-Wbackend-plugin] 144 # See https://crbug.com/978401 145 "-Wno-backend-plugin", 146 ] 147 148 # Enable basic block layout based on the extended TSP problem. This aims to 149 # improve icache utilization and reduce the binary size. 150 if (use_thin_lto) { 151 if (is_win) { 152 ldflags = [ "-mllvm:-enable-ext-tsp-block-placement=1" ] 153 } else { 154 ldflags = [ "-Wl,-mllvm,-enable-ext-tsp-block-placement=1" ] 155 } 156 } else { 157 cflags += [ 158 "-mllvm", 159 "-enable-ext-tsp-block-placement=1", 160 ] 161 } 162 } 163} 164 165# Applies flags necessary when profile-guided optimization is used. 166# Flags are only added if PGO is enabled, so that this config is safe to 167# include by default. 168config("default_pgo_flags") { 169 if (chrome_pgo_phase == 0) { 170 # Nothing. This config should be a no-op when chrome_pgo_phase == 0. 171 } else if (chrome_pgo_phase == 1) { 172 configs = [ ":pgo_instrumentation_flags" ] 173 } else if (chrome_pgo_phase == 2) { 174 configs = [ ":pgo_optimization_flags" ] 175 } 176} 177