Add support for thin LTO

ThinLTO achieves comparable performance to full LTO while taking much
less time for compilation.

Test: Build hwui with "thin" and "full" LTO
Change-Id: If3400b82af0d5e0226410c8b740999cdad746a59
This commit is contained in:
Yi Kong
2017-08-29 11:10:09 +08:00
parent 8edbb3acc9
commit 244bf079f9

View File

@@ -41,7 +41,10 @@ import (
type LTOProperties struct { type LTOProperties struct {
// Lto must violate capitialization style for acronyms so that it can be // Lto must violate capitialization style for acronyms so that it can be
// referred to in blueprint files as "lto" // referred to in blueprint files as "lto"
Lto *bool `android:"arch_variant"` Lto struct {
Full *bool `android:"arch_variant"`
Thin *bool `android:"arch_variant"`
} `android:"arch_variant"`
LTODep bool `blueprint:"mutated"` LTODep bool `blueprint:"mutated"`
} }
@@ -61,9 +64,16 @@ func (lto *lto) deps(ctx BaseModuleContext, deps Deps) Deps {
} }
func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
if Bool(lto.Properties.Lto) { if lto.LTO() {
flags.CFlags = append(flags.CFlags, "-flto") var ltoFlag string
flags.LdFlags = append(flags.LdFlags, "-flto") if Bool(lto.Properties.Lto.Thin) {
ltoFlag = "-flto=thin"
} else {
ltoFlag = "-flto"
}
flags.CFlags = append(flags.CFlags, ltoFlag)
flags.LdFlags = append(flags.LdFlags, ltoFlag)
if ctx.Device() { if ctx.Device() {
// Work around bug in Clang that doesn't pass correct emulated // Work around bug in Clang that doesn't pass correct emulated
// TLS option to target // TLS option to target
@@ -80,12 +90,20 @@ func (lto *lto) LTO() bool {
return false return false
} }
return Bool(lto.Properties.Lto) full := Bool(lto.Properties.Lto.Full)
thin := Bool(lto.Properties.Lto.Thin)
return full || thin
} }
// Propagate lto requirements down from binaries // Propagate lto requirements down from binaries
func ltoDepsMutator(mctx android.TopDownMutatorContext) { func ltoDepsMutator(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.lto.LTO() { if c, ok := mctx.Module().(*Module); ok && c.lto.LTO() {
full := Bool(c.lto.Properties.Lto.Full)
thin := Bool(c.lto.Properties.Lto.Thin)
if full && thin {
mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
}
mctx.VisitDepsDepthFirst(func(m blueprint.Module) { mctx.VisitDepsDepthFirst(func(m blueprint.Module) {
tag := mctx.OtherModuleDependencyTag(m) tag := mctx.OtherModuleDependencyTag(m)
switch tag { switch tag {
@@ -105,8 +123,8 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
mctx.SetDependencyVariation("lto") mctx.SetDependencyVariation("lto")
} else if c.lto.Properties.LTODep { } else if c.lto.Properties.LTODep {
modules := mctx.CreateVariations("", "lto") modules := mctx.CreateVariations("", "lto")
modules[0].(*Module).lto.Properties.Lto = boolPtr(false) modules[0].(*Module).lto.Properties.Lto.Full = boolPtr(false)
modules[1].(*Module).lto.Properties.Lto = boolPtr(true) modules[0].(*Module).lto.Properties.Lto.Thin = boolPtr(false)
modules[0].(*Module).lto.Properties.LTODep = false modules[0].(*Module).lto.Properties.LTODep = false
modules[1].(*Module).lto.Properties.LTODep = false modules[1].(*Module).lto.Properties.LTODep = false
modules[1].(*Module).Properties.PreventInstall = true modules[1].(*Module).Properties.PreventInstall = true