From 578fbbe3aa5cada6e32b686d71a5832d6ca846dc Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 7 Dec 2020 14:58:26 -0500 Subject: [PATCH] [dev.regabi] cmd/compile: rewrite some generic ir.Nod calls An automated rewrite is going to remove the bulk of the calls to ir.Nod and friends. This CL takes care of the ones that don't have fixed opcodes and so aren't amenable to automatic rewriting. Passes buildall w/ toolstash -cmp. Replay of CL 275886, lost to the bad-merge history rewrite. Change-Id: I5bf8d1d182f847f4ab44b7e278b752913e30e4c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/277956 Trust: Russ Cox Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/iimport.go | 50 +++++++++++++++++------- src/cmd/compile/internal/gc/noder.go | 27 +++++++++---- src/cmd/compile/internal/gc/order.go | 7 +--- src/cmd/compile/internal/gc/select.go | 6 ++- src/cmd/compile/internal/gc/subr.go | 5 +-- src/cmd/compile/internal/gc/typecheck.go | 20 ++++------ src/cmd/compile/internal/gc/walk.go | 42 ++++++++------------ 7 files changed, 89 insertions(+), 68 deletions(-) diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go index 0e2af562d0..1096d7988e 100644 --- a/src/cmd/compile/internal/gc/iimport.go +++ b/src/cmd/compile/internal/gc/iimport.go @@ -894,10 +894,10 @@ func (r *importReader) node() ir.Node { // unreachable - mapped to cases below by exporter case ir.OINDEX: - return ir.NodAt(r.pos(), op, r.expr(), r.expr()) + return ir.NodAt(r.pos(), ir.OINDEX, r.expr(), r.expr()) case ir.OSLICE, ir.OSLICE3: - n := ir.NodAt(r.pos(), op, r.expr(), nil) + n := ir.NewSliceExpr(r.pos(), op, r.expr()) low, high := r.exprsOrNil() var max ir.Node if n.Op().IsSlice3() { @@ -940,15 +940,25 @@ func (r *importReader) node() ir.Node { return n // unary expressions - case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV: - return ir.NodAt(r.pos(), op, r.expr(), nil) + case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV: + return ir.NewUnaryExpr(r.pos(), op, r.expr()) + case ir.OADDR: return nodAddrAt(r.pos(), r.expr()) + case ir.ODEREF: + return ir.NewStarExpr(r.pos(), r.expr()) + // binary expressions - case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, - ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR: - return ir.NodAt(r.pos(), op, r.expr(), r.expr()) + case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, + ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR: + return ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr()) + + case ir.OANDAND, ir.OOROR: + return ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr()) + + case ir.OSEND: + return ir.NewSendStmt(r.pos(), r.expr(), r.expr()) case ir.OADDSTR: pos := r.pos() @@ -1003,7 +1013,7 @@ func (r *importReader) node() ir.Node { // unreachable - generated by compiler for trampolin routines (not exported) case ir.OGO, ir.ODEFER: - return ir.NodAt(r.pos(), op, r.expr(), nil) + return ir.NewGoDeferStmt(r.pos(), op, r.expr()) case ir.OIF: n := ir.NodAt(r.pos(), ir.OIF, nil, nil) @@ -1029,8 +1039,16 @@ func (r *importReader) node() ir.Node { n.PtrBody().Set(r.stmtList()) return n - case ir.OSELECT, ir.OSWITCH: - n := ir.NodAt(r.pos(), op, nil, nil) + case ir.OSELECT: + n := ir.NodAt(r.pos(), ir.OSELECT, nil, nil) + n.PtrInit().Set(r.stmtList()) + left, _ := r.exprsOrNil() + n.SetLeft(left) + n.PtrList().Set(r.caseList(n)) + return n + + case ir.OSWITCH: + n := ir.NodAt(r.pos(), ir.OSWITCH, nil, nil) n.PtrInit().Set(r.stmtList()) left, _ := r.exprsOrNil() n.SetLeft(left) @@ -1047,12 +1065,16 @@ func (r *importReader) node() ir.Node { // case OEMPTY: // unreachable - not emitted by exporter - case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL: - n := ir.NodAt(r.pos(), op, nil, nil) + case ir.OBREAK, ir.OCONTINUE, ir.OGOTO: + var sym *types.Sym + pos := r.pos() if label := r.string(); label != "" { - n.SetSym(lookup(label)) + sym = lookup(label) } - return n + return ir.NewBranchStmt(pos, op, sym) + + case ir.OLABEL: + return ir.NewLabelStmt(r.pos(), lookup(r.string())) case ir.OEND: return nil diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index 55628352bd..4c8e56731b 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -699,7 +699,7 @@ func (p *noder) expr(expr syntax.Expr) ir.Node { if expr.Full { op = ir.OSLICE3 } - n := p.nod(expr, op, p.expr(expr.X), nil) + n := ir.NewSliceExpr(p.pos(expr), op, p.expr(expr.X)) var index [3]ir.Node for i, x := range &expr.Index { if x != nil { @@ -716,9 +716,22 @@ func (p *noder) expr(expr syntax.Expr) ir.Node { } x := p.expr(expr.X) if expr.Y == nil { - return p.nod(expr, p.unOp(expr.Op), x, nil) + pos, op := p.pos(expr), p.unOp(expr.Op) + switch op { + case ir.OADDR: + return nodAddrAt(pos, x) + case ir.ODEREF: + return ir.NewStarExpr(pos, x) + } + return ir.NewUnaryExpr(pos, op, x) + } + + pos, op, y := p.pos(expr), p.binOp(expr.Op), p.expr(expr.Y) + switch op { + case ir.OANDAND, ir.OOROR: + return ir.NewLogicalExpr(pos, op, x, y) } - return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y)) + return ir.NewBinaryExpr(pos, op, x, y) case *syntax.CallExpr: n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil) n.PtrList().Set(p.exprs(expr.ArgList)) @@ -1043,11 +1056,11 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node { default: panic("unhandled BranchStmt") } - n := p.nod(stmt, op, nil, nil) + var sym *types.Sym if stmt.Label != nil { - n.SetSym(p.name(stmt.Label)) + sym = p.name(stmt.Label) } - return n + return ir.NewBranchStmt(p.pos(stmt), op, sym) case *syntax.CallStmt: var op ir.Op switch stmt.Tok { @@ -1058,7 +1071,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node { default: panic("unhandled CallStmt") } - return p.nod(stmt, op, p.expr(stmt.Call), nil) + return ir.NewGoDeferStmt(p.pos(stmt), op, p.expr(stmt.Call)) case *syntax.ReturnStmt: var results []ir.Node if stmt.Results != nil { diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index 56acdf7528..fe64738856 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -619,11 +619,8 @@ func (o *Order) stmt(n ir.Node) { l2.SetIndexMapLValue(false) } l2 = o.copyExpr(l2) - r := ir.NodAt(n.Pos(), n.SubOp(), l2, n.Right()) - r = typecheck(r, ctxExpr) - r = o.expr(r, nil) - n = ir.NodAt(n.Pos(), ir.OAS, l1, r) - n = typecheck(n, ctxStmt) + r := o.expr(typecheck(ir.NewBinaryExpr(n.Pos(), n.SubOp(), l2, n.Right()), ctxExpr), nil) + n = typecheck(ir.NodAt(n.Pos(), ir.OAS, l1, r), ctxStmt) } o.mapAssign(n) diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go index 0c2f2a87a2..dd08b77b92 100644 --- a/src/cmd/compile/internal/gc/select.go +++ b/src/cmd/compile/internal/gc/select.go @@ -70,7 +70,8 @@ func typecheckselect(sel ir.Node) { case ir.ORECV: // convert <-c into OSELRECV(_, <-c) - n = ir.NodAt(n.Pos(), ir.OSELRECV, ir.BlankNode, n) + n = ir.NodAt(n.Pos(), ir.OAS, ir.BlankNode, n) + n.SetOp(ir.OSELRECV) n.SetTypecheck(1) ncase.SetLeft(n) @@ -164,7 +165,8 @@ func walkselectcases(cases *ir.Nodes) []ir.Node { // Lower x, _ = <-c to x = <-c. if n.Op() == ir.OSELRECV2 && ir.IsBlank(n.List().Second()) { - n = ir.NodAt(n.Pos(), ir.OSELRECV, n.List().First(), n.Rlist().First()) + n = ir.NodAt(n.Pos(), ir.OAS, n.List().First(), n.Rlist().First()) + n.SetOp(ir.OSELRECV) n.SetTypecheck(1) cas.SetLeft(n) } diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index ae100507f6..37e49d0544 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -547,8 +547,7 @@ func assignconvfn(n ir.Node, t *types.Type, context func() string) ir.Node { op = ir.OCONV } - r := ir.Nod(op, n, nil) - r.SetType(t) + r := ir.NewConvExpr(base.Pos, op, t, n) r.SetTypecheck(1) r.SetImplicit(true) return r @@ -1169,7 +1168,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { fn.PtrBody().Append(n) } - dot := adddot(nodSym(ir.OXDOT, nthis, method.Sym)) + dot := adddot(ir.NewSelectorExpr(base.Pos, ir.OXDOT, nthis, method.Sym)) // generate call // It's not possible to use a tail call when dynamic linking on ppc64le. The diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index be868afcd8..6dc9c5820d 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -766,8 +766,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { dowidth(l.Type()) if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 { - l = ir.Nod(aop, l, nil) - l.SetType(r.Type()) + l = ir.NewConvExpr(base.Pos, aop, r.Type(), l) l.SetTypecheck(1) n.SetLeft(l) } @@ -788,8 +787,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { dowidth(r.Type()) if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 { - r = ir.Nod(aop, r, nil) - r.SetType(l.Type()) + r = ir.NewConvExpr(base.Pos, aop, l.Type(), r) r.SetTypecheck(1) n.SetRight(r) } @@ -1361,12 +1359,12 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { switch l.SubOp() { default: base.Fatalf("unknown builtin %v", l) - return n case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER: n.SetOp(l.SubOp()) n.SetLeft(nil) n.SetTypecheck(0) // re-typechecking new op is OK, not a loop + return typecheck(n, top) case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL: typecheckargs(n) @@ -1377,9 +1375,8 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { n.SetType(nil) return n } - old := n - n = ir.NodAt(n.Pos(), l.SubOp(), arg, nil) - n = initExpr(old.Init().Slice(), n) // typecheckargs can add to old.Init + u := ir.NewUnaryExpr(n.Pos(), l.SubOp(), arg) + return typecheck(initExpr(n.Init().Slice(), u), top) // typecheckargs can add to old.Init case ir.OCOMPLEX, ir.OCOPY: typecheckargs(n) @@ -1388,11 +1385,10 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { n.SetType(nil) return n } - old := n - n = ir.NodAt(n.Pos(), l.SubOp(), arg1, arg2) - n = initExpr(old.Init().Slice(), n) // typecheckargs can add to old.Init + b := ir.NewBinaryExpr(n.Pos(), l.SubOp(), arg1, arg2) + return typecheck(initExpr(n.Init().Slice(), b), top) // typecheckargs can add to old.Init } - return typecheck(n, top) + panic("unreachable") } n.SetLeft(defaultlit(n.Left(), nil)) diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 790e51f1e6..ad5103f851 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -666,7 +666,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { if n.Op() == ir.OASOP { // Rewrite x op= y into x = x op y. n = ir.Nod(ir.OAS, n.Left(), - typecheck(ir.Nod(n.SubOp(), n.Left(), n.Right()), ctxExpr)) + typecheck(ir.NewBinaryExpr(base.Pos, n.SubOp(), n.Left(), n.Right()), ctxExpr)) } if oaslit(n, init) { @@ -3232,16 +3232,16 @@ func walkcompare(n ir.Node, init *ir.Nodes) ir.Node { if l.Type().IsEmptyInterface() { tab.SetType(types.NewPtr(types.Types[types.TUINT8])) tab.SetTypecheck(1) - eqtype = ir.Nod(eq, tab, rtyp) + eqtype = ir.NewBinaryExpr(base.Pos, eq, tab, rtyp) } else { - nonnil := ir.Nod(brcom(eq), nodnil(), tab) - match := ir.Nod(eq, itabType(tab), rtyp) - eqtype = ir.Nod(andor, nonnil, match) + nonnil := ir.NewBinaryExpr(base.Pos, brcom(eq), nodnil(), tab) + match := ir.NewBinaryExpr(base.Pos, eq, itabType(tab), rtyp) + eqtype = ir.NewLogicalExpr(base.Pos, andor, nonnil, match) } // Check for data equal. - eqdata := ir.Nod(eq, ifaceData(n.Pos(), l, r.Type()), r) + eqdata := ir.NewBinaryExpr(base.Pos, eq, ifaceData(n.Pos(), l, r.Type()), r) // Put it all together. - expr := ir.Nod(andor, eqtype, eqdata) + expr := ir.NewLogicalExpr(base.Pos, andor, eqtype, eqdata) n = finishcompare(n, expr, init) return n } @@ -3354,11 +3354,11 @@ func walkcompare(n ir.Node, init *ir.Nodes) ir.Node { } var expr ir.Node compare := func(el, er ir.Node) { - a := ir.Nod(n.Op(), el, er) + a := ir.NewBinaryExpr(base.Pos, n.Op(), el, er) if expr == nil { expr = a } else { - expr = ir.Nod(andor, expr, a) + expr = ir.NewLogicalExpr(base.Pos, andor, expr, a) } } cmpl = safeexpr(cmpl, init) @@ -3519,13 +3519,13 @@ func walkcompareString(n ir.Node, init *ir.Nodes) ir.Node { if len(s) > 0 { ncs = safeexpr(ncs, init) } - r := ir.Nod(cmp, ir.Nod(ir.OLEN, ncs, nil), nodintconst(int64(len(s)))) + r := ir.Node(ir.NewBinaryExpr(base.Pos, cmp, ir.Nod(ir.OLEN, ncs, nil), nodintconst(int64(len(s))))) remains := len(s) for i := 0; remains > 0; { if remains == 1 || !canCombineLoads { cb := nodintconst(int64(s[i])) ncb := ir.Nod(ir.OINDEX, ncs, nodintconst(int64(i))) - r = ir.Nod(and, r, ir.Nod(cmp, ncb, cb)) + r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, ncb, cb)) remains-- i++ continue @@ -3556,7 +3556,7 @@ func walkcompareString(n ir.Node, init *ir.Nodes) ir.Node { } csubstrPart := nodintconst(csubstr) // Compare "step" bytes as once - r = ir.Nod(and, r, ir.Nod(cmp, csubstrPart, ncsubstr)) + r = ir.NewLogicalExpr(base.Pos, and, r, ir.NewBinaryExpr(base.Pos, cmp, csubstrPart, ncsubstr)) remains -= step i += step } @@ -3583,7 +3583,7 @@ func walkcompareString(n ir.Node, init *ir.Nodes) ir.Node { } else { // sys_cmpstring(s1, s2) :: 0 r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.Left(), types.Types[types.TSTRING]), conv(n.Right(), types.Types[types.TSTRING])) - r = ir.Nod(n.Op(), r, nodintconst(0)) + r = ir.NewBinaryExpr(base.Pos, n.Op(), r, nodintconst(0)) } return finishcompare(n, r, init) @@ -3909,17 +3909,13 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node { if origArg == nil { continue } - arg := ir.Nod(origArg.Op(), args[i], nil) - arg.SetType(origArg.Type()) - args[i] = arg + args[i] = ir.NewConvExpr(base.Pos, origArg.Op(), origArg.Type(), args[i]) } - call := ir.Nod(n.Op(), nil, nil) + call := ir.NewCallExpr(base.Pos, n.Op(), n.Left(), args) if !isBuiltinCall { call.SetOp(ir.OCALL) - call.SetLeft(n.Left()) call.SetIsDDD(n.IsDDD()) } - call.PtrList().Set(args) fn.PtrBody().Set1(call) funcbody() @@ -3928,12 +3924,8 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node { typecheckslice(fn.Body().Slice(), ctxStmt) xtop = append(xtop, fn) - call = ir.Nod(ir.OCALL, nil, nil) - call.SetLeft(fn.Nname) - call.PtrList().Set(n.List().Slice()) - call = typecheck(call, ctxStmt) - call = walkexpr(call, init) - return call + call = ir.NewCallExpr(base.Pos, ir.OCALL, fn.Nname, n.List().Slice()) + return walkexpr(typecheck(call, ctxStmt), init) } // substArgTypes substitutes the given list of types for -- 2.48.1