From: Matthew Dempsky Date: Sun, 20 Aug 2023 22:07:00 +0000 (-0700) Subject: cmd/compile/internal/types: simplify iterating all parameters X-Git-Tag: go1.22rc1~1138 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3d15bfaa3e05c321dbec48bbcc634a3759b0b18a;p=gostls13.git cmd/compile/internal/types: simplify iterating all parameters The types.RecvsParamsResults, etc. helpers existed to make it "easier" to iterate over all parameters, or recvs+params, or params+results; but they end up still being quite clumsy to use due to the design goal of not allocating temporary slices. Now that recvs+params+results are stored in a single consecutive slice anyway, we can just return different subslices and simplify the loops. Change-Id: I84791b80dc099dfbfbbe6eddbc006135528c23b4 Reviewed-on: https://go-review.googlesource.com/c/go/+/521375 Auto-Submit: Matthew Dempsky TryBot-Result: Gopher Robot Reviewed-by: Cuong Manh Le Run-TryBot: Matthew Dempsky Reviewed-by: Than McIntosh --- diff --git a/src/cmd/compile/internal/dwarfgen/dwarf.go b/src/cmd/compile/internal/dwarfgen/dwarf.go index b3c97cb0c6..24f7ea237f 100644 --- a/src/cmd/compile/internal/dwarfgen/dwarf.go +++ b/src/cmd/compile/internal/dwarfgen/dwarf.go @@ -270,12 +270,10 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir func sortDeclsAndVars(fn *ir.Func, decls []*ir.Name, vars []*dwarf.Var) { paramOrder := make(map[*ir.Name]int) idx := 1 - for _, selfn := range &types.RecvsParamsResults { - for _, f := range selfn(fn.Type()) { - if n, ok := f.Nname.(*ir.Name); ok { - paramOrder[n] = idx - idx++ - } + for _, f := range fn.Type().RecvParamsResults() { + if n, ok := f.Nname.(*ir.Name); ok { + paramOrder[n] = idx + idx++ } } sort.Stable(varsAndDecls{decls, vars, paramOrder}) diff --git a/src/cmd/compile/internal/escape/escape.go b/src/cmd/compile/internal/escape/escape.go index b0c17ccb83..ef352fa078 100644 --- a/src/cmd/compile/internal/escape/escape.go +++ b/src/cmd/compile/internal/escape/escape.go @@ -273,12 +273,8 @@ func (b *batch) finish(fns []*ir.Func) { for _, fn := range fns { fn.SetEsc(escFuncTagged) - narg := 0 - for _, fs := range &types.RecvsParams { - for _, f := range fs(fn.Type()) { - narg++ - f.Note = b.paramTag(fn, narg, f) - } + for i, param := range fn.Type().RecvParams() { + param.Note = b.paramTag(fn, 1+i, param) } } diff --git a/src/cmd/compile/internal/noder/linker.go b/src/cmd/compile/internal/noder/linker.go index 71e57741a0..3a0b32501d 100644 --- a/src/cmd/compile/internal/noder/linker.go +++ b/src/cmd/compile/internal/noder/linker.go @@ -289,10 +289,8 @@ func (l *linker) relocFuncExt(w *pkgbits.Encoder, name *ir.Name) { w.Uint64(uint64(name.Func.ABI)) // Escape analysis. - for _, fs := range &types.RecvsParams { - for _, f := range fs(name.Type()) { - w.String(f.Note) - } + for _, f := range name.Type().RecvParams() { + w.String(f.Note) } if inl := name.Func.Inl; w.Bool(inl != nil) { diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 6ab7b272a6..2a526dbe69 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -1109,10 +1109,8 @@ func (r *reader) funcExt(name *ir.Name, method *types.Sym) { fn.ABI = obj.ABI(r.Uint64()) // Escape analysis. - for _, fs := range &types.RecvsParams { - for _, f := range fs(name.Type()) { - f.Note = r.String() - } + for _, f := range name.Type().RecvParams() { + f.Note = r.String() } if r.Bool() { diff --git a/src/cmd/compile/internal/types/identity.go b/src/cmd/compile/internal/types/identity.go index 78a644a6dd..fa28c038bd 100644 --- a/src/cmd/compile/internal/types/identity.go +++ b/src/cmd/compile/internal/types/identity.go @@ -122,18 +122,18 @@ cont: // Check parameters and result parameters for type equality. // We intentionally ignore receiver parameters for type // equality, because they're never relevant. - for _, f := range &ParamsResults { - // Loop over fields in structs, ignoring argument names. - fs1, fs2 := f(t1), f(t2) - if len(fs1) != len(fs2) { + if t1.NumParams() != t2.NumParams() || + t1.NumResults() != t2.NumResults() || + t1.IsVariadic() != t2.IsVariadic() { + return false + } + + fs1 := t1.ParamsResults() + fs2 := t2.ParamsResults() + for i, f1 := range fs1 { + if !identical(f1.Type, fs2[i].Type, flags, assumedEqual) { return false } - for i, f1 := range fs1 { - f2 := fs2[i] - if f1.IsDDD() != f2.IsDDD() || !identical(f1.Type, f2.Type, flags, assumedEqual) { - return false - } - } } return true diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index d80a03fa08..68073f6173 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -312,9 +312,11 @@ type Func struct { Argwid int64 } -func (ft *Func) recvs() []*Field { return ft.allParams[:ft.startParams] } -func (ft *Func) params() []*Field { return ft.allParams[ft.startParams:ft.startResults] } -func (ft *Func) results() []*Field { return ft.allParams[ft.startResults:] } +func (ft *Func) recvs() []*Field { return ft.allParams[:ft.startParams] } +func (ft *Func) params() []*Field { return ft.allParams[ft.startParams:ft.startResults] } +func (ft *Func) results() []*Field { return ft.allParams[ft.startResults:] } +func (ft *Func) recvParams() []*Field { return ft.allParams[:ft.startResults] } +func (ft *Func) paramsResults() []*Field { return ft.allParams[ft.startParams:] } // funcType returns t's extra func-specific fields. func (t *Type) funcType() *Func { @@ -807,6 +809,19 @@ func (t *Type) Params() []*Field { return t.funcType().params() } // Results returns a slice of result parameters of signature type t. func (t *Type) Results() []*Field { return t.funcType().results() } +// RecvsParamsResults returns a slice containing all of the +// signature's parameters in receiver (if any), (normal) parameters, +// and then results. +func (t *Type) RecvParamsResults() []*Field { return t.funcType().allParams } + +// RecvParams returns a slice containing the signature's receiver (if +// any) followed by its (normal) parameters. +func (t *Type) RecvParams() []*Field { return t.funcType().recvParams() } + +// ParamsResults returns a slice containing the signature's (normal) +// parameters followed by its results. +func (t *Type) ParamsResults() []*Field { return t.funcType().paramsResults() } + func (t *Type) NumRecvs() int { return len(t.Recvs()) } func (t *Type) NumParams() int { return len(t.Params()) } func (t *Type) NumResults() int { return len(t.Results()) } @@ -831,23 +846,6 @@ func (t *Type) Param(i int) *Field { return t.Params()[i] } // Result returns the i'th result of signature type t. func (t *Type) Result(i int) *Field { return t.Results()[i] } -// RecvsParamsResults stores the accessor functions for a function Type's -// receiver, parameters, and result parameters, in that order. -// It can be used to iterate over all of a function's parameter lists. -var RecvsParamsResults = [3]func(*Type) []*Field{ - (*Type).Recvs, (*Type).Params, (*Type).Results, -} - -// RecvsParams is like RecvsParamsResults, but omits result parameters. -var RecvsParams = [2]func(*Type) []*Field{ - (*Type).Recvs, (*Type).Params, -} - -// ParamsResults is like RecvsParamsResults, but omits receiver parameters. -var ParamsResults = [2]func(*Type) []*Field{ - (*Type).Params, (*Type).Results, -} - // Key returns the key type of map type t. func (t *Type) Key() *Type { t.wantEtype(TMAP) @@ -1221,22 +1219,24 @@ func (t *Type) cmp(x *Type) Cmp { return CMPeq case TFUNC: - for _, f := range &RecvsParamsResults { - // Loop over fields in structs, ignoring argument names. - tfs := f(t) - xfs := f(x) - for i := 0; i < len(tfs) && i < len(xfs); i++ { - ta := tfs[i] - tb := xfs[i] - if ta.IsDDD() != tb.IsDDD() { - return cmpForNe(!ta.IsDDD()) - } - if c := ta.Type.cmp(tb.Type); c != CMPeq { - return c - } - } - if len(tfs) != len(xfs) { - return cmpForNe(len(tfs) < len(xfs)) + if tn, xn := t.NumRecvs(), x.NumRecvs(); tn != xn { + return cmpForNe(tn < xn) + } + if tn, xn := t.NumParams(), x.NumParams(); tn != xn { + return cmpForNe(tn < xn) + } + if tn, xn := t.NumResults(), x.NumResults(); tn != xn { + return cmpForNe(tn < xn) + } + if tv, xv := t.IsVariadic(), x.IsVariadic(); tv != xv { + return cmpForNe(!tv) + } + + tfs := t.RecvParamsResults() + xfs := x.RecvParamsResults() + for i, tf := range tfs { + if c := tf.Type.cmp(xfs[i].Type); c != CMPeq { + return c } } return CMPeq