Merge "Propagate LTO type from binary/DSO to object files"

This commit is contained in:
Yi Kong
2017-12-15 21:36:02 +00:00
committed by Gerrit Code Review

101
cc/lto.go
View File

@@ -40,10 +40,15 @@ 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 struct { Lto struct {
Full *bool `android:"arch_variant"` Never *bool `android:"arch_variant"`
Thin *bool `android:"arch_variant"` Full *bool `android:"arch_variant"`
Thin *bool `android:"arch_variant"`
} `android:"arch_variant"` } `android:"arch_variant"`
LTODep bool `blueprint:"mutated"`
// 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"`
} }
type lto struct { type lto struct {
@@ -84,7 +89,7 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
// Can be called with a null receiver // Can be called with a null receiver
func (lto *lto) LTO() bool { func (lto *lto) LTO() bool {
if lto == nil { if lto == nil || lto.Disabled() {
return false return false
} }
@@ -93,41 +98,91 @@ func (lto *lto) LTO() bool {
return full || thin return full || thin
} }
// Is lto.never explicitly set to true?
func (lto *lto) Disabled() bool {
return lto.Properties.Lto.Never != nil && *lto.Properties.Lto.Never
}
// 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 m, ok := mctx.Module().(*Module); ok && m.lto.LTO() {
full := Bool(c.lto.Properties.Lto.Full) full := Bool(m.lto.Properties.Lto.Full)
thin := Bool(c.lto.Properties.Lto.Thin) thin := Bool(m.lto.Properties.Lto.Thin)
if full && thin { if full && thin {
mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive") mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
} }
mctx.VisitDepsDepthFirst(func(m android.Module) { mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
tag := mctx.OtherModuleDependencyTag(m) tag := mctx.OtherModuleDependencyTag(dep)
switch tag { switch tag {
case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag, objDepTag, reuseObjTag: case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag, objDepTag, reuseObjTag:
if cc, ok := m.(*Module); ok && cc.lto != nil { if dep, ok := dep.(*Module); ok && dep.lto != nil &&
cc.lto.Properties.LTODep = true !dep.lto.Disabled() {
if full && !Bool(dep.lto.Properties.Lto.Full) {
dep.lto.Properties.FullDep = true
}
if thin && !Bool(dep.lto.Properties.Lto.Thin) {
dep.lto.Properties.ThinDep = true
}
} }
// Recursively walk static dependencies
return true
} }
// Do not recurse down non-static dependencies
return false
}) })
} }
} }
// 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) {
if c, ok := mctx.Module().(*Module); ok && c.lto != nil { if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
if c.lto.LTO() { // Create variations for LTO types required as static
mctx.SetDependencyVariation("lto") // dependencies
} else if c.lto.Properties.LTODep { variationNames := []string{""}
modules := mctx.CreateVariations("", "lto") if m.lto.Properties.FullDep && !Bool(m.lto.Properties.Lto.Full) {
modules[0].(*Module).lto.Properties.Lto.Full = boolPtr(false) variationNames = append(variationNames, "lto-full")
modules[0].(*Module).lto.Properties.Lto.Thin = boolPtr(false) }
modules[0].(*Module).lto.Properties.LTODep = false if m.lto.Properties.ThinDep && !Bool(m.lto.Properties.Lto.Thin) {
modules[1].(*Module).lto.Properties.LTODep = false variationNames = append(variationNames, "lto-thin")
modules[1].(*Module).Properties.PreventInstall = true }
modules[1].(*Module).Properties.HideFromMake = true
// Use correct dependencies if LTO property is explicitly set
// (mutually exclusive)
if Bool(m.lto.Properties.Lto.Full) {
mctx.SetDependencyVariation("lto-full")
}
if Bool(m.lto.Properties.Lto.Thin) {
mctx.SetDependencyVariation("lto-thin")
}
if len(variationNames) > 1 {
modules := mctx.CreateVariations(variationNames...)
for i, name := range variationNames {
variation := modules[i].(*Module)
// Default module which will be
// installed. Variation set above according to
// explicit LTO properties
if name == "" {
continue
}
// LTO properties for dependencies
if name == "lto-full" {
variation.lto.Properties.Lto.Full = boolPtr(true)
variation.lto.Properties.Lto.Thin = boolPtr(false)
}
if name == "lto-thin" {
variation.lto.Properties.Lto.Full = boolPtr(false)
variation.lto.Properties.Lto.Thin = boolPtr(true)
}
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
variation.lto.Properties.FullDep = false
variation.lto.Properties.ThinDep = false
}
} }
c.lto.Properties.LTODep = false
} }
} }