From: Matthew Dempsky Date: Tue, 3 May 2022 22:29:43 +0000 (-0700) Subject: cmd/compile: construct ir.FuncType within typecheck.DeclFunc X-Git-Tag: go1.19beta1~405 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5073c1c7407ad5f23e54cc0a6410ffbde23758bb;p=gostls13.git cmd/compile: construct ir.FuncType within typecheck.DeclFunc Currently all typecheck.DeclFunc callers already construct a fresh new ir.FuncType, which is the last type expression kind that we represent in IR. This CL pushes all of the ir.FuncType construction down into typecheck.DeclFunc. The next CL will simplify the internals so that we can get rid of ir.FuncType altogether. Change-Id: I221ed324f157eb38bb57c8886609f53cc4fd99fe Reviewed-on: https://go-review.googlesource.com/c/go/+/403848 TryBot-Result: Gopher Robot Reviewed-by: David Chase Reviewed-by: Cuong Manh Le Run-TryBot: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/pkginit/init.go b/src/cmd/compile/internal/pkginit/init.go index d94482a962..9cd3e74abe 100644 --- a/src/cmd/compile/internal/pkginit/init.go +++ b/src/cmd/compile/internal/pkginit/init.go @@ -30,7 +30,7 @@ func MakeInit() { // Make a function that contains all the initialization statements. base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt initializers := typecheck.Lookup("init") - fn := typecheck.DeclFunc(initializers, ir.NewFuncType(base.Pos, nil, nil, nil)) + fn := typecheck.DeclFunc(initializers, nil, nil, nil) for _, dcl := range typecheck.InitTodoFunc.Dcl { dcl.Curfn = fn } diff --git a/src/cmd/compile/internal/reflectdata/alg.go b/src/cmd/compile/internal/reflectdata/alg.go index 0ed3eb2875..8f0c4e8bc3 100644 --- a/src/cmd/compile/internal/reflectdata/alg.go +++ b/src/cmd/compile/internal/reflectdata/alg.go @@ -133,11 +133,10 @@ func genhash(t *types.Type) *obj.LSym { ir.NewField(base.Pos, typecheck.Lookup("h"), types.Types[types.TUINTPTR]), } results := []*ir.Field{ir.NewField(base.Pos, nil, types.Types[types.TUINTPTR])} - tfn := ir.NewFuncType(base.Pos, nil, args, results) - fn := typecheck.DeclFunc(sym, tfn) - np := ir.AsNode(tfn.Type().Params().Field(0).Nname) - nh := ir.AsNode(tfn.Type().Params().Field(1).Nname) + fn := typecheck.DeclFunc(sym, nil, args, results) + np := ir.AsNode(fn.Type().Params().Field(0).Nname) + nh := ir.AsNode(fn.Type().Params().Field(1).Nname) switch t.Kind() { case types.TARRAY: @@ -358,14 +357,13 @@ func geneq(t *types.Type) *obj.LSym { typecheck.DeclContext = ir.PEXTERN // func sym(p, q *T) bool - tfn := ir.NewFuncType(base.Pos, nil, + fn := typecheck.DeclFunc(sym, nil, []*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("p"), types.NewPtr(t)), ir.NewField(base.Pos, typecheck.Lookup("q"), types.NewPtr(t))}, - []*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("r"), types.Types[types.TBOOL])}) - - fn := typecheck.DeclFunc(sym, tfn) - np := ir.AsNode(tfn.Type().Params().Field(0).Nname) - nq := ir.AsNode(tfn.Type().Params().Field(1).Nname) - nr := ir.AsNode(tfn.Type().Results().Field(0).Nname) + []*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("r"), types.Types[types.TBOOL])}, + ) + np := ir.AsNode(fn.Type().Params().Field(0).Nname) + nq := ir.AsNode(fn.Type().Params().Field(1).Nname) + nr := ir.AsNode(fn.Type().Results().Field(0).Nname) // Label to jump to if an equality test fails. neq := typecheck.AutoLabel(".neq") diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index 1804eaefe6..e92b5a6846 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -1855,18 +1855,16 @@ func methodWrapper(rcvr *types.Type, method *types.Field, forItab bool) *obj.LSy base.Pos = base.AutogeneratedPos typecheck.DeclContext = ir.PEXTERN - tfn := ir.NewFuncType(base.Pos, - ir.NewField(base.Pos, typecheck.Lookup(".this"), rcvr), - typecheck.NewFuncParams(method.Type.Params(), true), - typecheck.NewFuncParams(method.Type.Results(), false)) - // TODO(austin): SelectorExpr may have created one or more // ir.Names for these already with a nil Func field. We should // consolidate these and always attach a Func to the Name. - fn := typecheck.DeclFunc(newnam, tfn) + fn := typecheck.DeclFunc(newnam, ir.NewField(base.Pos, typecheck.Lookup(".this"), rcvr), + typecheck.NewFuncParams(method.Type.Params(), true), + typecheck.NewFuncParams(method.Type.Results(), false)) + fn.SetDupok(true) - nthis := ir.AsNode(tfn.Type().Recv().Nname) + nthis := ir.AsNode(fn.Type().Recv().Nname) indirect := rcvr.IsPtr() && rcvr.Elem() == methodrcvr @@ -1890,8 +1888,8 @@ func methodWrapper(rcvr *types.Type, method *types.Field, forItab bool) *obj.LSy // value for that function. if !base.Flag.Cfg.Instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !types.IsInterfaceMethod(method.Type) && !(base.Ctxt.Arch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) && !generic { call := ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil) - call.Args = ir.ParamNames(tfn.Type()) - call.IsDDD = tfn.Type().IsVariadic() + call.Args = ir.ParamNames(fn.Type()) + call.IsDDD = fn.Type().IsVariadic() fn.Body.Append(ir.NewTailCallStmt(base.Pos, call)) } else { fn.SetWrapper(true) // ignore frame for panic+recover matching @@ -1927,7 +1925,7 @@ func methodWrapper(rcvr *types.Type, method *types.Field, forItab bool) *obj.LSy } else { args = append(args, dot.X) } - args = append(args, ir.ParamNames(tfn.Type())...) + args = append(args, ir.ParamNames(fn.Type())...) // Target method uses shaped names. targs2 := make([]*types.Type, len(targs)) @@ -1958,9 +1956,9 @@ func methodWrapper(rcvr *types.Type, method *types.Field, forItab bool) *obj.LSy method.Nname = fn.Nname } else { call = ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil) - call.Args = ir.ParamNames(tfn.Type()) + call.Args = ir.ParamNames(fn.Type()) } - call.IsDDD = tfn.Type().IsVariadic() + call.IsDDD = fn.Type().IsVariadic() if method.Type.NumResults() > 0 { ret := ir.NewReturnStmt(base.Pos, nil) ret.Results = []ir.Node{call} diff --git a/src/cmd/compile/internal/ssagen/abi.go b/src/cmd/compile/internal/ssagen/abi.go index 3d3cba7dd3..e14f080a85 100644 --- a/src/cmd/compile/internal/ssagen/abi.go +++ b/src/cmd/compile/internal/ssagen/abi.go @@ -284,15 +284,10 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { panic("makeABIWrapper support for wrapping methods not implemented") } - // Manufacture a new func type to use for the wrapper. - var noReceiver *ir.Field - tfn := ir.NewFuncType(base.Pos, - noReceiver, + // Reuse f's types.Sym to create a new ODCLFUNC/function. + fn := typecheck.DeclFunc(f.Nname.Sym(), nil, typecheck.NewFuncParams(ft.Params(), true), typecheck.NewFuncParams(ft.Results(), false)) - - // Reuse f's types.Sym to create a new ODCLFUNC/function. - fn := typecheck.DeclFunc(f.Nname.Sym(), tfn) fn.ABI = wrapperABI fn.SetABIWrapper(true) @@ -334,7 +329,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { // to allocate any stack space). Doing this will require some // extra work in typecheck/walk/ssa, might want to add a new node // OTAILCALL or something to this effect. - tailcall := tfn.Type().NumResults() == 0 && tfn.Type().NumParams() == 0 && tfn.Type().NumRecvs() == 0 + tailcall := fn.Type().NumResults() == 0 && fn.Type().NumParams() == 0 && fn.Type().NumRecvs() == 0 if base.Ctxt.Arch.Name == "ppc64le" && base.Ctxt.Flag_dynlink { // cannot tailcall on PPC64 with dynamic linking, as we need // to restore R2 after call. @@ -348,12 +343,12 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { var tail ir.Node call := ir.NewCallExpr(base.Pos, ir.OCALL, f.Nname, nil) - call.Args = ir.ParamNames(tfn.Type()) - call.IsDDD = tfn.Type().IsVariadic() + call.Args = ir.ParamNames(fn.Type()) + call.IsDDD = fn.Type().IsVariadic() tail = call if tailcall { tail = ir.NewTailCallStmt(base.Pos, call) - } else if tfn.Type().NumResults() > 0 { + } else if fn.Type().NumResults() > 0 { n := ir.NewReturnStmt(base.Pos, nil) n.Results = []ir.Node{call} tail = n diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go index 93fcf236d8..14ff45b827 100644 --- a/src/cmd/compile/internal/typecheck/dcl.go +++ b/src/cmd/compile/internal/typecheck/dcl.go @@ -16,17 +16,13 @@ import ( var DeclContext ir.Class = ir.PEXTERN // PEXTERN/PAUTO -func DeclFunc(sym *types.Sym, tfn *ir.FuncType) *ir.Func { - if tfn.Op() != ir.OTFUNC { - base.Fatalf("expected OTFUNC node, got %v", tfn) - } - +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) fn.Nname.Func = fn fn.Nname.Defn = fn ir.MarkFunc(fn.Nname) - StartFuncBody(fn, tfn) + StartFuncBody(fn, recv, params, results) return fn } @@ -95,7 +91,7 @@ func Export(n *ir.Name) { // and declare the arguments. // called in extern-declaration context // returns in auto-declaration context. -func StartFuncBody(fn *ir.Func, tfn *ir.FuncType) { +func StartFuncBody(fn *ir.Func, recv *ir.Field, params, results []*ir.Field) { // change the declaration context from extern to auto funcStack = append(funcStack, funcStackEnt{ir.CurFunc, DeclContext}) ir.CurFunc = fn @@ -103,6 +99,7 @@ func StartFuncBody(fn *ir.Func, tfn *ir.FuncType) { types.Markdcl() + tfn := ir.NewFuncType(base.Pos, recv, params, results) funcargs(tfn) tfn = tcFuncType(tfn) diff --git a/src/cmd/compile/internal/walk/closure.go b/src/cmd/compile/internal/walk/closure.go index ee9b24d09d..590c9a3ad4 100644 --- a/src/cmd/compile/internal/walk/closure.go +++ b/src/cmd/compile/internal/walk/closure.go @@ -237,11 +237,9 @@ func methodValueWrapper(dot *ir.SelectorExpr) *ir.Name { base.Pos = base.AutogeneratedPos - tfn := ir.NewFuncType(base.Pos, nil, + fn := typecheck.DeclFunc(sym, nil, typecheck.NewFuncParams(t0.Params(), true), typecheck.NewFuncParams(t0.Results(), false)) - - fn := typecheck.DeclFunc(sym, tfn) fn.SetDupok(true) fn.SetWrapper(true) @@ -249,8 +247,8 @@ func methodValueWrapper(dot *ir.SelectorExpr) *ir.Name { ptr := ir.NewHiddenParam(base.Pos, fn, typecheck.Lookup(".this"), rcvrtype) call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil) - call.Args = ir.ParamNames(tfn.Type()) - call.IsDDD = tfn.Type().IsVariadic() + call.Args = ir.ParamNames(fn.Type()) + call.IsDDD = fn.Type().IsVariadic() var body ir.Node = call if t0.NumResults() != 0 {