Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ea56f9d authored by Yi Kong's avatar Yi Kong
Browse files

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
parent ddf4ebae
Loading
Loading
Loading
Loading
+53 −36
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ type LTOProperties struct {
	// since it is an object dependency of an LTO module.
	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
			}
		}
	}