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:
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