Merge changes I18acac41,Ib8baefed,I38e78bb9
* changes: Work around LLVM bug where TLS not emulated in LTO mode Add LTO support to soong Pass correct emulation string to gold
This commit is contained in:
@@ -115,6 +115,7 @@ bootstrap_go_package {
|
|||||||
"cc/check.go",
|
"cc/check.go",
|
||||||
"cc/coverage.go",
|
"cc/coverage.go",
|
||||||
"cc/gen.go",
|
"cc/gen.go",
|
||||||
|
"cc/lto.go",
|
||||||
"cc/makevars.go",
|
"cc/makevars.go",
|
||||||
"cc/prebuilt.go",
|
"cc/prebuilt.go",
|
||||||
"cc/proto.go",
|
"cc/proto.go",
|
||||||
|
18
cc/cc.go
18
cc/cc.go
@@ -51,6 +51,9 @@ func init() {
|
|||||||
|
|
||||||
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
|
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
|
||||||
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
||||||
|
|
||||||
|
ctx.TopDown("lto_deps", ltoDepsMutator)
|
||||||
|
ctx.BottomUp("lto", ltoMutator).Parallel()
|
||||||
})
|
})
|
||||||
|
|
||||||
pctx.Import("android/soong/cc/config")
|
pctx.Import("android/soong/cc/config")
|
||||||
@@ -295,6 +298,7 @@ type Module struct {
|
|||||||
coverage *coverage
|
coverage *coverage
|
||||||
sabi *sabi
|
sabi *sabi
|
||||||
vndkdep *vndkdep
|
vndkdep *vndkdep
|
||||||
|
lto *lto
|
||||||
|
|
||||||
androidMkSharedLibDeps []string
|
androidMkSharedLibDeps []string
|
||||||
|
|
||||||
@@ -334,6 +338,9 @@ func (c *Module) Init() android.Module {
|
|||||||
if c.vndkdep != nil {
|
if c.vndkdep != nil {
|
||||||
c.AddProperties(c.vndkdep.props()...)
|
c.AddProperties(c.vndkdep.props()...)
|
||||||
}
|
}
|
||||||
|
if c.lto != nil {
|
||||||
|
c.AddProperties(c.lto.props()...)
|
||||||
|
}
|
||||||
for _, feature := range c.features {
|
for _, feature := range c.features {
|
||||||
c.AddProperties(feature.props()...)
|
c.AddProperties(feature.props()...)
|
||||||
}
|
}
|
||||||
@@ -489,6 +496,7 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo
|
|||||||
module.coverage = &coverage{}
|
module.coverage = &coverage{}
|
||||||
module.sabi = &sabi{}
|
module.sabi = &sabi{}
|
||||||
module.vndkdep = &vndkdep{}
|
module.vndkdep = &vndkdep{}
|
||||||
|
module.lto = <o{}
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,6 +545,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
if c.coverage != nil {
|
if c.coverage != nil {
|
||||||
flags = c.coverage.flags(ctx, flags)
|
flags = c.coverage.flags(ctx, flags)
|
||||||
}
|
}
|
||||||
|
if c.lto != nil {
|
||||||
|
flags = c.lto.flags(ctx, flags)
|
||||||
|
}
|
||||||
for _, feature := range c.features {
|
for _, feature := range c.features {
|
||||||
flags = feature.flags(ctx, flags)
|
flags = feature.flags(ctx, flags)
|
||||||
}
|
}
|
||||||
@@ -620,6 +631,9 @@ func (c *Module) begin(ctx BaseModuleContext) {
|
|||||||
if c.vndkdep != nil {
|
if c.vndkdep != nil {
|
||||||
c.vndkdep.begin(ctx)
|
c.vndkdep.begin(ctx)
|
||||||
}
|
}
|
||||||
|
if c.lto != nil {
|
||||||
|
c.lto.begin(ctx)
|
||||||
|
}
|
||||||
for _, feature := range c.features {
|
for _, feature := range c.features {
|
||||||
feature.begin(ctx)
|
feature.begin(ctx)
|
||||||
}
|
}
|
||||||
@@ -656,6 +670,9 @@ func (c *Module) deps(ctx DepsContext) Deps {
|
|||||||
if c.vndkdep != nil {
|
if c.vndkdep != nil {
|
||||||
deps = c.vndkdep.deps(ctx, deps)
|
deps = c.vndkdep.deps(ctx, deps)
|
||||||
}
|
}
|
||||||
|
if c.lto != nil {
|
||||||
|
deps = c.lto.deps(ctx, deps)
|
||||||
|
}
|
||||||
for _, feature := range c.features {
|
for _, feature := range c.features {
|
||||||
deps = feature.deps(ctx, deps)
|
deps = feature.deps(ctx, deps)
|
||||||
}
|
}
|
||||||
@@ -1191,6 +1208,7 @@ func DefaultsFactory(props ...interface{}) android.Module {
|
|||||||
&CoverageProperties{},
|
&CoverageProperties{},
|
||||||
&SAbiProperties{},
|
&SAbiProperties{},
|
||||||
&VndkProperties{},
|
&VndkProperties{},
|
||||||
|
<OProperties{},
|
||||||
)
|
)
|
||||||
|
|
||||||
android.InitDefaultsModule(module)
|
android.InitDefaultsModule(module)
|
||||||
|
@@ -60,7 +60,7 @@ var (
|
|||||||
"-Wl,--build-id=md5",
|
"-Wl,--build-id=md5",
|
||||||
"-Wl,--warn-shared-textrel",
|
"-Wl,--warn-shared-textrel",
|
||||||
"-Wl,--fatal-warnings",
|
"-Wl,--fatal-warnings",
|
||||||
"-Wl,-maarch64linux",
|
"-Wl,-m,aarch64_elf64_le_vec",
|
||||||
"-Wl,--hash-style=gnu",
|
"-Wl,--hash-style=gnu",
|
||||||
"-Wl,--fix-cortex-a53-843419",
|
"-Wl,--fix-cortex-a53-843419",
|
||||||
"-fuse-ld=gold",
|
"-fuse-ld=gold",
|
||||||
|
@@ -67,6 +67,7 @@ var (
|
|||||||
"-Wl,--icf=safe",
|
"-Wl,--icf=safe",
|
||||||
"-Wl,--hash-style=gnu",
|
"-Wl,--hash-style=gnu",
|
||||||
"-Wl,--no-undefined-version",
|
"-Wl,--no-undefined-version",
|
||||||
|
"-Wl,-m,armelf",
|
||||||
}
|
}
|
||||||
|
|
||||||
armArmCflags = []string{
|
armArmCflags = []string{
|
||||||
|
@@ -16,6 +16,7 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
@@ -149,6 +150,11 @@ func init() {
|
|||||||
return ClangDefaultShortVersion, nil
|
return ClangDefaultShortVersion, nil
|
||||||
})
|
})
|
||||||
pctx.StaticVariable("ClangAsanLibDir", "${ClangPath}/lib64/clang/${ClangShortVersion}/lib/linux")
|
pctx.StaticVariable("ClangAsanLibDir", "${ClangPath}/lib64/clang/${ClangShortVersion}/lib/linux")
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
pctx.StaticVariable("LLVMGoldPlugin", "${ClangPath}/lib64/LLVMgold.dylib")
|
||||||
|
} else {
|
||||||
|
pctx.StaticVariable("LLVMGoldPlugin", "${ClangPath}/lib64/LLVMgold.so")
|
||||||
|
}
|
||||||
|
|
||||||
// These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts
|
// These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts
|
||||||
// being used for the rest of the build process.
|
// being used for the rest of the build process.
|
||||||
|
117
cc/lto.go
Normal file
117
cc/lto.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
// Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/blueprint"
|
||||||
|
|
||||||
|
"android/soong/android"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// To properly build a module with LTO, the module and all recursive static
|
||||||
|
// dependencies should be compiled with -flto which directs the compiler to emit
|
||||||
|
// bitcode rather than native object files. These bitcode files are then passed
|
||||||
|
// by the linker to the LLVM plugin for compilation at link time. Static
|
||||||
|
// dependencies not built as bitcode will still function correctly but cannot be
|
||||||
|
// optimized at link time and may not be compatible with features that require
|
||||||
|
// LTO, such as CFI.
|
||||||
|
//
|
||||||
|
// This file adds support to soong to automatically propogate LTO options to a
|
||||||
|
// new variant of all static dependencies for each module with LTO enabled.
|
||||||
|
|
||||||
|
type LTOProperties struct {
|
||||||
|
// Lto must violate capitialization style for acronyms so that it can be
|
||||||
|
// referred to in blueprint files as "lto"
|
||||||
|
Lto *bool `android:"arch_variant"`
|
||||||
|
LTODep bool `blueprint:"mutated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type lto struct {
|
||||||
|
Properties LTOProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lto *lto) props() []interface{} {
|
||||||
|
return []interface{}{<o.Properties}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lto *lto) begin(ctx BaseModuleContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lto *lto) deps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
|
return deps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
|
||||||
|
if Bool(lto.Properties.Lto) {
|
||||||
|
flags.CFlags = append(flags.CFlags, "-flto")
|
||||||
|
flags.LdFlags = append(flags.LdFlags, "-flto")
|
||||||
|
if ctx.Device() {
|
||||||
|
// Work around bug in Clang that doesn't pass correct emulated
|
||||||
|
// TLS option to target
|
||||||
|
flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-emulated-tls")
|
||||||
|
}
|
||||||
|
flags.ArFlags = append(flags.ArFlags, " --plugin ${config.LLVMGoldPlugin}")
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can be called with a null receiver
|
||||||
|
func (lto *lto) LTO() bool {
|
||||||
|
if lto == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bool(lto.Properties.Lto)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Propagate lto requirements down from binaries
|
||||||
|
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
|
||||||
|
if c, ok := mctx.Module().(*Module); ok && c.lto.LTO() {
|
||||||
|
mctx.VisitDepsDepthFirst(func(m blueprint.Module) {
|
||||||
|
tag := mctx.OtherModuleDependencyTag(m)
|
||||||
|
switch tag {
|
||||||
|
case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag, objDepTag, reuseObjTag:
|
||||||
|
if cc, ok := m.(*Module); ok && cc.lto != nil {
|
||||||
|
cc.lto.Properties.LTODep = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create lto variants for modules that need them
|
||||||
|
func ltoMutator(mctx android.BottomUpMutatorContext) {
|
||||||
|
if c, ok := mctx.Module().(*Module); ok && c.lto != nil {
|
||||||
|
if c.lto.LTO() {
|
||||||
|
mctx.SetDependencyVariation("lto")
|
||||||
|
} else if c.lto.Properties.LTODep {
|
||||||
|
modules := mctx.CreateVariations("", "lto")
|
||||||
|
modules[0].(*Module).lto.Properties.Lto = boolPtr(false)
|
||||||
|
modules[1].(*Module).lto.Properties.Lto = boolPtr(true)
|
||||||
|
modules[0].(*Module).lto.Properties.LTODep = false
|
||||||
|
modules[1].(*Module).lto.Properties.LTODep = false
|
||||||
|
modules[1].(*Module).Properties.PreventInstall = true
|
||||||
|
modules[1].(*Module).Properties.HideFromMake = true
|
||||||
|
}
|
||||||
|
c.lto.Properties.LTODep = false
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user