Merge "Refactor LTO"
This commit is contained in:
94
cc/lto.go
94
cc/lto.go
@@ -46,12 +46,12 @@ type LTOProperties struct {
|
|||||||
Thin *bool `android:"arch_variant"`
|
Thin *bool `android:"arch_variant"`
|
||||||
} `android:"arch_variant"`
|
} `android:"arch_variant"`
|
||||||
|
|
||||||
|
LtoEnabled bool `blueprint:"mutated"`
|
||||||
|
|
||||||
// Dep properties indicate that this module needs to be built with LTO
|
// Dep properties indicate that this module needs to be built with LTO
|
||||||
// since it is an object dependency of an LTO module.
|
// since it is an object dependency of an LTO module.
|
||||||
ThinEnabled bool `blueprint:"mutated"`
|
LtoDep bool `blueprint:"mutated"`
|
||||||
NoLtoEnabled bool `blueprint:"mutated"`
|
NoLtoDep bool `blueprint:"mutated"`
|
||||||
ThinDep bool `blueprint:"mutated"`
|
|
||||||
NoLtoDep bool `blueprint:"mutated"`
|
|
||||||
|
|
||||||
// Use -fwhole-program-vtables cflag.
|
// Use -fwhole-program-vtables cflag.
|
||||||
Whole_program_vtables *bool
|
Whole_program_vtables *bool
|
||||||
@@ -66,19 +66,16 @@ func (lto *lto) props() []interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (lto *lto) begin(ctx BaseModuleContext) {
|
func (lto *lto) begin(ctx BaseModuleContext) {
|
||||||
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
|
lto.Properties.LtoEnabled = lto.LTO(ctx)
|
||||||
lto.Properties.NoLtoEnabled = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
|
func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
|
||||||
// TODO(b/131771163): Disable LTO when using explicit fuzzing configurations.
|
// TODO(b/131771163): CFI and Fuzzer controls LTO flags by themselves.
|
||||||
// LTO breaks fuzzer builds.
|
// This has be checked late because these properties can be mutated.
|
||||||
if ctx.isFuzzer() {
|
if ctx.isCfi() || ctx.isFuzzer() {
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
if lto.Properties.LtoEnabled {
|
||||||
if lto.LTO(ctx) {
|
|
||||||
var ltoCFlag string
|
var ltoCFlag string
|
||||||
var ltoLdFlag string
|
var ltoLdFlag string
|
||||||
if lto.ThinLTO() {
|
if lto.ThinLTO() {
|
||||||
@@ -97,7 +94,7 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
|
|||||||
flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables")
|
flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") {
|
if ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") {
|
||||||
// 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()
|
||||||
@@ -120,30 +117,40 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine which LTO mode to use for the given module.
|
||||||
func (lto *lto) LTO(ctx BaseModuleContext) bool {
|
func (lto *lto) LTO(ctx BaseModuleContext) bool {
|
||||||
return lto.ThinLTO() || lto.DefaultThinLTO(ctx)
|
if lto.Never() {
|
||||||
}
|
return false
|
||||||
|
}
|
||||||
func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool {
|
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Module explicitly requests for LTO.
|
||||||
|
if lto.ThinLTO() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
// LP32 has many subtle issues and less test coverage.
|
// LP32 has many subtle issues and less test coverage.
|
||||||
lib32 := ctx.Arch().ArchType.Multilib == "lib32"
|
if ctx.Arch().ArchType.Multilib == "lib32" {
|
||||||
// CFI adds LTO flags by itself.
|
return false
|
||||||
cfi := ctx.isCfi()
|
}
|
||||||
// Performance and binary size are less important for host binaries and tests.
|
// Performance and binary size are less important for host binaries and tests.
|
||||||
host := ctx.Host()
|
if ctx.Host() || ctx.testBinary() || ctx.testLibrary() {
|
||||||
test := ctx.testBinary() || ctx.testLibrary()
|
return false
|
||||||
|
}
|
||||||
// FIXME: ThinLTO for VNDK produces different output.
|
// FIXME: ThinLTO for VNDK produces different output.
|
||||||
// b/169217596
|
// b/169217596
|
||||||
vndk := ctx.isVndk()
|
if ctx.isVndk() {
|
||||||
return GlobalThinLTO(ctx) && !lto.Never() && !lib32 && !cfi && !host && !test && !vndk
|
return false
|
||||||
|
}
|
||||||
|
return GlobalThinLTO(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lto *lto) ThinLTO() bool {
|
func (lto *lto) ThinLTO() bool {
|
||||||
return lto != nil && (proptools.Bool(lto.Properties.Lto.Thin) || lto.Properties.ThinEnabled)
|
return lto != nil && proptools.Bool(lto.Properties.Lto.Thin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lto *lto) Never() bool {
|
func (lto *lto) Never() bool {
|
||||||
return lto != nil && (proptools.Bool(lto.Properties.Lto.Never) || lto.Properties.NoLtoEnabled)
|
return lto != nil && proptools.Bool(lto.Properties.Lto.Never)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GlobalThinLTO(ctx android.BaseModuleContext) bool {
|
func GlobalThinLTO(ctx android.BaseModuleContext) bool {
|
||||||
@@ -152,11 +159,12 @@ func GlobalThinLTO(ctx android.BaseModuleContext) bool {
|
|||||||
|
|
||||||
// Propagate lto requirements down from binaries
|
// Propagate lto requirements down from binaries
|
||||||
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
|
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
|
||||||
globalThinLTO := GlobalThinLTO(mctx)
|
defaultLTOMode := GlobalThinLTO(mctx)
|
||||||
|
|
||||||
if m, ok := mctx.Module().(*Module); ok {
|
if m, ok := mctx.Module().(*Module); ok {
|
||||||
thin := m.lto.ThinLTO()
|
if m.lto == nil || m.lto.Properties.LtoEnabled == defaultLTOMode {
|
||||||
never := m.lto.Never()
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
|
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
|
||||||
tag := mctx.OtherModuleDependencyTag(dep)
|
tag := mctx.OtherModuleDependencyTag(dep)
|
||||||
@@ -174,10 +182,9 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if dep, ok := dep.(*Module); ok {
|
if dep, ok := dep.(*Module); ok {
|
||||||
if !globalThinLTO && thin && !dep.lto.ThinLTO() {
|
if m.lto.Properties.LtoEnabled {
|
||||||
dep.lto.Properties.ThinDep = true
|
dep.lto.Properties.LtoDep = true
|
||||||
}
|
} else {
|
||||||
if globalThinLTO && never && !dep.lto.Never() {
|
|
||||||
dep.lto.Properties.NoLtoDep = true
|
dep.lto.Properties.NoLtoDep = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,22 +203,19 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
// Create variations for LTO types required as static
|
// Create variations for LTO types required as static
|
||||||
// dependencies
|
// dependencies
|
||||||
variationNames := []string{""}
|
variationNames := []string{""}
|
||||||
if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
|
if m.lto.Properties.LtoDep {
|
||||||
variationNames = append(variationNames, "lto-thin")
|
variationNames = append(variationNames, "lto-thin")
|
||||||
}
|
}
|
||||||
if globalThinLTO && m.lto.Properties.NoLtoDep && !m.lto.Never() {
|
if m.lto.Properties.NoLtoDep {
|
||||||
variationNames = append(variationNames, "lto-none")
|
variationNames = append(variationNames, "lto-none")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use correct dependencies if LTO property is explicitly set
|
if globalThinLTO && !m.lto.Properties.LtoEnabled {
|
||||||
// (mutually exclusive)
|
|
||||||
if !globalThinLTO && m.lto.ThinLTO() {
|
|
||||||
mctx.SetDependencyVariation("lto-thin")
|
|
||||||
}
|
|
||||||
// Never must be the last, it overrides Thin.
|
|
||||||
if globalThinLTO && m.lto.Never() {
|
|
||||||
mctx.SetDependencyVariation("lto-none")
|
mctx.SetDependencyVariation("lto-none")
|
||||||
}
|
}
|
||||||
|
if !globalThinLTO && m.lto.Properties.LtoEnabled {
|
||||||
|
mctx.SetDependencyVariation("lto-thin")
|
||||||
|
}
|
||||||
|
|
||||||
if len(variationNames) > 1 {
|
if len(variationNames) > 1 {
|
||||||
modules := mctx.CreateVariations(variationNames...)
|
modules := mctx.CreateVariations(variationNames...)
|
||||||
@@ -226,14 +230,14 @@ func ltoMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
|
|
||||||
// LTO properties for dependencies
|
// LTO properties for dependencies
|
||||||
if name == "lto-thin" {
|
if name == "lto-thin" {
|
||||||
variation.lto.Properties.ThinEnabled = true
|
variation.lto.Properties.LtoEnabled = true
|
||||||
}
|
}
|
||||||
if name == "lto-none" {
|
if name == "lto-none" {
|
||||||
variation.lto.Properties.NoLtoEnabled = true
|
variation.lto.Properties.LtoEnabled = false
|
||||||
}
|
}
|
||||||
variation.Properties.PreventInstall = true
|
variation.Properties.PreventInstall = true
|
||||||
variation.Properties.HideFromMake = true
|
variation.Properties.HideFromMake = true
|
||||||
variation.lto.Properties.ThinDep = false
|
variation.lto.Properties.LtoDep = false
|
||||||
variation.lto.Properties.NoLtoDep = false
|
variation.lto.Properties.NoLtoDep = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user