Commit 1220ac27 authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: don't copy all type nodes for builtin functions

Only copy the ones that actually change.  Also combine deep and substAny
functions into one.  The Type.Copyany field is now unused, so remove it.

Passes toolstash -cmp.

Change-Id: Id28a9bf144ecf3e522aad00496f8a21ae2b74680
Reviewed-on: https://go-review.googlesource.com/20600Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
parent 055dcb75
......@@ -1078,51 +1078,91 @@ func substArgTypes(np **Node, types ...*Type) {
for _, t := range types {
dowidth(t)
}
n.Type = deep(n.Type)
substAny(&n.Type, &types)
n.Type = substAny(n.Type, &types)
if len(types) > 0 {
Fatalf("substArgTypes: too many argument types")
}
}
// substAny walks *tp, replacing instances of "any" with successive
// elements removed from types.
func substAny(tp **Type, types *[]*Type) {
for {
t := *tp
if t == nil {
return
}
if t.Etype == TANY && t.Copyany {
if len(*types) == 0 {
Fatalf("substArgTypes: not enough argument types")
}
*tp = (*types)[0]
*types = (*types)[1:]
// substAny walks t, replacing instances of "any" with successive
// elements removed from types. It returns the substituted type.
func substAny(t *Type, types *[]*Type) *Type {
if t == nil {
return nil
}
switch t.Etype {
default:
// Leave the type unchanged.
case TANY:
if len(*types) == 0 {
Fatalf("substArgTypes: not enough argument types")
}
t = (*types)[0]
*types = (*types)[1:]
switch t.Etype {
case TPTR32, TPTR64, TCHAN, TARRAY:
tp = &t.Type
continue
case TPTR32, TPTR64, TCHAN, TARRAY, TFIELD:
elem := substAny(t.Type, types)
if elem != t.Type {
t = t.Copy()
t.Type = elem
}
case TMAP:
substAny(&t.Down, types)
tp = &t.Type
continue
case TMAP:
key := substAny(t.Down, types)
val := substAny(t.Type, types)
if key != t.Down || val != t.Type {
t = t.Copy()
t.Down = key
t.Type = val
}
case TFUNC:
substAny(t.RecvsP(), types)
substAny(t.ParamsP(), types)
substAny(t.ResultsP(), types)
case TFUNC:
recvs := substAny(t.Recvs(), types)
params := substAny(t.Params(), types)
results := substAny(t.Results(), types)
if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
// Note that this code has to be aware of the
// representation underlying Recvs/Results/Params.
if recvs == t.Recvs() {
recvs = recvs.Copy()
}
if results == t.Results() {
results = results.Copy()
}
t = t.Copy()
*t.RecvsP() = recvs
*t.ResultsP() = results
*t.ParamsP() = params
}
case TSTRUCT:
for t, it := IterFields(t); t != nil; t = it.Next() {
substAny(&t.Type, types)
case TSTRUCT:
// nfs only has to be big enough for the builtin functions.
var nfs [8]*Type
fields := t.FieldSlice()
changed := false
for i, f := range fields {
nf := substAny(f, types)
if nf != f {
if !changed {
for j := 0; j < i; j++ {
nfs[j] = fields[j].Copy()
}
}
changed = true
} else if changed {
nf = f.Copy()
}
nfs[i] = nf
}
if changed {
t = t.Copy()
t.SetFields(nfs[:len(fields)])
}
return
}
return t
}
// Is this a 64-bit type?
......@@ -1166,50 +1206,6 @@ func Noconv(t1 *Type, t2 *Type) bool {
return false
}
func deep(t *Type) *Type {
if t == nil {
return nil
}
var nt *Type
switch t.Etype {
default:
nt = t // share from here down
case TANY:
nt = t.Copy()
nt.Copyany = true
case TPTR32, TPTR64, TCHAN, TARRAY:
nt = t.Copy()
nt.Type = deep(t.Type)
case TMAP:
nt = t.Copy()
nt.Down = deep(t.Down)
nt.Type = deep(t.Type)
case TFUNC:
nt = t.Copy()
*nt.RecvsP() = deep(t.Recvs())
*nt.ResultsP() = deep(t.Results())
*nt.ParamsP() = deep(t.Params())
case TSTRUCT:
nt = t.Copy()
nt.Type = t.Type.Copy()
xt := nt.Type
for t, it := IterFields(t); t != nil; t = it.Next() {
xt.Type = deep(t.Type)
xt.Down = t.Down.Copy()
xt = xt.Down
}
}
return nt
}
func syslook(name string) *Node {
s := Pkglookup(name, Runtimepkg)
if s == nil || s.Def == nil {
......
......@@ -110,8 +110,7 @@ type Type struct {
Printed bool
Embedded uint8 // TFIELD embedded type
Funarg bool // on TSTRUCT and TFIELD
Copyany bool
Local bool // created in this file
Local bool // created in this file
Deferwidth bool
Broke bool // broken type definition.
Isddd bool // TFIELD is ... argument
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment