Merge "Turn on Global ThinLTO by default" into main
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 7534db2..fe54463 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4979,6 +4979,7 @@
 
 	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 @@
 		{
 			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 510dd79..ff2bf5a 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -47,6 +47,7 @@
 	} `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) 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 @@
 	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 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 @@
 				}
 				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
 			}