Add Global ThinLTO option (2nd try)

Instead of making everything into ThinLTO variant by default (it works
but many Soong tests don't like this, and got bit rot due to lack of
active builder for this configuration), let the default option be
ThinLTO and no LTO be a special variant.

Test: m GLOBAL_THINLTO=true
Test: m
Bug: 195134194
Change-Id: I2fd98061ba55eba1fdfdd056fb2f8c2051fd2553
This commit is contained in:
Yi Kong
2021-10-14 01:07:42 +08:00
parent ddf4ebae19
commit 8ea56f9da9

View File

@@ -49,8 +49,9 @@ type LTOProperties struct {
// Dep properties indicate that this module needs to be built with LTO
// since it is an object dependency of an LTO module.
FullDep bool `blueprint:"mutated"`
ThinDep bool `blueprint:"mutated"`
FullDep bool `blueprint:"mutated"`
ThinDep bool `blueprint:"mutated"`
NoLtoDep bool `blueprint:"mutated"`
// Use clang lld instead of gnu ld.
Use_clang_lld *bool
@@ -70,15 +71,6 @@ func (lto *lto) props() []interface{} {
func (lto *lto) begin(ctx BaseModuleContext) {
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
lto.Properties.Lto.Never = proptools.BoolPtr(true)
} else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") {
staticLib := ctx.static() && !ctx.staticBinary()
hostBin := ctx.Host()
vndk := ctx.isVndk() // b/169217596
if !staticLib && !hostBin && !vndk {
if !lto.Never() && !lto.FullLTO() {
lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
}
}
}
@@ -96,22 +88,27 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
return flags
}
if lto.LTO() {
var ltoFlag string
if lto.LTO(ctx) {
var ltoCFlag string
var ltoLdFlag string
if lto.ThinLTO() {
ltoFlag = "-flto=thin -fsplit-lto-unit"
ltoCFlag = "-flto=thin -fsplit-lto-unit"
} else if lto.FullLTO() {
ltoCFlag = "-flto"
} else {
ltoFlag = "-flto"
ltoCFlag = "-flto=thin -fsplit-lto-unit"
ltoLdFlag = "-Wl,--lto-O0"
}
flags.Local.CFlags = append(flags.Local.CFlags, ltoFlag)
flags.Local.LdFlags = append(flags.Local.LdFlags, ltoFlag)
flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag)
flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag)
flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag)
if Bool(lto.Properties.Whole_program_vtables) {
flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables")
}
if lto.ThinLTO() && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) {
if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) {
// Set appropriate ThinLTO cache policy
cacheDirFormat := "-Wl,--thinlto-cache-dir="
cacheDir := android.PathForOutput(ctx, "thinlto-cache").String()
@@ -134,33 +131,40 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
return flags
}
// Can be called with a null receiver
func (lto *lto) LTO() bool {
if lto == nil || lto.Never() {
return false
}
func (lto *lto) LTO(ctx BaseModuleContext) bool {
return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx)
}
return lto.FullLTO() || lto.ThinLTO()
func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool {
host := ctx.Host()
vndk := ctx.isVndk() // b/169217596
return GlobalThinLTO(ctx) && !lto.Never() && !host && !vndk
}
func (lto *lto) FullLTO() bool {
return Bool(lto.Properties.Lto.Full)
return lto != nil && Bool(lto.Properties.Lto.Full)
}
func (lto *lto) ThinLTO() bool {
return Bool(lto.Properties.Lto.Thin)
return lto != nil && Bool(lto.Properties.Lto.Thin)
}
// Is lto.never explicitly set to true?
func (lto *lto) Never() bool {
return Bool(lto.Properties.Lto.Never)
return lto != nil && Bool(lto.Properties.Lto.Never)
}
func GlobalThinLTO(ctx android.BaseModuleContext) bool {
return ctx.Config().IsEnvTrue("GLOBAL_THINLTO")
}
// Propagate lto requirements down from binaries
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
if m, ok := mctx.Module().(*Module); ok && m.lto.LTO() {
globalThinLTO := GlobalThinLTO(mctx)
if m, ok := mctx.Module().(*Module); ok {
full := m.lto.FullLTO()
thin := m.lto.ThinLTO()
never := m.lto.Never()
if full && thin {
mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
}
@@ -180,14 +184,16 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
}
}
if dep, ok := dep.(*Module); ok && dep.lto != nil &&
!dep.lto.Never() {
if dep, ok := dep.(*Module); ok {
if full && !dep.lto.FullLTO() {
dep.lto.Properties.FullDep = true
}
if thin && !dep.lto.ThinLTO() {
if !globalThinLTO && thin && !dep.lto.ThinLTO() {
dep.lto.Properties.ThinDep = true
}
if globalThinLTO && never && !dep.lto.Never() {
dep.lto.Properties.NoLtoDep = true
}
}
// Recursively walk static dependencies
@@ -198,6 +204,8 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
// Create lto variants for modules that need them
func ltoMutator(mctx android.BottomUpMutatorContext) {
globalThinLTO := GlobalThinLTO(mctx)
if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
// Create variations for LTO types required as static
// dependencies
@@ -205,18 +213,25 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
if m.lto.Properties.FullDep && !m.lto.FullLTO() {
variationNames = append(variationNames, "lto-full")
}
if m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
variationNames = append(variationNames, "lto-thin")
}
if globalThinLTO && m.lto.Properties.NoLtoDep && !m.lto.Never() {
variationNames = append(variationNames, "lto-none")
}
// Use correct dependencies if LTO property is explicitly set
// (mutually exclusive)
if m.lto.FullLTO() {
mctx.SetDependencyVariation("lto-full")
}
if m.lto.ThinLTO() {
if !globalThinLTO && m.lto.ThinLTO() {
mctx.SetDependencyVariation("lto-thin")
}
// Never must be the last, it overrides Thin or Full.
if globalThinLTO && m.lto.Never() {
mctx.SetDependencyVariation("lto-none")
}
if len(variationNames) > 1 {
modules := mctx.CreateVariations(variationNames...)
@@ -232,16 +247,18 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
// LTO properties for dependencies
if name == "lto-full" {
variation.lto.Properties.Lto.Full = proptools.BoolPtr(true)
variation.lto.Properties.Lto.Thin = proptools.BoolPtr(false)
}
if name == "lto-thin" {
variation.lto.Properties.Lto.Full = proptools.BoolPtr(false)
variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
if name == "lto-none" {
variation.lto.Properties.Lto.Never = proptools.BoolPtr(true)
}
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
variation.lto.Properties.FullDep = false
variation.lto.Properties.ThinDep = false
variation.lto.Properties.NoLtoDep = false
}
}
}