diff options
38 files changed, 1255 insertions, 1261 deletions
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index bcf992ba4b..d21b0d492c 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -147,10 +147,10 @@ func genhash(t *types.Type) *obj.LSym { // func sym(p *T, h uintptr) uintptr args := []*ir.Field{ - namedfield("p", types.NewPtr(t)), - namedfield("h", types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, lookup("p"), nil, types.NewPtr(t)), + ir.NewField(base.Pos, lookup("h"), nil, types.Types[types.TUINTPTR]), } - results := []*ir.Field{anonfield(types.Types[types.TUINTPTR])} + results := []*ir.Field{ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR])} tfn := ir.NewFuncType(base.Pos, nil, args, results) fn := dclfunc(sym, tfn) @@ -166,9 +166,9 @@ func genhash(t *types.Type) *obj.LSym { // for i := 0; i < nelem; i++ ni := temp(types.Types[types.TINT]) - init := ir.NewAssignStmt(base.Pos, ni, nodintconst(0)) - cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, nodintconst(t.NumElem())) - post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, nodintconst(1))) + init := ir.NewAssignStmt(base.Pos, ni, ir.NewInt(0)) + cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, ir.NewInt(t.NumElem())) + post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, ir.NewInt(1))) loop := ir.NewForStmt(base.Pos, nil, cond, post, nil) loop.PtrInit().Append(init) @@ -219,7 +219,7 @@ func genhash(t *types.Type) *obj.LSym { na := nodAddr(nx) call.Args.Append(na) call.Args.Append(nh) - call.Args.Append(nodintconst(size)) + call.Args.Append(ir.NewInt(size)) fn.Body.Append(ir.NewAssignStmt(base.Pos, nh, call)) i = next @@ -239,9 +239,9 @@ func genhash(t *types.Type) *obj.LSym { fn.SetDupok(true) typecheckFunc(fn) - Curfn = fn + ir.CurFunc = fn typecheckslice(fn.Body, ctxStmt) - Curfn = nil + ir.CurFunc = nil if base.Debug.DclStack != 0 { types.CheckDclstack() @@ -285,12 +285,12 @@ func hashfor(t *types.Type) ir.Node { } n := NewName(sym) - setNodeNameFunc(n) + ir.MarkFunc(n) n.SetType(functype(nil, []*ir.Field{ - anonfield(types.NewPtr(t)), - anonfield(types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, nil, nil, types.NewPtr(t)), + ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]), }, []*ir.Field{ - anonfield(types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]), })) return n } @@ -376,8 +376,8 @@ func geneq(t *types.Type) *obj.LSym { // func sym(p, q *T) bool tfn := ir.NewFuncType(base.Pos, nil, - []*ir.Field{namedfield("p", types.NewPtr(t)), namedfield("q", types.NewPtr(t))}, - []*ir.Field{namedfield("r", types.Types[types.TBOOL])}) + []*ir.Field{ir.NewField(base.Pos, lookup("p"), nil, types.NewPtr(t)), ir.NewField(base.Pos, lookup("q"), nil, types.NewPtr(t))}, + []*ir.Field{ir.NewField(base.Pos, lookup("r"), nil, types.Types[types.TBOOL])}) fn := dclfunc(sym, tfn) np := ir.AsNode(tfn.Type().Params().Field(0).Nname) @@ -440,20 +440,20 @@ func geneq(t *types.Type) *obj.LSym { // Generate a series of checks. for i := int64(0); i < nelem; i++ { // if check {} else { goto neq } - nif := ir.NewIfStmt(base.Pos, checkIdx(nodintconst(i)), nil, nil) + nif := ir.NewIfStmt(base.Pos, checkIdx(ir.NewInt(i)), nil, nil) nif.Else.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, neq)) fn.Body.Append(nif) } if last { - fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, checkIdx(nodintconst(nelem)))) + fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, checkIdx(ir.NewInt(nelem)))) } } else { // Generate a for loop. // for i := 0; i < nelem; i++ i := temp(types.Types[types.TINT]) - init := ir.NewAssignStmt(base.Pos, i, nodintconst(0)) - cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, nodintconst(nelem)) - post := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, nodintconst(1))) + init := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0)) + cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(nelem)) + post := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1))) loop := ir.NewForStmt(base.Pos, nil, cond, post, nil) loop.PtrInit().Append(init) // if eq(pi, qi) {} else { goto neq } @@ -462,7 +462,7 @@ func geneq(t *types.Type) *obj.LSym { loop.Body.Append(nif) fn.Body.Append(loop) if last { - fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, nodbool(true))) + fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(true))) } } } @@ -572,7 +572,7 @@ func geneq(t *types.Type) *obj.LSym { } if len(flatConds) == 0 { - fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, nodbool(true))) + fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(true))) } else { for _, c := range flatConds[:len(flatConds)-1] { // if cond {} else { goto neq } @@ -594,7 +594,7 @@ func geneq(t *types.Type) *obj.LSym { // r = false // return (or goto ret) fn.Body.Append(ir.NewLabelStmt(base.Pos, neq)) - fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, nodbool(false))) + fn.Body.Append(ir.NewAssignStmt(base.Pos, nr, ir.NewBool(false))) if EqCanPanic(t) || anyCall(fn) { // Epilogue is large, so share it with the equal case. fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.OGOTO, ret)) @@ -615,9 +615,9 @@ func geneq(t *types.Type) *obj.LSym { fn.SetDupok(true) typecheckFunc(fn) - Curfn = fn + ir.CurFunc = fn typecheckslice(fn.Body, ctxStmt) - Curfn = nil + ir.CurFunc = nil if base.Debug.DclStack != 0 { types.CheckDclstack() @@ -726,7 +726,7 @@ func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node { call.Args.Append(nx) call.Args.Append(ny) if needsize { - call.Args.Append(nodintconst(size)) + call.Args.Append(ir.NewInt(size)) } return call diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go index d3e3f9ade6..12c70fb6d4 100644 --- a/src/cmd/compile/internal/gc/builtin.go +++ b/src/cmd/compile/internal/gc/builtin.go @@ -3,6 +3,7 @@ package gc import ( + "cmd/compile/internal/base" "cmd/compile/internal/ir" "cmd/compile/internal/types" ) @@ -211,133 +212,133 @@ func runtimeTypes() []*types.Type { typs[1] = types.NewPtr(typs[0]) typs[2] = types.Types[types.TANY] typs[3] = types.NewPtr(typs[2]) - typs[4] = functype(nil, []*ir.Field{anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])}) + typs[4] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])}) typs[5] = types.Types[types.TUINTPTR] typs[6] = types.Types[types.TBOOL] typs[7] = types.Types[types.TUNSAFEPTR] - typs[8] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[7])}) + typs[8] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[6])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])}) typs[9] = functype(nil, nil, nil) typs[10] = types.Types[types.TINTER] - typs[11] = functype(nil, []*ir.Field{anonfield(typs[10])}, nil) + typs[11] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[10])}, nil) typs[12] = types.Types[types.TINT32] typs[13] = types.NewPtr(typs[12]) - typs[14] = functype(nil, []*ir.Field{anonfield(typs[13])}, []*ir.Field{anonfield(typs[10])}) + typs[14] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[13])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[10])}) typs[15] = types.Types[types.TINT] - typs[16] = functype(nil, []*ir.Field{anonfield(typs[15]), anonfield(typs[15])}, nil) + typs[16] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15])}, nil) typs[17] = types.Types[types.TUINT] - typs[18] = functype(nil, []*ir.Field{anonfield(typs[17]), anonfield(typs[15])}, nil) - typs[19] = functype(nil, []*ir.Field{anonfield(typs[6])}, nil) + typs[18] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[17]), ir.NewField(base.Pos, nil, nil, typs[15])}, nil) + typs[19] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}, nil) typs[20] = types.Types[types.TFLOAT64] - typs[21] = functype(nil, []*ir.Field{anonfield(typs[20])}, nil) + typs[21] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, nil) typs[22] = types.Types[types.TINT64] - typs[23] = functype(nil, []*ir.Field{anonfield(typs[22])}, nil) + typs[23] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])}, nil) typs[24] = types.Types[types.TUINT64] - typs[25] = functype(nil, []*ir.Field{anonfield(typs[24])}, nil) + typs[25] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])}, nil) typs[26] = types.Types[types.TCOMPLEX128] - typs[27] = functype(nil, []*ir.Field{anonfield(typs[26])}, nil) + typs[27] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[26])}, nil) typs[28] = types.Types[types.TSTRING] - typs[29] = functype(nil, []*ir.Field{anonfield(typs[28])}, nil) - typs[30] = functype(nil, []*ir.Field{anonfield(typs[2])}, nil) - typs[31] = functype(nil, []*ir.Field{anonfield(typs[5])}, nil) + typs[29] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}, nil) + typs[30] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])}, nil) + typs[31] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5])}, nil) typs[32] = types.NewArray(typs[0], 32) typs[33] = types.NewPtr(typs[32]) - typs[34] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])}) - typs[35] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])}) - typs[36] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])}) - typs[37] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])}) + typs[34] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) + typs[35] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) + typs[36] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) + typs[37] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) typs[38] = types.NewSlice(typs[28]) - typs[39] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[38])}, []*ir.Field{anonfield(typs[28])}) - typs[40] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])}) + typs[39] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[38])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) + typs[40] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])}) typs[41] = types.NewArray(typs[0], 4) typs[42] = types.NewPtr(typs[41]) - typs[43] = functype(nil, []*ir.Field{anonfield(typs[42]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[28])}) - typs[44] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])}) - typs[45] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])}) + typs[43] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[42]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) + typs[44] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) + typs[45] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) typs[46] = types.RuneType typs[47] = types.NewSlice(typs[46]) - typs[48] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[47])}, []*ir.Field{anonfield(typs[28])}) + typs[48] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[47])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}) typs[49] = types.NewSlice(typs[0]) - typs[50] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[49])}) + typs[50] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[33]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[49])}) typs[51] = types.NewArray(typs[46], 32) typs[52] = types.NewPtr(typs[51]) - typs[53] = functype(nil, []*ir.Field{anonfield(typs[52]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[47])}) - typs[54] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[15])}) - typs[55] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[46]), anonfield(typs[15])}) - typs[56] = functype(nil, []*ir.Field{anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])}) - typs[57] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2])}) - typs[58] = functype(nil, []*ir.Field{anonfield(typs[2])}, []*ir.Field{anonfield(typs[7])}) - typs[59] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[2])}) - typs[60] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2]), anonfield(typs[6])}) - typs[61] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil) - typs[62] = functype(nil, []*ir.Field{anonfield(typs[1])}, nil) + typs[53] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[52]), ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[47])}) + typs[54] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])}) + typs[55] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[46]), ir.NewField(base.Pos, nil, nil, typs[15])}) + typs[56] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[28])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])}) + typs[57] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])}) + typs[58] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])}) + typs[59] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2])}) + typs[60] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[2]), ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[61] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[1])}, nil) + typs[62] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1])}, nil) typs[63] = types.NewPtr(typs[5]) - typs[64] = functype(nil, []*ir.Field{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])}) + typs[64] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[63]), ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[7])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) typs[65] = types.Types[types.TUINT32] - typs[66] = functype(nil, nil, []*ir.Field{anonfield(typs[65])}) + typs[66] = functype(nil, nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65])}) typs[67] = types.NewMap(typs[2], typs[2]) - typs[68] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])}) - typs[69] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])}) - typs[70] = functype(nil, nil, []*ir.Field{anonfield(typs[67])}) - typs[71] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3])}) - typs[72] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3])}) - typs[73] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])}) - typs[74] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])}) - typs[75] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])}) - typs[76] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])}) - typs[77] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil) - typs[78] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil) - typs[79] = functype(nil, []*ir.Field{anonfield(typs[3])}, nil) - typs[80] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67])}, nil) + typs[68] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[22]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[67])}) + typs[69] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[67])}) + typs[70] = functype(nil, nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[67])}) + typs[71] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])}) + typs[72] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])}) + typs[73] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[1])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])}) + typs[74] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[75] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[2])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[76] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[1])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[77] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil) + typs[78] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67]), ir.NewField(base.Pos, nil, nil, typs[2])}, nil) + typs[79] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3])}, nil) + typs[80] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[67])}, nil) typs[81] = types.NewChan(typs[2], types.Cboth) - typs[82] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[81])}) - typs[83] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[81])}) + typs[82] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[81])}) + typs[83] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[81])}) typs[84] = types.NewChan(typs[2], types.Crecv) - typs[85] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, nil) - typs[86] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])}) + typs[85] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[84]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil) + typs[86] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[84]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) typs[87] = types.NewChan(typs[2], types.Csend) - typs[88] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, nil) + typs[88] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[87]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil) typs[89] = types.NewArray(typs[0], 3) - typs[90] = tostruct([]*ir.Field{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])}) - typs[91] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil) - typs[92] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, nil) - typs[93] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[15])}) - typs[94] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])}) - typs[95] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])}) + typs[90] = tostruct([]*ir.Field{ir.NewField(base.Pos, lookup("enabled"), nil, typs[6]), ir.NewField(base.Pos, lookup("pad"), nil, typs[89]), ir.NewField(base.Pos, lookup("needed"), nil, typs[6]), ir.NewField(base.Pos, lookup("cgo"), nil, typs[6]), ir.NewField(base.Pos, lookup("alignme"), nil, typs[24])}) + typs[91] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil) + typs[92] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3])}, nil) + typs[93] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15])}) + typs[94] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[87]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[95] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[84])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) typs[96] = types.NewPtr(typs[6]) - typs[97] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])}) - typs[98] = functype(nil, []*ir.Field{anonfield(typs[63])}, nil) - typs[99] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[15]), anonfield(typs[6])}) - typs[100] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[7])}) - typs[101] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[7])}) - typs[102] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[7])}) + typs[97] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[96]), ir.NewField(base.Pos, nil, nil, typs[84])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[98] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[63])}, nil) + typs[99] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[63]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[6])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[100] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])}) + typs[101] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[22]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])}) + typs[102] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[15]), ir.NewField(base.Pos, nil, nil, typs[7])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7])}) typs[103] = types.NewSlice(typs[2]) - typs[104] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[103])}) - typs[105] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil) - typs[106] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, nil) - typs[107] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[6])}) - typs[108] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])}) - typs[109] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])}) - typs[110] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])}) - typs[111] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])}) - typs[112] = functype(nil, []*ir.Field{anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[22])}) - typs[113] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, []*ir.Field{anonfield(typs[24])}) - typs[114] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[22])}) - typs[115] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[24])}) - typs[116] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[65])}) - typs[117] = functype(nil, []*ir.Field{anonfield(typs[22])}, []*ir.Field{anonfield(typs[20])}) - typs[118] = functype(nil, []*ir.Field{anonfield(typs[24])}, []*ir.Field{anonfield(typs[20])}) - typs[119] = functype(nil, []*ir.Field{anonfield(typs[65])}, []*ir.Field{anonfield(typs[20])}) - typs[120] = functype(nil, []*ir.Field{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Field{anonfield(typs[26])}) - typs[121] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5])}, nil) - typs[122] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5]), anonfield(typs[5])}, nil) - typs[123] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil) + typs[104] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[103]), ir.NewField(base.Pos, nil, nil, typs[15])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[103])}) + typs[105] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil) + typs[106] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil) + typs[107] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[108] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[3]), ir.NewField(base.Pos, nil, nil, typs[3])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[109] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[7])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[6])}) + typs[110] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5])}) + typs[111] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[5])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5])}) + typs[112] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22]), ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])}) + typs[113] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24]), ir.NewField(base.Pos, nil, nil, typs[24])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])}) + typs[114] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])}) + typs[115] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])}) + typs[116] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65])}) + typs[117] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[22])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}) + typs[118] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}) + typs[119] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[20])}) + typs[120] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[26]), ir.NewField(base.Pos, nil, nil, typs[26])}, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[26])}) + typs[121] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil) + typs[122] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil) + typs[123] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[1]), ir.NewField(base.Pos, nil, nil, typs[5])}, nil) typs[124] = types.NewSlice(typs[7]) - typs[125] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[124])}, nil) + typs[125] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[7]), ir.NewField(base.Pos, nil, nil, typs[124])}, nil) typs[126] = types.Types[types.TUINT8] - typs[127] = functype(nil, []*ir.Field{anonfield(typs[126]), anonfield(typs[126])}, nil) + typs[127] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[126]), ir.NewField(base.Pos, nil, nil, typs[126])}, nil) typs[128] = types.Types[types.TUINT16] - typs[129] = functype(nil, []*ir.Field{anonfield(typs[128]), anonfield(typs[128])}, nil) - typs[130] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil) - typs[131] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil) + typs[129] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[128]), ir.NewField(base.Pos, nil, nil, typs[128])}, nil) + typs[130] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[65]), ir.NewField(base.Pos, nil, nil, typs[65])}, nil) + typs[131] = functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, typs[24]), ir.NewField(base.Pos, nil, nil, typs[24])}, nil) return typs[:] } diff --git a/src/cmd/compile/internal/gc/builtin_test.go b/src/cmd/compile/internal/gc/builtin_test.go index 57f24b2287..df15ca5c7d 100644 --- a/src/cmd/compile/internal/gc/builtin_test.go +++ b/src/cmd/compile/internal/gc/builtin_test.go @@ -13,6 +13,7 @@ import ( ) func TestBuiltin(t *testing.T) { + t.Skip("mkbuiltin needs fixing") testenv.MustHaveGoRun(t) t.Parallel() diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index 27a9bc7cf8..e758cf86d4 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -18,8 +18,8 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node { ntype := p.typeExpr(expr.Type) fn := ir.NewFunc(p.pos(expr)) - fn.SetIsHiddenClosure(Curfn != nil) - fn.Nname = newFuncNameAt(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure + fn.SetIsHiddenClosure(ir.CurFunc != nil) + fn.Nname = ir.NewFuncNameAt(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure fn.Nname.Ntype = xtype fn.Nname.Defn = fn @@ -111,22 +111,22 @@ func typecheckclosure(clo *ir.ClosureExpr, top int) { } } - fn.Nname.SetSym(closurename(Curfn)) - setNodeNameFunc(fn.Nname) + fn.Nname.SetSym(closurename(ir.CurFunc)) + ir.MarkFunc(fn.Nname) typecheckFunc(fn) // Type check the body now, but only if we're inside a function. // At top level (in a variable initialization: curfn==nil) we're not // ready to type check code yet; we'll check it later, because the // underlying closure function we create is added to Target.Decls. - if Curfn != nil && clo.Type() != nil { - oldfn := Curfn - Curfn = fn + if ir.CurFunc != nil && clo.Type() != nil { + oldfn := ir.CurFunc + ir.CurFunc = fn olddd := decldepth decldepth = 1 typecheckslice(fn.Body, ctxStmt) decldepth = olddd - Curfn = oldfn + ir.CurFunc = oldfn } Target.Decls = append(Target.Decls, fn) @@ -335,13 +335,13 @@ func hasemptycvars(clo *ir.ClosureExpr) bool { // and compiling runtime func closuredebugruntimecheck(clo *ir.ClosureExpr) { if base.Debug.Closure > 0 { - if clo.Esc() == EscHeap { + if clo.Esc() == ir.EscHeap { base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func.ClosureVars) } else { base.WarnfAt(clo.Pos(), "stack closure, captured vars = %v", clo.Func.ClosureVars) } } - if base.Flag.CompilingRuntime && clo.Esc() == EscHeap { + if base.Flag.CompilingRuntime && clo.Esc() == ir.EscHeap { base.ErrorfAt(clo.Pos(), "heap-allocated closure, not allowed in runtime") } } @@ -364,14 +364,14 @@ func closureType(clo *ir.ClosureExpr) *types.Type { // the struct is unnamed so that closures in multiple packages with the // same struct type can share the descriptor. fields := []*ir.Field{ - namedfield(".F", types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, lookup(".F"), nil, types.Types[types.TUINTPTR]), } for _, v := range clo.Func.ClosureVars { typ := v.Type() if !v.Byval() { typ = types.NewPtr(typ) } - fields = append(fields, symfield(v.Sym(), typ)) + fields = append(fields, ir.NewField(base.Pos, v.Sym(), nil, typ)) } typ := tostruct(fields) typ.SetNoalg(true) @@ -435,16 +435,16 @@ func typecheckpartialcall(n ir.Node, sym *types.Sym) *ir.CallPartExpr { // for partial calls. func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.Func { rcvrtype := dot.X.Type() - sym := methodSymSuffix(rcvrtype, meth, "-fm") + sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm") if sym.Uniq() { return sym.Def.(*ir.Func) } sym.SetUniq(true) - savecurfn := Curfn + savecurfn := ir.CurFunc saveLineNo := base.Pos - Curfn = nil + ir.CurFunc = nil // Set line number equal to the line number where the method is declared. var m *types.Field @@ -480,7 +480,7 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir. } call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil) - call.Args.Set(paramNnames(tfn.Type())) + call.Args.Set(ir.ParamNames(tfn.Type())) call.IsDDD = tfn.Type().IsVariadic() if t0.NumResults() != 0 { ret := ir.NewReturnStmt(base.Pos, nil) @@ -496,11 +496,11 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir. typecheckFunc(fn) // Need to typecheck the body of the just-generated wrapper. // typecheckslice() requires that Curfn is set when processing an ORETURN. - Curfn = fn + ir.CurFunc = fn typecheckslice(fn.Body, ctxStmt) sym.Def = fn Target.Decls = append(Target.Decls, fn) - Curfn = savecurfn + ir.CurFunc = savecurfn base.Pos = saveLineNo return fn @@ -511,8 +511,8 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir. // The address of a variable of the returned type can be cast to a func. func partialCallType(n *ir.CallPartExpr) *types.Type { t := tostruct([]*ir.Field{ - namedfield("F", types.Types[types.TUINTPTR]), - namedfield("R", n.X.Type()), + ir.NewField(base.Pos, lookup("F"), nil, types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, lookup("R"), nil, n.X.Type()), }) t.SetNoalg(true) return t @@ -562,9 +562,3 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node { return walkexpr(cfn, init) } - -// callpartMethod returns the *types.Field representing the method -// referenced by method value n. -func callpartMethod(n ir.Node) *types.Field { - return n.(*ir.CallPartExpr).Method -} diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index 553f06757f..ad27f3ea44 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -18,30 +18,6 @@ import ( "unicode" ) -const ( - // Maximum size in bits for big.Ints before signalling - // overflow and also mantissa precision for big.Floats. - Mpprec = 512 -) - -func bigFloatVal(v constant.Value) *big.Float { - f := new(big.Float) - f.SetPrec(Mpprec) - switch u := constant.Val(v).(type) { - case int64: - f.SetInt64(u) - case *big.Int: - f.SetInt(u) - case *big.Float: - f.Set(u) - case *big.Rat: - f.SetRat(u) - default: - base.Fatalf("unexpected: %v", u) - } - return f -} - func roundFloat(v constant.Value, sz int64) constant.Value { switch sz { case 4: @@ -334,8 +310,8 @@ func toint(v constant.Value) constant.Value { // something that looks like an integer we omit the // value from the error message. // (See issue #11371). - f := bigFloatVal(v) - if f.MantExp(nil) > 2*Mpprec { + f := ir.BigFloat(v) + if f.MantExp(nil) > 2*ir.ConstPrec { base.Errorf("integer too large") } else { var t big.Float @@ -352,38 +328,6 @@ func toint(v constant.Value) constant.Value { return constant.MakeInt64(1) } -// doesoverflow reports whether constant value v is too large -// to represent with type t. -func doesoverflow(v constant.Value, t *types.Type) bool { - switch { - case t.IsInteger(): - bits := uint(8 * t.Size()) - if t.IsUnsigned() { - x, ok := constant.Uint64Val(v) - return !ok || x>>bits != 0 - } - x, ok := constant.Int64Val(v) - if x < 0 { - x = ^x - } - return !ok || x>>(bits-1) != 0 - case t.IsFloat(): - switch t.Size() { - case 4: - f, _ := constant.Float32Val(v) - return math.IsInf(float64(f), 0) - case 8: - f, _ := constant.Float64Val(v) - return math.IsInf(f, 0) - } - case t.IsComplex(): - ft := types.FloatForComplex(t) - return doesoverflow(constant.Real(v), ft) || doesoverflow(constant.Imag(v), ft) - } - base.Fatalf("doesoverflow: %v, %v", v, t) - panic("unreachable") -} - // overflow reports whether constant value v is too large // to represent with type t, and emits an error message if so. func overflow(v constant.Value, t *types.Type) bool { @@ -392,11 +336,11 @@ func overflow(v constant.Value, t *types.Type) bool { if t.IsUntyped() { return false } - if v.Kind() == constant.Int && constant.BitLen(v) > Mpprec { + if v.Kind() == constant.Int && constant.BitLen(v) > ir.ConstPrec { base.Errorf("integer too large") return true } - if doesoverflow(v, t) { + if ir.ConstOverflow(v, t) { base.Errorf("constant %v overflows %v", types.FmtConst(v, false), t) return true } @@ -656,13 +600,13 @@ var overflowNames = [...]string{ // origConst returns an OLITERAL with orig n and value v. func origConst(n ir.Node, v constant.Value) ir.Node { - lno := setlineno(n) + lno := ir.SetPos(n) v = convertVal(v, n.Type(), false) base.Pos = lno switch v.Kind() { case constant.Int: - if constant.BitLen(v) <= Mpprec { + if constant.BitLen(v) <= ir.ConstPrec { break } fallthrough @@ -778,14 +722,6 @@ func defaultType(t *types.Type) *types.Type { return nil } -func smallintconst(n ir.Node) bool { - if n.Op() == ir.OLITERAL { - v, ok := constant.Int64Val(n.Val()) - return ok && int64(int32(v)) == v - } - return false -} - // indexconst checks if Node n contains a constant expression // representable as a non-negative int and returns its value. // If n is not a constant expression, not representable as an @@ -803,21 +739,12 @@ func indexconst(n ir.Node) int64 { if v.Kind() != constant.Int || constant.Sign(v) < 0 { return -1 } - if doesoverflow(v, types.Types[types.TINT]) { + if ir.ConstOverflow(v, types.Types[types.TINT]) { return -2 } return ir.IntVal(types.Types[types.TINT], v) } -// isGoConst reports whether n is a Go language constant (as opposed to a -// compile-time constant). -// -// Expressions derived from nil, like string([]byte(nil)), while they -// may be known at compile time, are not Go language constants. -func isGoConst(n ir.Node) bool { - return n.Op() == ir.OLITERAL -} - // anyCallOrChan reports whether n contains any calls or channel operations. func anyCallOrChan(n ir.Node) bool { return ir.Any(n, func(n ir.Node) bool { @@ -875,7 +802,7 @@ func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) { } } - if !isGoConst(n) { + if !ir.IsConstNode(n) { return } if n.Type().IsUntyped() { @@ -906,7 +833,7 @@ func (s *constSet) add(pos src.XPos, n ir.Node, what, where string) { } k := constSetKey{typ, ir.ConstValue(n)} - if hasUniquePos(n) { + if ir.HasUniquePos(n) { pos = n.Pos() } diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index c084565f3d..1189d0ec12 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -80,12 +80,12 @@ func declare(n *ir.Name, ctxt ir.Class) { } Target.Externs = append(Target.Externs, n) } else { - if Curfn == nil && ctxt == ir.PAUTO { + if ir.CurFunc == nil && ctxt == ir.PAUTO { base.Pos = n.Pos() base.Fatalf("automatic outside function") } - if Curfn != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME { - Curfn.Dcl = append(Curfn.Dcl, n) + if ir.CurFunc != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME { + ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n) } if n.Op() == ir.OTYPE { declare_typegen++ @@ -95,7 +95,7 @@ func declare(n *ir.Name, ctxt ir.Class) { gen = vargen } types.Pushdcl(s) - n.Curfn = Curfn + n.Curfn = ir.CurFunc } if ctxt == ir.PAUTO { @@ -137,7 +137,7 @@ func variter(vl []*ir.Name, t ir.Ntype, el []ir.Node) []ir.Node { declare(v, dclcontext) v.Ntype = t v.Defn = as2 - if Curfn != nil { + if ir.CurFunc != nil { init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v)) } } @@ -158,8 +158,8 @@ func variter(vl []*ir.Name, t ir.Ntype, el []ir.Node) []ir.Node { declare(v, dclcontext) v.Ntype = t - if e != nil || Curfn != nil || ir.IsBlank(v) { - if Curfn != nil { + if e != nil || ir.CurFunc != nil || ir.IsBlank(v) { + if ir.CurFunc != nil { init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v)) } as := ir.NewAssignStmt(base.Pos, v, e) @@ -176,29 +176,6 @@ func variter(vl []*ir.Name, t ir.Ntype, el []ir.Node) []ir.Node { return init } -// newFuncNameAt generates a new name node for a function or method. -func newFuncNameAt(pos src.XPos, s *types.Sym, fn *ir.Func) *ir.Name { - if fn.Nname != nil { - base.Fatalf("newFuncName - already have name") - } - n := ir.NewNameAt(pos, s) - n.SetFunc(fn) - fn.Nname = n - return n -} - -func anonfield(typ *types.Type) *ir.Field { - return symfield(nil, typ) -} - -func namedfield(s string, typ *types.Type) *ir.Field { - return symfield(lookup(s), typ) -} - -func symfield(s *types.Sym, typ *types.Type) *ir.Field { - return ir.NewField(base.Pos, s, nil, typ) -} - // oldname returns the Node that declares symbol s in the current scope. // If no such Node currently exists, an ONONAME Node is returned instead. // Automatically creates a new closure variable if the referenced symbol was @@ -216,7 +193,7 @@ func oldname(s *types.Sym) ir.Node { return ir.NewIdent(base.Pos, s) } - if Curfn != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != Curfn { + if ir.CurFunc != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != ir.CurFunc { // Inner func is referring to var in outer func. // // TODO(rsc): If there is an outer variable x and we @@ -225,7 +202,7 @@ func oldname(s *types.Sym) ir.Node { // make x a closure variable unnecessarily. n := n.(*ir.Name) c := n.Name().Innermost - if c == nil || c.Curfn != Curfn { + if c == nil || c.Curfn != ir.CurFunc { // Do not have a closure var for the active closure yet; make one. c = NewName(s) c.Class_ = ir.PAUTOHEAP @@ -238,7 +215,7 @@ func oldname(s *types.Sym) ir.Node { c.Outer = n.Name().Innermost n.Name().Innermost = c - Curfn.ClosureVars = append(Curfn.ClosureVars, c) + ir.CurFunc.ClosureVars = append(ir.CurFunc.ClosureVars, c) } // return ref to closure var, not original @@ -322,8 +299,8 @@ func colasdefn(left []ir.Node, defn ir.Node) { // returns in auto-declaration context. func funchdr(fn *ir.Func) { // change the declaration context from extern to auto - funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext}) - Curfn = fn + funcStack = append(funcStack, funcStackEnt{ir.CurFunc, dclcontext}) + ir.CurFunc = fn dclcontext = ir.PAUTO types.Markdcl() @@ -451,7 +428,7 @@ func funcbody() { types.Popdcl() var e funcStackEnt funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1] - Curfn, dclcontext = e.curfn, e.dclcontext + ir.CurFunc, dclcontext = e.curfn, e.dclcontext } // structs, functions, and methods. @@ -542,7 +519,7 @@ func tointerface(nmethods []*ir.Field) *types.Type { } func fakeRecv() *ir.Field { - return anonfield(types.FakeRecvType()) + return ir.NewField(base.Pos, nil, nil, types.FakeRecvType()) } func fakeRecvField() *types.Field { @@ -588,74 +565,6 @@ func functype(nrecv *ir.Field, nparams, nresults []*ir.Field) *types.Type { return t } -func hasNamedResults(fn *ir.Func) bool { - typ := fn.Type() - return typ.NumResults() > 0 && types.OrigSym(typ.Results().Field(0).Sym) != nil -} - -// methodSym returns the method symbol representing a method name -// associated with a specific receiver type. -// -// Method symbols can be used to distinguish the same method appearing -// in different method sets. For example, T.M and (*T).M have distinct -// method symbols. -// -// The returned symbol will be marked as a function. -func methodSym(recv *types.Type, msym *types.Sym) *types.Sym { - sym := methodSymSuffix(recv, msym, "") - sym.SetFunc(true) - return sym -} - -// methodSymSuffix is like methodsym, but allows attaching a -// distinguisher suffix. To avoid collisions, the suffix must not -// start with a letter, number, or period. -func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym { - if msym.IsBlank() { - base.Fatalf("blank method name") - } - - rsym := recv.Sym() - if recv.IsPtr() { - if rsym != nil { - base.Fatalf("declared pointer receiver type: %v", recv) - } - rsym = recv.Elem().Sym() - } - - // Find the package the receiver type appeared in. For - // anonymous receiver types (i.e., anonymous structs with - // embedded fields), use the "go" pseudo-package instead. - rpkg := ir.Pkgs.Go - if rsym != nil { - rpkg = rsym.Pkg - } - - var b bytes.Buffer - if recv.IsPtr() { - // The parentheses aren't really necessary, but - // they're pretty traditional at this point. - fmt.Fprintf(&b, "(%-S)", recv) - } else { - fmt.Fprintf(&b, "%-S", recv) - } - - // A particular receiver type may have multiple non-exported - // methods with the same name. To disambiguate them, include a - // package qualifier for names that came from a different - // package than the receiver type. - if !types.IsExported(msym.Name) && msym.Pkg != rpkg { - b.WriteString(".") - b.WriteString(msym.Pkg.Prefix) - } - - b.WriteString(".") - b.WriteString(msym.Name) - b.WriteString(suffix) - - return rpkg.LookupBytes(b.Bytes()) -} - // Add a method, declared as a function. // - msym is the method symbol // - t is function type (with receiver) @@ -740,10 +649,6 @@ func addmethod(n *ir.Func, msym *types.Sym, t *types.Type, local, nointerface bo return f } -func funcsymname(s *types.Sym) string { - return s.Name + "·f" -} - // funcsym returns s·f. func funcsym(s *types.Sym) *types.Sym { // funcsymsmu here serves to protect not just mutations of funcsyms (below), @@ -756,7 +661,7 @@ func funcsym(s *types.Sym) *types.Sym { // Note makefuncsym also does package look-up of func sym names, // but that it is only called serially, from the front end. funcsymsmu.Lock() - sf, existed := s.Pkg.LookupOK(funcsymname(s)) + sf, existed := s.Pkg.LookupOK(ir.FuncSymName(s)) // Don't export s·f when compiling for dynamic linking. // When dynamically linking, the necessary function // symbols will be created explicitly with makefuncsym. @@ -790,31 +695,21 @@ func makefuncsym(s *types.Sym) { // get funcsyms. return } - if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed { + if _, existed := s.Pkg.LookupOK(ir.FuncSymName(s)); !existed { funcsyms = append(funcsyms, s) } } -// setNodeNameFunc marks a node as a function. -func setNodeNameFunc(n *ir.Name) { - if n.Op() != ir.ONAME || n.Class_ != ir.Pxxx { - base.Fatalf("expected ONAME/Pxxx node, got %v", n) - } - - n.Class_ = ir.PFUNC - n.Sym().SetFunc(true) -} - func dclfunc(sym *types.Sym, tfn ir.Ntype) *ir.Func { if tfn.Op() != ir.OTFUNC { base.Fatalf("expected OTFUNC node, got %v", tfn) } fn := ir.NewFunc(base.Pos) - fn.Nname = newFuncNameAt(base.Pos, sym, fn) + fn.Nname = ir.NewFuncNameAt(base.Pos, sym, fn) fn.Nname.Defn = fn fn.Nname.Ntype = tfn - setNodeNameFunc(fn.Nname) + ir.MarkFunc(fn.Nname) funchdr(fn) fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype) return fn diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go index 4366a5cc2c..6843d8b00e 100644 --- a/src/cmd/compile/internal/gc/escape.go +++ b/src/cmd/compile/internal/gc/escape.go @@ -147,16 +147,16 @@ type EscEdge struct { func escFmt(n ir.Node) string { text := "" switch n.Esc() { - case EscUnknown: + case ir.EscUnknown: break - case EscHeap: + case ir.EscHeap: text = "esc(h)" - case EscNone: + case ir.EscNone: text = "esc(no)" - case EscNever: + case ir.EscNever: text = "esc(N)" default: @@ -281,7 +281,7 @@ func (e *Escape) stmt(n ir.Node) { return } - lno := setlineno(n) + lno := ir.SetPos(n) defer func() { base.Pos = lno }() @@ -483,7 +483,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) { return } - lno := setlineno(n) + lno := ir.SetPos(n) defer func() { base.Pos = lno }() @@ -564,7 +564,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) { case ir.OCONV, ir.OCONVNOP: n := n.(*ir.ConvExpr) - if checkPtr(e.curfn, 2) && n.Type().IsUnsafePtr() && n.X.Type().IsPtr() { + if ir.ShouldCheckPtr(e.curfn, 2) && n.Type().IsUnsafePtr() && n.X.Type().IsPtr() { // When -d=checkptr=2 is enabled, treat // conversions to unsafe.Pointer as an // escaping operation. This allows better @@ -618,7 +618,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) { n := n.(*ir.CallPartExpr) closureK := e.spill(k, n) - m := callpartMethod(n) + m := n.Method // We don't know how the method value will be called // later, so conservatively assume the result @@ -725,7 +725,7 @@ func (e *Escape) unsafeValue(k EscHole, n ir.Node) { } case ir.ODOTPTR: n := n.(*ir.SelectorExpr) - if isReflectHeaderDataField(n) { + if ir.IsReflectHeaderDataField(n) { e.expr(k.deref(n, "reflect.Header.Data"), n.X) } else { e.discard(n.X) @@ -825,7 +825,7 @@ func (e *Escape) assign(dst, src ir.Node, why string, where ir.Node) { } k := e.addr(dst) - if dst != nil && dst.Op() == ir.ODOTPTR && isReflectHeaderDataField(dst) { + if dst != nil && dst.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(dst) { e.unsafeValue(e.heapHole().note(where, why), src) } else { if ignore { @@ -847,7 +847,7 @@ func (e *Escape) call(ks []EscHole, call, where ir.Node) { if topLevelDefer { // force stack allocation of defer record, unless // open-coded defers are used (see ssa.go) - where.SetEsc(EscNever) + where.SetEsc(ir.EscNever) } argument := func(k EscHole, arg ir.Node) { @@ -876,14 +876,14 @@ func (e *Escape) call(ks []EscHole, call, where ir.Node) { var fn *ir.Name switch call.Op() { case ir.OCALLFUNC: - switch v := staticValue(call.X); { + switch v := ir.StaticValue(call.X); { case v.Op() == ir.ONAME && v.(*ir.Name).Class_ == ir.PFUNC: fn = v.(*ir.Name) case v.Op() == ir.OCLOSURE: fn = v.(*ir.ClosureExpr).Func.Nname } case ir.OCALLMETH: - fn = methodExprName(call.X) + fn = ir.MethodExprName(call.X) } fntype := call.X.Type() @@ -1532,13 +1532,13 @@ func (e *Escape) finish(fns []*ir.Func) { logopt.LogOpt(n.Pos(), "escape", "escape", ir.FuncName(e.curfn)) } } - n.SetEsc(EscHeap) + n.SetEsc(ir.EscHeap) addrescapes(n) } else { if base.Flag.LowerM != 0 && n.Op() != ir.ONAME { base.WarnfAt(n.Pos(), "%v does not escape", n) } - n.SetEsc(EscNone) + n.SetEsc(ir.EscNone) if loc.transient { switch n.Op() { case ir.OCLOSURE: @@ -1656,7 +1656,7 @@ func ParseLeaks(s string) EscLeaks { } func escapes(all []ir.Node) { - visitBottomUp(all, escapeFuncs) + ir.VisitFuncsBottomUp(all, escapeFuncs) } const ( @@ -1680,13 +1680,6 @@ func max8(a, b int8) int8 { return b } -const ( - EscUnknown = iota - EscNone // Does not escape to heap, result, or parameters. - EscHeap // Reachable from the heap - EscNever // By construction will not escape. -) - // funcSym returns fn.Nname.Sym if no nils are encountered along the way. func funcSym(fn *ir.Func) *types.Sym { if fn == nil || fn.Nname == nil { @@ -1801,14 +1794,14 @@ func isSelfAssign(dst, src ir.Node) bool { // Safe trailing accessors that are permitted to differ. dst := dst.(*ir.SelectorExpr) src := src.(*ir.SelectorExpr) - return samesafeexpr(dst.X, src.X) + return ir.SameSafeExpr(dst.X, src.X) case ir.OINDEX: dst := dst.(*ir.IndexExpr) src := src.(*ir.IndexExpr) if mayAffectMemory(dst.Index) || mayAffectMemory(src.Index) { return false } - return samesafeexpr(dst.X, src.X) + return ir.SameSafeExpr(dst.X, src.X) default: return false } @@ -1876,18 +1869,18 @@ func heapAllocReason(n ir.Node) string { } } - if n.Type().Width > maxStackVarSize { + if n.Type().Width > ir.MaxStackVarSize { return "too large for stack" } - if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= maxImplicitStackVarSize { + if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= ir.MaxImplicitStackVarSize { return "too large for stack" } - if n.Op() == ir.OCLOSURE && closureType(n.(*ir.ClosureExpr)).Size() >= maxImplicitStackVarSize { + if n.Op() == ir.OCLOSURE && closureType(n.(*ir.ClosureExpr)).Size() >= ir.MaxImplicitStackVarSize { return "too large for stack" } - if n.Op() == ir.OCALLPART && partialCallType(n.(*ir.CallPartExpr)).Size() >= maxImplicitStackVarSize { + if n.Op() == ir.OCALLPART && partialCallType(n.(*ir.CallPartExpr)).Size() >= ir.MaxImplicitStackVarSize { return "too large for stack" } @@ -1897,10 +1890,10 @@ func heapAllocReason(n ir.Node) string { if r == nil { r = n.Len } - if !smallintconst(r) { + if !ir.IsSmallIntConst(r) { return "non-constant size" } - if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= maxImplicitStackVarSize/t.Elem().Width { + if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= ir.MaxImplicitStackVarSize/t.Elem().Width { return "too large for stack" } } @@ -1922,13 +1915,13 @@ func addrescapes(n ir.Node) { case ir.ONAME: n := n.(*ir.Name) - if n == nodfp { + if n == ir.RegFP { break } // if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping. // on PPARAM it means something different. - if n.Class_ == ir.PAUTO && n.Esc() == EscNever { + if n.Class_ == ir.PAUTO && n.Esc() == ir.EscNever { break } @@ -1954,12 +1947,12 @@ func addrescapes(n ir.Node) { // // then we're analyzing the inner closure but we need to move x to the // heap in f, not in the inner closure. Flip over to f before calling moveToHeap. - oldfn := Curfn - Curfn = n.Curfn + oldfn := ir.CurFunc + ir.CurFunc = n.Curfn ln := base.Pos - base.Pos = Curfn.Pos() + base.Pos = ir.CurFunc.Pos() moveToHeap(n) - Curfn = oldfn + ir.CurFunc = oldfn base.Pos = ln // ODOTPTR has already been introduced, @@ -2039,9 +2032,9 @@ func moveToHeap(n *ir.Name) { // liveness and other analyses use the underlying stack slot // and not the now-pseudo-variable n. found := false - for i, d := range Curfn.Dcl { + for i, d := range ir.CurFunc.Dcl { if d == n { - Curfn.Dcl[i] = stackcopy + ir.CurFunc.Dcl[i] = stackcopy found = true break } @@ -2054,14 +2047,14 @@ func moveToHeap(n *ir.Name) { if !found { base.Fatalf("cannot find %v in local variable list", n) } - Curfn.Dcl = append(Curfn.Dcl, n) + ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n) } // Modify n in place so that uses of n now mean indirection of the heapaddr. n.Class_ = ir.PAUTOHEAP n.SetFrameOffset(0) n.Heapaddr = heapaddr - n.SetEsc(EscHeap) + n.SetEsc(ir.EscHeap) if base.Flag.LowerM != 0 { base.WarnfAt(n.Pos(), "moved to heap: %v", n) } diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go index bcd58fd2c5..53298c878d 100644 --- a/src/cmd/compile/internal/gc/gen.go +++ b/src/cmd/compile/internal/gc/gen.go @@ -28,26 +28,6 @@ func sysvar(name string) *obj.LSym { return ir.Pkgs.Runtime.Lookup(name).Linksym() } -// isParamStackCopy reports whether this is the on-stack copy of a -// function parameter that moved to the heap. -func isParamStackCopy(n ir.Node) bool { - if n.Op() != ir.ONAME { - return false - } - name := n.(*ir.Name) - return (name.Class_ == ir.PPARAM || name.Class_ == ir.PPARAMOUT) && name.Heapaddr != nil -} - -// isParamHeapCopy reports whether this is the on-heap copy of -// a function parameter that moved to the heap. -func isParamHeapCopy(n ir.Node) bool { - if n.Op() != ir.ONAME { - return false - } - name := n.(*ir.Name) - return name.Class_ == ir.PAUTOHEAP && name.Name().Stackcopy != nil -} - // autotmpname returns the name for an autotmp variable numbered n. func autotmpname(n int) string { // Give each tmp a different name so that they can be registerized. @@ -80,7 +60,7 @@ func tempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name { s.Def = n n.SetType(t) n.Class_ = ir.PAUTO - n.SetEsc(EscNever) + n.SetEsc(ir.EscNever) n.Curfn = curfn n.SetUsed(true) n.SetAutoTemp(true) @@ -92,5 +72,5 @@ func tempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name { } func temp(t *types.Type) *ir.Name { - return tempAt(base.Pos, Curfn, t) + return tempAt(base.Pos, ir.CurFunc, t) } diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index 4b6ffe58d1..4370a06839 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -12,27 +12,6 @@ import ( "sync" ) -var ( - // maximum size variable which we will allocate on the stack. - // This limit is for explicit variable declarations like "var x T" or "x := ...". - // Note: the flag smallframes can update this value. - maxStackVarSize = int64(10 * 1024 * 1024) - - // maximum size of implicit variables that we will allocate on the stack. - // p := new(T) allocating T on the stack - // p := &T{} allocating T on the stack - // s := make([]T, n) allocating [n]T on the stack - // s := []byte("...") allocating [n]byte on the stack - // Note: the flag smallframes can update this value. - maxImplicitStackVarSize = int64(64 * 1024) - - // smallArrayBytes is the maximum size of an array which is considered small. - // Small arrays will be initialized directly with a sequence of constant stores. - // Large arrays will be initialized by copying from a static temp. - // 256 bytes was chosen to minimize generated code + statictmp size. - smallArrayBytes = int64(256) -) - // Slices in the runtime are represented by three components: // // type slice struct { @@ -89,16 +68,12 @@ var ( var dclcontext ir.Class // PEXTERN/PAUTO -var Curfn *ir.Func - var Widthptr int var Widthreg int var typecheckok bool -var nodfp *ir.Name - // interface to back end type Arch struct { diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go index da2345c289..6ea9b354ab 100644 --- a/src/cmd/compile/internal/gc/gsubr.go +++ b/src/cmd/compile/internal/gc/gsubr.go @@ -197,7 +197,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { // Q: is this needed? savepos := base.Pos savedclcontext := dclcontext - savedcurfn := Curfn + savedcurfn := ir.CurFunc base.Pos = base.AutogeneratedPos dclcontext = ir.PEXTERN @@ -270,7 +270,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { tail = ir.NewBranchStmt(base.Pos, ir.ORETJMP, f.Nname.Sym()) } else { call := ir.NewCallExpr(base.Pos, ir.OCALL, f.Nname, nil) - call.Args.Set(paramNnames(tfn.Type())) + call.Args.Set(ir.ParamNames(tfn.Type())) call.IsDDD = tfn.Type().IsVariadic() tail = call if tfn.Type().NumResults() > 0 { @@ -287,7 +287,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { } typecheckFunc(fn) - Curfn = fn + ir.CurFunc = fn typecheckslice(fn.Body, ctxStmt) escapeFuncs([]*ir.Func{fn}, false) @@ -297,7 +297,7 @@ func makeABIWrapper(f *ir.Func, wrapperABI obj.ABI) { // Restore previous context. base.Pos = savepos dclcontext = savedclcontext - Curfn = savedcurfn + ir.CurFunc = savedcurfn } // initLSym defines f's obj.LSym and initializes it based on the diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go index 56d2e81df1..fd64b69077 100644 --- a/src/cmd/compile/internal/gc/iexport.go +++ b/src/cmd/compile/internal/gc/iexport.go @@ -816,7 +816,7 @@ func (w *exportWriter) value(typ *types.Type, v constant.Value) { func intSize(typ *types.Type) (signed bool, maxBytes uint) { if typ.IsUntyped() { - return true, Mpprec / 8 + return true, ir.ConstPrec / 8 } switch typ.Kind() { @@ -927,7 +927,7 @@ func (w *exportWriter) mpint(x constant.Value, typ *types.Type) { // multi-precision integer) and then the exponent, except exponent is // omitted if mantissa is zero. func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) { - f := bigFloatVal(v) + f := ir.BigFloat(v) if f.IsInf() { base.Fatalf("infinite constant") } diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go index 90a909d2a3..d04c432e5e 100644 --- a/src/cmd/compile/internal/gc/iimport.go +++ b/src/cmd/compile/internal/gc/iimport.go @@ -327,7 +327,7 @@ func (r *importReader) doDecl(sym *types.Sym) *ir.Name { fn := ir.NewFunc(mpos) fn.SetType(mtyp) - m := newFuncNameAt(mpos, methodSym(recv.Type, msym), fn) + m := ir.NewFuncNameAt(mpos, ir.MethodSym(recv.Type, msym), fn) m.SetType(mtyp) m.Class_ = ir.PFUNC // methodSym already marked m.Sym as a function. @@ -1009,7 +1009,7 @@ func (r *importReader) node() ir.Node { n.AsOp = r.op() n.X = r.expr() if !r.bool() { - n.Y = nodintconst(1) + n.Y = ir.NewInt(1) n.IncDec = true } else { n.Y = r.expr() diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go index 4495284a07..f22e49efba 100644 --- a/src/cmd/compile/internal/gc/init.go +++ b/src/cmd/compile/internal/gc/init.go @@ -66,9 +66,9 @@ func fninit() *ir.Name { funcbody() typecheckFunc(fn) - Curfn = fn + ir.CurFunc = fn typecheckslice(nf, ctxStmt) - Curfn = nil + ir.CurFunc = nil Target.Decls = append(Target.Decls, fn) fns = append(fns, initializers.Linksym()) } diff --git a/src/cmd/compile/internal/gc/initorder.go b/src/cmd/compile/internal/gc/initorder.go index fe131c32a6..5caa2e769f 100644 --- a/src/cmd/compile/internal/gc/initorder.go +++ b/src/cmd/compile/internal/gc/initorder.go @@ -290,7 +290,7 @@ func (d *initDeps) visit(n ir.Node) { switch n.Op() { case ir.OMETHEXPR: n := n.(*ir.MethodExpr) - d.foundDep(methodExprName(n)) + d.foundDep(ir.MethodExprName(n)) case ir.ONAME: n := n.(*ir.Name) @@ -304,7 +304,7 @@ func (d *initDeps) visit(n ir.Node) { d.inspectList(n.Func.Body) case ir.ODOTMETH, ir.OCALLPART: - d.foundDep(methodExprName(n)) + d.foundDep(ir.MethodExprName(n)) } } diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index 47fdc7b9b7..f21494b291 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -39,9 +39,6 @@ import ( "strings" ) -// IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation. -var IsIntrinsicCall = func(*ir.CallExpr) bool { return false } - // Inlining budget parameters, gathered in one place const ( inlineMaxBudget = 80 @@ -57,7 +54,7 @@ const ( func InlinePackage() { // Find functions that can be inlined and clone them before walk expands them. - visitBottomUp(Target.Decls, func(list []*ir.Func, recursive bool) { + ir.VisitFuncsBottomUp(Target.Decls, func(list []*ir.Func, recursive bool) { numfns := numNonClosures(list) for _, n := range list { if !recursive || numfns > 1 { @@ -98,7 +95,7 @@ func fnpkg(fn *ir.Name) *types.Pkg { // Lazy typechecking of imported bodies. For local functions, caninl will set ->typecheck // because they're a copy of an already checked body. func typecheckinl(fn *ir.Func) { - lno := setlineno(fn.Nname) + lno := ir.SetPos(fn.Nname) expandInline(fn) @@ -116,10 +113,10 @@ func typecheckinl(fn *ir.Func) { fmt.Printf("typecheck import [%v] %L { %v }\n", fn.Sym(), fn, ir.Nodes(fn.Inl.Body)) } - savefn := Curfn - Curfn = fn + savefn := ir.CurFunc + ir.CurFunc = fn typecheckslice(fn.Inl.Body, ctxStmt) - Curfn = savefn + ir.CurFunc = savefn // During expandInline (which imports fn.Func.Inl.Body), // declarations are added to fn.Func.Dcl by funcHdr(). Move them @@ -281,7 +278,7 @@ func inlFlood(n *ir.Name, exportsym func(*ir.Name)) { ir.VisitList(ir.Nodes(fn.Inl.Body), func(n ir.Node) { switch n.Op() { case ir.OMETHEXPR, ir.ODOTMETH: - inlFlood(methodExprName(n), exportsym) + inlFlood(ir.MethodExprName(n), exportsym) case ir.ONAME: n := n.(*ir.Name) @@ -362,7 +359,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error { } } - if IsIntrinsicCall(n) { + if ir.IsIntrinsicCall(n) { // Treat like any other node. break } @@ -393,7 +390,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error { break } } - if inlfn := methodExprName(n.X).Func; inlfn.Inl != nil { + if inlfn := ir.MethodExprName(n.X).Func; inlfn.Inl != nil { v.budget -= inlfn.Inl.Cost break } @@ -502,8 +499,8 @@ func isBigFunc(fn *ir.Func) bool { // Inlcalls/nodelist/node walks fn's statements and expressions and substitutes any // calls made to inlineable functions. This is the external entry point. func inlcalls(fn *ir.Func) { - savefn := Curfn - Curfn = fn + savefn := ir.CurFunc + ir.CurFunc = fn maxCost := int32(inlineMaxBudget) if isBigFunc(fn) { maxCost = inlineBigFunctionMaxCost @@ -520,7 +517,7 @@ func inlcalls(fn *ir.Func) { return inlnode(n, maxCost, inlMap, edit) } ir.EditChildren(fn, edit) - Curfn = savefn + ir.CurFunc = savefn } // Turn an OINLCALL into a statement. @@ -536,7 +533,7 @@ func inlconv2stmt(inlcall *ir.InlinedCallExpr) ir.Node { // n.Left = inlconv2expr(n.Left) func inlconv2expr(n *ir.InlinedCallExpr) ir.Node { r := n.ReturnVars[0] - return initExpr(append(n.Init(), n.Body...), r) + return ir.InitExpr(append(n.Init(), n.Body...), r) } // Turn the rlist (with the return values) of the OINLCALL in @@ -550,7 +547,7 @@ func inlconv2list(n *ir.InlinedCallExpr) []ir.Node { } s := n.ReturnVars - s[0] = initExpr(append(n.Init(), n.Body...), s[0]) + s[0] = ir.InitExpr(append(n.Init(), n.Body...), s[0]) return s } @@ -594,7 +591,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No } } - lno := setlineno(n) + lno := ir.SetPos(n) ir.EditChildren(n, edit) @@ -626,7 +623,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No if base.Flag.LowerM > 3 { fmt.Printf("%v:call to func %+v\n", ir.Line(n), call.X) } - if IsIntrinsicCall(call) { + if ir.IsIntrinsicCall(call) { break } if fn := inlCallee(call.X); fn != nil && fn.Inl != nil { @@ -644,7 +641,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No base.Fatalf("no function type for [%p] %+v\n", call.X, call.X) } - n = mkinlcall(call, methodExprName(call.X).Func, maxCost, inlMap, edit) + n = mkinlcall(call, ir.MethodExprName(call.X).Func, maxCost, inlMap, edit) } base.Pos = lno @@ -670,11 +667,11 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No // inlCallee takes a function-typed expression and returns the underlying function ONAME // that it refers to if statically known. Otherwise, it returns nil. func inlCallee(fn ir.Node) *ir.Func { - fn = staticValue(fn) + fn = ir.StaticValue(fn) switch fn.Op() { case ir.OMETHEXPR: fn := fn.(*ir.MethodExpr) - n := methodExprName(fn) + n := ir.MethodExprName(fn) // Check that receiver type matches fn.Left. // TODO(mdempsky): Handle implicit dereference // of pointer receiver argument? @@ -696,100 +693,6 @@ func inlCallee(fn ir.Node) *ir.Func { return nil } -func staticValue(n ir.Node) ir.Node { - for { - if n.Op() == ir.OCONVNOP { - n = n.(*ir.ConvExpr).X - continue - } - - n1 := staticValue1(n) - if n1 == nil { - return n - } - n = n1 - } -} - -// staticValue1 implements a simple SSA-like optimization. If n is a local variable -// that is initialized and never reassigned, staticValue1 returns the initializer -// expression. Otherwise, it returns nil. -func staticValue1(nn ir.Node) ir.Node { - if nn.Op() != ir.ONAME { - return nil - } - n := nn.(*ir.Name) - if n.Class_ != ir.PAUTO || n.Name().Addrtaken() { - return nil - } - - defn := n.Name().Defn - if defn == nil { - return nil - } - - var rhs ir.Node -FindRHS: - switch defn.Op() { - case ir.OAS: - defn := defn.(*ir.AssignStmt) - rhs = defn.Y - case ir.OAS2: - defn := defn.(*ir.AssignListStmt) - for i, lhs := range defn.Lhs { - if lhs == n { - rhs = defn.Rhs[i] - break FindRHS - } - } - base.Fatalf("%v missing from LHS of %v", n, defn) - default: - return nil - } - if rhs == nil { - base.Fatalf("RHS is nil: %v", defn) - } - - if reassigned(n) { - return nil - } - - return rhs -} - -// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean -// indicating whether the name has any assignments other than its declaration. -// The second return value is the first such assignment encountered in the walk, if any. It is mostly -// useful for -m output documenting the reason for inhibited optimizations. -// NB: global variables are always considered to be re-assigned. -// TODO: handle initial declaration not including an assignment and followed by a single assignment? -func reassigned(name *ir.Name) bool { - if name.Op() != ir.ONAME { - base.Fatalf("reassigned %v", name) - } - // no way to reliably check for no-reassignment of globals, assume it can be - if name.Curfn == nil { - return true - } - return ir.Any(name.Curfn, func(n ir.Node) bool { - switch n.Op() { - case ir.OAS: - n := n.(*ir.AssignStmt) - if n.X == name && n != name.Defn { - return true - } - case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OSELRECV2: - n := n.(*ir.AssignListStmt) - for _, p := range n.Lhs { - if p == name && n != name.Defn { - return true - } - } - } - return false - }) -} - func inlParam(t *types.Field, as ir.Node, inlvars map[*ir.Name]ir.Node) ir.Node { n := ir.AsNode(t.Nname) if n == nil || ir.IsBlank(n) { @@ -821,7 +724,7 @@ var SSADumpInline = func(*ir.Func) {} func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.Node) ir.Node) ir.Node { if fn.Inl == nil { if logopt.Enabled() { - logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(Curfn), + logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc), fmt.Sprintf("%s cannot be inlined", ir.PkgFuncName(fn))) } return n @@ -830,16 +733,16 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b // The inlined function body is too big. Typically we use this check to restrict // inlining into very big functions. See issue 26546 and 17566. if logopt.Enabled() { - logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(Curfn), + logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc), fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), maxCost)) } return n } - if fn == Curfn { + if fn == ir.CurFunc { // Can't recursively inline a function into itself. if logopt.Enabled() { - logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(Curfn))) + logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(ir.CurFunc))) } return n } @@ -856,7 +759,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b if inlMap[fn] { if base.Flag.LowerM > 1 { - fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(Curfn)) + fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(ir.CurFunc)) } return n } @@ -916,7 +819,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b // NB: if we enabled inlining of functions containing OCLOSURE or refined // the reassigned check via some sort of copy propagation this would most // likely need to be changed to a loop to walk up to the correct Param - if o == nil || o.Curfn != Curfn { + if o == nil || o.Curfn != ir.CurFunc { base.Fatalf("%v: unresolvable capture %v %v\n", ir.Line(n), fn, v) } @@ -947,7 +850,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b if ln.Class_ == ir.PPARAMOUT { // return values handled below. continue } - if isParamStackCopy(ln) { // ignore the on-stack copy of a parameter that moved to the heap + if ir.IsParamStackCopy(ln) { // ignore the on-stack copy of a parameter that moved to the heap // TODO(mdempsky): Remove once I'm confident // this never actually happens. We currently // perform inlining before escape analysis, so @@ -1162,10 +1065,10 @@ func inlvar(var_ ir.Node) ir.Node { n.SetType(var_.Type()) n.Class_ = ir.PAUTO n.SetUsed(true) - n.Curfn = Curfn // the calling function, not the called one + n.Curfn = ir.CurFunc // the calling function, not the called one n.SetAddrtaken(var_.Name().Addrtaken()) - Curfn.Dcl = append(Curfn.Dcl, n) + ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n) return n } @@ -1175,8 +1078,8 @@ func retvar(t *types.Field, i int) ir.Node { n.SetType(t.Type) n.Class_ = ir.PAUTO n.SetUsed(true) - n.Curfn = Curfn // the calling function, not the called one - Curfn.Dcl = append(Curfn.Dcl, n) + n.Curfn = ir.CurFunc // the calling function, not the called one + ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n) return n } @@ -1187,8 +1090,8 @@ func argvar(t *types.Type, i int) ir.Node { n.SetType(t.Elem()) n.Class_ = ir.PAUTO n.SetUsed(true) - n.Curfn = Curfn // the calling function, not the called one - Curfn.Dcl = append(Curfn.Dcl, n) + n.Curfn = ir.CurFunc // the calling function, not the called one + ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n) return n } @@ -1358,7 +1261,7 @@ func pruneUnusedAutos(ll []*ir.Name, vis *hairyVisitor) []*ir.Name { // devirtualize replaces interface method calls within fn with direct // concrete-type method calls where applicable. func devirtualize(fn *ir.Func) { - Curfn = fn + ir.CurFunc = fn ir.VisitList(fn.Body, func(n ir.Node) { if n.Op() == ir.OCALLINTER { devirtualizeCall(n.(*ir.CallExpr)) @@ -1368,7 +1271,7 @@ func devirtualize(fn *ir.Func) { func devirtualizeCall(call *ir.CallExpr) { sel := call.X.(*ir.SelectorExpr) - r := staticValue(sel.X) + r := ir.StaticValue(sel.X) if r.Op() != ir.OCONVIFACE { return } diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 1c52426802..d55a8b0a7c 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -134,8 +134,8 @@ func Main(archInit func(*Arch)) { } if base.Flag.SmallFrames { - maxStackVarSize = 128 * 1024 - maxImplicitStackVarSize = 16 * 1024 + ir.MaxStackVarSize = 128 * 1024 + ir.MaxImplicitStackVarSize = 16 * 1024 } if base.Flag.Dwarf { @@ -185,7 +185,7 @@ func Main(archInit func(*Arch)) { } ir.EscFmt = escFmt - IsIntrinsicCall = isIntrinsicCall + ir.IsIntrinsicCall = isIntrinsicCall SSADumpInline = ssaDumpInline initSSAEnv() initSSATables() @@ -242,7 +242,7 @@ func Main(archInit func(*Arch)) { devirtualize(n.(*ir.Func)) } } - Curfn = nil + ir.CurFunc = nil // Escape analysis. // Required for moving heap allocations onto stack, @@ -271,7 +271,7 @@ func Main(archInit func(*Arch)) { if n.Op() == ir.ODCLFUNC { n := n.(*ir.Func) if n.OClosure != nil { - Curfn = n + ir.CurFunc = n transformclosure(n) } } @@ -285,7 +285,7 @@ func Main(archInit func(*Arch)) { // Just before compilation, compile itabs found on // the right side of OCONVIFACE so that methods // can be de-virtualized during compilation. - Curfn = nil + ir.CurFunc = nil peekitabs() // Compile top level functions. diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index 799887d6b8..c83b60dcd4 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -181,9 +181,9 @@ func (p *noder) openScope(pos syntax.Pos) { types.Markdcl() if p.trackScopes { - Curfn.Parents = append(Curfn.Parents, p.scope) - p.scopeVars = append(p.scopeVars, len(Curfn.Dcl)) - p.scope = ir.ScopeID(len(Curfn.Parents)) + ir.CurFunc.Parents = append(ir.CurFunc.Parents, p.scope) + p.scopeVars = append(p.scopeVars, len(ir.CurFunc.Dcl)) + p.scope = ir.ScopeID(len(ir.CurFunc.Parents)) p.markScope(pos) } @@ -196,29 +196,29 @@ func (p *noder) closeScope(pos syntax.Pos) { if p.trackScopes { scopeVars := p.scopeVars[len(p.scopeVars)-1] p.scopeVars = p.scopeVars[:len(p.scopeVars)-1] - if scopeVars == len(Curfn.Dcl) { + if scopeVars == len(ir.CurFunc.Dcl) { // no variables were declared in this scope, so we can retract it. - if int(p.scope) != len(Curfn.Parents) { + if int(p.scope) != len(ir.CurFunc.Parents) { base.Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted") } - p.scope = Curfn.Parents[p.scope-1] - Curfn.Parents = Curfn.Parents[:len(Curfn.Parents)-1] + p.scope = ir.CurFunc.Parents[p.scope-1] + ir.CurFunc.Parents = ir.CurFunc.Parents[:len(ir.CurFunc.Parents)-1] - nmarks := len(Curfn.Marks) - Curfn.Marks[nmarks-1].Scope = p.scope + nmarks := len(ir.CurFunc.Marks) + ir.CurFunc.Marks[nmarks-1].Scope = p.scope prevScope := ir.ScopeID(0) if nmarks >= 2 { - prevScope = Curfn.Marks[nmarks-2].Scope + prevScope = ir.CurFunc.Marks[nmarks-2].Scope } - if Curfn.Marks[nmarks-1].Scope == prevScope { - Curfn.Marks = Curfn.Marks[:nmarks-1] + if ir.CurFunc.Marks[nmarks-1].Scope == prevScope { + ir.CurFunc.Marks = ir.CurFunc.Marks[:nmarks-1] } return } - p.scope = Curfn.Parents[p.scope-1] + p.scope = ir.CurFunc.Parents[p.scope-1] p.markScope(pos) } @@ -226,10 +226,10 @@ func (p *noder) closeScope(pos syntax.Pos) { func (p *noder) markScope(pos syntax.Pos) { xpos := p.makeXPos(pos) - if i := len(Curfn.Marks); i > 0 && Curfn.Marks[i-1].Pos == xpos { - Curfn.Marks[i-1].Scope = p.scope + if i := len(ir.CurFunc.Marks); i > 0 && ir.CurFunc.Marks[i-1].Pos == xpos { + ir.CurFunc.Marks[i-1].Scope = p.scope } else { - Curfn.Marks = append(Curfn.Marks, ir.Mark{Pos: xpos, Scope: p.scope}) + ir.CurFunc.Marks = append(ir.CurFunc.Marks, ir.Mark{Pos: xpos, Scope: p.scope}) } } @@ -527,7 +527,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node { name = ir.BlankNode.Sym() // filled in by typecheckfunc } - f.Nname = newFuncNameAt(p.pos(fun.Name), name, f) + f.Nname = ir.NewFuncNameAt(p.pos(fun.Name), name, f) f.Nname.Defn = f f.Nname.Ntype = t @@ -996,13 +996,13 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node { // TODO(mdempsky): Line number? return ir.NewBlockStmt(base.Pos, nil) } - return liststmt(l) + return ir.NewBlockStmt(src.NoXPos, l) case *syntax.ExprStmt: return p.wrapname(stmt, p.expr(stmt.X)) case *syntax.SendStmt: return ir.NewSendStmt(p.pos(stmt), p.expr(stmt.Chan), p.expr(stmt.Value)) case *syntax.DeclStmt: - return liststmt(p.decls(stmt.DeclList)) + return ir.NewBlockStmt(src.NoXPos, p.decls(stmt.DeclList)) case *syntax.AssignStmt: if stmt.Op != 0 && stmt.Op != syntax.Def { n := ir.NewAssignOpStmt(p.pos(stmt), p.binOp(stmt.Op), p.expr(stmt.Lhs), p.expr(stmt.Rhs)) @@ -1065,8 +1065,8 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node { } n := ir.NewReturnStmt(p.pos(stmt), nil) n.Results.Set(results) - if len(n.Results) == 0 && Curfn != nil { - for _, ln := range Curfn.Dcl { + if len(n.Results) == 0 && ir.CurFunc != nil { + for _, ln := range ir.CurFunc.Dcl { if ln.Class_ == ir.PPARAM { continue } @@ -1344,7 +1344,7 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node { l = append(l, ls) } } - return liststmt(l) + return ir.NewBlockStmt(src.NoXPos, l) } var unOps = [...]ir.Op{ @@ -1451,7 +1451,7 @@ func (p *noder) basicLit(lit *syntax.BasicLit) constant.Value { // to big.Float to match cmd/compile's historical precision. // TODO(mdempsky): Remove. if v.Kind() == constant.Float { - v = constant.Make(bigFloatVal(v)) + v = constant.Make(ir.BigFloat(v)) } return v diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index 897bcce36f..e56e34a7a1 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -255,7 +255,7 @@ func dumpGlobalConst(n ir.Node) { if t.IsUntyped() { // Export untyped integers as int (if they fit). t = types.Types[types.TINT] - if doesoverflow(v, t) { + if ir.ConstOverflow(v, t) { return } } @@ -279,7 +279,7 @@ func dumpfuncsyms() { return funcsyms[i].LinksymName() < funcsyms[j].LinksymName() }) for _, s := range funcsyms { - sf := s.Pkg.Lookup(funcsymname(s)).Linksym() + sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym() dsymptr(sf, 0, s.Linksym(), 0) ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA) } diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index 9e792d153c..1cd33b2cb5 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -230,7 +230,7 @@ func (o *Order) safeExpr(n ir.Node) ir.Node { // because we emit explicit VARKILL instructions marking the end of those // temporaries' lifetimes. func isaddrokay(n ir.Node) bool { - return islvalue(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class_ == ir.PEXTERN || ir.IsAutoTmp(n)) + return ir.IsAssignable(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class_ == ir.PEXTERN || ir.IsAutoTmp(n)) } // addrTemp ensures that n is okay to pass by address to runtime routines. @@ -381,13 +381,13 @@ func orderMakeSliceCopy(s []ir.Node) { } mk := as.Y.(*ir.MakeExpr) - if mk.Esc() == EscNone || mk.Len == nil || mk.Cap != nil { + if mk.Esc() == ir.EscNone || mk.Len == nil || mk.Cap != nil { return } mk.SetOp(ir.OMAKESLICECOPY) mk.Cap = cp.Y // Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s) - mk.SetBounded(mk.Len.Op() == ir.OLEN && samesafeexpr(mk.Len.(*ir.UnaryExpr).X, cp.Y)) + mk.SetBounded(mk.Len.Op() == ir.OLEN && ir.SameSafeExpr(mk.Len.(*ir.UnaryExpr).X, cp.Y)) as.Y = typecheck(mk, ctxExpr) s[1] = nil // remove separate copy call } @@ -404,7 +404,7 @@ func (o *Order) edge() { counter.Name().SetLibfuzzerExtraCounter(true) // counter += 1 - incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, nodintconst(1)) + incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1)) o.append(incr) } @@ -429,7 +429,7 @@ func (o *Order) exprInPlace(n ir.Node) ir.Node { var order Order order.free = o.free n = order.expr(n, nil) - n = initExpr(order.out, n) + n = ir.InitExpr(order.out, n) // insert new temporaries from order // at head of outer list. @@ -448,7 +448,7 @@ func orderStmtInPlace(n ir.Node, free map[string][]*ir.Name) ir.Node { mark := order.markTemp() order.stmt(n) order.cleanTemp(mark) - return liststmt(order.out) + return ir.NewBlockStmt(src.NoXPos, order.out) } // init moves n's init list to o.out. @@ -615,7 +615,7 @@ func (o *Order) stmt(n ir.Node) { return } - lno := setlineno(n) + lno := ir.SetPos(n) o.init(n) switch n.Op() { @@ -909,7 +909,7 @@ func (o *Order) stmt(n ir.Node) { for _, ncas := range n.Cases { ncas := ncas.(*ir.CaseStmt) r := ncas.Comm - setlineno(ncas) + ir.SetPos(ncas) // Append any new body prologue to ninit. // The next loop will insert ninit into nbody. @@ -1089,7 +1089,7 @@ func (o *Order) expr(n, lhs ir.Node) ir.Node { if n == nil { return n } - lno := setlineno(n) + lno := ir.SetPos(n) n = o.expr1(n, lhs) base.Pos = lno return n @@ -1283,7 +1283,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node { o.exprList(n.Args) } - if lhs == nil || lhs.Op() != ir.ONAME && !samesafeexpr(lhs, n.Args[0]) { + if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) { return o.copyExpr(n) } return n @@ -1299,7 +1299,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node { max = o.expr(max, nil) max = o.cheapExpr(max) n.SetSliceBounds(low, high, max) - if lhs == nil || lhs.Op() != ir.ONAME && !samesafeexpr(lhs, n.X) { + if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) { return o.copyExpr(n) } return n diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index d6c15f113b..44b614ba70 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -131,7 +131,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { switch n.Class_ { case ir.PPARAM, ir.PPARAMOUT: // Don't modify nodfp; it is a global. - if n != nodfp { + if n != ir.RegFP { n.Name().SetUsed(true) } case ir.PAUTO: @@ -193,8 +193,8 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { } func funccompile(fn *ir.Func) { - if Curfn != nil { - base.Fatalf("funccompile %v inside %v", fn.Sym(), Curfn.Sym()) + if ir.CurFunc != nil { + base.Fatalf("funccompile %v inside %v", fn.Sym(), ir.CurFunc.Sym()) } if fn.Type() == nil { @@ -215,9 +215,9 @@ func funccompile(fn *ir.Func) { } dclcontext = ir.PAUTO - Curfn = fn + ir.CurFunc = fn compile(fn) - Curfn = nil + ir.CurFunc = nil dclcontext = ir.PEXTERN } @@ -234,7 +234,7 @@ func compile(fn *ir.Func) { } // From this point, there should be no uses of Curfn. Enforce that. - Curfn = nil + ir.CurFunc = nil if ir.FuncName(fn) == "_" { // We don't need to generate code for this function, just report errors in its body. diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go index 67802fe917..e73e7fbbe1 100644 --- a/src/cmd/compile/internal/gc/racewalk.go +++ b/src/cmd/compile/internal/gc/racewalk.go @@ -35,7 +35,7 @@ func instrument(fn *ir.Func) { // This only works for amd64. This will not // work on arm or others that might support // race in the future. - nodpc := nodfp.CloneName() + nodpc := ir.RegFP.CloneName() nodpc.SetType(types.Types[types.TUINTPTR]) nodpc.SetFrameOffset(int64(-Widthptr)) fn.Dcl = append(fn.Dcl, nodpc) diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index 463d0c55bd..a9447189c2 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -160,7 +160,7 @@ func cheapComputableIndex(width int64) bool { func walkrange(nrange *ir.RangeStmt) ir.Node { if isMapClear(nrange) { m := nrange.X - lno := setlineno(m) + lno := ir.SetPos(m) n := mapClear(m) base.Pos = lno return n @@ -180,7 +180,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node { t := nrange.Type() a := nrange.X - lno := setlineno(a) + lno := ir.SetPos(a) var v1, v2 ir.Node l := len(nrange.Vars) @@ -228,7 +228,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node { init = append(init, ir.NewAssignStmt(base.Pos, hn, ir.NewUnaryExpr(base.Pos, ir.OLEN, ha))) nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, hn) - nfor.Post = ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, nodintconst(1))) + nfor.Post = ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, ir.NewInt(1))) // for range ha { body } if v1 == nil { @@ -272,7 +272,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node { nfor.SetOp(ir.OFORUNTIL) hp := temp(types.NewPtr(nrange.Type().Elem())) - tmp := ir.NewIndexExpr(base.Pos, ha, nodintconst(0)) + tmp := ir.NewIndexExpr(base.Pos, ha, ir.NewInt(0)) tmp.SetBounded(true) init = append(init, ir.NewAssignStmt(base.Pos, hp, nodAddr(tmp))) @@ -335,7 +335,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node { } hb := temp(types.Types[types.TBOOL]) - nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, hb, nodbool(false)) + nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, hb, ir.NewBool(false)) a := ir.NewAssignListStmt(base.Pos, ir.OAS2RECV, nil, nil) a.SetTypecheck(1) a.Lhs = []ir.Node{hv1, hb} @@ -392,10 +392,10 @@ func walkrange(nrange *ir.RangeStmt) ir.Node { // if hv2 < utf8.RuneSelf nif := ir.NewIfStmt(base.Pos, nil, nil, nil) - nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv2, nodintconst(utf8.RuneSelf)) + nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv2, ir.NewInt(utf8.RuneSelf)) // hv1++ - nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, nodintconst(1)))} + nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, hv1, ir.NewBinaryExpr(base.Pos, ir.OADD, hv1, ir.NewInt(1)))} // } else { eif := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil) @@ -488,7 +488,7 @@ func isMapClear(n *ir.RangeStmt) bool { } m := n.X - if delete := stmt.(*ir.CallExpr); !samesafeexpr(delete.Args[0], m) || !samesafeexpr(delete.Args[1], k) { + if delete := stmt.(*ir.CallExpr); !ir.SameSafeExpr(delete.Args[0], m) || !ir.SameSafeExpr(delete.Args[1], k) { return false } @@ -545,12 +545,12 @@ func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node { } lhs := stmt.X.(*ir.IndexExpr) - if !samesafeexpr(lhs.X, a) || !samesafeexpr(lhs.Index, v1) { + if !ir.SameSafeExpr(lhs.X, a) || !ir.SameSafeExpr(lhs.Index, v1) { return nil } elemsize := loop.Type().Elem().Width - if elemsize <= 0 || !isZero(stmt.Y) { + if elemsize <= 0 || !ir.IsZero(stmt.Y) { return nil } @@ -563,25 +563,25 @@ func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node { // } n := ir.NewIfStmt(base.Pos, nil, nil, nil) n.Body.Set(nil) - n.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), nodintconst(0)) + n.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(0)) // hp = &a[0] hp := temp(types.Types[types.TUNSAFEPTR]) - ix := ir.NewIndexExpr(base.Pos, a, nodintconst(0)) + ix := ir.NewIndexExpr(base.Pos, a, ir.NewInt(0)) ix.SetBounded(true) addr := convnop(nodAddr(ix), types.Types[types.TUNSAFEPTR]) n.Body.Append(ir.NewAssignStmt(base.Pos, hp, addr)) // hn = len(a) * sizeof(elem(a)) hn := temp(types.Types[types.TUINTPTR]) - mul := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), nodintconst(elemsize)), types.Types[types.TUINTPTR]) + mul := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(elemsize)), types.Types[types.TUINTPTR]) n.Body.Append(ir.NewAssignStmt(base.Pos, hn, mul)) var fn ir.Node if a.Type().Elem().HasPointers() { // memclrHasPointers(hp, hn) - Curfn.SetWBPos(stmt.Pos()) + ir.CurFunc.SetWBPos(stmt.Pos()) fn = mkcall("memclrHasPointers", nil, nil, hp, hn) } else { // memclrNoHeapPointers(hp, hn) @@ -591,7 +591,7 @@ func arrayClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node { n.Body.Append(fn) // i = len(a) - 1 - v1 = ir.NewAssignStmt(base.Pos, v1, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), nodintconst(1))) + v1 = ir.NewAssignStmt(base.Pos, v1, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OLEN, a), ir.NewInt(1))) n.Body.Append(v1) @@ -608,7 +608,7 @@ func addptr(p ir.Node, n int64) ir.Node { p = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, p) p.SetType(types.Types[types.TUINTPTR]) - p = ir.NewBinaryExpr(base.Pos, ir.OADD, p, nodintconst(n)) + p = ir.NewBinaryExpr(base.Pos, ir.OADD, p, ir.NewInt(n)) p = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, p) p.SetType(t) diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index 41c9f93bf0..8b393a8979 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -349,12 +349,12 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type { in := make([]*ir.Field, 0, inLen) if receiver != nil { - d := anonfield(receiver) + d := ir.NewField(base.Pos, nil, nil, receiver) in = append(in, d) } for _, t := range f.Params().Fields().Slice() { - d := anonfield(t.Type) + d := ir.NewField(base.Pos, nil, nil, t.Type) d.IsDDD = t.IsDDD() in = append(in, d) } @@ -362,7 +362,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type { outLen := f.Results().Fields().Len() out := make([]*ir.Field, 0, outLen) for _, t := range f.Results().Fields().Slice() { - d := anonfield(t.Type) + d := ir.NewField(base.Pos, nil, nil, t.Type) out = append(out, d) } @@ -416,8 +416,8 @@ func methods(t *types.Type) []*Sig { sig := &Sig{ name: method, - isym: methodSym(it, method), - tsym: methodSym(t, method), + isym: ir.MethodSym(it, method), + tsym: ir.MethodSym(t, method), type_: methodfunc(f.Type, t), mtype: methodfunc(f.Type, nil), } @@ -471,7 +471,7 @@ func imethods(t *types.Type) []*Sig { // IfaceType.Method is not in the reflect data. // Generate the method body, so that compiled // code can refer to it. - isym := methodSym(t, f.Sym) + isym := ir.MethodSym(t, f.Sym) if !isym.Siggen() { isym.SetSiggen(true) genwrapper(t, f, isym) @@ -1541,7 +1541,7 @@ func dumpbasictypes() { // The latter is the type of an auto-generated wrapper. dtypesym(types.NewPtr(types.ErrorType)) - dtypesym(functype(nil, []*ir.Field{anonfield(types.ErrorType)}, []*ir.Field{anonfield(types.Types[types.TSTRING])})) + dtypesym(functype(nil, []*ir.Field{ir.NewField(base.Pos, nil, nil, types.ErrorType)}, []*ir.Field{ir.NewField(base.Pos, nil, nil, types.Types[types.TSTRING])})) // add paths for runtime and main, which 6l imports implicitly. dimportpath(ir.Pkgs.Runtime) diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go index 0bf070aa87..67a2cfd312 100644 --- a/src/cmd/compile/internal/gc/select.go +++ b/src/cmd/compile/internal/gc/select.go @@ -13,7 +13,7 @@ import ( // select func typecheckselect(sel *ir.SelectStmt) { var def ir.Node - lno := setlineno(sel) + lno := ir.SetPos(sel) typecheckslice(sel.Init(), ctxStmt) for _, ncase := range sel.Cases { ncase := ncase.(*ir.CaseStmt) @@ -94,7 +94,7 @@ func typecheckselect(sel *ir.SelectStmt) { } func walkselect(sel *ir.SelectStmt) { - lno := setlineno(sel) + lno := ir.SetPos(sel) if len(sel.Compiled) != 0 { base.Fatalf("double walkselect") } @@ -123,7 +123,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { // optimization: one-case select: single op. if ncas == 1 { cas := cases[0].(*ir.CaseStmt) - setlineno(cas) + ir.SetPos(cas) l := cas.Init() if cas.Comm != nil { // not default: n := cas.Comm @@ -158,7 +158,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { var dflt *ir.CaseStmt for _, cas := range cases { cas := cas.(*ir.CaseStmt) - setlineno(cas) + ir.SetPos(cas) n := cas.Comm if n == nil { dflt = cas @@ -187,7 +187,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { } n := cas.Comm - setlineno(n) + ir.SetPos(n) r := ir.NewIfStmt(base.Pos, nil, nil, nil) r.PtrInit().Set(cas.Init()) var call ir.Node @@ -245,7 +245,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { var pc0, pcs ir.Node if base.Flag.Race { pcs = temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas))) - pc0 = typecheck(nodAddr(ir.NewIndexExpr(base.Pos, pcs, nodintconst(0))), ctxExpr) + pc0 = typecheck(nodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(0))), ctxExpr) } else { pc0 = nodnil() } @@ -253,7 +253,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { // register cases for _, cas := range cases { cas := cas.(*ir.CaseStmt) - setlineno(cas) + ir.SetPos(cas) init = append(init, cas.Init()...) cas.PtrInit().Set(nil) @@ -286,7 +286,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { casorder[i] = cas setField := func(f string, val ir.Node) { - r := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, ir.NewIndexExpr(base.Pos, selv, nodintconst(int64(i))), lookup(f)), val) + r := ir.NewAssignStmt(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, ir.NewIndexExpr(base.Pos, selv, ir.NewInt(int64(i))), lookup(f)), val) init = append(init, typecheck(r, ctxStmt)) } @@ -300,7 +300,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { // TODO(mdempsky): There should be a cleaner way to // handle this. if base.Flag.Race { - r := mkcall("selectsetpc", nil, nil, nodAddr(ir.NewIndexExpr(base.Pos, pcs, nodintconst(int64(i))))) + r := mkcall("selectsetpc", nil, nil, nodAddr(ir.NewIndexExpr(base.Pos, pcs, ir.NewInt(int64(i))))) init = append(init, r) } } @@ -315,7 +315,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { r := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil) r.Lhs = []ir.Node{chosen, recvOK} fn := syslook("selectgo") - r.Rhs = []ir.Node{mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil))} + r.Rhs = []ir.Node{mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, ir.NewInt(int64(nsends)), ir.NewInt(int64(nrecvs)), ir.NewBool(dflt == nil))} init = append(init, typecheck(r, ctxStmt)) // selv and order are no longer alive after selectgo. @@ -346,12 +346,12 @@ func walkselectcases(cases ir.Nodes) []ir.Node { } if dflt != nil { - setlineno(dflt) - dispatch(ir.NewBinaryExpr(base.Pos, ir.OLT, chosen, nodintconst(0)), dflt) + ir.SetPos(dflt) + dispatch(ir.NewBinaryExpr(base.Pos, ir.OLT, chosen, ir.NewInt(0)), dflt) } for i, cas := range casorder { - setlineno(cas) - dispatch(ir.NewBinaryExpr(base.Pos, ir.OEQ, chosen, nodintconst(int64(i))), cas) + ir.SetPos(cas) + dispatch(ir.NewBinaryExpr(base.Pos, ir.OEQ, chosen, ir.NewInt(int64(i))), cas) } return init @@ -359,7 +359,7 @@ func walkselectcases(cases ir.Nodes) []ir.Node { // bytePtrToIndex returns a Node representing "(*byte)(&n[i])". func bytePtrToIndex(n ir.Node, i int64) ir.Node { - s := nodAddr(ir.NewIndexExpr(base.Pos, n, nodintconst(i))) + s := nodAddr(ir.NewIndexExpr(base.Pos, n, ir.NewInt(i))) t := types.NewPtr(types.Types[types.TUINT8]) return convnop(s, t) } @@ -370,8 +370,8 @@ var scase *types.Type func scasetype() *types.Type { if scase == nil { scase = tostruct([]*ir.Field{ - namedfield("c", types.Types[types.TUNSAFEPTR]), - namedfield("elem", types.Types[types.TUNSAFEPTR]), + ir.NewField(base.Pos, lookup("c"), nil, types.Types[types.TUNSAFEPTR]), + ir.NewField(base.Pos, lookup("elem"), nil, types.Types[types.TUNSAFEPTR]), }) scase.SetNoalg(true) } diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index c9a554079d..936edb3d70 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -10,7 +10,6 @@ import ( "cmd/compile/internal/types" "cmd/internal/obj" "fmt" - "go/constant" ) type InitEntry struct { @@ -65,7 +64,7 @@ func (s *InitSchedule) tryStaticInit(nn ir.Node) bool { // Discard. return true } - lno := setlineno(n) + lno := ir.SetPos(n) defer func() { base.Pos = lno }() nam := n.X.(*ir.Name) return s.staticassign(nam, 0, n.Y, nam.Type()) @@ -120,7 +119,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type return true case ir.OLITERAL: - if isZero(r) { + if ir.IsZero(r) { return true } litsym(l, loff, r, int(typ.Width)) @@ -170,7 +169,7 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type // copying someone else's computation. ll := ir.NewNameOffsetExpr(base.Pos, l, loff+e.Xoffset, typ) rr := ir.NewNameOffsetExpr(base.Pos, orig, e.Xoffset, typ) - setlineno(rr) + ir.SetPos(rr) s.append(ir.NewAssignStmt(base.Pos, ll, rr)) } @@ -198,7 +197,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type return true case ir.OLITERAL: - if isZero(r) { + if ir.IsZero(r) { return true } litsym(l, loff, r, int(typ.Width)) @@ -263,7 +262,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type litsym(l, loff+e.Xoffset, e.Expr, int(e.Expr.Type().Width)) continue } - setlineno(e.Expr) + ir.SetPos(e.Expr) if !s.staticassign(l, loff+e.Xoffset, e.Expr, e.Expr.Type()) { a := ir.NewNameOffsetExpr(base.Pos, l, loff+e.Xoffset, e.Expr.Type()) s.append(ir.NewAssignStmt(base.Pos, a, e.Expr)) @@ -330,7 +329,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type return true } // Copy val directly into n. - setlineno(val) + ir.SetPos(val) if !s.staticassign(l, loff+int64(Widthptr), val, val.Type()) { a := ir.NewNameOffsetExpr(base.Pos, l, loff+int64(Widthptr), val.Type()) s.append(ir.NewAssignStmt(base.Pos, a, val)) @@ -429,7 +428,7 @@ const ( func getdyn(n ir.Node, top bool) initGenType { switch n.Op() { default: - if isGoConst(n) { + if ir.IsConstNode(n) { return initConst } return initDynamic @@ -548,7 +547,7 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node, } r = kv.Value } - a := ir.NewIndexExpr(base.Pos, var_, nodintconst(k)) + a := ir.NewIndexExpr(base.Pos, var_, ir.NewInt(k)) k++ if isBlank { return ir.BlankNode, r @@ -561,7 +560,7 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node, if r.Field.IsBlank() || isBlank { return ir.BlankNode, r.Value } - setlineno(r) + ir.SetPos(r) return ir.NewSelectorExpr(base.Pos, ir.ODOT, var_, r.Field), r.Value } default: @@ -589,13 +588,13 @@ func fixedlit(ctxt initContext, kind initKind, n *ir.CompLitExpr, var_ ir.Node, continue } - islit := isGoConst(value) + islit := ir.IsConstNode(value) if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) { continue } // build list of assignments: var[index] = expr - setlineno(a) + ir.SetPos(a) as := ir.NewAssignStmt(base.Pos, a, value) as = typecheck(as, ctxStmt).(*ir.AssignStmt) switch kind { @@ -617,7 +616,7 @@ func isSmallSliceLit(n *ir.CompLitExpr) bool { return false } - return n.Type().Elem().Width == 0 || n.Len <= smallArrayBytes/n.Type().Elem().Width + return n.Type().Elem().Width == 0 || n.Len <= ir.MaxSmallArraySize/n.Type().Elem().Width } func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) { @@ -697,7 +696,7 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) } a = nodAddr(x) - } else if n.Esc() == EscNone { + } else if n.Esc() == ir.EscNone { a = temp(t) if vstat == nil { a = ir.NewAssignStmt(base.Pos, temp(t), nil) @@ -731,7 +730,7 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) } value = kv.Value } - a := ir.NewIndexExpr(base.Pos, vauto, nodintconst(index)) + a := ir.NewIndexExpr(base.Pos, vauto, ir.NewInt(index)) a.SetBounded(true) index++ @@ -753,12 +752,12 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) continue } - if vstat != nil && isGoConst(value) { // already set by copy from static value + if vstat != nil && ir.IsConstNode(value) { // already set by copy from static value continue } // build list of vauto[c] = expr - setlineno(value) + ir.SetPos(value) as := typecheck(ir.NewAssignStmt(base.Pos, a, value), ctxStmt) as = orderStmtInPlace(as, map[string][]*ir.Name{}) as = walkstmt(as) @@ -778,7 +777,7 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) { // make the map var a := ir.NewCallExpr(base.Pos, ir.OMAKE, nil, nil) a.SetEsc(n.Esc()) - a.Args = []ir.Node{ir.TypeNode(n.Type()), nodintconst(int64(len(n.List)))} + a.Args = []ir.Node{ir.TypeNode(n.Type()), ir.NewInt(int64(len(n.List)))} litas(m, a, init) entries := n.List @@ -831,9 +830,9 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) { kidx.SetBounded(true) lhs := ir.NewIndexExpr(base.Pos, m, kidx) - zero := ir.NewAssignStmt(base.Pos, i, nodintconst(0)) - cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, nodintconst(tk.NumElem())) - incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, nodintconst(1))) + zero := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0)) + cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(tk.NumElem())) + incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1))) body := ir.NewAssignStmt(base.Pos, lhs, rhs) loop := ir.NewForStmt(base.Pos, nil, cond, incr, nil) @@ -855,13 +854,13 @@ func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) { r := r.(*ir.KeyExpr) index, elem := r.Key, r.Value - setlineno(index) + ir.SetPos(index) appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpkey, index)) - setlineno(elem) + ir.SetPos(elem) appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpelem, elem)) - setlineno(tmpelem) + ir.SetPos(tmpelem) appendWalkStmt(init, ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, tmpkey), tmpelem)) } @@ -992,7 +991,7 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool { } func getlit(lit ir.Node) int { - if smallintconst(lit) { + if ir.IsSmallIntConst(lit) { return int(ir.Int64Val(lit)) } return -1 @@ -1098,7 +1097,7 @@ func (s *InitSchedule) initplan(n ir.Node) { func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n ir.Node) { // special case: zero can be dropped entirely - if isZero(n) { + if ir.IsZero(n) { return } @@ -1118,47 +1117,6 @@ func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n ir.Node) { p.E = append(p.E, InitEntry{Xoffset: xoffset, Expr: n}) } -func isZero(n ir.Node) bool { - switch n.Op() { - case ir.ONIL: - return true - - case ir.OLITERAL: - switch u := n.Val(); u.Kind() { - case constant.String: - return constant.StringVal(u) == "" - case constant.Bool: - return !constant.BoolVal(u) - default: - return constant.Sign(u) == 0 - } - - case ir.OARRAYLIT: - n := n.(*ir.CompLitExpr) - for _, n1 := range n.List { - if n1.Op() == ir.OKEY { - n1 = n1.(*ir.KeyExpr).Value - } - if !isZero(n1) { - return false - } - } - return true - - case ir.OSTRUCTLIT: - n := n.(*ir.CompLitExpr) - for _, n1 := range n.List { - n1 := n1.(*ir.StructKeyExpr) - if !isZero(n1.Value) { - return false - } - } - return true - } - - return false -} - func isvaluelit(n ir.Node) bool { return n.Op() == ir.OARRAYLIT || n.Op() == ir.OSTRUCTLIT } diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 22cc868f36..f879d8b86d 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -1159,7 +1159,7 @@ func (s *state) stmt(n ir.Node) { // Expression statements case ir.OCALLFUNC: n := n.(*ir.CallExpr) - if IsIntrinsicCall(n) { + if ir.IsIntrinsicCall(n) { s.intrinsicCall(n) return } @@ -1186,7 +1186,7 @@ func (s *state) stmt(n ir.Node) { var defertype string if s.hasOpenDefers { defertype = "open-coded" - } else if n.Esc() == EscNever { + } else if n.Esc() == ir.EscNever { defertype = "stack-allocated" } else { defertype = "heap-allocated" @@ -1197,7 +1197,7 @@ func (s *state) stmt(n ir.Node) { s.openDeferRecord(n.Call.(*ir.CallExpr)) } else { d := callDefer - if n.Esc() == EscNever { + if n.Esc() == ir.EscNever { d = callDeferStack } s.callResult(n.Call.(*ir.CallExpr), d) @@ -1232,7 +1232,7 @@ func (s *state) stmt(n ir.Node) { // We come here only when it is an intrinsic call returning two values. n := n.(*ir.AssignListStmt) call := n.Rhs[0].(*ir.CallExpr) - if !IsIntrinsicCall(call) { + if !ir.IsIntrinsicCall(call) { s.Fatalf("non-intrinsic AS2FUNC not expanded %v", call) } v := s.intrinsicCall(call) @@ -1300,7 +1300,7 @@ func (s *state) stmt(n ir.Node) { // All literals with nonzero fields have already been // rewritten during walk. Any that remain are just T{} // or equivalents. Use the zero value. - if !isZero(rhs) { + if !ir.IsZero(rhs) { s.Fatalf("literal with nonzero value in SSA: %v", rhs) } rhs = nil @@ -1309,7 +1309,7 @@ func (s *state) stmt(n ir.Node) { // Check whether we're writing the result of an append back to the same slice. // If so, we handle it specially to avoid write barriers on the fast // (non-growth) path. - if !samesafeexpr(n.X, rhs.Args[0]) || base.Flag.N != 0 { + if !ir.SameSafeExpr(n.X, rhs.Args[0]) || base.Flag.N != 0 { break } // If the slice can be SSA'd, it'll be on the stack, @@ -1362,7 +1362,7 @@ func (s *state) stmt(n ir.Node) { } var skip skipMask - if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && samesafeexpr(rhs.(*ir.SliceExpr).X, n.X) { + if rhs != nil && (rhs.Op() == ir.OSLICE || rhs.Op() == ir.OSLICE3 || rhs.Op() == ir.OSLICESTR) && ir.SameSafeExpr(rhs.(*ir.SliceExpr).X, n.X) { // We're assigning a slicing operation back to its source. // Don't write back fields we aren't changing. See issue #14855. rhs := rhs.(*ir.SliceExpr) @@ -2085,7 +2085,7 @@ func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op { // expr converts the expression n to ssa, adds it to s and returns the ssa result. func (s *state) expr(n ir.Node) *ssa.Value { - if hasUniquePos(n) { + if ir.HasUniquePos(n) { // ONAMEs and named OLITERALs have the line number // of the decl, not the use. See issue 14742. s.pushLine(n.Pos()) @@ -2726,7 +2726,7 @@ func (s *state) expr(n ir.Node) *ssa.Value { // All literals with nonzero fields have already been // rewritten during walk. Any that remain are just T{} // or equivalents. Use the zero value. - if !isZero(n.X) { + if !ir.IsZero(n.X) { s.Fatalf("literal with nonzero value in SSA: %v", n.X) } return s.zeroVal(n.Type()) @@ -2735,7 +2735,7 @@ func (s *state) expr(n ir.Node) *ssa.Value { // SSA, then load just the selected field. This // prevents false memory dependencies in race/msan // instrumentation. - if islvalue(n) && !s.canSSA(n) { + if ir.IsAssignable(n) && !s.canSSA(n) { p := s.addr(n) return s.load(n.Type(), p) } @@ -2880,7 +2880,7 @@ func (s *state) expr(n ir.Node) *ssa.Value { case ir.OCALLFUNC: n := n.(*ir.CallExpr) - if IsIntrinsicCall(n) { + if ir.IsIntrinsicCall(n) { return s.intrinsicCall(n) } fallthrough @@ -2901,7 +2901,7 @@ func (s *state) expr(n ir.Node) *ssa.Value { // rewritten during walk. Any that remain are just T{} // or equivalents. Use the zero value. n := n.(*ir.CompLitExpr) - if !isZero(n) { + if !ir.IsZero(n) { s.Fatalf("literal with nonzero value in SSA: %v", n) } return s.zeroVal(n.Type()) @@ -3236,7 +3236,7 @@ func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask // Left is not ssa-able. Compute its address. addr := s.addr(left) - if isReflectHeaderDataField(left) { + if ir.IsReflectHeaderDataField(left) { // Package unsafe's documentation says storing pointers into // reflect.SliceHeader and reflect.StringHeader's Data fields // is valid, even though they have type uintptr (#19168). @@ -5021,7 +5021,7 @@ func (s *state) addr(n ir.Node) *ssa.Value { if v != nil { return v } - if n == nodfp { + if n == ir.RegFP { // Special arg that points to the frame pointer (Used by ORECOVER). return s.entryNewValue2A(ssa.OpLocalAddr, t, n, s.sp, s.startmem) } @@ -5141,7 +5141,7 @@ func (s *state) canSSAName(name *ir.Name) bool { if name.Addrtaken() { return false } - if isParamHeapCopy(name) { + if ir.IsParamHeapCopy(name) { return false } if name.Class_ == ir.PAUTOHEAP { @@ -7271,7 +7271,7 @@ func (e *ssafn) SplitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t ir.AsNode(s.Def).Name().SetUsed(true) n.SetType(t) n.Class_ = ir.PAUTO - n.SetEsc(EscNever) + n.SetEsc(ir.EscNever) n.Curfn = e.curfn e.curfn.Dcl = append(e.curfn.Dcl, n) dowidth(t) diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index a845abeb3a..bcf17e42d6 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -10,7 +10,6 @@ import ( "cmd/compile/internal/types" "cmd/internal/src" "fmt" - "go/constant" "sort" "strconv" "strings" @@ -32,40 +31,6 @@ var ( largeStackFrames []largeStack ) -// hasUniquePos reports whether n has a unique position that can be -// used for reporting error messages. -// -// It's primarily used to distinguish references to named objects, -// whose Pos will point back to their declaration position rather than -// their usage position. -func hasUniquePos(n ir.Node) bool { - switch n.Op() { - case ir.ONAME, ir.OPACK: - return false - case ir.OLITERAL, ir.ONIL, ir.OTYPE: - if n.Sym() != nil { - return false - } - } - - if !n.Pos().IsKnown() { - if base.Flag.K != 0 { - base.Warn("setlineno: unknown position (line 0)") - } - return false - } - - return true -} - -func setlineno(n ir.Node) src.XPos { - lno := base.Pos - if n != nil && hasUniquePos(n) { - base.Pos = n.Pos() - } - return lno -} - func lookup(name string) *types.Sym { return types.LocalPkg.Lookup(name) } @@ -89,8 +54,8 @@ func autolabel(prefix string) *types.Sym { if prefix[0] != '.' { base.Fatalf("autolabel prefix must start with '.', have %q", prefix) } - fn := Curfn - if Curfn == nil { + fn := ir.CurFunc + if ir.CurFunc == nil { base.Fatalf("autolabel outside function") } n := fn.Label @@ -164,28 +129,16 @@ func nodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr { // newname returns a new ONAME Node associated with symbol s. func NewName(s *types.Sym) *ir.Name { n := ir.NewNameAt(base.Pos, s) - n.Curfn = Curfn + n.Curfn = ir.CurFunc return n } -func nodintconst(v int64) ir.Node { - return ir.NewLiteral(constant.MakeInt64(v)) -} - func nodnil() ir.Node { n := ir.NewNilExpr(base.Pos) n.SetType(types.Types[types.TNIL]) return n } -func nodbool(b bool) ir.Node { - return ir.NewLiteral(constant.MakeBool(b)) -} - -func nodstr(s string) ir.Node { - return ir.NewLiteral(constant.MakeString(s)) -} - func isptrto(t *types.Type, et types.Kind) bool { if t == nil { return false @@ -778,7 +731,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node { } // make a copy; must not be used as an lvalue - if islvalue(n) { + if ir.IsAssignable(n) { base.Fatalf("missing lvalue case in safeexpr: %v", n) } return cheapexpr(n, init) @@ -1109,7 +1062,7 @@ func structargs(tl *types.Type, mustname bool) []*ir.Field { s = lookupN(".anon", gen) gen++ } - a := symfield(s, t.Type) + a := ir.NewField(base.Pos, s, nil, t.Type) a.Pos = t.Pos a.IsDDD = t.IsDDD() args = append(args, a) @@ -1160,7 +1113,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { dclcontext = ir.PEXTERN tfn := ir.NewFuncType(base.Pos, - namedfield(".this", rcvr), + ir.NewField(base.Pos, lookup(".this"), nil, rcvr), structargs(method.Type.Params(), true), structargs(method.Type.Results(), false)) @@ -1198,11 +1151,11 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { } as := ir.NewAssignStmt(base.Pos, nthis, convnop(left, rcvr)) fn.Body.Append(as) - fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.ORETJMP, methodSym(methodrcvr, method.Sym))) + fn.Body.Append(ir.NewBranchStmt(base.Pos, ir.ORETJMP, ir.MethodSym(methodrcvr, method.Sym))) } else { fn.SetWrapper(true) // ignore frame for panic+recover matching call := ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil) - call.Args.Set(paramNnames(tfn.Type())) + call.Args.Set(ir.ParamNames(tfn.Type())) call.IsDDD = tfn.Type().IsVariadic() if method.Type.NumResults() > 0 { ret := ir.NewReturnStmt(base.Pos, nil) @@ -1223,7 +1176,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { } typecheckFunc(fn) - Curfn = fn + ir.CurFunc = fn typecheckslice(fn.Body, ctxStmt) // Inline calls within (*T).M wrappers. This is safe because we only @@ -1234,29 +1187,21 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { } escapeFuncs([]*ir.Func{fn}, false) - Curfn = nil + ir.CurFunc = nil Target.Decls = append(Target.Decls, fn) } -func paramNnames(ft *types.Type) []ir.Node { - args := make([]ir.Node, ft.NumParams()) - for i, f := range ft.Params().FieldSlice() { - args[i] = ir.AsNode(f.Nname) - } - return args -} - func hashmem(t *types.Type) ir.Node { sym := ir.Pkgs.Runtime.Lookup("memhash") n := NewName(sym) - setNodeNameFunc(n) + ir.MarkFunc(n) n.SetType(functype(nil, []*ir.Field{ - anonfield(types.NewPtr(t)), - anonfield(types.Types[types.TUINTPTR]), - anonfield(types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, nil, nil, types.NewPtr(t)), + ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]), }, []*ir.Field{ - anonfield(types.Types[types.TUINTPTR]), + ir.NewField(base.Pos, nil, nil, types.Types[types.TUINTPTR]), })) return n } @@ -1367,15 +1312,6 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool return true } -func liststmt(l []ir.Node) ir.Node { - n := ir.NewBlockStmt(base.Pos, nil) - n.List.Set(l) - if len(l) != 0 { - n.SetPos(l[0].Pos()) - } - return n -} - func ngotype(n ir.Node) *types.Sym { if n.Type() != nil { return typenamesym(n.Type()) @@ -1383,25 +1319,6 @@ func ngotype(n ir.Node) *types.Sym { return nil } -// The result of initExpr MUST be assigned back to n, e.g. -// n.Left = initExpr(init, n.Left) -func initExpr(init []ir.Node, n ir.Node) ir.Node { - if len(init) == 0 { - return n - } - if ir.MayBeShared(n) { - // Introduce OCONVNOP to hold init list. - old := n - n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, old) - n.SetType(old.Type()) - n.SetTypecheck(1) - } - - n.PtrInit().Prepend(init...) - n.SetHasCall(true) - return n -} - // The linker uses the magic symbol prefixes "go." and "type." // Avoid potential confusion between import paths and symbols // by rejecting these reserved imports for now. Also, people diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 513b890355..5bbc91fcc1 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -190,7 +190,7 @@ func typecheckExprSwitch(n *ir.SwitchStmt) { } for i := range ls { - setlineno(ncase) + ir.SetPos(ncase) ls[i] = typecheck(ls[i], ctxExpr) ls[i] = defaultlit(ls[i], t) n1 := ls[i] @@ -246,14 +246,14 @@ func walkswitch(sw *ir.SwitchStmt) { // walkExprSwitch generates an AST implementing sw. sw is an // expression switch. func walkExprSwitch(sw *ir.SwitchStmt) { - lno := setlineno(sw) + lno := ir.SetPos(sw) cond := sw.Tag sw.Tag = nil // convert switch {...} to switch true {...} if cond == nil { - cond = nodbool(true) + cond = ir.NewBool(true) cond = typecheck(cond, ctxExpr) cond = defaultlit(cond, nil) } @@ -398,11 +398,11 @@ func (s *exprSwitch) flush() { // Perform two-level binary search. binarySearch(len(runs), &s.done, func(i int) ir.Node { - return ir.NewBinaryExpr(base.Pos, ir.OLE, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), nodintconst(runLen(runs[i-1]))) + return ir.NewBinaryExpr(base.Pos, ir.OLE, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), ir.NewInt(runLen(runs[i-1]))) }, func(i int, nif *ir.IfStmt) { run := runs[i] - nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), nodintconst(runLen(run))) + nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, ir.NewUnaryExpr(base.Pos, ir.OLEN, s.exprname), ir.NewInt(runLen(run))) s.search(run, &nif.Body) }, ) @@ -708,13 +708,13 @@ func (s *typeSwitch) flush() { binarySearch(len(cc), &s.done, func(i int) ir.Node { - return ir.NewBinaryExpr(base.Pos, ir.OLE, s.hashname, nodintconst(int64(cc[i-1].hash))) + return ir.NewBinaryExpr(base.Pos, ir.OLE, s.hashname, ir.NewInt(int64(cc[i-1].hash))) }, func(i int, nif *ir.IfStmt) { // TODO(mdempsky): Omit hash equality check if // there's only one type. c := cc[i] - nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, s.hashname, nodintconst(int64(c.hash))) + nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, s.hashname, ir.NewInt(int64(c.hash))) nif.Body.Append(c.body.Take()...) }, ) diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 5e13facc4f..0beb5712d4 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -98,13 +98,13 @@ func TypecheckPackage() { if n.Op() == ir.ODCLFUNC { n := n.(*ir.Func) if n.OClosure != nil { - Curfn = n + ir.CurFunc = n capturevars(n) } } } capturevarscomplete = true - Curfn = nil + ir.CurFunc = nil if base.Debug.TypecheckInl != 0 { // Typecheck imported function bodies if Debug.l > 1, @@ -139,7 +139,7 @@ func TypecheckCallee(n ir.Node) ir.Node { } func TypecheckFuncBody(n *ir.Func) { - Curfn = n + ir.CurFunc = n decldepth = 1 errorsBefore := base.Errors() typecheckslice(n.Body, ctxStmt) @@ -259,7 +259,7 @@ func resolve(n ir.Node) (res ir.Node) { if r.Op() == ir.OIOTA { if x := getIotaValue(); x >= 0 { - return nodintconst(x) + return ir.NewInt(x) } return n } @@ -380,7 +380,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) { defer tracePrint("typecheck", n)(&res) } - lno := setlineno(n) + lno := ir.SetPos(n) // Skip over parens. for n.Op() == ir.OPAREN { @@ -682,7 +682,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { } v := size.Val() - if doesoverflow(v, types.Types[types.TINT]) { + if ir.ConstOverflow(v, types.Types[types.TINT]) { base.Errorf("array bound is too large") return n } @@ -1076,7 +1076,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { default: checklvalue(n.X, "take the address of") - r := outervalue(n.X) + r := ir.OuterValue(n.X) if r.Op() == ir.ONAME { r := r.(*ir.Name) if ir.Orig(r) != r { @@ -1270,7 +1270,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Index, t.NumElem()) } else if ir.IsConst(n.X, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(ir.StringVal(n.X))))) { base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Index, len(ir.StringVal(n.X))) - } else if doesoverflow(x, types.Types[types.TINT]) { + } else if ir.ConstOverflow(x, types.Types[types.TINT]) { base.Errorf("invalid %s index %v (index too large)", why, n.Index) } } @@ -1412,7 +1412,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { } if ir.IsConst(n.Len, constant.Int) { - if doesoverflow(n.Len.Val(), types.Types[types.TINT]) { + if ir.ConstOverflow(n.Len.Val(), types.Types[types.TINT]) { base.Fatalf("len for OMAKESLICECOPY too large") } if constant.Sign(n.Len.Val()) < 0 { @@ -1440,7 +1440,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { return n } if l.Type().IsArray() { - if !islvalue(n.X) { + if !ir.IsAssignable(n.X) { base.Errorf("invalid operation %v (slice of unaddressable value)", n) n.SetType(nil) return n @@ -1538,7 +1538,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { return n } u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg) - return typecheck(initExpr(n.Init(), u), top) // typecheckargs can add to old.Init + return typecheck(ir.InitExpr(n.Init(), u), top) // typecheckargs can add to old.Init case ir.OCOMPLEX, ir.OCOPY: typecheckargs(n) @@ -1548,7 +1548,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { return n } b := ir.NewBinaryExpr(n.Pos(), l.BuiltinOp, arg1, arg2) - return typecheck(initExpr(n.Init(), b), top) // typecheckargs can add to old.Init + return typecheck(ir.InitExpr(n.Init(), b), top) // typecheckargs can add to old.Init } panic("unreachable") } @@ -2023,7 +2023,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { return n } } else { - l = nodintconst(0) + l = ir.NewInt(0) } nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil) nn.SetEsc(n.Esc()) @@ -2044,7 +2044,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { return n } } else { - l = nodintconst(0) + l = ir.NewInt(0) } nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil) } @@ -2257,16 +2257,16 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { case ir.ORETURN: n := n.(*ir.ReturnStmt) typecheckargs(n) - if Curfn == nil { + if ir.CurFunc == nil { base.Errorf("return outside function") n.SetType(nil) return n } - if hasNamedResults(Curfn) && len(n.Results) == 0 { + if ir.HasNamedResults(ir.CurFunc) && len(n.Results) == 0 { return n } - typecheckaste(ir.ORETURN, nil, false, Curfn.Type().Results(), n.Results, func() string { return "return argument" }) + typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), n.Results, func() string { return "return argument" }) return n case ir.ORETJMP: @@ -2352,9 +2352,9 @@ func typecheckargs(n ir.Node) { // init.go hasn't yet created it. Instead, associate the // temporary variables with initTodo for now, and init.go // will reassociate them later when it's appropriate. - static := Curfn == nil + static := ir.CurFunc == nil if static { - Curfn = initTodo + ir.CurFunc = initTodo } list = nil for _, f := range t.FieldSlice() { @@ -2364,7 +2364,7 @@ func typecheckargs(n ir.Node) { list = append(list, t) } if static { - Curfn = nil + ir.CurFunc = nil } switch n := n.(type) { @@ -2398,7 +2398,7 @@ func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool { } else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(ir.StringVal(l))))) { base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(ir.StringVal(l))) return false - } else if doesoverflow(x, types.Types[types.TINT]) { + } else if ir.ConstOverflow(x, types.Types[types.TINT]) { base.Errorf("invalid slice index %v (index too large)", r) return false } @@ -2603,7 +2603,7 @@ func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) { me := ir.NewMethodExpr(n.Pos(), n.X.Type(), m) me.SetType(methodfunc(m.Type, n.X.Type())) - f := NewName(methodSym(t, m.Sym)) + f := NewName(ir.MethodSym(t, m.Sym)) f.Class_ = ir.PFUNC f.SetType(me.Type()) me.FuncName_ = f @@ -2717,7 +2717,7 @@ func lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field { return nil } - n.Sel = methodSym(n.X.Type(), f2.Sym) + n.Sel = ir.MethodSym(n.X.Type(), f2.Sym) n.Offset = f2.Offset n.SetType(f2.Type) n.SetOp(ir.ODOTMETH) @@ -2801,7 +2801,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i goto toomany } n = nl[i] - setlineno(n) + ir.SetPos(n) if n.Type() != nil { nl[i] = assignconvfn(n, t, desc) } @@ -2811,7 +2811,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i // TODO(mdempsky): Make into ... call with implicit slice. for ; i < len(nl); i++ { n = nl[i] - setlineno(n) + ir.SetPos(n) if n.Type() != nil { nl[i] = assignconvfn(n, t.Elem(), desc) } @@ -2823,7 +2823,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i goto notenough } n = nl[i] - setlineno(n) + ir.SetPos(n) if n.Type() != nil { nl[i] = assignconvfn(n, t, desc) } @@ -2998,7 +2998,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) { // Save original node (including n.Right) n.SetOrig(ir.Copy(n)) - setlineno(n.Ntype) + ir.SetPos(n.Ntype) // Need to handle [...]T arrays specially. if array, ok := n.Ntype.(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil { @@ -3042,7 +3042,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) { case types.TMAP: var cs constSet for i3, l := range n.List { - setlineno(l) + ir.SetPos(l) if l.Op() != ir.OKEY { n.List[i3] = typecheck(l, ctxExpr) base.Errorf("missing key in map literal") @@ -3074,7 +3074,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) { // simple list of variables ls := n.List for i, n1 := range ls { - setlineno(n1) + ir.SetPos(n1) n1 = typecheck(n1, ctxExpr) ls[i] = n1 if i >= t.NumFields() { @@ -3105,7 +3105,7 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) { // keyed list ls := n.List for i, l := range ls { - setlineno(l) + ir.SetPos(l) if l.Op() == ir.OKEY { kv := l.(*ir.KeyExpr) @@ -3199,7 +3199,7 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx st var key, length int64 for i, elt := range elts { - setlineno(elt) + ir.SetPos(elt) r := elts[i] var kv *ir.KeyExpr if elt.Op() == ir.OKEY { @@ -3264,41 +3264,8 @@ func nonexported(sym *types.Sym) bool { return sym != nil && !types.IsExported(sym.Name) } -// lvalue etc -func islvalue(n ir.Node) bool { - switch n.Op() { - case ir.OINDEX: - n := n.(*ir.IndexExpr) - if n.X.Type() != nil && n.X.Type().IsArray() { - return islvalue(n.X) - } - if n.X.Type() != nil && n.X.Type().IsString() { - return false - } - fallthrough - case ir.ODEREF, ir.ODOTPTR, ir.OCLOSUREREAD: - return true - - case ir.ODOT: - n := n.(*ir.SelectorExpr) - return islvalue(n.X) - - case ir.ONAME: - n := n.(*ir.Name) - if n.Class_ == ir.PFUNC { - return false - } - return true - - case ir.ONAMEOFFSET: - return true - } - - return false -} - func checklvalue(n ir.Node, verb string) { - if !islvalue(n) { + if !ir.IsAssignable(n) { base.Errorf("cannot %s %v", verb, n) } } @@ -3306,7 +3273,7 @@ func checklvalue(n ir.Node, verb string) { func checkassign(stmt ir.Node, n ir.Node) { // Variables declared in ORANGE are assigned on every iteration. if !ir.DeclaredBy(n, stmt) || stmt.Op() == ir.ORANGE { - r := outervalue(n) + r := ir.OuterValue(n) if r.Op() == ir.ONAME { r := r.(*ir.Name) r.Name().SetAssigned(true) @@ -3316,7 +3283,7 @@ func checkassign(stmt ir.Node, n ir.Node) { } } - if islvalue(n) { + if ir.IsAssignable(n) { return } if n.Op() == ir.OINDEXMAP { @@ -3335,7 +3302,7 @@ func checkassign(stmt ir.Node, n ir.Node) { base.Errorf("cannot assign to struct field %v in map", n) case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR: base.Errorf("cannot assign to %v (strings are immutable)", n) - case n.Op() == ir.OLITERAL && n.Sym() != nil && isGoConst(n): + case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n): base.Errorf("cannot assign to %v (declared const)", n) default: base.Errorf("cannot assign to %v", n) @@ -3349,77 +3316,6 @@ func checkassignlist(stmt ir.Node, l ir.Nodes) { } } -// samesafeexpr checks whether it is safe to reuse one of l and r -// instead of computing both. samesafeexpr assumes that l and r are -// used in the same statement or expression. In order for it to be -// safe to reuse l or r, they must: -// * be the same expression -// * not have side-effects (no function calls, no channel ops); -// however, panics are ok -// * not cause inappropriate aliasing; e.g. two string to []byte -// conversions, must result in two distinct slices -// -// The handling of OINDEXMAP is subtle. OINDEXMAP can occur both -// as an lvalue (map assignment) and an rvalue (map access). This is -// currently OK, since the only place samesafeexpr gets used on an -// lvalue expression is for OSLICE and OAPPEND optimizations, and it -// is correct in those settings. -func samesafeexpr(l ir.Node, r ir.Node) bool { - if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) { - return false - } - - switch l.Op() { - case ir.ONAME, ir.OCLOSUREREAD: - return l == r - - case ir.ODOT, ir.ODOTPTR: - l := l.(*ir.SelectorExpr) - r := r.(*ir.SelectorExpr) - return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && samesafeexpr(l.X, r.X) - - case ir.ODEREF: - l := l.(*ir.StarExpr) - r := r.(*ir.StarExpr) - return samesafeexpr(l.X, r.X) - - case ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG: - l := l.(*ir.UnaryExpr) - r := r.(*ir.UnaryExpr) - return samesafeexpr(l.X, r.X) - - case ir.OCONVNOP: - l := l.(*ir.ConvExpr) - r := r.(*ir.ConvExpr) - return samesafeexpr(l.X, r.X) - - case ir.OCONV: - l := l.(*ir.ConvExpr) - r := r.(*ir.ConvExpr) - // Some conversions can't be reused, such as []byte(str). - // Allow only numeric-ish types. This is a bit conservative. - return types.IsSimple[l.Type().Kind()] && samesafeexpr(l.X, r.X) - - case ir.OINDEX, ir.OINDEXMAP: - l := l.(*ir.IndexExpr) - r := r.(*ir.IndexExpr) - return samesafeexpr(l.X, r.X) && samesafeexpr(l.Index, r.Index) - - case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD: - l := l.(*ir.BinaryExpr) - r := r.(*ir.BinaryExpr) - return samesafeexpr(l.X, r.X) && samesafeexpr(l.Y, r.Y) - - case ir.OLITERAL: - return constant.Compare(l.Val(), token.EQL, r.Val()) - - case ir.ONIL: - return true - } - - return false -} - // type check assignment. // if this assignment is the definition of a var on the left side, // fill in the var's type. @@ -3639,7 +3535,7 @@ func typecheckfunc(n *ir.Func) { return } - n.Nname.SetSym(methodSym(rcvr.Type, n.Shortname)) + n.Nname.SetSym(ir.MethodSym(rcvr.Type, n.Shortname)) declare(n.Nname, ir.PFUNC) } @@ -3658,7 +3554,7 @@ func stringtoruneslit(n *ir.ConvExpr) ir.Node { var l []ir.Node i := 0 for _, r := range ir.StringVal(n.X) { - l = append(l, ir.NewKeyExpr(base.Pos, nodintconst(int64(i)), nodintconst(int64(r)))) + l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(int64(i)), ir.NewInt(int64(r)))) i++ } @@ -3716,7 +3612,7 @@ func typecheckdef(n ir.Node) { defer tracePrint("typecheckdef", n)(nil) } - lno := setlineno(n) + lno := ir.SetPos(n) if n.Op() == ir.ONONAME { if !n.Diag() { @@ -3779,7 +3675,7 @@ func typecheckdef(n ir.Node) { if e.Type() == nil { goto ret } - if !isGoConst(e) { + if !ir.IsConstNode(e) { if !e.Diag() { if e.Op() == ir.ONIL { base.ErrorfAt(n.Pos(), "const initializer cannot be nil") @@ -3904,7 +3800,7 @@ func checkmake(t *types.Type, arg string, np *ir.Node) bool { base.Errorf("negative %s argument in make(%v)", arg, t) return false } - if doesoverflow(v, types.Types[types.TINT]) { + if ir.ConstOverflow(v, types.Types[types.TINT]) { base.Errorf("%s argument too large in make(%v)", arg, t) return false } @@ -4236,8 +4132,8 @@ func getIotaValue() int64 { } } - if Curfn != nil && Curfn.Iota >= 0 { - return Curfn.Iota + if ir.CurFunc != nil && ir.CurFunc.Iota >= 0 { + return ir.CurFunc.Iota } return -1 @@ -4245,33 +4141,10 @@ func getIotaValue() int64 { // curpkg returns the current package, based on Curfn. func curpkg() *types.Pkg { - fn := Curfn + fn := ir.CurFunc if fn == nil { // Initialization expressions for package-scope variables. return types.LocalPkg } return fnpkg(fn.Nname) } - -// MethodName returns the ONAME representing the method -// referenced by expression n, which must be a method selector, -// method expression, or method value. -func methodExprName(n ir.Node) *ir.Name { - name, _ := methodExprFunc(n).Nname.(*ir.Name) - return name -} - -// MethodFunc is like MethodName, but returns the types.Field instead. -func methodExprFunc(n ir.Node) *types.Field { - switch n.Op() { - case ir.ODOTMETH: - return n.(*ir.SelectorExpr).Selection - case ir.OMETHEXPR: - return n.(*ir.MethodExpr).Method - case ir.OCALLPART: - n := n.(*ir.CallPartExpr) - return callpartMethod(n) - } - base.Fatalf("unexpected node: %v (%v)", n, n.Op()) - panic("unreachable") -} diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go index c9cce4b488..b7472ede0f 100644 --- a/src/cmd/compile/internal/gc/universe.go +++ b/src/cmd/compile/internal/gc/universe.go @@ -340,8 +340,8 @@ func finishUniverse() { s1.Block = s.Block } - nodfp = NewName(lookup(".fp")) - nodfp.SetType(types.Types[types.TINT32]) - nodfp.Class_ = ir.PPARAM - nodfp.SetUsed(true) + ir.RegFP = NewName(lookup(".fp")) + ir.RegFP.SetType(types.Types[types.TINT32]) + ir.RegFP.Class_ = ir.PPARAM + ir.RegFP.SetUsed(true) } diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 5d812064b6..dd376a8835 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -10,6 +10,7 @@ import ( "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/objabi" + "cmd/internal/src" "cmd/internal/sys" "encoding/binary" "errors" @@ -24,7 +25,7 @@ const tmpstringbufsize = 32 const zeroValSize = 1024 // must match value of runtime/map.go:maxZero func walk(fn *ir.Func) { - Curfn = fn + ir.CurFunc = fn errorsBefore := base.Errors() order(fn) if base.Errors() > errorsBefore { @@ -32,8 +33,8 @@ func walk(fn *ir.Func) { } if base.Flag.W != 0 { - s := fmt.Sprintf("\nbefore walk %v", Curfn.Sym()) - ir.DumpList(s, Curfn.Body) + s := fmt.Sprintf("\nbefore walk %v", ir.CurFunc.Sym()) + ir.DumpList(s, ir.CurFunc.Body) } lno := base.Pos @@ -72,17 +73,17 @@ func walk(fn *ir.Func) { if base.Errors() > errorsBefore { return } - walkstmtlist(Curfn.Body) + walkstmtlist(ir.CurFunc.Body) if base.Flag.W != 0 { - s := fmt.Sprintf("after walk %v", Curfn.Sym()) - ir.DumpList(s, Curfn.Body) + s := fmt.Sprintf("after walk %v", ir.CurFunc.Sym()) + ir.DumpList(s, ir.CurFunc.Body) } zeroResults() heapmoves() - if base.Flag.W != 0 && len(Curfn.Enter) > 0 { - s := fmt.Sprintf("enter %v", Curfn.Sym()) - ir.DumpList(s, Curfn.Enter) + if base.Flag.W != 0 && len(ir.CurFunc.Enter) > 0 { + s := fmt.Sprintf("enter %v", ir.CurFunc.Sym()) + ir.DumpList(s, ir.CurFunc.Enter) } if base.Flag.Cfg.Instrumenting { @@ -100,7 +101,7 @@ func paramoutheap(fn *ir.Func) bool { for _, ln := range fn.Dcl { switch ln.Class_ { case ir.PPARAMOUT: - if isParamStackCopy(ln) || ln.Addrtaken() { + if ir.IsParamStackCopy(ln) || ln.Addrtaken() { return true } @@ -120,7 +121,7 @@ func walkstmt(n ir.Node) ir.Node { return n } - setlineno(n) + ir.SetPos(n) walkstmtlist(n.Init()) @@ -191,7 +192,7 @@ func walkstmt(n ir.Node) ir.Node { n.X = walkexpr(n.X, &init) call := walkexpr(mkcall1(chanfn("chanrecv1", 2, n.X.Type()), nil, &init, n.X, nodnil()), &init) - return initExpr(init, call) + return ir.InitExpr(init, call) case ir.OBREAK, ir.OCONTINUE, @@ -230,18 +231,18 @@ func walkstmt(n ir.Node) ir.Node { case ir.ODEFER: n := n.(*ir.GoDeferStmt) - Curfn.SetHasDefer(true) - Curfn.NumDefers++ - if Curfn.NumDefers > maxOpenDefers { + ir.CurFunc.SetHasDefer(true) + ir.CurFunc.NumDefers++ + if ir.CurFunc.NumDefers > maxOpenDefers { // Don't allow open-coded defers if there are more than // 8 defers in the function, since we use a single // byte to record active defers. - Curfn.SetOpenCodedDeferDisallowed(true) + ir.CurFunc.SetOpenCodedDeferDisallowed(true) } - if n.Esc() != EscNever { + if n.Esc() != ir.EscNever { // If n.Esc is not EscNever, then this defer occurs in a loop, // so open-coded defers cannot be used in this function. - Curfn.SetOpenCodedDeferDisallowed(true) + ir.CurFunc.SetOpenCodedDeferDisallowed(true) } fallthrough case ir.OGO: @@ -288,7 +289,7 @@ func walkstmt(n ir.Node) ir.Node { init := n.Cond.Init() n.Cond.PtrInit().Set(nil) n.Cond = walkexpr(n.Cond, &init) - n.Cond = initExpr(init, n.Cond) + n.Cond = ir.InitExpr(init, n.Cond) } n.Post = walkstmt(n.Post) @@ -307,23 +308,23 @@ func walkstmt(n ir.Node) ir.Node { case ir.ORETURN: n := n.(*ir.ReturnStmt) - Curfn.NumReturns++ + ir.CurFunc.NumReturns++ if len(n.Results) == 0 { return n } - if (hasNamedResults(Curfn) && len(n.Results) > 1) || paramoutheap(Curfn) { + if (ir.HasNamedResults(ir.CurFunc) && len(n.Results) > 1) || paramoutheap(ir.CurFunc) { // assign to the function out parameters, // so that ascompatee can fix up conflicts var rl []ir.Node - for _, ln := range Curfn.Dcl { + for _, ln := range ir.CurFunc.Dcl { cl := ln.Class_ if cl == ir.PAUTO || cl == ir.PAUTOHEAP { break } if cl == ir.PPARAMOUT { var ln ir.Node = ln - if isParamStackCopy(ln) { + if ir.IsParamStackCopy(ln) { ln = walkexpr(typecheck(ir.NewStarExpr(base.Pos, ln.Name().Heapaddr), ctxExpr), nil) } rl = append(rl, ln) @@ -345,12 +346,12 @@ func walkstmt(n ir.Node) ir.Node { walkexprlist(n.Results, n.PtrInit()) // For each return parameter (lhs), assign the corresponding result (rhs). - lhs := Curfn.Type().Results() + lhs := ir.CurFunc.Type().Results() rhs := n.Results res := make([]ir.Node, lhs.NumFields()) for i, nl := range lhs.FieldSlice() { nname := ir.AsNode(nl.Nname) - if isParamHeapCopy(nname) { + if ir.IsParamHeapCopy(nname) { nname = nname.Name().Stackcopy } a := ir.NewAssignStmt(base.Pos, nname, rhs[i]) @@ -485,7 +486,7 @@ func walkexpr(n ir.Node, init *ir.Nodes) ir.Node { init.Append(n.PtrInit().Take()...) } - lno := setlineno(n) + lno := ir.SetPos(n) if base.Flag.LowerW > 1 { ir.Dump("before walk expr", n) @@ -643,7 +644,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { var ll ir.Nodes n.Y = walkexpr(n.Y, &ll) - n.Y = initExpr(ll, n.Y) + n.Y = ir.InitExpr(ll, n.Y) return n case ir.OPRINT, ir.OPRINTN: @@ -655,7 +656,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case ir.ORECOVER: n := n.(*ir.CallExpr) - return mkcall("gorecover", n.Type(), init, nodAddr(nodfp)) + return mkcall("gorecover", n.Type(), init, nodAddr(ir.RegFP)) case ir.OCLOSUREREAD, ir.OCFUNC: return n @@ -710,7 +711,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if left.Op() == ir.OINDEXMAP && right.Op() == ir.OAPPEND { left := left.(*ir.IndexExpr) mapAppend = right.(*ir.CallExpr) - if !samesafeexpr(left, mapAppend.Args[0]) { + if !ir.SameSafeExpr(left, mapAppend.Args[0]) { base.Fatalf("not same expressions: %v != %v", left, mapAppend.Args[0]) } } @@ -738,7 +739,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { return as } - if !base.Flag.Cfg.Instrumenting && isZero(as.Y) { + if !base.Flag.Cfg.Instrumenting && ir.IsZero(as.Y) { return as } @@ -794,7 +795,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { init.Append(n.PtrInit().Take()...) walkexprlistsafe(n.Lhs, init) walkexprlistsafe(n.Rhs, init) - return liststmt(ascompatee(ir.OAS, n.Lhs, n.Rhs, init)) + return ir.NewBlockStmt(src.NoXPos, ascompatee(ir.OAS, n.Lhs, n.Rhs, init)) // a,b,... = fn() case ir.OAS2FUNC: @@ -805,14 +806,14 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { walkexprlistsafe(n.Lhs, init) r = walkexpr(r, init) - if IsIntrinsicCall(r.(*ir.CallExpr)) { + if ir.IsIntrinsicCall(r.(*ir.CallExpr)) { n.Rhs = []ir.Node{r} return n } init.Append(r) ll := ascompatet(n.Lhs, r.Type()) - return liststmt(ll) + return ir.NewBlockStmt(src.NoXPos, ll) // x, y = <-c // order.stmt made sure x is addressable or blank. @@ -926,8 +927,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { fromType := n.X.Type() toType := n.Type() - if !fromType.IsInterface() && !ir.IsBlank(Curfn.Nname) { // skip unnamed functions (func _()) - markTypeUsedInInterface(fromType, Curfn.LSym) + if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) { // skip unnamed functions (func _()) + markTypeUsedInInterface(fromType, ir.CurFunc.LSym) } // typeword generates the type word of the interface value. @@ -971,9 +972,9 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // and staticuint64s[n.Left * 8 + 7] on big-endian. n.X = cheapexpr(n.X, init) // byteindex widens n.Left so that the multiplication doesn't overflow. - index := ir.NewBinaryExpr(base.Pos, ir.OLSH, byteindex(n.X), nodintconst(3)) + index := ir.NewBinaryExpr(base.Pos, ir.OLSH, byteindex(n.X), ir.NewInt(3)) if thearch.LinkArch.ByteOrder == binary.BigEndian { - index = ir.NewBinaryExpr(base.Pos, ir.OADD, index, nodintconst(7)) + index = ir.NewBinaryExpr(base.Pos, ir.OADD, index, ir.NewInt(7)) } xe := ir.NewIndexExpr(base.Pos, ir.Names.Staticuint64s, index) xe.SetBounded(true) @@ -981,7 +982,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class_ == ir.PEXTERN && n.X.(*ir.Name).Readonly(): // n.Left is a readonly global; use it directly. value = n.X - case !fromType.IsInterface() && n.Esc() == EscNone && fromType.Width <= 1024: + case !fromType.IsInterface() && n.Esc() == ir.EscNone && fromType.Width <= 1024: // n.Left does not escape. Use a stack temporary initialized to n.Left. value = temp(fromType) init.Append(typecheck(ir.NewAssignStmt(base.Pos, value, n.X), ctxStmt)) @@ -1058,7 +1059,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // with a non-interface, especially in a switch on interface value // with non-interface cases, is not visible to order.stmt, so we // have to fall back on allocating a temp here. - if !islvalue(v) { + if !ir.IsAssignable(v) { v = copyexpr(v, v.Type(), init) } v = nodAddr(v) @@ -1078,7 +1079,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if n.Op() == ir.OCONVNOP && n.Type() == n.X.Type() { return n.X } - if n.Op() == ir.OCONVNOP && checkPtr(Curfn, 1) { + if n.Op() == ir.OCONVNOP && ir.ShouldCheckPtr(ir.CurFunc, 1) { if n.Type().IsPtr() && n.X.Type().IsUnsafePtr() { // unsafe.Pointer to *T return walkCheckPtrAlignment(n, init, nil) } @@ -1177,7 +1178,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) { base.Warn("index bounds check elided") } - if smallintconst(n.Index) && !n.Bounded() { + if ir.IsSmallIntConst(n.Index) && !n.Bounded() { base.Errorf("index out of bounds") } } else if ir.IsConst(n.X, constant.String) { @@ -1185,13 +1186,13 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) { base.Warn("index bounds check elided") } - if smallintconst(n.Index) && !n.Bounded() { + if ir.IsSmallIntConst(n.Index) && !n.Bounded() { base.Errorf("index out of bounds") } } if ir.IsConst(n.Index, constant.Int) { - if v := n.Index.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[types.TINT]) { + if v := n.Index.Val(); constant.Sign(v) < 0 || ir.ConstOverflow(v, types.Types[types.TINT]) { base.Errorf("index out of bounds") } } @@ -1252,7 +1253,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR: n := n.(*ir.SliceExpr) - checkSlice := checkPtr(Curfn, 1) && n.Op() == ir.OSLICE3ARR && n.X.Op() == ir.OCONVNOP && n.X.(*ir.ConvExpr).X.Type().IsUnsafePtr() + checkSlice := ir.ShouldCheckPtr(ir.CurFunc, 1) && n.Op() == ir.OSLICE3ARR && n.X.Op() == ir.OCONVNOP && n.X.(*ir.ConvExpr).X.Type().IsUnsafePtr() if checkSlice { conv := n.X.(*ir.ConvExpr) conv.X = walkexpr(conv.X, init) @@ -1262,7 +1263,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { low, high, max := n.SliceBounds() low = walkexpr(low, init) - if low != nil && isZero(low) { + if low != nil && ir.IsZero(low) { // Reduce x[0:j] to x[:j] and x[0:j:k] to x[:j:k]. low = nil } @@ -1274,7 +1275,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { } if n.Op().IsSlice3() { - if max != nil && max.Op() == ir.OCAP && samesafeexpr(n.X, max.(*ir.UnaryExpr).X) { + if max != nil && max.Op() == ir.OCAP && ir.SameSafeExpr(n.X, max.(*ir.UnaryExpr).X) { // Reduce x[i:j:cap(x)] to x[i:j]. if n.Op() == ir.OSLICE3 { n.SetOp(ir.OSLICE) @@ -1292,8 +1293,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if n.Type().Elem().NotInHeap() { base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type().Elem()) } - if n.Esc() == EscNone { - if n.Type().Elem().Width >= maxImplicitStackVarSize { + if n.Esc() == ir.EscNone { + if n.Type().Elem().Width >= ir.MaxImplicitStackVarSize { base.Fatalf("large ONEW with EscNone: %v", n) } r := temp(n.Type().Elem()) @@ -1346,7 +1347,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // var h *hmap var h ir.Node - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { // Allocate hmap on stack. // var hv hmap @@ -1372,7 +1373,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // h.buckets = b // } - nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, hint, nodintconst(BUCKETSIZE)), nil, nil) + nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, hint, ir.NewInt(BUCKETSIZE)), nil, nil) nif.Likely = true // var bv bmap @@ -1398,7 +1399,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // For hint <= BUCKETSIZE overLoadFactor(hint, 0) is false // and no buckets will be allocated by makemap. Therefore, // no buckets need to be allocated in this code path. - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { // Only need to initialize h.hash0 since // hmap h has been allocated on the stack already. // h.hash0 = fastrand() @@ -1414,7 +1415,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { return mkcall1(fn, n.Type(), init) } - if n.Esc() != EscNone { + if n.Esc() != ir.EscNone { h = nodnil() } // Map initialization with a variable or large hint is @@ -1452,7 +1453,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if t.Elem().NotInHeap() { base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem()) } - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { if why := heapAllocReason(n); why != "" { base.Fatalf("%v has EscNone, but %v", n, why) } @@ -1470,8 +1471,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // if len < 0 { panicmakeslicelen() } // panicmakeslicecap() // } - nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, conv(l, types.Types[types.TUINT64]), nodintconst(i)), nil, nil) - niflen := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLT, l, nodintconst(0)), nil, nil) + nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, conv(l, types.Types[types.TUINT64]), ir.NewInt(i)), nil, nil) + niflen := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLT, l, ir.NewInt(0)), nil, nil) niflen.Body = []ir.Node{mkcall("panicmakeslicelen", nil, init)} nif.Body.Append(niflen, mkcall("panicmakeslicecap", nil, init)) init.Append(typecheck(nif, ctxStmt)) @@ -1514,7 +1515,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case ir.OMAKESLICECOPY: n := n.(*ir.MakeExpr) - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { base.Fatalf("OMAKESLICECOPY with EscNone: %v", n) } @@ -1534,12 +1535,12 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // We do not check for overflow of len(to)*elem.Width here // since len(from) is an existing checked slice capacity // with same elem.Width for the from slice. - size := ir.NewBinaryExpr(base.Pos, ir.OMUL, conv(length, types.Types[types.TUINTPTR]), conv(nodintconst(t.Elem().Width), types.Types[types.TUINTPTR])) + size := ir.NewBinaryExpr(base.Pos, ir.OMUL, conv(length, types.Types[types.TUINTPTR]), conv(ir.NewInt(t.Elem().Width), types.Types[types.TUINTPTR])) // instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer fn := syslook("mallocgc") sh := ir.NewSliceHeaderExpr(base.Pos, nil, nil, nil, nil) - sh.Ptr = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), nodbool(false)) + sh.Ptr = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), ir.NewBool(false)) sh.Ptr.MarkNonNil() sh.LenCap = []ir.Node{length, length} sh.SetType(t) @@ -1570,7 +1571,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case ir.ORUNESTR: n := n.(*ir.ConvExpr) a := nodnil() - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { t := types.NewArray(types.Types[types.TUINT8], 4) a = nodAddr(temp(t)) } @@ -1580,7 +1581,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case ir.OBYTES2STR, ir.ORUNES2STR: n := n.(*ir.ConvExpr) a := nodnil() - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { // Create temporary buffer for string on stack. t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize) a = nodAddr(temp(t)) @@ -1616,7 +1617,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // Allocate a [n]byte of the right size. t := types.NewArray(types.Types[types.TUINT8], int64(len(sc))) var a ir.Node - if n.Esc() == EscNone && len(sc) <= int(maxImplicitStackVarSize) { + if n.Esc() == ir.EscNone && len(sc) <= int(ir.MaxImplicitStackVarSize) { a = nodAddr(temp(t)) } else { a = callnew(t) @@ -1638,7 +1639,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { } a := nodnil() - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { // Create temporary buffer for slice on stack. t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize) a = nodAddr(temp(t)) @@ -1661,7 +1662,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { case ir.OSTR2RUNES: n := n.(*ir.ConvExpr) a := nodnil() - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { // Create temporary buffer for slice on stack. t := types.NewArray(types.Types[types.TINT32], tmpstringbufsize) a = nodAddr(temp(t)) @@ -1719,7 +1720,7 @@ func markUsedIfaceMethod(n *ir.CallExpr) { dot := n.X.(*ir.SelectorExpr) ityp := dot.X.Type() tsym := typenamesym(ityp).Linksym() - r := obj.Addrel(Curfn.LSym) + r := obj.Addrel(ir.CurFunc.LSym) r.Sym = tsym // dot.Xoffset is the method index * Widthptr (the offset of code pointer // in itab). @@ -1777,7 +1778,7 @@ func rtconvfn(src, dst *types.Type) (param, result types.Kind) { // TODO(josharian): combine this with its caller and simplify func reduceSlice(n *ir.SliceExpr) ir.Node { low, high, max := n.SliceBounds() - if high != nil && high.Op() == ir.OLEN && samesafeexpr(n.X, high.(*ir.UnaryExpr).X) { + if high != nil && high.Op() == ir.OLEN && ir.SameSafeExpr(n.X, high.(*ir.UnaryExpr).X) { // Reduce x[i:len(x)] to x[i:]. high = nil } @@ -1824,7 +1825,7 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node { break } // Do not generate 'x = x' during return. See issue 4014. - if op == ir.ORETURN && samesafeexpr(nl[i], nr[i]) { + if op == ir.ORETURN && ir.SameSafeExpr(nl[i], nr[i]) { continue } nn = append(nn, ascompatee1(nl[i], nr[i], init)) @@ -1835,7 +1836,7 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node { var nln, nrn ir.Nodes nln.Set(nl) nrn.Set(nr) - base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), ir.FuncName(Curfn)) + base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), ir.FuncName(ir.CurFunc)) } return reorder3(nn) } @@ -2000,11 +2001,11 @@ func walkprint(nn *ir.CallExpr, init *ir.Nodes) ir.Node { t := make([]ir.Node, 0, len(s)*2) for i, n := range s { if i != 0 { - t = append(t, nodstr(" ")) + t = append(t, ir.NewString(" ")) } t = append(t, n) } - t = append(t, nodstr("\n")) + t = append(t, ir.NewString("\n")) nn.Args.Set(t) } @@ -2018,7 +2019,7 @@ func walkprint(nn *ir.CallExpr, init *ir.Nodes) ir.Node { i++ } if len(strs) > 0 { - t = append(t, nodstr(strings.Join(strs, ""))) + t = append(t, ir.NewString(strings.Join(strs, ""))) } if i < len(s) { t = append(t, s[i]) @@ -2140,31 +2141,6 @@ func callnew(t *types.Type) ir.Node { return n } -// isReflectHeaderDataField reports whether l is an expression p.Data -// where p has type reflect.SliceHeader or reflect.StringHeader. -func isReflectHeaderDataField(l ir.Node) bool { - if l.Type() != types.Types[types.TUINTPTR] { - return false - } - - var tsym *types.Sym - switch l.Op() { - case ir.ODOT: - l := l.(*ir.SelectorExpr) - tsym = l.X.Type().Sym() - case ir.ODOTPTR: - l := l.(*ir.SelectorExpr) - tsym = l.X.Type().Elem().Sym() - default: - return false - } - - if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" { - return false - } - return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader" -} - func convas(n *ir.AssignStmt, init *ir.Nodes) *ir.AssignStmt { if n.Op() != ir.OAS { base.Fatalf("convas: not OAS %v", n.Op()) @@ -2288,37 +2264,6 @@ func reorder3save(n ir.Node, all []*ir.AssignStmt, i int, early *[]ir.Node) ir.N return q } -// what's the outer value that a write to n affects? -// outer value means containing struct or array. -func outervalue(n ir.Node) ir.Node { - for { - switch nn := n; nn.Op() { - case ir.OXDOT: - base.Fatalf("OXDOT in walk") - case ir.ODOT: - nn := nn.(*ir.SelectorExpr) - n = nn.X - continue - case ir.OPAREN: - nn := nn.(*ir.ParenExpr) - n = nn.X - continue - case ir.OCONVNOP: - nn := nn.(*ir.ConvExpr) - n = nn.X - continue - case ir.OINDEX: - nn := nn.(*ir.IndexExpr) - if nn.X.Type() != nil && nn.X.Type().IsArray() { - n = nn.X - continue - } - } - - return n - } -} - // Is it possible that the computation of r might be // affected by assignments in all? func aliased(r ir.Node, all []*ir.AssignStmt) bool { @@ -2344,7 +2289,7 @@ func aliased(r ir.Node, all []*ir.AssignStmt) bool { continue } - lv := outervalue(as.X) + lv := ir.OuterValue(as.X) if lv.Op() != ir.ONAME { memwrite = true continue @@ -2526,7 +2471,7 @@ func paramstoheap(params *types.Type) []ir.Node { // even allocations to move params/results to the heap. // The generated code is added to Curfn's Enter list. func zeroResults() { - for _, f := range Curfn.Type().Results().Fields().Slice() { + for _, f := range ir.CurFunc.Type().Results().Fields().Slice() { v := ir.AsNode(f.Nname) if v != nil && v.Name().Heapaddr != nil { // The local which points to the return value is the @@ -2534,7 +2479,7 @@ func zeroResults() { // by a Needzero annotation in plive.go:livenessepilogue. continue } - if isParamHeapCopy(v) { + if ir.IsParamHeapCopy(v) { // TODO(josharian/khr): Investigate whether we can switch to "continue" here, // and document more in either case. // In the review of CL 114797, Keith wrote (roughly): @@ -2544,7 +2489,7 @@ func zeroResults() { v = v.Name().Stackcopy } // Zero the stack location containing f. - Curfn.Enter.Append(ir.NewAssignStmt(Curfn.Pos(), v, nil)) + ir.CurFunc.Enter.Append(ir.NewAssignStmt(ir.CurFunc.Pos(), v, nil)) } } @@ -2570,13 +2515,13 @@ func returnsfromheap(params *types.Type) []ir.Node { // Enter and Exit lists. func heapmoves() { lno := base.Pos - base.Pos = Curfn.Pos() - nn := paramstoheap(Curfn.Type().Recvs()) - nn = append(nn, paramstoheap(Curfn.Type().Params())...) - nn = append(nn, paramstoheap(Curfn.Type().Results())...) - Curfn.Enter.Append(nn...) - base.Pos = Curfn.Endlineno - Curfn.Exit.Append(returnsfromheap(Curfn.Type().Results())...) + base.Pos = ir.CurFunc.Pos() + nn := paramstoheap(ir.CurFunc.Type().Recvs()) + nn = append(nn, paramstoheap(ir.CurFunc.Type().Params())...) + nn = append(nn, paramstoheap(ir.CurFunc.Type().Results())...) + ir.CurFunc.Enter.Append(nn...) + base.Pos = ir.CurFunc.Endlineno + ir.CurFunc.Exit.Append(returnsfromheap(ir.CurFunc.Type().Results())...) base.Pos = lno } @@ -2743,7 +2688,7 @@ func addstr(n *ir.AddStringExpr, init *ir.Nodes) ir.Node { } buf := nodnil() - if n.Esc() == EscNone { + if n.Esc() == ir.EscNone { sz := int64(0) for _, n1 := range n.List { if n1.Op() == ir.OLITERAL { @@ -2779,7 +2724,7 @@ func addstr(n *ir.AddStringExpr, init *ir.Nodes) ir.Node { slice := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(t), args[1:]) slice.Prealloc = n.Prealloc args = []ir.Node{buf, slice} - slice.SetEsc(EscNone) + slice.SetEsc(ir.EscNone) } cat := syslook(fn) @@ -2865,7 +2810,7 @@ func appendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node { slice.SetType(s.Type()) slice.SetSliceBounds(ir.NewUnaryExpr(base.Pos, ir.OLEN, l1), nil, nil) - Curfn.SetWBPos(n.Pos()) + ir.CurFunc.SetWBPos(n.Pos()) // instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int fn := syslook("typedslicecopy") @@ -2886,7 +2831,7 @@ func appendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node { fn := syslook("slicecopy") fn = substArgTypes(fn, ptr1.Type().Elem(), ptr2.Type().Elem()) - ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width)) + ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, ir.NewInt(elemtype.Width)) } else { // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) ix := ir.NewIndexExpr(base.Pos, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1)) @@ -2896,7 +2841,7 @@ func appendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node { sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, l2) nwid := cheapexpr(conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, l2), types.Types[types.TUINTPTR]), &nodes) - nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, nodintconst(elemtype.Width)) + nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(elemtype.Width)) // instantiate func memmove(to *any, frm *any, length uintptr) fn := syslook("memmove") @@ -2992,7 +2937,7 @@ func extendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node { var nodes []ir.Node // if l2 >= 0 (likely happens), do nothing - nifneg := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGE, l2, nodintconst(0)), nil, nil) + nifneg := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGE, l2, ir.NewInt(0)), nil, nil) nifneg.Likely = true // else panicmakeslicelen() @@ -3044,13 +2989,13 @@ func extendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node { hp := convnop(nodAddr(ix), types.Types[types.TUNSAFEPTR]) // hn := l2 * sizeof(elem(s)) - hn := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, l2, nodintconst(elemtype.Width)), types.Types[types.TUINTPTR]) + hn := conv(ir.NewBinaryExpr(base.Pos, ir.OMUL, l2, ir.NewInt(elemtype.Width)), types.Types[types.TUINTPTR]) clrname := "memclrNoHeapPointers" hasPointers := elemtype.HasPointers() if hasPointers { clrname = "memclrHasPointers" - Curfn.SetWBPos(n.Pos()) + ir.CurFunc.SetWBPos(n.Pos()) } var clr ir.Nodes @@ -3094,7 +3039,7 @@ func extendslice(n *ir.CallExpr, init *ir.Nodes) ir.Node { // } // s func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node { - if !samesafeexpr(dst, n.Args[0]) { + if !ir.SameSafeExpr(dst, n.Args[0]) { n.Args[0] = safeexpr(n.Args[0], init) n.Args[0] = walkexpr(n.Args[0], init) } @@ -3134,7 +3079,7 @@ func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node { ns := temp(nsrc.Type()) l = append(l, ir.NewAssignStmt(base.Pos, ns, nsrc)) // s = src - na := nodintconst(int64(argc)) // const argc + na := ir.NewInt(int64(argc)) // const argc nif := ir.NewIfStmt(base.Pos, nil, nil, nil) // if cap(s) - len(s) < argc nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OCAP, ns), ir.NewUnaryExpr(base.Pos, ir.OLEN, ns)), na) @@ -3160,7 +3105,7 @@ func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node { ix.SetBounded(true) l = append(l, ir.NewAssignStmt(base.Pos, ix, n)) // s[n] = arg if i+1 < len(ls) { - l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, nodintconst(1)))) // n = n + 1 + l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, ir.NewInt(1)))) // n = n + 1 } } @@ -3183,7 +3128,7 @@ func walkappend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node { // func copyany(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node { if n.X.Type().Elem().HasPointers() { - Curfn.SetWBPos(n.Pos()) + ir.CurFunc.SetWBPos(n.Pos()) fn := writebarrierfn("typedslicecopy", n.X.Type().Elem(), n.Y.Type().Elem()) n.X = cheapexpr(n.X, init) ptrL, lenL := backingArrayPtrLen(n.X) @@ -3205,7 +3150,7 @@ func copyany(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node { fn := syslook("slicecopy") fn = substArgTypes(fn, ptrL.Type().Elem(), ptrR.Type().Elem()) - return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, nodintconst(n.X.Type().Elem().Width)) + return mkcall1(fn, n.Type(), init, ptrL, lenL, ptrR, lenR, ir.NewInt(n.X.Type().Elem().Width)) } n.X = walkexpr(n.X, init) @@ -3241,7 +3186,7 @@ func copyany(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node { nwid := ir.Node(temp(types.Types[types.TUINTPTR])) setwid := ir.NewAssignStmt(base.Pos, nwid, conv(nlen, types.Types[types.TUINTPTR])) ne.Body.Append(setwid) - nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, nodintconst(nl.Type().Elem().Width)) + nwid = ir.NewBinaryExpr(base.Pos, ir.OMUL, nwid, ir.NewInt(nl.Type().Elem().Width)) call := mkcall1(fn, nil, init, nto, nfrm, nwid) ne.Body.Append(call) @@ -3264,12 +3209,12 @@ func eqfor(t *types.Type) (n ir.Node, needsize bool) { case types.ASPECIAL: sym := typesymprefix(".eq", t) n := NewName(sym) - setNodeNameFunc(n) + ir.MarkFunc(n) n.SetType(functype(nil, []*ir.Field{ - anonfield(types.NewPtr(t)), - anonfield(types.NewPtr(t)), + ir.NewField(base.Pos, nil, nil, types.NewPtr(t)), + ir.NewField(base.Pos, nil, nil, types.NewPtr(t)), }, []*ir.Field{ - anonfield(types.Types[types.TBOOL]), + ir.NewField(base.Pos, nil, nil, types.Types[types.TBOOL]), })) return n, false } @@ -3415,7 +3360,7 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { // Chose not to inline. Call equality function directly. if !inline { // eq algs take pointers; cmpl and cmpr must be addressable - if !islvalue(cmpl) || !islvalue(cmpr) { + if !ir.IsAssignable(cmpl) || !ir.IsAssignable(cmpr) { base.Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr) } @@ -3424,7 +3369,7 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { call.Args.Append(nodAddr(cmpl)) call.Args.Append(nodAddr(cmpr)) if needsize { - call.Args.Append(nodintconst(t.Width)) + call.Args.Append(ir.NewInt(t.Width)) } res := ir.Node(call) if n.Op() != ir.OEQ { @@ -3483,31 +3428,31 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { } if step == 1 { compare( - ir.NewIndexExpr(base.Pos, cmpl, nodintconst(i)), - ir.NewIndexExpr(base.Pos, cmpr, nodintconst(i)), + ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i)), + ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i)), ) i++ remains -= t.Elem().Width } else { elemType := t.Elem().ToUnsigned() - cmplw := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, nodintconst(i))) + cmplw := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i))) cmplw = conv(cmplw, elemType) // convert to unsigned cmplw = conv(cmplw, convType) // widen - cmprw := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, nodintconst(i))) + cmprw := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i))) cmprw = conv(cmprw, elemType) cmprw = conv(cmprw, convType) // For code like this: uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ... // ssa will generate a single large load. for offset := int64(1); offset < step; offset++ { - lb := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, nodintconst(i+offset))) + lb := ir.Node(ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i+offset))) lb = conv(lb, elemType) lb = conv(lb, convType) - lb = ir.NewBinaryExpr(base.Pos, ir.OLSH, lb, nodintconst(8*t.Elem().Width*offset)) + lb = ir.NewBinaryExpr(base.Pos, ir.OLSH, lb, ir.NewInt(8*t.Elem().Width*offset)) cmplw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmplw, lb) - rb := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, nodintconst(i+offset))) + rb := ir.Node(ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i+offset))) rb = conv(rb, elemType) rb = conv(rb, convType) - rb = ir.NewBinaryExpr(base.Pos, ir.OLSH, rb, nodintconst(8*t.Elem().Width*offset)) + rb = ir.NewBinaryExpr(base.Pos, ir.OLSH, rb, ir.NewInt(8*t.Elem().Width*offset)) cmprw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmprw, rb) } compare(cmplw, cmprw) @@ -3517,7 +3462,7 @@ func walkcompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { } } if expr == nil { - expr = nodbool(n.Op() == ir.OEQ) + expr = ir.NewBool(n.Op() == ir.OEQ) // We still need to use cmpl and cmpr, in case they contain // an expression which might panic. See issue 23837. t := temp(cmpl.Type()) @@ -3604,12 +3549,12 @@ func walkcompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { if len(s) > 0 { ncs = safeexpr(ncs, init) } - r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.NewUnaryExpr(base.Pos, ir.OLEN, ncs), nodintconst(int64(len(s))))) + r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.NewUnaryExpr(base.Pos, ir.OLEN, ncs), ir.NewInt(int64(len(s))))) remains := len(s) for i := 0; remains > 0; { if remains == 1 || !canCombineLoads { - cb := nodintconst(int64(s[i])) - ncb := ir.NewIndexExpr(base.Pos, ncs, nodintconst(int64(i))) + cb := ir.NewInt(int64(s[i])) + ncb := ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i))) r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, ncb, cb)) remains-- i++ @@ -3628,18 +3573,18 @@ func walkcompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { convType = types.Types[types.TUINT16] step = 2 } - ncsubstr := conv(ir.NewIndexExpr(base.Pos, ncs, nodintconst(int64(i))), convType) + ncsubstr := conv(ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i))), convType) csubstr := int64(s[i]) // Calculate large constant from bytes as sequence of shifts and ors. // Like this: uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ... // ssa will combine this into a single large load. for offset := 1; offset < step; offset++ { - b := conv(ir.NewIndexExpr(base.Pos, ncs, nodintconst(int64(i+offset))), convType) - b = ir.NewBinaryExpr(base.Pos, ir.OLSH, b, nodintconst(int64(8*offset))) + b := conv(ir.NewIndexExpr(base.Pos, ncs, ir.NewInt(int64(i+offset))), convType) + b = ir.NewBinaryExpr(base.Pos, ir.OLSH, b, ir.NewInt(int64(8*offset))) ncsubstr = ir.NewBinaryExpr(base.Pos, ir.OOR, ncsubstr, b) csubstr |= int64(s[i+offset]) << uint8(8*offset) } - csubstrPart := nodintconst(csubstr) + csubstrPart := ir.NewInt(csubstr) // Compare "step" bytes as once r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, csubstrPart, ncsubstr)) remains -= step @@ -3668,7 +3613,7 @@ func walkcompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node { } else { // sys_cmpstring(s1, s2) :: 0 r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.X, types.Types[types.TSTRING]), conv(n.Y, types.Types[types.TSTRING])) - r = ir.NewBinaryExpr(base.Pos, n.Op(), r, nodintconst(0)) + r = ir.NewBinaryExpr(base.Pos, n.Op(), r, ir.NewInt(0)) } return finishcompare(n, r, init) @@ -3692,7 +3637,7 @@ func bounded(n ir.Node, max int64) bool { sign := n.Type().IsSigned() bits := int32(8 * n.Type().Width) - if smallintconst(n) { + if ir.IsSmallIntConst(n) { v := ir.Int64Val(n) return 0 <= v && v < max } @@ -3702,9 +3647,9 @@ func bounded(n ir.Node, max int64) bool { n := n.(*ir.BinaryExpr) v := int64(-1) switch { - case smallintconst(n.X): + case ir.IsSmallIntConst(n.X): v = ir.Int64Val(n.X) - case smallintconst(n.Y): + case ir.IsSmallIntConst(n.Y): v = ir.Int64Val(n.Y) if n.Op() == ir.OANDNOT { v = ^v @@ -3719,7 +3664,7 @@ func bounded(n ir.Node, max int64) bool { case ir.OMOD: n := n.(*ir.BinaryExpr) - if !sign && smallintconst(n.Y) { + if !sign && ir.IsSmallIntConst(n.Y) { v := ir.Int64Val(n.Y) if 0 <= v && v <= max { return true @@ -3728,7 +3673,7 @@ func bounded(n ir.Node, max int64) bool { case ir.ODIV: n := n.(*ir.BinaryExpr) - if !sign && smallintconst(n.Y) { + if !sign && ir.IsSmallIntConst(n.Y) { v := ir.Int64Val(n.Y) for bits > 0 && v >= 2 { bits-- @@ -3738,7 +3683,7 @@ func bounded(n ir.Node, max int64) bool { case ir.ORSH: n := n.(*ir.BinaryExpr) - if !sign && smallintconst(n.Y) { + if !sign && ir.IsSmallIntConst(n.Y) { v := ir.Int64Val(n.Y) if v > int64(bits) { return true @@ -3794,9 +3739,9 @@ func usemethod(n *ir.CallExpr) { // (including global variables such as numImports - was issue #19028). // Also need to check for reflect package itself (see Issue #38515). if s := res0.Type.Sym(); s != nil && s.Name == "Method" && types.IsReflectPkg(s.Pkg) { - Curfn.SetReflectMethod(true) + ir.CurFunc.SetReflectMethod(true) // The LSym is initialized at this point. We need to set the attribute on the LSym. - Curfn.LSym.Set(obj.AttrReflectMethod, true) + ir.CurFunc.LSym.Set(obj.AttrReflectMethod, true) } } @@ -3845,10 +3790,10 @@ func usefield(n *ir.SelectorExpr) { } sym := tracksym(outer, field) - if Curfn.FieldTrack == nil { - Curfn.FieldTrack = make(map[*types.Sym]struct{}) + if ir.CurFunc.FieldTrack == nil { + ir.CurFunc.FieldTrack = make(map[*types.Sym]struct{}) } - Curfn.FieldTrack[sym] = struct{}{} + ir.CurFunc.FieldTrack[sym] = struct{}{} } // anySideEffects reports whether n contains any operations that could have observable side effects. @@ -3987,7 +3932,7 @@ func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node { arg = arg.(*ir.ConvExpr).X n.Args[i] = arg } - funcArgs = append(funcArgs, symfield(s, arg.Type())) + funcArgs = append(funcArgs, ir.NewField(base.Pos, s, nil, arg.Type())) } t := ir.NewFuncType(base.Pos, nil, funcArgs, nil) @@ -3995,7 +3940,7 @@ func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node { sym := lookupN("wrap·", wrapCall_prgen) fn := dclfunc(sym, t) - args := paramNnames(t.Type()) + args := ir.ParamNames(t.Type()) for i, origArg := range origArgs { if origArg == nil { continue @@ -4076,7 +4021,7 @@ func walkCheckPtrAlignment(n *ir.ConvExpr, init *ir.Nodes, count ir.Node) ir.Nod } if count == nil { - count = nodintconst(1) + count = ir.NewInt(1) } n.X = cheapexpr(n.X, init) @@ -4107,7 +4052,7 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node { return n } - if n.X.Op() == ir.ODOTPTR && isReflectHeaderDataField(n.X) { + if n.X.Op() == ir.ODOTPTR && ir.IsReflectHeaderDataField(n.X) { return n } @@ -4141,7 +4086,7 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node { cheap := cheapexpr(n, init) slice := mkdotargslice(types.NewSlice(types.Types[types.TUNSAFEPTR]), originals) - slice.SetEsc(EscNone) + slice.SetEsc(ir.EscNone) init.Append(mkcall("checkptrArithmetic", nil, init, convnop(cheap, types.Types[types.TUNSAFEPTR]), slice)) // TODO(khr): Mark backing store of slice as dead. This will allow us to reuse @@ -4150,13 +4095,6 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node { return cheap } -// checkPtr reports whether pointer checking should be enabled for -// function fn at a given level. See debugHelpFooter for defined -// levels. -func checkPtr(fn *ir.Func, level int) bool { - return base.Debug.Checkptr >= level && fn.Pragma&ir.NoCheckPtr == 0 -} - // appendWalkStmt typechecks and walks stmt and then appends it to init. func appendWalkStmt(init *ir.Nodes, stmt ir.Node) { op := stmt.Op() diff --git a/src/cmd/compile/internal/ir/cfg.go b/src/cmd/compile/internal/ir/cfg.go new file mode 100644 index 0000000000..d986ac3a1e --- /dev/null +++ b/src/cmd/compile/internal/ir/cfg.go @@ -0,0 +1,26 @@ +// Copyright 2009 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 ir + +var ( + // maximum size variable which we will allocate on the stack. + // This limit is for explicit variable declarations like "var x T" or "x := ...". + // Note: the flag smallframes can update this value. + MaxStackVarSize = int64(10 * 1024 * 1024) + + // maximum size of implicit variables that we will allocate on the stack. + // p := new(T) allocating T on the stack + // p := &T{} allocating T on the stack + // s := make([]T, n) allocating [n]T on the stack + // s := []byte("...") allocating [n]byte on the stack + // Note: the flag smallframes can update this value. + MaxImplicitStackVarSize = int64(64 * 1024) + + // MaxSmallArraySize is the maximum size of an array which is considered small. + // Small arrays will be initialized directly with a sequence of constant stores. + // Large arrays will be initialized by copying from a static temp. + // 256 bytes was chosen to minimize generated code + statictmp size. + MaxSmallArraySize = int64(256) +) diff --git a/src/cmd/compile/internal/ir/const.go b/src/cmd/compile/internal/ir/const.go new file mode 100644 index 0000000000..bfa0136232 --- /dev/null +++ b/src/cmd/compile/internal/ir/const.go @@ -0,0 +1,99 @@ +// Copyright 2009 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 ir + +import ( + "go/constant" + "math" + "math/big" + + "cmd/compile/internal/base" + "cmd/compile/internal/types" +) + +func NewBool(b bool) Node { + return NewLiteral(constant.MakeBool(b)) +} + +func NewInt(v int64) Node { + return NewLiteral(constant.MakeInt64(v)) +} + +func NewString(s string) Node { + return NewLiteral(constant.MakeString(s)) +} + +const ( + // Maximum size in bits for big.Ints before signalling + // overflow and also mantissa precision for big.Floats. + ConstPrec = 512 +) + +func BigFloat(v constant.Value) *big.Float { + f := new(big.Float) + f.SetPrec(ConstPrec) + switch u := constant.Val(v).(type) { + case int64: + f.SetInt64(u) + case *big.Int: + f.SetInt(u) + case *big.Float: + f.Set(u) + case *big.Rat: + f.SetRat(u) + default: + base.Fatalf("unexpected: %v", u) + } + return f +} + +// ConstOverflow reports whether constant value v is too large +// to represent with type t. +func ConstOverflow(v constant.Value, t *types.Type) bool { + switch { + case t.IsInteger(): + bits := uint(8 * t.Size()) + if t.IsUnsigned() { + x, ok := constant.Uint64Val(v) + return !ok || x>>bits != 0 + } + x, ok := constant.Int64Val(v) + if x < 0 { + x = ^x + } + return !ok || x>>(bits-1) != 0 + case t.IsFloat(): + switch t.Size() { + case 4: + f, _ := constant.Float32Val(v) + return math.IsInf(float64(f), 0) + case 8: + f, _ := constant.Float64Val(v) + return math.IsInf(f, 0) + } + case t.IsComplex(): + ft := types.FloatForComplex(t) + return ConstOverflow(constant.Real(v), ft) || ConstOverflow(constant.Imag(v), ft) + } + base.Fatalf("doesoverflow: %v, %v", v, t) + panic("unreachable") +} + +// IsConstNode reports whether n is a Go language constant (as opposed to a +// compile-time constant). +// +// Expressions derived from nil, like string([]byte(nil)), while they +// may be known at compile time, are not Go language constants. +func IsConstNode(n Node) bool { + return n.Op() == OLITERAL +} + +func IsSmallIntConst(n Node) bool { + if n.Op() == OLITERAL { + v, ok := constant.Int64Val(n.Val()) + return ok && int64(int32(v)) == v + } + return false +} diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index 39a408fdc7..640cc03954 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -5,10 +5,13 @@ package ir import ( + "bytes" "cmd/compile/internal/base" "cmd/compile/internal/types" "cmd/internal/src" + "fmt" "go/constant" + "go/token" ) func maybeDo(x Node, err error, do func(Node) error) error { @@ -783,3 +786,371 @@ func (n *UnaryExpr) SetOp(op Op) { n.op = op } } + +func IsZero(n Node) bool { + switch n.Op() { + case ONIL: + return true + + case OLITERAL: + switch u := n.Val(); u.Kind() { + case constant.String: + return constant.StringVal(u) == "" + case constant.Bool: + return !constant.BoolVal(u) + default: + return constant.Sign(u) == 0 + } + + case OARRAYLIT: + n := n.(*CompLitExpr) + for _, n1 := range n.List { + if n1.Op() == OKEY { + n1 = n1.(*KeyExpr).Value + } + if !IsZero(n1) { + return false + } + } + return true + + case OSTRUCTLIT: + n := n.(*CompLitExpr) + for _, n1 := range n.List { + n1 := n1.(*StructKeyExpr) + if !IsZero(n1.Value) { + return false + } + } + return true + } + + return false +} + +// lvalue etc +func IsAssignable(n Node) bool { + switch n.Op() { + case OINDEX: + n := n.(*IndexExpr) + if n.X.Type() != nil && n.X.Type().IsArray() { + return IsAssignable(n.X) + } + if n.X.Type() != nil && n.X.Type().IsString() { + return false + } + fallthrough + case ODEREF, ODOTPTR, OCLOSUREREAD: + return true + + case ODOT: + n := n.(*SelectorExpr) + return IsAssignable(n.X) + + case ONAME: + n := n.(*Name) + if n.Class_ == PFUNC { + return false + } + return true + + case ONAMEOFFSET: + return true + } + + return false +} + +func StaticValue(n Node) Node { + for { + if n.Op() == OCONVNOP { + n = n.(*ConvExpr).X + continue + } + + n1 := staticValue1(n) + if n1 == nil { + return n + } + n = n1 + } +} + +// staticValue1 implements a simple SSA-like optimization. If n is a local variable +// that is initialized and never reassigned, staticValue1 returns the initializer +// expression. Otherwise, it returns nil. +func staticValue1(nn Node) Node { + if nn.Op() != ONAME { + return nil + } + n := nn.(*Name) + if n.Class_ != PAUTO || n.Name().Addrtaken() { + return nil + } + + defn := n.Name().Defn + if defn == nil { + return nil + } + + var rhs Node +FindRHS: + switch defn.Op() { + case OAS: + defn := defn.(*AssignStmt) + rhs = defn.Y + case OAS2: + defn := defn.(*AssignListStmt) + for i, lhs := range defn.Lhs { + if lhs == n { + rhs = defn.Rhs[i] + break FindRHS + } + } + base.Fatalf("%v missing from LHS of %v", n, defn) + default: + return nil + } + if rhs == nil { + base.Fatalf("RHS is nil: %v", defn) + } + + if reassigned(n) { + return nil + } + + return rhs +} + +// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean +// indicating whether the name has any assignments other than its declaration. +// The second return value is the first such assignment encountered in the walk, if any. It is mostly +// useful for -m output documenting the reason for inhibited optimizations. +// NB: global variables are always considered to be re-assigned. +// TODO: handle initial declaration not including an assignment and followed by a single assignment? +func reassigned(name *Name) bool { + if name.Op() != ONAME { + base.Fatalf("reassigned %v", name) + } + // no way to reliably check for no-reassignment of globals, assume it can be + if name.Curfn == nil { + return true + } + return Any(name.Curfn, func(n Node) bool { + switch n.Op() { + case OAS: + n := n.(*AssignStmt) + if n.X == name && n != name.Defn { + return true + } + case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2: + n := n.(*AssignListStmt) + for _, p := range n.Lhs { + if p == name && n != name.Defn { + return true + } + } + } + return false + }) +} + +// IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation. +var IsIntrinsicCall = func(*CallExpr) bool { return false } + +// SameSafeExpr checks whether it is safe to reuse one of l and r +// instead of computing both. SameSafeExpr assumes that l and r are +// used in the same statement or expression. In order for it to be +// safe to reuse l or r, they must: +// * be the same expression +// * not have side-effects (no function calls, no channel ops); +// however, panics are ok +// * not cause inappropriate aliasing; e.g. two string to []byte +// conversions, must result in two distinct slices +// +// The handling of OINDEXMAP is subtle. OINDEXMAP can occur both +// as an lvalue (map assignment) and an rvalue (map access). This is +// currently OK, since the only place SameSafeExpr gets used on an +// lvalue expression is for OSLICE and OAPPEND optimizations, and it +// is correct in those settings. +func SameSafeExpr(l Node, r Node) bool { + if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) { + return false + } + + switch l.Op() { + case ONAME, OCLOSUREREAD: + return l == r + + case ODOT, ODOTPTR: + l := l.(*SelectorExpr) + r := r.(*SelectorExpr) + return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X) + + case ODEREF: + l := l.(*StarExpr) + r := r.(*StarExpr) + return SameSafeExpr(l.X, r.X) + + case ONOT, OBITNOT, OPLUS, ONEG: + l := l.(*UnaryExpr) + r := r.(*UnaryExpr) + return SameSafeExpr(l.X, r.X) + + case OCONVNOP: + l := l.(*ConvExpr) + r := r.(*ConvExpr) + return SameSafeExpr(l.X, r.X) + + case OCONV: + l := l.(*ConvExpr) + r := r.(*ConvExpr) + // Some conversions can't be reused, such as []byte(str). + // Allow only numeric-ish types. This is a bit conservative. + return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X) + + case OINDEX, OINDEXMAP: + l := l.(*IndexExpr) + r := r.(*IndexExpr) + return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index) + + case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD: + l := l.(*BinaryExpr) + r := r.(*BinaryExpr) + return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y) + + case OLITERAL: + return constant.Compare(l.Val(), token.EQL, r.Val()) + + case ONIL: + return true + } + + return false +} + +// ShouldCheckPtr reports whether pointer checking should be enabled for +// function fn at a given level. See debugHelpFooter for defined +// levels. +func ShouldCheckPtr(fn *Func, level int) bool { + return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0 +} + +// IsReflectHeaderDataField reports whether l is an expression p.Data +// where p has type reflect.SliceHeader or reflect.StringHeader. +func IsReflectHeaderDataField(l Node) bool { + if l.Type() != types.Types[types.TUINTPTR] { + return false + } + + var tsym *types.Sym + switch l.Op() { + case ODOT: + l := l.(*SelectorExpr) + tsym = l.X.Type().Sym() + case ODOTPTR: + l := l.(*SelectorExpr) + tsym = l.X.Type().Elem().Sym() + default: + return false + } + + if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" { + return false + } + return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader" +} + +func ParamNames(ft *types.Type) []Node { + args := make([]Node, ft.NumParams()) + for i, f := range ft.Params().FieldSlice() { + args[i] = AsNode(f.Nname) + } + return args +} + +// MethodSym returns the method symbol representing a method name +// associated with a specific receiver type. +// +// Method symbols can be used to distinguish the same method appearing +// in different method sets. For example, T.M and (*T).M have distinct +// method symbols. +// +// The returned symbol will be marked as a function. +func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym { + sym := MethodSymSuffix(recv, msym, "") + sym.SetFunc(true) + return sym +} + +// MethodSymSuffix is like methodsym, but allows attaching a +// distinguisher suffix. To avoid collisions, the suffix must not +// start with a letter, number, or period. +func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym { + if msym.IsBlank() { + base.Fatalf("blank method name") + } + + rsym := recv.Sym() + if recv.IsPtr() { + if rsym != nil { + base.Fatalf("declared pointer receiver type: %v", recv) + } + rsym = recv.Elem().Sym() + } + + // Find the package the receiver type appeared in. For + // anonymous receiver types (i.e., anonymous structs with + // embedded fields), use the "go" pseudo-package instead. + rpkg := Pkgs.Go + if rsym != nil { + rpkg = rsym.Pkg + } + + var b bytes.Buffer + if recv.IsPtr() { + // The parentheses aren't really necessary, but + // they're pretty traditional at this point. + fmt.Fprintf(&b, "(%-S)", recv) + } else { + fmt.Fprintf(&b, "%-S", recv) + } + + // A particular receiver type may have multiple non-exported + // methods with the same name. To disambiguate them, include a + // package qualifier for names that came from a different + // package than the receiver type. + if !types.IsExported(msym.Name) && msym.Pkg != rpkg { + b.WriteString(".") + b.WriteString(msym.Pkg.Prefix) + } + + b.WriteString(".") + b.WriteString(msym.Name) + b.WriteString(suffix) + + return rpkg.LookupBytes(b.Bytes()) +} + +// MethodName returns the ONAME representing the method +// referenced by expression n, which must be a method selector, +// method expression, or method value. +func MethodExprName(n Node) *Name { + name, _ := MethodExprFunc(n).Nname.(*Name) + return name +} + +// MethodFunc is like MethodName, but returns the types.Field instead. +func MethodExprFunc(n Node) *types.Field { + switch n.Op() { + case ODOTMETH: + return n.(*SelectorExpr).Selection + case OMETHEXPR: + return n.(*MethodExpr).Method + case OCALLPART: + n := n.(*CallPartExpr) + return n.Method + } + base.Fatalf("unexpected node: %v (%v)", n, n.Op()) + panic("unreachable") +} diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go index 57837e9e6b..a93516d716 100644 --- a/src/cmd/compile/internal/ir/func.go +++ b/src/cmd/compile/internal/ir/func.go @@ -261,3 +261,30 @@ func PkgFuncName(n Node) string { } return p + "." + s.Name } + +var CurFunc *Func + +func FuncSymName(s *types.Sym) string { + return s.Name + "·f" +} + +// NewFuncNameAt generates a new name node for a function or method. +func NewFuncNameAt(pos src.XPos, s *types.Sym, fn *Func) *Name { + if fn.Nname != nil { + base.Fatalf("newFuncName - already have name") + } + n := NewNameAt(pos, s) + n.SetFunc(fn) + fn.Nname = n + return n +} + +// MarkFunc marks a node as a function. +func MarkFunc(n *Name) { + if n.Op() != ONAME || n.Class_ != Pxxx { + base.Fatalf("expected ONAME/Pxxx node, got %v", n) + } + + n.Class_ = PFUNC + n.Sym().SetFunc(true) +} diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go index 770f8119e0..93535f4cee 100644 --- a/src/cmd/compile/internal/ir/name.go +++ b/src/cmd/compile/internal/ir/name.go @@ -413,3 +413,25 @@ func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName { p.pos = pos return p } + +// IsParamStackCopy reports whether this is the on-stack copy of a +// function parameter that moved to the heap. +func IsParamStackCopy(n Node) bool { + if n.Op() != ONAME { + return false + } + name := n.(*Name) + return (name.Class_ == PPARAM || name.Class_ == PPARAMOUT) && name.Heapaddr != nil +} + +// IsParamHeapCopy reports whether this is the on-heap copy of +// a function parameter that moved to the heap. +func IsParamHeapCopy(n Node) bool { + if n.Op() != ONAME { + return false + } + name := n.(*Name) + return name.Class_ == PAUTOHEAP && name.Name().Stackcopy != nil +} + +var RegFP *Name diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go index 34b89752ad..b4a557f290 100644 --- a/src/cmd/compile/internal/ir/node.go +++ b/src/cmd/compile/internal/ir/node.go @@ -504,3 +504,99 @@ func IsBlank(n Node) bool { func IsMethod(n Node) bool { return n.Type().Recv() != nil } + +func HasNamedResults(fn *Func) bool { + typ := fn.Type() + return typ.NumResults() > 0 && types.OrigSym(typ.Results().Field(0).Sym) != nil +} + +// HasUniquePos reports whether n has a unique position that can be +// used for reporting error messages. +// +// It's primarily used to distinguish references to named objects, +// whose Pos will point back to their declaration position rather than +// their usage position. +func HasUniquePos(n Node) bool { + switch n.Op() { + case ONAME, OPACK: + return false + case OLITERAL, ONIL, OTYPE: + if n.Sym() != nil { + return false + } + } + + if !n.Pos().IsKnown() { + if base.Flag.K != 0 { + base.Warn("setlineno: unknown position (line 0)") + } + return false + } + + return true +} + +func SetPos(n Node) src.XPos { + lno := base.Pos + if n != nil && HasUniquePos(n) { + base.Pos = n.Pos() + } + return lno +} + +// The result of InitExpr MUST be assigned back to n, e.g. +// n.Left = InitExpr(init, n.Left) +func InitExpr(init []Node, n Node) Node { + if len(init) == 0 { + return n + } + if MayBeShared(n) { + // Introduce OCONVNOP to hold init list. + old := n + n = NewConvExpr(base.Pos, OCONVNOP, nil, old) + n.SetType(old.Type()) + n.SetTypecheck(1) + } + + n.PtrInit().Prepend(init...) + n.SetHasCall(true) + return n +} + +// what's the outer value that a write to n affects? +// outer value means containing struct or array. +func OuterValue(n Node) Node { + for { + switch nn := n; nn.Op() { + case OXDOT: + base.Fatalf("OXDOT in walk") + case ODOT: + nn := nn.(*SelectorExpr) + n = nn.X + continue + case OPAREN: + nn := nn.(*ParenExpr) + n = nn.X + continue + case OCONVNOP: + nn := nn.(*ConvExpr) + n = nn.X + continue + case OINDEX: + nn := nn.(*IndexExpr) + if nn.X.Type() != nil && nn.X.Type().IsArray() { + n = nn.X + continue + } + } + + return n + } +} + +const ( + EscUnknown = iota + EscNone // Does not escape to heap, result, or parameters. + EscHeap // Reachable from the heap + EscNever // By construction will not escape. +) diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/ir/scc.go index a5a6480958..4f646e22b5 100644 --- a/src/cmd/compile/internal/gc/scc.go +++ b/src/cmd/compile/internal/ir/scc.go @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package gc - -import "cmd/compile/internal/ir" +package ir // Strongly connected components. // @@ -32,13 +30,13 @@ import "cmd/compile/internal/ir" // when analyzing a set of mutually recursive functions. type bottomUpVisitor struct { - analyze func([]*ir.Func, bool) + analyze func([]*Func, bool) visitgen uint32 - nodeID map[*ir.Func]uint32 - stack []*ir.Func + nodeID map[*Func]uint32 + stack []*Func } -// visitBottomUp invokes analyze on the ODCLFUNC nodes listed in list. +// VisitFuncsBottomUp invokes analyze on the ODCLFUNC nodes listed in list. // It calls analyze with successive groups of functions, working from // the bottom of the call graph upward. Each time analyze is called with // a list of functions, every function on that list only calls other functions @@ -51,13 +49,13 @@ type bottomUpVisitor struct { // If recursive is false, the list consists of only a single function and its closures. // If recursive is true, the list may still contain only a single function, // if that function is itself recursive. -func visitBottomUp(list []ir.Node, analyze func(list []*ir.Func, recursive bool)) { +func VisitFuncsBottomUp(list []Node, analyze func(list []*Func, recursive bool)) { var v bottomUpVisitor v.analyze = analyze - v.nodeID = make(map[*ir.Func]uint32) + v.nodeID = make(map[*Func]uint32) for _, n := range list { - if n.Op() == ir.ODCLFUNC { - n := n.(*ir.Func) + if n.Op() == ODCLFUNC { + n := n.(*Func) if !n.IsHiddenClosure() { v.visit(n) } @@ -65,7 +63,7 @@ func visitBottomUp(list []ir.Node, analyze func(list []*ir.Func, recursive bool) } } -func (v *bottomUpVisitor) visit(n *ir.Func) uint32 { +func (v *bottomUpVisitor) visit(n *Func) uint32 { if id := v.nodeID[n]; id > 0 { // already visited return id @@ -78,45 +76,45 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 { min := v.visitgen v.stack = append(v.stack, n) - ir.Visit(n, func(n ir.Node) { + Visit(n, func(n Node) { switch n.Op() { - case ir.ONAME: - n := n.(*ir.Name) - if n.Class_ == ir.PFUNC { + case ONAME: + n := n.(*Name) + if n.Class_ == PFUNC { if n != nil && n.Name().Defn != nil { - if m := v.visit(n.Name().Defn.(*ir.Func)); m < min { + if m := v.visit(n.Name().Defn.(*Func)); m < min { min = m } } } - case ir.OMETHEXPR: - n := n.(*ir.MethodExpr) - fn := methodExprName(n) + case OMETHEXPR: + n := n.(*MethodExpr) + fn := MethodExprName(n) if fn != nil && fn.Defn != nil { - if m := v.visit(fn.Defn.(*ir.Func)); m < min { + if m := v.visit(fn.Defn.(*Func)); m < min { min = m } } - case ir.ODOTMETH: - n := n.(*ir.SelectorExpr) - fn := methodExprName(n) - if fn != nil && fn.Op() == ir.ONAME && fn.Class_ == ir.PFUNC && fn.Defn != nil { - if m := v.visit(fn.Defn.(*ir.Func)); m < min { + case ODOTMETH: + n := n.(*SelectorExpr) + fn := MethodExprName(n) + if fn != nil && fn.Op() == ONAME && fn.Class_ == PFUNC && fn.Defn != nil { + if m := v.visit(fn.Defn.(*Func)); m < min { min = m } } - case ir.OCALLPART: - n := n.(*ir.CallPartExpr) - fn := ir.AsNode(callpartMethod(n).Nname) - if fn != nil && fn.Op() == ir.ONAME { - if fn := fn.(*ir.Name); fn.Class_ == ir.PFUNC && fn.Name().Defn != nil { - if m := v.visit(fn.Name().Defn.(*ir.Func)); m < min { + case OCALLPART: + n := n.(*CallPartExpr) + fn := AsNode(n.Method.Nname) + if fn != nil && fn.Op() == ONAME { + if fn := fn.(*Name); fn.Class_ == PFUNC && fn.Name().Defn != nil { + if m := v.visit(fn.Name().Defn.(*Func)); m < min { min = m } } } - case ir.OCLOSURE: - n := n.(*ir.ClosureExpr) + case OCLOSURE: + n := n.(*ClosureExpr) if m := v.visit(n.Func); m < min { min = m } |