From 5786f5cf1df41f3e536bebe1140465b510d85fb9 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Tue, 28 May 2024 02:22:34 +0900 Subject: [PATCH 1/2] Add "Optimize_for_size" build property Projects with this property will be aggresively optimized for size. This is useful for large binaries that are rarely executed and performance insensitive (e.g. debugging tools, deprecated libraries). This changeset reduces total system native binary size by 1.1%. Test: presubmit Bug: 342090838 Change-Id: I46a1db0c44e2e7d482b14eca1299f8ad48661d2d --- cc/cc.go | 15 +++++++++++++++ cc/compiler.go | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/cc/cc.go b/cc/cc.go index cb82f8610..0db1bd678 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -286,6 +286,11 @@ type BaseProperties struct { // Deprecated. true is the default, false is invalid. Clang *bool `android:"arch_variant"` + // Aggresively trade performance for smaller binary size. + // This should only be used for on-device binaries that are rarely executed and not + // performance critical. + Optimize_for_size *bool `android:"arch_variant"` + // The API level that this module is built against. The APIs of this API level will be // visible at build time, but use of any APIs newer than min_sdk_version will render the // module unloadable on older devices. In the future it will be possible to weakly-link new @@ -546,6 +551,7 @@ type ModuleContextIntf interface { isCfiAssemblySupportEnabled() bool getSharedFlags() *SharedFlags notInPlatform() bool + optimizeForSize() bool } type SharedFlags struct { @@ -985,6 +991,7 @@ func (c *Module) AddJSONData(d *map[string]interface{}) { "WinMsgSrcs": hasWinMsg, "YaccSrsc": hasYacc, "OnlyCSrcs": !(hasAidl || hasLex || hasProto || hasRenderscript || hasSysprop || hasWinMsg || hasYacc), + "OptimizeForSize": c.OptimizeForSize(), } } @@ -1070,6 +1077,10 @@ func (c *Module) StubDecorator() bool { return false } +func (c *Module) OptimizeForSize() bool { + return Bool(c.Properties.Optimize_for_size) +} + func (c *Module) SdkVersion() string { return String(c.Properties.Sdk_version) } @@ -1613,6 +1624,10 @@ func (ctx *moduleContextImpl) object() bool { return ctx.mod.Object() } +func (ctx *moduleContextImpl) optimizeForSize() bool { + return ctx.mod.OptimizeForSize() +} + func (ctx *moduleContextImpl) canUseSdk() bool { return ctx.mod.canUseSdk() } diff --git a/cc/compiler.go b/cc/compiler.go index 34d98c02d..d13cd9506 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -693,6 +693,10 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp") } + if ctx.optimizeForSize() { + flags.Local.CFlags = append(flags.Local.CFlags, "-Oz") + } + // Exclude directories from manual binder interface allowed list. //TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths. if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) { From 2cd77d671c365df0c24f867532e67b13ebae5904 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Thu, 6 Jun 2024 03:05:04 +0900 Subject: [PATCH 2/2] Enable MLGO inliner optimization for optimize_for_size cases This helps reduce binary size for these projects by ~3%. Test: presubmit Bug: 342090838 Change-Id: Ie1e0586ddf5f40aa1e81fc2628a6499093de9699 --- cc/compiler.go | 1 + cc/lto.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cc/compiler.go b/cc/compiler.go index d13cd9506..83080fd72 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -695,6 +695,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps if ctx.optimizeForSize() { flags.Local.CFlags = append(flags.Local.CFlags, "-Oz") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") } // Exclude directories from manual binder interface allowed list. diff --git a/cc/lto.go b/cc/lto.go index a084db7be..60eb4d6b1 100644 --- a/cc/lto.go +++ b/cc/lto.go @@ -144,7 +144,7 @@ func (lto *lto) flags(ctx ModuleContext, flags Flags) Flags { if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") { // Register allocation MLGO flags for ARM64. - if ctx.Arch().ArchType == android.Arm64 { + if ctx.Arch().ArchType == android.Arm64 && !ctx.optimizeForSize() { ltoLdFlags = append(ltoLdFlags, "-Wl,-mllvm,-regalloc-enable-advisor=release") } // Flags for training MLGO model.