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:
85
cc/lto.go
85
cc/lto.go
@@ -51,6 +51,7 @@ type LTOProperties struct {
|
|||||||
// since it is an object dependency of an LTO module.
|
// since it is an object dependency of an LTO module.
|
||||||
FullDep bool `blueprint:"mutated"`
|
FullDep bool `blueprint:"mutated"`
|
||||||
ThinDep bool `blueprint:"mutated"`
|
ThinDep bool `blueprint:"mutated"`
|
||||||
|
NoLtoDep bool `blueprint:"mutated"`
|
||||||
|
|
||||||
// Use clang lld instead of gnu ld.
|
// Use clang lld instead of gnu ld.
|
||||||
Use_clang_lld *bool
|
Use_clang_lld *bool
|
||||||
@@ -70,15 +71,6 @@ func (lto *lto) props() []interface{} {
|
|||||||
func (lto *lto) begin(ctx BaseModuleContext) {
|
func (lto *lto) begin(ctx BaseModuleContext) {
|
||||||
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
|
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
|
||||||
lto.Properties.Lto.Never = proptools.BoolPtr(true)
|
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
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
if lto.LTO() {
|
if lto.LTO(ctx) {
|
||||||
var ltoFlag string
|
var ltoCFlag string
|
||||||
|
var ltoLdFlag string
|
||||||
if lto.ThinLTO() {
|
if lto.ThinLTO() {
|
||||||
ltoFlag = "-flto=thin -fsplit-lto-unit"
|
ltoCFlag = "-flto=thin -fsplit-lto-unit"
|
||||||
|
} else if lto.FullLTO() {
|
||||||
|
ltoCFlag = "-flto"
|
||||||
} else {
|
} else {
|
||||||
ltoFlag = "-flto"
|
ltoCFlag = "-flto=thin -fsplit-lto-unit"
|
||||||
|
ltoLdFlag = "-Wl,--lto-O0"
|
||||||
}
|
}
|
||||||
|
|
||||||
flags.Local.CFlags = append(flags.Local.CFlags, ltoFlag)
|
flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag)
|
||||||
flags.Local.LdFlags = append(flags.Local.LdFlags, ltoFlag)
|
flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag)
|
||||||
|
flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag)
|
||||||
|
|
||||||
if Bool(lto.Properties.Whole_program_vtables) {
|
if Bool(lto.Properties.Whole_program_vtables) {
|
||||||
flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-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
|
// Set appropriate ThinLTO cache policy
|
||||||
cacheDirFormat := "-Wl,--thinlto-cache-dir="
|
cacheDirFormat := "-Wl,--thinlto-cache-dir="
|
||||||
cacheDir := android.PathForOutput(ctx, "thinlto-cache").String()
|
cacheDir := android.PathForOutput(ctx, "thinlto-cache").String()
|
||||||
@@ -134,33 +131,40 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can be called with a null receiver
|
func (lto *lto) LTO(ctx BaseModuleContext) bool {
|
||||||
func (lto *lto) LTO() bool {
|
return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx)
|
||||||
if lto == nil || lto.Never() {
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
func (lto *lto) FullLTO() bool {
|
||||||
return Bool(lto.Properties.Lto.Full)
|
return lto != nil && Bool(lto.Properties.Lto.Full)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lto *lto) ThinLTO() bool {
|
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 {
|
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
|
// Propagate lto requirements down from binaries
|
||||||
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
|
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()
|
full := m.lto.FullLTO()
|
||||||
thin := m.lto.ThinLTO()
|
thin := m.lto.ThinLTO()
|
||||||
|
never := m.lto.Never()
|
||||||
if full && thin {
|
if full && thin {
|
||||||
mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
|
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 &&
|
if dep, ok := dep.(*Module); ok {
|
||||||
!dep.lto.Never() {
|
|
||||||
if full && !dep.lto.FullLTO() {
|
if full && !dep.lto.FullLTO() {
|
||||||
dep.lto.Properties.FullDep = true
|
dep.lto.Properties.FullDep = true
|
||||||
}
|
}
|
||||||
if thin && !dep.lto.ThinLTO() {
|
if !globalThinLTO && thin && !dep.lto.ThinLTO() {
|
||||||
dep.lto.Properties.ThinDep = true
|
dep.lto.Properties.ThinDep = true
|
||||||
}
|
}
|
||||||
|
if globalThinLTO && never && !dep.lto.Never() {
|
||||||
|
dep.lto.Properties.NoLtoDep = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively walk static dependencies
|
// Recursively walk static dependencies
|
||||||
@@ -198,6 +204,8 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
|
|||||||
|
|
||||||
// Create lto variants for modules that need them
|
// Create lto variants for modules that need them
|
||||||
func ltoMutator(mctx android.BottomUpMutatorContext) {
|
func ltoMutator(mctx android.BottomUpMutatorContext) {
|
||||||
|
globalThinLTO := GlobalThinLTO(mctx)
|
||||||
|
|
||||||
if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
|
if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
|
||||||
// Create variations for LTO types required as static
|
// Create variations for LTO types required as static
|
||||||
// dependencies
|
// dependencies
|
||||||
@@ -205,18 +213,25 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
if m.lto.Properties.FullDep && !m.lto.FullLTO() {
|
if m.lto.Properties.FullDep && !m.lto.FullLTO() {
|
||||||
variationNames = append(variationNames, "lto-full")
|
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")
|
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
|
// Use correct dependencies if LTO property is explicitly set
|
||||||
// (mutually exclusive)
|
// (mutually exclusive)
|
||||||
if m.lto.FullLTO() {
|
if m.lto.FullLTO() {
|
||||||
mctx.SetDependencyVariation("lto-full")
|
mctx.SetDependencyVariation("lto-full")
|
||||||
}
|
}
|
||||||
if m.lto.ThinLTO() {
|
if !globalThinLTO && m.lto.ThinLTO() {
|
||||||
mctx.SetDependencyVariation("lto-thin")
|
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 {
|
if len(variationNames) > 1 {
|
||||||
modules := mctx.CreateVariations(variationNames...)
|
modules := mctx.CreateVariations(variationNames...)
|
||||||
@@ -232,16 +247,18 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
// LTO properties for dependencies
|
// LTO properties for dependencies
|
||||||
if name == "lto-full" {
|
if name == "lto-full" {
|
||||||
variation.lto.Properties.Lto.Full = proptools.BoolPtr(true)
|
variation.lto.Properties.Lto.Full = proptools.BoolPtr(true)
|
||||||
variation.lto.Properties.Lto.Thin = proptools.BoolPtr(false)
|
|
||||||
}
|
}
|
||||||
if name == "lto-thin" {
|
if name == "lto-thin" {
|
||||||
variation.lto.Properties.Lto.Full = proptools.BoolPtr(false)
|
|
||||||
variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true)
|
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.PreventInstall = true
|
||||||
variation.Properties.HideFromMake = true
|
variation.Properties.HideFromMake = true
|
||||||
variation.lto.Properties.FullDep = false
|
variation.lto.Properties.FullDep = false
|
||||||
variation.lto.Properties.ThinDep = false
|
variation.lto.Properties.ThinDep = false
|
||||||
|
variation.lto.Properties.NoLtoDep = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user