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:
89
cc/lto.go
89
cc/lto.go
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user