Add LTO support to soong

Enabling the lto property for a module builds that module and all static
dependencies with LTO.

LTO (link-time optimization) allows the compiler to optimize and
generate code for the entire module at link time, rather than
per-compilation unit. LTO is required for Clang CFI and other
whole-program optimization techniques. LTO also allows cross-compilation
unit optimizations that should result in faster and smaller code, at the
expense of additional compilation time.

Test: make -j12 libc with lto: true for libc

Change-Id: Ib8baefedf60e02701d44673a7c473e0845730101
diff --git a/cc/cc.go b/cc/cc.go
index 983ffc0..ba06be2 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -51,6 +51,9 @@
 
 		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
 		ctx.TopDown("vndk_deps", sabiDepsMutator)
+
+		ctx.TopDown("lto_deps", ltoDepsMutator)
+		ctx.BottomUp("lto", ltoMutator).Parallel()
 	})
 
 	pctx.Import("android/soong/cc/config")
@@ -295,6 +298,7 @@
 	coverage  *coverage
 	sabi      *sabi
 	vndkdep   *vndkdep
+	lto       *lto
 
 	androidMkSharedLibDeps []string
 
@@ -334,6 +338,9 @@
 	if c.vndkdep != nil {
 		c.AddProperties(c.vndkdep.props()...)
 	}
+	if c.lto != nil {
+		c.AddProperties(c.lto.props()...)
+	}
 	for _, feature := range c.features {
 		c.AddProperties(feature.props()...)
 	}
@@ -489,6 +496,7 @@
 	module.coverage = &coverage{}
 	module.sabi = &sabi{}
 	module.vndkdep = &vndkdep{}
+	module.lto = &lto{}
 	return module
 }
 
@@ -537,6 +545,9 @@
 	if c.coverage != nil {
 		flags = c.coverage.flags(ctx, flags)
 	}
+	if c.lto != nil {
+		flags = c.lto.flags(ctx, flags)
+	}
 	for _, feature := range c.features {
 		flags = feature.flags(ctx, flags)
 	}
@@ -620,6 +631,9 @@
 	if c.vndkdep != nil {
 		c.vndkdep.begin(ctx)
 	}
+	if c.lto != nil {
+		c.lto.begin(ctx)
+	}
 	for _, feature := range c.features {
 		feature.begin(ctx)
 	}
@@ -656,6 +670,9 @@
 	if c.vndkdep != nil {
 		deps = c.vndkdep.deps(ctx, deps)
 	}
+	if c.lto != nil {
+		deps = c.lto.deps(ctx, deps)
+	}
 	for _, feature := range c.features {
 		deps = feature.deps(ctx, deps)
 	}
@@ -1191,6 +1208,7 @@
 		&CoverageProperties{},
 		&SAbiProperties{},
 		&VndkProperties{},
+		&LTOProperties{},
 	)
 
 	android.InitDefaultsModule(module)