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

Commit ead0d42f authored by Yi Kong's avatar Yi Kong Committed by Automerger Merge Worker
Browse files

Add Global ThinLTO option (2nd try) am: 8ea56f9d am: 370a0be4 am: 2d2452c8 am: 2168e3ba

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1857453

Change-Id: I7391e9e298f6736359b2e61c0c535bfa4d00b95c
parents 28e6e409 2168e3ba
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
			}
		}
	}