diff --git a/cc/cc_test.go b/cc/cc_test.go index 7534db222..fe54463f1 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -4979,6 +4979,7 @@ func TestIncludeDirectoryOrdering(t *testing.T) { conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"} cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"} + ltoFlags := []string{"-flto=thin", "-fsplit-lto-unit"} cflags := []string{"-Werror", "-std=candcpp"} cstd := []string{"-std=gnu17", "-std=conly"} @@ -5005,17 +5006,17 @@ func TestIncludeDirectoryOrdering(t *testing.T) { { name: "c", src: "foo.c", - expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}), + expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, ltoFlags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}), }, { name: "cc", src: "foo.cc", - expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}), + expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, ltoFlags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}), }, { name: "assemble", src: "foo.s", - expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes), + expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, ltoFlags, lastIncludes), }, } diff --git a/cc/lto.go b/cc/lto.go index 510dd79de..ff2bf5a0c 100644 --- a/cc/lto.go +++ b/cc/lto.go @@ -47,6 +47,7 @@ type LTOProperties struct { } `android:"arch_variant"` LtoEnabled bool `blueprint:"mutated"` + LtoDefault bool `blueprint:"mutated"` // Dep properties indicate that this module needs to be built with LTO // since it is an object dependency of an LTO module. @@ -66,7 +67,34 @@ func (lto *lto) props() []interface{} { } func (lto *lto) begin(ctx BaseModuleContext) { - lto.Properties.LtoEnabled = lto.LTO(ctx) + // First, determine the module indepedent default LTO mode. + ltoDefault := GlobalThinLTO(ctx) + if ctx.Config().IsEnvTrue("DISABLE_LTO") { + ltoDefault = false + } else if ctx.Host() { + // Performance and binary size are less important for host binaries. + ltoDefault = false + } + + // Then, determine the actual LTO mode to use. If different from `ltoDefault`, a variant needs + // to be created. + ltoEnabled := ltoDefault + if lto.Never() { + ltoEnabled = false + } else if lto.ThinLTO() { + // Module explicitly requests for LTO. + ltoEnabled = true + } else if ctx.testBinary() || ctx.testLibrary() { + // Do not enable LTO for tests for better debugging. + ltoEnabled = false + } else if ctx.isVndk() { + // FIXME: ThinLTO for VNDK produces different output. + // b/169217596 + ltoEnabled = false + } + + lto.Properties.LtoDefault = ltoDefault + lto.Properties.LtoEnabled = ltoEnabled } func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { @@ -118,34 +146,6 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { return flags } -// Determine which LTO mode to use for the given module. -func (lto *lto) LTO(ctx BaseModuleContext) bool { - if lto.Never() { - return false - } - if ctx.Config().IsEnvTrue("DISABLE_LTO") { - return false - } - // Module explicitly requests for LTO. - if lto.ThinLTO() { - return true - } - // LP32 has many subtle issues and less test coverage. - if ctx.Arch().ArchType.Multilib == "lib32" { - return false - } - // Performance and binary size are less important for host binaries and tests. - if ctx.Host() || ctx.testBinary() || ctx.testLibrary() { - return false - } - // FIXME: ThinLTO for VNDK produces different output. - // b/169217596 - if ctx.isVndk() { - return false - } - return GlobalThinLTO(ctx) -} - func (lto *lto) ThinLTO() bool { return lto != nil && proptools.Bool(lto.Properties.Lto.Thin) } @@ -155,15 +155,13 @@ func (lto *lto) Never() bool { } func GlobalThinLTO(ctx android.BaseModuleContext) bool { - return ctx.Config().IsEnvTrue("GLOBAL_THINLTO") + return !ctx.Config().IsEnvFalse("GLOBAL_THINLTO") } // Propagate lto requirements down from binaries func ltoDepsMutator(mctx android.TopDownMutatorContext) { - defaultLTOMode := GlobalThinLTO(mctx) - if m, ok := mctx.Module().(*Module); ok { - if m.lto == nil || m.lto.Properties.LtoEnabled == defaultLTOMode { + if m.lto == nil || m.lto.Properties.LtoEnabled == m.lto.Properties.LtoDefault { return } @@ -238,6 +236,7 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { } variation.Properties.PreventInstall = true variation.Properties.HideFromMake = true + variation.lto.Properties.LtoDefault = m.lto.Properties.LtoDefault variation.lto.Properties.LtoDep = false variation.lto.Properties.NoLtoDep = false }