mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: do not emit a few more basic types from every compilation
We already emit types for any and func(error) string in runtime.a but unlike the other pre-emitted types, we don't then exclude them from being emitted in other packages. Fix that. Also add slices of non-func types that we already emit. Saves 0.3% of .a files in std cmd deps, computed by adding sizes from: ls -l $(go list -export -f '{{.Export}}' -deps std cmd The effect is small and not worth doing on its own. The real improvement is making “what to write always in runtime” and “what not to write in other packages” more obviously aligned. Change-Id: Ie5cb5fd7e5a3025d2776d9b4cece775fdf92d3b6 Reviewed-on: https://go-review.googlesource.com/c/go/+/450135 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
c085c6cbff
commit
cb5534c1c6
@ -1395,6 +1395,35 @@ func WriteImportStrings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writtenByWriteBasicTypes reports whether typ is written by WriteBasicTypes.
|
||||||
|
// WriteBasicTypes always writes pointer types; any pointer has been stripped off typ already.
|
||||||
|
func writtenByWriteBasicTypes(typ *types.Type) bool {
|
||||||
|
if typ.Sym() == nil && typ.Kind() == types.TFUNC {
|
||||||
|
f := typ.FuncType()
|
||||||
|
// func(error) string
|
||||||
|
if f.Receiver.NumFields() == 0 && f.TParams.NumFields() == 0 &&
|
||||||
|
f.Params.NumFields() == 1 && f.Results.NumFields() == 1 &&
|
||||||
|
f.Params.FieldType(0) == types.ErrorType &&
|
||||||
|
f.Results.FieldType(0) == types.Types[types.TSTRING] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we have left the basic types plus any and error, plus slices of them.
|
||||||
|
// Strip the slice.
|
||||||
|
if typ.Sym() == nil && typ.IsSlice() {
|
||||||
|
typ = typ.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic types.
|
||||||
|
sym := typ.Sym()
|
||||||
|
if sym != nil && (sym.Pkg == types.BuiltinPkg || sym.Pkg == types.UnsafePkg) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// any or error
|
||||||
|
return (sym == nil && typ.IsEmptyInterface()) || typ == types.ErrorType
|
||||||
|
}
|
||||||
|
|
||||||
func WriteBasicTypes() {
|
func WriteBasicTypes() {
|
||||||
// do basic types if compiling package runtime.
|
// do basic types if compiling package runtime.
|
||||||
// they have to be in at least one package,
|
// they have to be in at least one package,
|
||||||
@ -1402,23 +1431,30 @@ func WriteBasicTypes() {
|
|||||||
// so this is as good as any.
|
// so this is as good as any.
|
||||||
// another possible choice would be package main,
|
// another possible choice would be package main,
|
||||||
// but using runtime means fewer copies in object files.
|
// but using runtime means fewer copies in object files.
|
||||||
|
// The code here needs to be in sync with writtenByWriteBasicTypes above.
|
||||||
if base.Ctxt.Pkgpath == "runtime" {
|
if base.Ctxt.Pkgpath == "runtime" {
|
||||||
|
// Note: always write NewPtr(t) because NeedEmit's caller strips the pointer.
|
||||||
|
var list []*types.Type
|
||||||
for i := types.Kind(1); i <= types.TBOOL; i++ {
|
for i := types.Kind(1); i <= types.TBOOL; i++ {
|
||||||
writeType(types.NewPtr(types.Types[i]))
|
list = append(list, types.Types[i])
|
||||||
|
}
|
||||||
|
list = append(list,
|
||||||
|
types.Types[types.TSTRING],
|
||||||
|
types.Types[types.TUNSAFEPTR],
|
||||||
|
types.AnyType,
|
||||||
|
types.ErrorType)
|
||||||
|
for _, t := range list {
|
||||||
|
writeType(types.NewPtr(t))
|
||||||
|
writeType(types.NewPtr(types.NewSlice(t)))
|
||||||
}
|
}
|
||||||
writeType(types.NewPtr(types.Types[types.TSTRING]))
|
|
||||||
writeType(types.NewPtr(types.Types[types.TUNSAFEPTR]))
|
|
||||||
writeType(types.AnyType)
|
|
||||||
|
|
||||||
// emit type structs for error and func(error) string.
|
// emit type for func(error) string,
|
||||||
// The latter is the type of an auto-generated wrapper.
|
// which is the type of an auto-generated wrapper.
|
||||||
writeType(types.NewPtr(types.ErrorType))
|
writeType(types.NewPtr(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
|
||||||
|
|
||||||
writeType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
|
|
||||||
types.NewField(base.Pos, nil, types.ErrorType),
|
types.NewField(base.Pos, nil, types.ErrorType),
|
||||||
}, []*types.Field{
|
}, []*types.Field{
|
||||||
types.NewField(base.Pos, nil, types.Types[types.TSTRING]),
|
types.NewField(base.Pos, nil, types.Types[types.TSTRING]),
|
||||||
}))
|
})))
|
||||||
|
|
||||||
// add paths for runtime and main, which 6l imports implicitly.
|
// add paths for runtime and main, which 6l imports implicitly.
|
||||||
dimportpath(ir.Pkgs.Runtime)
|
dimportpath(ir.Pkgs.Runtime)
|
||||||
@ -1759,6 +1795,9 @@ func NeedEmit(typ *types.Type) bool {
|
|||||||
// instantiated generic functions too.
|
// instantiated generic functions too.
|
||||||
|
|
||||||
switch sym := typ.Sym(); {
|
switch sym := typ.Sym(); {
|
||||||
|
case writtenByWriteBasicTypes(typ):
|
||||||
|
return base.Ctxt.Pkgpath == "runtime"
|
||||||
|
|
||||||
case sym == nil:
|
case sym == nil:
|
||||||
// Anonymous type; possibly never seen before or ever again.
|
// Anonymous type; possibly never seen before or ever again.
|
||||||
// Need to emit to be safe (however, see TODO above).
|
// Need to emit to be safe (however, see TODO above).
|
||||||
@ -1768,11 +1807,6 @@ func NeedEmit(typ *types.Type) bool {
|
|||||||
// Local defined type; our responsibility.
|
// Local defined type; our responsibility.
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case base.Ctxt.Pkgpath == "runtime" && (sym.Pkg == types.BuiltinPkg || sym.Pkg == types.UnsafePkg):
|
|
||||||
// Package runtime is responsible for including code for builtin
|
|
||||||
// types (predeclared and package unsafe).
|
|
||||||
return true
|
|
||||||
|
|
||||||
case typ.IsFullyInstantiated():
|
case typ.IsFullyInstantiated():
|
||||||
// Instantiated type; possibly instantiated with unique type arguments.
|
// Instantiated type; possibly instantiated with unique type arguments.
|
||||||
// Need to emit to be safe (however, see TODO above).
|
// Need to emit to be safe (however, see TODO above).
|
||||||
|
@ -539,6 +539,9 @@ func (d *dwctxt) newtype(gotype loader.Sym) *dwarf.DWDie {
|
|||||||
sn := d.ldr.SymName(gotype)
|
sn := d.ldr.SymName(gotype)
|
||||||
name := sn[5:] // could also decode from Type.string
|
name := sn[5:] // could also decode from Type.string
|
||||||
tdata := d.ldr.Data(gotype)
|
tdata := d.ldr.Data(gotype)
|
||||||
|
if len(tdata) == 0 {
|
||||||
|
d.linkctxt.Errorf(gotype, "missing type")
|
||||||
|
}
|
||||||
kind := decodetypeKind(d.arch, tdata)
|
kind := decodetypeKind(d.arch, tdata)
|
||||||
bytesize := decodetypeSize(d.arch, tdata)
|
bytesize := decodetypeSize(d.arch, tdata)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user