1
0
mirror of https://github.com/golang/go synced 2024-07-03 00:40:45 +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:
Russ Cox 2022-11-12 12:27:33 -05:00 committed by Gopher Robot
parent c085c6cbff
commit cb5534c1c6
2 changed files with 52 additions and 15 deletions

View File

@ -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() {
// do basic types if compiling package runtime.
// they have to be in at least one package,
@ -1402,23 +1431,30 @@ func WriteBasicTypes() {
// so this is as good as any.
// another possible choice would be package main,
// 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" {
// 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++ {
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.
// The latter is the type of an auto-generated wrapper.
writeType(types.NewPtr(types.ErrorType))
writeType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
// emit type for func(error) string,
// which is the type of an auto-generated wrapper.
writeType(types.NewPtr(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
types.NewField(base.Pos, nil, types.ErrorType),
}, []*types.Field{
types.NewField(base.Pos, nil, types.Types[types.TSTRING]),
}))
})))
// add paths for runtime and main, which 6l imports implicitly.
dimportpath(ir.Pkgs.Runtime)
@ -1759,6 +1795,9 @@ func NeedEmit(typ *types.Type) bool {
// instantiated generic functions too.
switch sym := typ.Sym(); {
case writtenByWriteBasicTypes(typ):
return base.Ctxt.Pkgpath == "runtime"
case sym == nil:
// Anonymous type; possibly never seen before or ever again.
// 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.
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():
// Instantiated type; possibly instantiated with unique type arguments.
// Need to emit to be safe (however, see TODO above).

View File

@ -539,6 +539,9 @@ func (d *dwctxt) newtype(gotype loader.Sym) *dwarf.DWDie {
sn := d.ldr.SymName(gotype)
name := sn[5:] // could also decode from Type.string
tdata := d.ldr.Data(gotype)
if len(tdata) == 0 {
d.linkctxt.Errorf(gotype, "missing type")
}
kind := decodetypeKind(d.arch, tdata)
bytesize := decodetypeSize(d.arch, tdata)