Merge "Remove PGO build support" into main
diff --git a/cc/Android.bp b/cc/Android.bp
index 77e96db..9496bac 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -40,7 +40,6 @@
"lto.go",
"makevars.go",
"orderfile.go",
- "pgo.go",
"prebuilt.go",
"proto.go",
"rs.go",
diff --git a/cc/cc.go b/cc/cc.go
index a2cbb36..74a8d35 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -531,7 +531,6 @@
baseModuleName() string
getVndkExtendsModuleName() string
isAfdoCompile() bool
- isPgoCompile() bool
isOrderfileCompile() bool
isCfi() bool
isFuzzer() bool
@@ -895,7 +894,6 @@
vndkdep *vndkdep
lto *lto
afdo *afdo
- pgo *pgo
orderfile *orderfile
library libraryInterface
@@ -1278,9 +1276,6 @@
if c.afdo != nil {
c.AddProperties(c.afdo.props()...)
}
- if c.pgo != nil {
- c.AddProperties(c.pgo.props()...)
- }
if c.orderfile != nil {
c.AddProperties(c.orderfile.props()...)
}
@@ -1410,13 +1405,6 @@
return false
}
-func (c *Module) isPgoCompile() bool {
- if pgo := c.pgo; pgo != nil {
- return pgo.Properties.PgoCompile
- }
- return false
-}
-
func (c *Module) isOrderfileCompile() bool {
if orderfile := c.orderfile; orderfile != nil {
return orderfile.Properties.OrderfileLoad
@@ -1725,10 +1713,6 @@
return ctx.mod.isAfdoCompile()
}
-func (ctx *moduleContextImpl) isPgoCompile() bool {
- return ctx.mod.isPgoCompile()
-}
-
func (ctx *moduleContextImpl) isOrderfileCompile() bool {
return ctx.mod.isOrderfileCompile()
}
@@ -1841,7 +1825,6 @@
module.vndkdep = &vndkdep{}
module.lto = <o{}
module.afdo = &afdo{}
- module.pgo = &pgo{}
module.orderfile = &orderfile{}
return module
}
@@ -2267,9 +2250,6 @@
if c.afdo != nil {
flags = c.afdo.flags(ctx, flags)
}
- if c.pgo != nil {
- flags = c.pgo.flags(ctx, flags)
- }
if c.orderfile != nil {
flags = c.orderfile.flags(ctx, flags)
}
@@ -2421,9 +2401,6 @@
if c.orderfile != nil {
c.orderfile.begin(ctx)
}
- if c.pgo != nil {
- c.pgo.begin(ctx)
- }
if ctx.useSdk() && c.IsSdkVariant() {
version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion())
if err != nil {
@@ -4333,7 +4310,6 @@
&VndkProperties{},
<OProperties{},
&AfdoProperties{},
- &PgoProperties{},
&OrderfileProperties{},
&android.ProtoProperties{},
// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
diff --git a/cc/lto.go b/cc/lto.go
index 30d7b757..d2a43d2 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -140,7 +140,7 @@
// Reduce the inlining threshold for a better balance of binary size and
// performance.
if !ctx.Darwin() {
- if ctx.isPgoCompile() || ctx.isAfdoCompile() {
+ if ctx.isAfdoCompile() {
ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=40")
} else {
ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=5")
diff --git a/cc/pgo.go b/cc/pgo.go
deleted file mode 100644
index 463e2e6..0000000
--- a/cc/pgo.go
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cc
-
-import (
- "fmt"
- "path/filepath"
- "strings"
-
- "github.com/google/blueprint/proptools"
-
- "android/soong/android"
-)
-
-var (
- // Add flags to ignore warnings that profiles are old or missing for
- // some functions.
- profileUseOtherFlags = []string{
- "-Wno-backend-plugin",
- }
-
- globalPgoProfileProjects = []string{
- "toolchain/pgo-profiles/pgo",
- "vendor/google_data/pgo_profile/pgo",
- }
-)
-
-var pgoProfileProjectsConfigKey = android.NewOnceKey("PgoProfileProjects")
-
-const profileInstrumentFlag = "-fprofile-generate=/data/local/tmp"
-const profileUseInstrumentFormat = "-fprofile-use=%s"
-
-func getPgoProfileProjects(config android.DeviceConfig) []string {
- return config.OnceStringSlice(pgoProfileProjectsConfigKey, func() []string {
- return append(globalPgoProfileProjects, config.PgoAdditionalProfileDirs()...)
- })
-}
-
-func recordMissingProfileFile(ctx BaseModuleContext, missing string) {
- getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true)
-}
-
-type PgoProperties struct {
- Pgo struct {
- Instrumentation *bool
- Profile_file *string `android:"arch_variant"`
- Benchmarks []string
- Enable_profile_use *bool `android:"arch_variant"`
- // Additional compiler flags to use when building this module
- // for profiling.
- Cflags []string `android:"arch_variant"`
- } `android:"arch_variant"`
-
- PgoPresent bool `blueprint:"mutated"`
- ShouldProfileModule bool `blueprint:"mutated"`
- PgoCompile bool `blueprint:"mutated"`
- PgoInstrLink bool `blueprint:"mutated"`
-}
-
-type pgo struct {
- Properties PgoProperties
-}
-
-func (props *PgoProperties) isInstrumentation() bool {
- return props.Pgo.Instrumentation != nil && *props.Pgo.Instrumentation == true
-}
-
-func (pgo *pgo) props() []interface{} {
- return []interface{}{&pgo.Properties}
-}
-
-func (props *PgoProperties) addInstrumentationProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
- // Add to C flags iff PGO is explicitly enabled for this module.
- if props.ShouldProfileModule {
- flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...)
- flags.Local.CFlags = append(flags.Local.CFlags, profileInstrumentFlag)
- }
- flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrumentFlag)
- return flags
-}
-
-func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath {
- profileFile := *props.Pgo.Profile_file
-
- // Test if the profile_file is present in any of the PGO profile projects
- for _, profileProject := range getPgoProfileProjects(ctx.DeviceConfig()) {
- // Bug: http://b/74395273 If the profile_file is unavailable,
- // use a versioned file named
- // <profile_file>.<arbitrary-version> when available. This
- // works around an issue where ccache serves stale cache
- // entries when the profile file has changed.
- globPattern := filepath.Join(profileProject, profileFile+".*")
- versionedProfiles, err := ctx.GlobWithDeps(globPattern, nil)
- if err != nil {
- ctx.ModuleErrorf("glob: %s", err.Error())
- }
-
- path := android.ExistentPathForSource(ctx, profileProject, profileFile)
- if path.Valid() {
- if len(versionedProfiles) != 0 {
- ctx.PropertyErrorf("pgo.profile_file", "Profile_file has multiple versions: "+filepath.Join(profileProject, profileFile)+", "+strings.Join(versionedProfiles, ", "))
- }
- return path
- }
-
- if len(versionedProfiles) > 1 {
- ctx.PropertyErrorf("pgo.profile_file", "Profile_file has multiple versions: "+strings.Join(versionedProfiles, ", "))
- } else if len(versionedProfiles) == 1 {
- return android.OptionalPathForPath(android.PathForSource(ctx, versionedProfiles[0]))
- }
- }
-
- // Record that this module's profile file is absent
- missing := *props.Pgo.Profile_file + ":" + ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
- recordMissingProfileFile(ctx, missing)
-
- return android.OptionalPathForPath(nil)
-}
-
-func (props *PgoProperties) profileUseFlags(ctx ModuleContext, file string) []string {
- flags := []string{fmt.Sprintf(profileUseInstrumentFormat, file)}
- flags = append(flags, profileUseOtherFlags...)
- return flags
-}
-
-func (props *PgoProperties) addProfileUseFlags(ctx ModuleContext, flags Flags) Flags {
- // Return if 'pgo' property is not present in this module.
- if !props.PgoPresent {
- return flags
- }
-
- if props.PgoCompile {
- profileFile := props.getPgoProfileFile(ctx)
- profileFilePath := profileFile.Path()
- profileUseFlags := props.profileUseFlags(ctx, profileFilePath.String())
-
- flags.Local.CFlags = append(flags.Local.CFlags, profileUseFlags...)
- flags.Local.LdFlags = append(flags.Local.LdFlags, profileUseFlags...)
-
- // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
- // if profileFile gets updated
- flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath)
- flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath)
- }
- return flags
-}
-
-func (props *PgoProperties) isPGO(ctx BaseModuleContext) bool {
- isInstrumentation := props.isInstrumentation()
-
- profileKindPresent := isInstrumentation
- filePresent := props.Pgo.Profile_file != nil
- benchmarksPresent := len(props.Pgo.Benchmarks) > 0
-
- // If all three properties are absent, PGO is OFF for this module
- if !profileKindPresent && !filePresent && !benchmarksPresent {
- return false
- }
-
- // profileKindPresent and filePresent are mandatory properties.
- if !profileKindPresent || !filePresent {
- var missing []string
- if !profileKindPresent {
- missing = append(missing, "profile kind")
- }
- if !filePresent {
- missing = append(missing, "profile_file property")
- }
- missingProps := strings.Join(missing, ", ")
- ctx.ModuleErrorf("PGO specification is missing properties: " + missingProps)
- }
-
- // Benchmark property is mandatory for instrumentation PGO.
- if isInstrumentation && !benchmarksPresent {
- ctx.ModuleErrorf("Instrumentation PGO specification is missing benchmark property")
- }
-
- return true
-}
-
-func (pgo *pgo) begin(ctx BaseModuleContext) {
- // TODO Evaluate if we need to support PGO for host modules
- if ctx.Host() {
- return
- }
-
- // Check if PGO is needed for this module
- pgo.Properties.PgoPresent = pgo.Properties.isPGO(ctx)
-
- if !pgo.Properties.PgoPresent {
- return
- }
-
- // This module should be instrumented if ANDROID_PGO_INSTRUMENT is set
- // and includes 'all', 'ALL' or a benchmark listed for this module.
- //
- // TODO Validate that each benchmark instruments at least one module
- pgo.Properties.ShouldProfileModule = false
- pgoBenchmarks := ctx.Config().Getenv("ANDROID_PGO_INSTRUMENT")
- pgoBenchmarksMap := make(map[string]bool)
- for _, b := range strings.Split(pgoBenchmarks, ",") {
- pgoBenchmarksMap[b] = true
- }
-
- if pgoBenchmarksMap["all"] == true || pgoBenchmarksMap["ALL"] == true {
- pgo.Properties.ShouldProfileModule = true
- pgo.Properties.PgoInstrLink = pgo.Properties.isInstrumentation()
- } else {
- for _, b := range pgo.Properties.Pgo.Benchmarks {
- if pgoBenchmarksMap[b] == true {
- pgo.Properties.ShouldProfileModule = true
- pgo.Properties.PgoInstrLink = pgo.Properties.isInstrumentation()
- break
- }
- }
- }
-
- // PGO profile use is not feasible for a Clang coverage build because
- // -fprofile-use and -fprofile-instr-generate are incompatible.
- if ctx.DeviceConfig().ClangCoverageEnabled() {
- return
- }
-
- if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") &&
- proptools.BoolDefault(pgo.Properties.Pgo.Enable_profile_use, true) {
- if profileFile := pgo.Properties.getPgoProfileFile(ctx); profileFile.Valid() {
- pgo.Properties.PgoCompile = true
- }
- }
-}
-
-func (pgo *pgo) flags(ctx ModuleContext, flags Flags) Flags {
- if ctx.Host() {
- return flags
- }
-
- // Deduce PgoInstrLink property i.e. whether this module needs to be
- // linked with profile-generation flags. Here, we're setting it if any
- // dependency needs PGO instrumentation. It is initially set in
- // begin() if PGO is directly enabled for this module.
- if ctx.static() && !ctx.staticBinary() {
- // For static libraries, check if any whole_static_libs are
- // linked with profile generation
- ctx.VisitDirectDeps(func(m android.Module) {
- if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
- if depTag.static() && depTag.wholeStatic {
- if cc, ok := m.(*Module); ok {
- if cc.pgo.Properties.PgoInstrLink {
- pgo.Properties.PgoInstrLink = true
- }
- }
- }
- }
- })
- } else {
- // For executables and shared libraries, check all static dependencies.
- ctx.VisitDirectDeps(func(m android.Module) {
- if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
- if depTag.static() {
- if cc, ok := m.(*Module); ok {
- if cc.pgo.Properties.PgoInstrLink {
- pgo.Properties.PgoInstrLink = true
- }
- }
- }
- }
- })
- }
-
- props := pgo.Properties
- // Add flags to profile this module based on its profile_kind
- if (props.ShouldProfileModule && props.isInstrumentation()) || props.PgoInstrLink {
- // Instrumentation PGO use and gather flags cannot coexist.
- return props.addInstrumentationProfileGatherFlags(ctx, flags)
- }
-
- if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") {
- flags = props.addProfileUseFlags(ctx, flags)
- }
-
- return flags
-}