Add Global ThinLTO option (2nd try) am: 8ea56f9da9

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1857453

Change-Id: I09ed730f75ae10daf8293ede971b35342d6f61d2
This commit is contained in:
Yi Kong
2021-10-14 11:52:00 +00:00
committed by Automerger Merge Worker

View File

@@ -51,6 +51,7 @@ type LTOProperties struct {
// since it is an object dependency of an LTO module.
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
}
}
}