From: Matthew Dempsky Date: Thu, 17 Aug 2023 02:45:12 +0000 (-0700) Subject: cmd/compile: cleanup Func construction X-Git-Tag: go1.22rc1~1236 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4e411e7bc44378422fa52f478927d9f71c39f385;p=gostls13.git cmd/compile: cleanup Func construction This CL moves more common Func-setup logic into ir.NewFunc. In particular, it now handles constructing the Name and wiring them together, setting the Typecheck bit, and setting Sym.Func. Relatedly, this CL also extends typecheck.DeclFunc to append the function to typecheck.Target.Funcs, so that callers no longer need to do this. Change-Id: Ifa0aded8df0517188eb295d0dccc107af85f1e8a Reviewed-on: https://go-review.googlesource.com/c/go/+/520338 TryBot-Result: Gopher Robot Reviewed-by: Cuong Manh Le Auto-Submit: Matthew Dempsky Reviewed-by: Dmitri Shuralyov Run-TryBot: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go index 908d6ca347..19244fbe7f 100644 --- a/src/cmd/compile/internal/inline/inl.go +++ b/src/cmd/compile/internal/inline/inl.go @@ -818,9 +818,8 @@ func inlcopy(n ir.Node) ir.Node { // x.Func.Nname.Ntype, x.Func.Dcl, x.Func.ClosureVars, and // x.Func.Body for iexport and local inlining. oldfn := x.Func - newfn := ir.NewFunc(oldfn.Pos()) + newfn := ir.NewFunc(oldfn.Pos(), oldfn.Nname.Pos(), oldfn.Nname.Sym(), oldfn.Nname.Type()) m.(*ir.ClosureExpr).Func = newfn - newfn.Nname = ir.NewNameAt(oldfn.Nname.Pos(), oldfn.Nname.Sym(), oldfn.Nname.Type()) // XXX OK to share fn.Type() ?? newfn.Body = inlcopylist(oldfn.Body) // Make shallow copy of the Dcl and ClosureVar slices diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go index 406c614d19..7efc71d2c7 100644 --- a/src/cmd/compile/internal/ir/func.go +++ b/src/cmd/compile/internal/ir/func.go @@ -147,14 +147,29 @@ type WasmImport struct { Name string } -func NewFunc(pos src.XPos) *Func { - f := new(Func) - f.pos = pos - f.op = ODCLFUNC +// NewFunc returns a new Func with the given name and type. +// +// fpos is the position of the "func" token, and npos is the position +// of the name identifier. +// +// TODO(mdempsky): I suspect there's no need for separate fpos and +// npos. +func NewFunc(fpos, npos src.XPos, sym *types.Sym, typ *types.Type) *Func { + name := NewNameAt(npos, sym, typ) + name.Class = PFUNC + sym.SetFunc(true) + + fn := &Func{Nname: name} + fn.pos = fpos + fn.op = ODCLFUNC // Most functions are ABIInternal. The importer or symabis // pass may override this. - f.ABI = obj.ABIInternal - return f + fn.ABI = obj.ABIInternal + fn.SetTypecheck(1) + + name.Func = fn + + return fn } func (f *Func) isStmt() {} @@ -318,16 +333,6 @@ func FuncSymName(s *types.Sym) string { return s.Name + "·f" } -// MarkFunc marks a node as a function. -func MarkFunc(n *Name) { - if n.Op() != ONAME || n.Class != Pxxx { - base.FatalfAt(n.Pos(), "expected ONAME/Pxxx node, got %v (%v/%v)", n, n.Op(), n.Class) - } - - n.Class = PFUNC - n.Sym().SetFunc(true) -} - // ClosureDebugRuntimeCheck applies boilerplate checks for debug flags // and compiling runtime. func ClosureDebugRuntimeCheck(clo *ClosureExpr) { @@ -402,24 +407,17 @@ func closureName(outerfn *Func, pos src.XPos) *types.Sym { // outerfn is the enclosing function, if any. The returned function is // appending to pkg.Funcs. func NewClosureFunc(fpos, cpos src.XPos, typ *types.Type, outerfn *Func, pkg *Package) *Func { - fn := NewFunc(fpos) + fn := NewFunc(fpos, fpos, closureName(outerfn, cpos), typ) fn.SetIsHiddenClosure(outerfn != nil) - name := NewNameAt(fpos, closureName(outerfn, cpos), typ) - MarkFunc(name) - name.Func = fn - name.Defn = fn - fn.Nname = name - clo := &ClosureExpr{Func: fn} clo.op = OCLOSURE clo.pos = cpos - fn.OClosure = clo - - fn.SetTypecheck(1) clo.SetType(typ) clo.SetTypecheck(1) + fn.OClosure = clo + fn.Nname.Defn = fn pkg.Funcs = append(pkg.Funcs, fn) return fn diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index d71a1fc5fa..59b10b3b33 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -750,12 +750,22 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Typ if sym.Name == "init" { sym = Renameinit() } - name := do(ir.ONAME, true) - setType(name, r.signature(nil)) - name.Func = ir.NewFunc(r.pos()) - name.Func.Nname = name - name.Func.SetTypecheck(1) + npos := r.pos() + setBasePos(npos) + r.typeParamNames() + typ := r.signature(nil) + fpos := r.pos() + + fn := ir.NewFunc(fpos, npos, sym, typ) + name := fn.Nname + if !sym.IsBlank() { + if sym.Def != nil { + base.FatalfAt(name.Pos(), "already have a definition for %v", name) + } + assert(sym.Def == nil) + sym.Def = name + } if r.hasTypeParams() { name.Func.SetDupok(true) @@ -990,17 +1000,15 @@ func (r *reader) typeParamNames() { func (r *reader) method(rext *reader) *types.Field { r.Sync(pkgbits.SyncMethod) - pos := r.pos() + npos := r.pos() _, sym := r.selector() r.typeParamNames() _, recv := r.param() typ := r.signature(recv) - name := ir.NewNameAt(pos, ir.MethodSym(recv.Type, sym), typ) - - name.Func = ir.NewFunc(r.pos()) - name.Func.Nname = name - name.Func.SetTypecheck(1) + fpos := r.pos() + fn := ir.NewFunc(fpos, npos, ir.MethodSym(recv.Type, sym), typ) + name := fn.Nname if r.hasTypeParams() { name.Func.SetDupok(true) @@ -1062,9 +1070,6 @@ func (dict *readerDict) hasTypeParams() bool { func (r *reader) funcExt(name *ir.Name, method *types.Sym) { r.Sync(pkgbits.SyncFuncExt) - name.Class = 0 // so MarkFunc doesn't complain - ir.MarkFunc(name) - fn := name.Func // XXX: Workaround because linker doesn't know how to copy Pos. @@ -3447,9 +3452,7 @@ func unifiedInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.Inlined r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody) // TODO(mdempsky): This still feels clumsy. Can we do better? - tmpfn := ir.NewFunc(fn.Pos()) - tmpfn.Nname = ir.NewNameAt(fn.Nname.Pos(), callerfn.Sym(), fn.Type()) - tmpfn.SetTypecheck(1) + tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), callerfn.Sym(), fn.Type()) tmpfn.Closgen = callerfn.Closgen defer func() { callerfn.Closgen = tmpfn.Closgen }() @@ -3623,9 +3626,7 @@ func expandInline(fn *ir.Func, pri pkgReaderIndex) { fndcls := len(fn.Dcl) topdcls := len(typecheck.Target.Funcs) - tmpfn := ir.NewFunc(fn.Pos()) - tmpfn.Nname = ir.NewNameAt(fn.Nname.Pos(), fn.Sym(), fn.Type()) - tmpfn.SetTypecheck(1) + tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), fn.Sym(), fn.Type()) tmpfn.ClosureVars = fn.ClosureVars { @@ -3860,18 +3861,9 @@ func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Packa func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func { sig := newWrapperType(wrapper, method) - fn := ir.NewFunc(pos) + fn := ir.NewFunc(pos, pos, sym, sig) fn.SetDupok(true) // TODO(mdempsky): Leave unset for local, non-generic wrappers? - name := ir.NewNameAt(pos, sym, sig) - ir.MarkFunc(name) - name.Func = fn - name.Defn = fn - fn.Nname = name - - setType(name, sig) - fn.SetTypecheck(1) - // TODO(mdempsky): De-duplicate with similar logic in funcargs. defParams := func(class ir.Class, params *types.Type) { for _, param := range params.FieldSlice() { @@ -3909,6 +3901,7 @@ func finishWrapperFunc(fn *ir.Func, target *ir.Package) { } }) + fn.Nname.Defn = fn target.Funcs = append(target.Funcs, fn) } diff --git a/src/cmd/compile/internal/pkginit/init.go b/src/cmd/compile/internal/pkginit/init.go index 4a4bc1f399..4636c740e2 100644 --- a/src/cmd/compile/internal/pkginit/init.go +++ b/src/cmd/compile/internal/pkginit/init.go @@ -39,8 +39,7 @@ func MakeInit() { fn.SetIsPackageInit(true) // Outline (if legal/profitable) global map inits. - newfuncs := []*ir.Func{} - nf, newfuncs = staticinit.OutlineMapInits(nf) + nf, newfuncs := staticinit.OutlineMapInits(nf) // Suppress useless "can inline" diagnostics. // Init functions are only called dynamically. @@ -55,17 +54,10 @@ func MakeInit() { ir.WithFunc(fn, func() { typecheck.Stmts(nf) }) - typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn) if base.Debug.WrapGlobalMapDbg > 1 { fmt.Fprintf(os.Stderr, "=-= len(newfuncs) is %d for %v\n", len(newfuncs), fn) } - for _, nfn := range newfuncs { - if base.Debug.WrapGlobalMapDbg > 1 { - fmt.Fprintf(os.Stderr, "=-= add to target.decls %v\n", nfn) - } - typecheck.Target.Funcs = append(typecheck.Target.Funcs, nfn) - } // Prepend to Inits, so it runs first, before any user-declared init // functions. @@ -131,13 +123,14 @@ func MakeTask() { // Call runtime.asanregisterglobals function to poison redzones. // runtime.asanregisterglobals(unsafe.Pointer(&globals[0]), ni) - asanf := ir.NewNameAt(base.Pos, ir.Pkgs.Runtime.Lookup("asanregisterglobals"), + // + // TODO(mdempsky): Move into typecheck builtins. + asanf := ir.NewFunc(src.NoXPos, src.NoXPos, ir.Pkgs.Runtime.Lookup("asanregisterglobals"), types.NewSignature(nil, []*types.Field{ types.NewField(base.Pos, nil, types.Types[types.TUNSAFEPTR]), types.NewField(base.Pos, nil, types.Types[types.TUINTPTR]), }, nil)) - ir.MarkFunc(asanf) - asancall := ir.NewCallExpr(base.Pos, ir.OCALL, asanf, nil) + asancall := ir.NewCallExpr(base.Pos, ir.OCALL, asanf.Nname, nil) asancall.Args.Append(typecheck.ConvNop(typecheck.NodAddr( ir.NewIndexExpr(base.Pos, globals, ir.NewInt(base.Pos, 0))), types.Types[types.TUNSAFEPTR])) asancall.Args.Append(typecheck.DefaultLit(ir.NewInt(base.Pos, int64(ni)), types.Types[types.TUINTPTR])) @@ -148,7 +141,6 @@ func MakeTask() { typecheck.Stmts(fnInit.Body) ir.CurFunc = nil - typecheck.Target.Funcs = append(typecheck.Target.Funcs, fnInit) typecheck.Target.Inits = append(typecheck.Target.Inits, fnInit) } } diff --git a/src/cmd/compile/internal/reflectdata/alg.go b/src/cmd/compile/internal/reflectdata/alg.go index a561c1e8b5..edfd92fb40 100644 --- a/src/cmd/compile/internal/reflectdata/alg.go +++ b/src/cmd/compile/internal/reflectdata/alg.go @@ -243,7 +243,6 @@ func hashFunc(t *types.Type) *ir.Func { }) fn.SetNilCheckDisabled(true) - typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn) return fn } @@ -632,7 +631,6 @@ func eqFunc(t *types.Type) *ir.Func { // neither of which can be nil, and our comparisons // are shallow. fn.SetNilCheckDisabled(true) - typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn) return fn } diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go index 53a5b3070b..f02cfd2cd4 100644 --- a/src/cmd/compile/internal/ssa/export_test.go +++ b/src/cmd/compile/internal/ssa/export_test.go @@ -55,8 +55,7 @@ type Conf struct { func (c *Conf) Frontend() Frontend { if c.fe == nil { - f := ir.NewFunc(src.NoXPos) - f.Nname = ir.NewNameAt(f.Pos(), &types.Sym{ + f := ir.NewFunc(src.NoXPos, src.NoXPos, &types.Sym{ Pkg: types.NewPkg("my/import/path", "path"), Name: "function", }, nil) diff --git a/src/cmd/compile/internal/ssagen/abi.go b/src/cmd/compile/internal/ssagen/abi.go index f01563e776..a1ed4c124c 100644 --- a/src/cmd/compile/internal/ssagen/abi.go +++ b/src/cmd/compile/internal/ssagen/abi.go @@ -327,8 +327,6 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { ir.CurFunc = fn typecheck.Stmts(fn.Body) - typecheck.Target.Funcs = append(typecheck.Target.Funcs, fn) - // Restore previous context. base.Pos = savepos typecheck.DeclContext = savedclcontext diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go index 9da2c8f324..d0783760f6 100644 --- a/src/cmd/compile/internal/typecheck/dcl.go +++ b/src/cmd/compile/internal/typecheck/dcl.go @@ -18,11 +18,7 @@ import ( var DeclContext ir.Class = ir.PEXTERN // PEXTERN/PAUTO func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.Func { - fn := ir.NewFunc(base.Pos) - fn.Nname = ir.NewNameAt(base.Pos, sym, nil) - fn.Nname.Func = fn - fn.Nname.Defn = fn - ir.MarkFunc(fn.Nname) + fn := ir.NewFunc(base.Pos, base.Pos, sym, nil) StartFuncBody(fn) var recv1 *types.Field @@ -32,9 +28,12 @@ func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.F typ := types.NewSignature(recv1, declareParams(fn, ir.PPARAM, params), declareParams(fn, ir.PPARAMOUT, results)) checkdupfields("argument", typ.Recvs().FieldSlice(), typ.Params().FieldSlice(), typ.Results().FieldSlice()) + fn.Nname.SetType(typ) fn.Nname.SetTypecheck(1) - fn.SetTypecheck(1) + + fn.Nname.Defn = fn + Target.Funcs = append(Target.Funcs, fn) return fn } diff --git a/src/cmd/compile/internal/typecheck/export.go b/src/cmd/compile/internal/typecheck/export.go index 40cf451d6a..585c1b78c2 100644 --- a/src/cmd/compile/internal/typecheck/export.go +++ b/src/cmd/compile/internal/typecheck/export.go @@ -12,38 +12,22 @@ import ( ) // importfunc declares symbol s as an imported function with type t. -// ipkg is the package being imported. -func importfunc(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name { - n := importobj(pos, s, ir.ONAME, ir.PFUNC, t) - n.Func = ir.NewFunc(pos) - n.Func.Nname = n - return n +func importfunc(s *types.Sym, t *types.Type) { + fn := ir.NewFunc(src.NoXPos, src.NoXPos, s, t) + importsym(fn.Nname) } -// importobj declares symbol s as an imported object representable by op. -// ipkg is the package being imported. -func importobj(pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Name { - n := importsym(pos, s, op, ctxt) - n.SetType(t) - if ctxt == ir.PFUNC { - n.Sym().SetFunc(true) - } - return n +// importvar declares symbol s as an imported variable with type t. +func importvar(s *types.Sym, t *types.Type) { + n := ir.NewNameAt(src.NoXPos, s, t) + n.Class = ir.PEXTERN + importsym(n) } -func importsym(pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class) *ir.Name { - if n := s.PkgDef(); n != nil { - base.Fatalf("importsym of symbol that already exists: %v", n) +func importsym(name *ir.Name) { + sym := name.Sym() + if sym.Def != nil { + base.Fatalf("importsym of symbol that already exists: %v", sym.Def) } - - n := ir.NewDeclNameAt(pos, op, s) - n.Class = ctxt // TODO(mdempsky): Move this into NewDeclNameAt too? - s.SetPkgDef(n) - return n -} - -// importvar declares symbol s as an imported variable with type t. -// ipkg is the package being imported. -func importvar(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name { - return importobj(pos, s, ir.ONAME, ir.PEXTERN, t) + sym.Def = name } diff --git a/src/cmd/compile/internal/typecheck/syms.go b/src/cmd/compile/internal/typecheck/syms.go index 55160e47f0..4f75129998 100644 --- a/src/cmd/compile/internal/typecheck/syms.go +++ b/src/cmd/compile/internal/typecheck/syms.go @@ -9,7 +9,6 @@ import ( "cmd/compile/internal/ir" "cmd/compile/internal/types" "cmd/internal/obj" - "cmd/internal/src" ) func LookupRuntime(name string) *ir.Name { @@ -74,9 +73,9 @@ func InitRuntime() { typ := typs[d.typ] switch d.tag { case funcTag: - importfunc(src.NoXPos, sym, typ) + importfunc(sym, typ) case varTag: - importvar(src.NoXPos, sym, typ) + importvar(sym, typ) default: base.Fatalf("unhandled declaration tag %v", d.tag) } @@ -110,9 +109,9 @@ func InitCoverage() { typ := typs[d.typ] switch d.tag { case funcTag: - importfunc(src.NoXPos, sym, typ) + importfunc(sym, typ) case varTag: - importvar(src.NoXPos, sym, typ) + importvar(sym, typ) default: base.Fatalf("unhandled declaration tag %v", d.tag) } diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go index a36acb9300..2ab812e548 100644 --- a/src/cmd/compile/internal/typecheck/typecheck.go +++ b/src/cmd/compile/internal/typecheck/typecheck.go @@ -19,7 +19,7 @@ import ( // Function collecting autotmps generated during typechecking, // to be included in the package-level init function. -var InitTodoFunc = ir.NewFunc(base.Pos) +var InitTodoFunc = ir.NewFunc(base.Pos, base.Pos, Lookup("$InitTodo"), types.NewSignature(nil, nil, nil)) var ( NeedRuntimeType = func(*types.Type) {} diff --git a/src/cmd/compile/internal/types/scope.go b/src/cmd/compile/internal/types/scope.go deleted file mode 100644 index 438a3f9a47..0000000000 --- a/src/cmd/compile/internal/types/scope.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -// PkgDef returns the definition associated with s at package scope. -func (s *Sym) PkgDef() Object { return s.Def } - -// SetPkgDef sets the definition associated with s at package scope. -func (s *Sym) SetPkgDef(n Object) { s.Def = n }