diff options
-rw-r--r-- | android/config.go | 8 | ||||
-rw-r--r-- | cc/afdo.go | 171 | ||||
-rw-r--r-- | cc/afdo_test.go | 4 | ||||
-rw-r--r-- | cc/cc.go | 9 | ||||
-rw-r--r-- | rust/afdo.go | 4 |
5 files changed, 113 insertions, 83 deletions
diff --git a/android/config.go b/android/config.go index a62e786c1..eb1e647d4 100644 --- a/android/config.go +++ b/android/config.go @@ -1462,18 +1462,18 @@ func (c *deviceConfig) PgoAdditionalProfileDirs() []string { } // AfdoProfile returns fully qualified path associated to the given module name -func (c *deviceConfig) AfdoProfile(name string) (string, error) { +func (c *deviceConfig) AfdoProfile(name string) (*string, error) { for _, afdoProfile := range c.config.productVariables.AfdoProfiles { split := strings.Split(afdoProfile, ":") if len(split) != 3 { - return "", fmt.Errorf("AFDO_PROFILES has invalid value: %s. "+ + return nil, fmt.Errorf("AFDO_PROFILES has invalid value: %s. "+ "The expected format is <module>:<fully-qualified-path-to-fdo_profile>", afdoProfile) } if split[0] == name { - return strings.Join([]string{split[1], split[2]}, ":"), nil + return proptools.StringPtr(strings.Join([]string{split[1], split[2]}, ":")), nil } } - return "", nil + return nil, nil } func (c *deviceConfig) VendorSepolicyDirs() []string { diff --git a/cc/afdo.go b/cc/afdo.go index 61550845d..79fbae157 100644 --- a/cc/afdo.go +++ b/cc/afdo.go @@ -27,12 +27,23 @@ import ( // This flag needs to be in both CFlags and LdFlags to ensure correct symbol ordering const afdoFlagsFormat = "-fprofile-sample-use=%s -fprofile-sample-accurate" +func recordMissingAfdoProfileFile(ctx android.BaseModuleContext, missing string) { + getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true) +} + +type afdoRdep struct { + VariationName *string + ProfilePath *string +} + type AfdoProperties struct { // Afdo allows developers self-service enroll for // automatic feedback-directed optimization using profile data. Afdo bool FdoProfilePath *string `blueprint:"mutated"` + + AfdoRDeps []afdoRdep `blueprint:"mutated"` } type afdo struct { @@ -91,107 +102,121 @@ func (afdo *afdo) flags(ctx ModuleContext, flags Flags) Flags { return flags } -// FdoProfileMutator reads the FdoProfileProvider from a direct dep with FdoProfileTag -// assigns FdoProfileInfo.Path to the FdoProfilePath mutated property -func (c *Module) fdoProfileMutator(ctx android.BottomUpMutatorContext) { - if !c.Enabled() { - return - } - - if !c.afdo.afdoEnabled() { - return - } - - if c.Host() { +func (afdo *afdo) addDep(ctx BaseModuleContext, actx android.BottomUpMutatorContext) { + if ctx.Host() { return } - if c.static() && !c.staticBinary() { + if ctx.static() && !ctx.staticBinary() { return } if c, ok := ctx.Module().(*Module); ok && c.Enabled() { - if fdoProfileName, err := ctx.DeviceConfig().AfdoProfile(ctx.ModuleName()); fdoProfileName != "" && err == nil { - deps := ctx.AddFarVariationDependencies( + if fdoProfileName, err := actx.DeviceConfig().AfdoProfile(actx.ModuleName()); fdoProfileName != nil && err == nil { + actx.AddFarVariationDependencies( []blueprint.Variation{ - {Mutator: "arch", Variation: ctx.Target().ArchVariation()}, + {Mutator: "arch", Variation: actx.Target().ArchVariation()}, {Mutator: "os", Variation: "android"}, }, FdoProfileTag, - fdoProfileName) - if len(deps) > 0 && deps[0] != nil { - if info, ok := android.OtherModuleProvider(ctx, deps[0], FdoProfileProvider); ok { - c.afdo.Properties.FdoProfilePath = proptools.StringPtr(info.Path.String()) - } - } + []string{*fdoProfileName}..., + ) } } } -var _ FdoProfileMutatorInterface = (*Module)(nil) - -func afdoPropagateViaDepTag(tag blueprint.DependencyTag) bool { - libTag, isLibTag := tag.(libraryDependencyTag) - // Do not recurse down non-static dependencies - if isLibTag { - return libTag.static() - } else { - return tag == objDepTag || tag == reuseObjTag || tag == staticVariantTag +// FdoProfileMutator reads the FdoProfileProvider from a direct dep with FdoProfileTag +// assigns FdoProfileInfo.Path to the FdoProfilePath mutated property +func (c *Module) fdoProfileMutator(ctx android.BottomUpMutatorContext) { + if !c.Enabled() { + return } -} -// afdoTransitionMutator creates afdo variants of cc modules. -type afdoTransitionMutator struct{} + if !c.afdo.afdoEnabled() { + return + } -func (a *afdoTransitionMutator) Split(ctx android.BaseModuleContext) []string { - return []string{""} + ctx.VisitDirectDepsWithTag(FdoProfileTag, func(m android.Module) { + if info, ok := android.OtherModuleProvider(ctx, m, FdoProfileProvider); ok { + c.afdo.Properties.FdoProfilePath = proptools.StringPtr(info.Path.String()) + } + }) } -func (a *afdoTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { - if m, ok := ctx.Module().(*Module); ok && m.afdo != nil { - if !afdoPropagateViaDepTag(ctx.DepTag()) { - return "" - } +var _ FdoProfileMutatorInterface = (*Module)(nil) - if sourceVariation != "" { - return sourceVariation - } +// Propagate afdo requirements down from binaries and shared libraries +func afdoDepsMutator(mctx android.TopDownMutatorContext) { + if m, ok := mctx.Module().(*Module); ok && m.afdo.afdoEnabled() { + path := m.afdo.Properties.FdoProfilePath + mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { + tag := mctx.OtherModuleDependencyTag(dep) + libTag, isLibTag := tag.(libraryDependencyTag) + + // Do not recurse down non-static dependencies + if isLibTag { + if !libTag.static() { + return false + } + } else { + if tag != objDepTag && tag != reuseObjTag { + return false + } + } - if m.afdo.afdoEnabled() && !(m.static() && !m.staticBinary()) && !m.Host() { - return encodeTarget(ctx.Module().Name()) - } - } - return "" -} + if dep, ok := dep.(*Module); ok { + dep.afdo.Properties.AfdoRDeps = append( + dep.afdo.Properties.AfdoRDeps, + afdoRdep{ + VariationName: proptools.StringPtr(encodeTarget(m.Name())), + ProfilePath: path, + }, + ) + } -func (a *afdoTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { - if m, ok := ctx.Module().(*Module); ok && m.afdo != nil { - return incomingVariation + return true + }) } - return "" } -func (a *afdoTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { - if variation == "" { - return - } +// Create afdo variants for modules that need them +func afdoMutator(mctx android.BottomUpMutatorContext) { + if m, ok := mctx.Module().(*Module); ok && m.afdo != nil { + if !m.static() && m.afdo.Properties.Afdo { + mctx.SetDependencyVariation(encodeTarget(m.Name())) + return + } - if m, ok := ctx.Module().(*Module); ok && m.afdo != nil { - m.Properties.PreventInstall = true - m.Properties.HideFromMake = true - m.afdo.Properties.Afdo = true - if fdoProfileName, err := ctx.DeviceConfig().AfdoProfile(decodeTarget(variation)); fdoProfileName != "" && err == nil { - deps := ctx.AddFarVariationDependencies( - []blueprint.Variation{ - {Mutator: "arch", Variation: ctx.Target().ArchVariation()}, - {Mutator: "os", Variation: "android"}, - }, - FdoProfileTag, - fdoProfileName) - if len(deps) > 0 && deps[0] != nil { - if info, ok := android.OtherModuleProvider(ctx, deps[0], FdoProfileProvider); ok { - m.afdo.Properties.FdoProfilePath = proptools.StringPtr(info.Path.String()) + variationNames := []string{""} + + variantNameToProfilePath := make(map[string]*string) + + for _, afdoRDep := range m.afdo.Properties.AfdoRDeps { + variantName := *afdoRDep.VariationName + // An rdep can be set twice in AfdoRDeps because there can be + // more than one path from an afdo-enabled module to + // a static dep such as + // afdo_enabled_foo -> static_bar ----> static_baz + // \ ^ + // ----------------------| + // We only need to create one variant per unique rdep + if _, exists := variantNameToProfilePath[variantName]; !exists { + variationNames = append(variationNames, variantName) + variantNameToProfilePath[variantName] = afdoRDep.ProfilePath + } + } + + if len(variationNames) > 1 { + modules := mctx.CreateVariations(variationNames...) + for i, name := range variationNames { + if name == "" { + continue } + variation := modules[i].(*Module) + variation.Properties.PreventInstall = true + variation.Properties.HideFromMake = true + variation.afdo.Properties.Afdo = true + variation.afdo.Properties.FdoProfilePath = variantNameToProfilePath[name] } } } diff --git a/cc/afdo_test.go b/cc/afdo_test.go index 584af0d6f..b250ad1a1 100644 --- a/cc/afdo_test.go +++ b/cc/afdo_test.go @@ -174,11 +174,11 @@ func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) { libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module() if !hasDirectDep(result, libTest, libFoo.Module()) { - t.Errorf("libTest missing dependency on non-afdo variant of libFoo") + t.Errorf("libTest missing dependency on afdo variant of libFoo") } if !hasDirectDep(result, libFoo.Module(), libBar) { - t.Errorf("libFoo missing dependency on non-afdo variant of libBar") + t.Errorf("libFoo missing dependency on afdo variant of libBar") } fooVariants := result.ModuleVariantsForTests("foo") @@ -55,7 +55,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() - ctx.BottomUp("fdo_profile", fdoProfileMutator).Parallel() + ctx.BottomUp("fdo_profile", fdoProfileMutator) }) ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { @@ -70,7 +70,8 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.Transition("coverage", &coverageTransitionMutator{}) - ctx.Transition("afdo", &afdoTransitionMutator{}) + ctx.TopDown("afdo_deps", afdoDepsMutator) + ctx.BottomUp("afdo", afdoMutator).Parallel() ctx.Transition("orderfile", &orderfileTransitionMutator{}) @@ -2338,6 +2339,10 @@ func (c *Module) beginMutator(actx android.BottomUpMutatorContext) { } ctx.ctx = ctx + if !actx.Host() || !ctx.static() || ctx.staticBinary() { + c.afdo.addDep(ctx, actx) + } + c.begin(ctx) } diff --git a/rust/afdo.go b/rust/afdo.go index 6116c5e21..323ee36a5 100644 --- a/rust/afdo.go +++ b/rust/afdo.go @@ -44,14 +44,14 @@ func (afdo *afdo) addDep(ctx BaseModuleContext, actx android.BottomUpMutatorCont if err != nil { ctx.ModuleErrorf("%s", err.Error()) } - if fdoProfileName != "" { + if fdoProfileName != nil { actx.AddFarVariationDependencies( []blueprint.Variation{ {Mutator: "arch", Variation: actx.Target().ArchVariation()}, {Mutator: "os", Variation: "android"}, }, cc.FdoProfileTag, - []string{fdoProfileName}..., + []string{*fdoProfileName}..., ) } } |