1
0
mirror of https://github.com/golang/go synced 2024-09-29 12:14:28 -06:00

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 <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2022-05-03 15:29:43 -07:00
parent cce0064399
commit 5073c1c740
6 changed files with 33 additions and 47 deletions

View File

@ -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
}

View File

@ -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")

View File

@ -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}

View File

@ -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

View File

@ -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)

View File

@ -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 {