1
0
mirror of https://github.com/golang/go synced 2024-11-14 06:30:22 -07:00

[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 <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-12-07 14:58:26 -05:00
parent 5ae70b85c6
commit 578fbbe3aa
7 changed files with 89 additions and 68 deletions

View File

@ -894,10 +894,10 @@ func (r *importReader) node() ir.Node {
// unreachable - mapped to cases below by exporter // unreachable - mapped to cases below by exporter
case ir.OINDEX: 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: 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() low, high := r.exprsOrNil()
var max ir.Node var max ir.Node
if n.Op().IsSlice3() { if n.Op().IsSlice3() {
@ -940,15 +940,25 @@ func (r *importReader) node() ir.Node {
return n return n
// unary expressions // unary expressions
case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV: case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
return ir.NodAt(r.pos(), op, r.expr(), nil) return ir.NewUnaryExpr(r.pos(), op, r.expr())
case ir.OADDR: case ir.OADDR:
return nodAddrAt(r.pos(), r.expr()) return nodAddrAt(r.pos(), r.expr())
case ir.ODEREF:
return ir.NewStarExpr(r.pos(), r.expr())
// binary expressions // binary expressions
case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, 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.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR: ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
return ir.NodAt(r.pos(), op, r.expr(), r.expr()) 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: case ir.OADDSTR:
pos := r.pos() pos := r.pos()
@ -1003,7 +1013,7 @@ func (r *importReader) node() ir.Node {
// unreachable - generated by compiler for trampolin routines (not exported) // unreachable - generated by compiler for trampolin routines (not exported)
case ir.OGO, ir.ODEFER: 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: case ir.OIF:
n := ir.NodAt(r.pos(), ir.OIF, nil, nil) n := ir.NodAt(r.pos(), ir.OIF, nil, nil)
@ -1029,8 +1039,16 @@ func (r *importReader) node() ir.Node {
n.PtrBody().Set(r.stmtList()) n.PtrBody().Set(r.stmtList())
return n return n
case ir.OSELECT, ir.OSWITCH: case ir.OSELECT:
n := ir.NodAt(r.pos(), op, nil, nil) 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()) n.PtrInit().Set(r.stmtList())
left, _ := r.exprsOrNil() left, _ := r.exprsOrNil()
n.SetLeft(left) n.SetLeft(left)
@ -1047,12 +1065,16 @@ func (r *importReader) node() ir.Node {
// case OEMPTY: // case OEMPTY:
// unreachable - not emitted by exporter // unreachable - not emitted by exporter
case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL: case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
n := ir.NodAt(r.pos(), op, nil, nil) var sym *types.Sym
pos := r.pos()
if label := r.string(); label != "" { 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: case ir.OEND:
return nil return nil

View File

@ -699,7 +699,7 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
if expr.Full { if expr.Full {
op = ir.OSLICE3 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 var index [3]ir.Node
for i, x := range &expr.Index { for i, x := range &expr.Index {
if x != nil { if x != nil {
@ -716,9 +716,22 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
} }
x := p.expr(expr.X) x := p.expr(expr.X)
if expr.Y == nil { 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 p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y)) 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 ir.NewBinaryExpr(pos, op, x, y)
case *syntax.CallExpr: case *syntax.CallExpr:
n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil) n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil)
n.PtrList().Set(p.exprs(expr.ArgList)) n.PtrList().Set(p.exprs(expr.ArgList))
@ -1043,11 +1056,11 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
default: default:
panic("unhandled BranchStmt") panic("unhandled BranchStmt")
} }
n := p.nod(stmt, op, nil, nil) var sym *types.Sym
if stmt.Label != nil { 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: case *syntax.CallStmt:
var op ir.Op var op ir.Op
switch stmt.Tok { switch stmt.Tok {
@ -1058,7 +1071,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
default: default:
panic("unhandled CallStmt") 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: case *syntax.ReturnStmt:
var results []ir.Node var results []ir.Node
if stmt.Results != nil { if stmt.Results != nil {

View File

@ -619,11 +619,8 @@ func (o *Order) stmt(n ir.Node) {
l2.SetIndexMapLValue(false) l2.SetIndexMapLValue(false)
} }
l2 = o.copyExpr(l2) l2 = o.copyExpr(l2)
r := ir.NodAt(n.Pos(), n.SubOp(), l2, n.Right()) r := o.expr(typecheck(ir.NewBinaryExpr(n.Pos(), n.SubOp(), l2, n.Right()), ctxExpr), nil)
r = typecheck(r, ctxExpr) n = typecheck(ir.NodAt(n.Pos(), ir.OAS, l1, r), ctxStmt)
r = o.expr(r, nil)
n = ir.NodAt(n.Pos(), ir.OAS, l1, r)
n = typecheck(n, ctxStmt)
} }
o.mapAssign(n) o.mapAssign(n)

View File

@ -70,7 +70,8 @@ func typecheckselect(sel ir.Node) {
case ir.ORECV: case ir.ORECV:
// convert <-c into OSELRECV(_, <-c) // 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) n.SetTypecheck(1)
ncase.SetLeft(n) ncase.SetLeft(n)
@ -164,7 +165,8 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
// Lower x, _ = <-c to x = <-c. // Lower x, _ = <-c to x = <-c.
if n.Op() == ir.OSELRECV2 && ir.IsBlank(n.List().Second()) { 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) n.SetTypecheck(1)
cas.SetLeft(n) cas.SetLeft(n)
} }

View File

@ -547,8 +547,7 @@ func assignconvfn(n ir.Node, t *types.Type, context func() string) ir.Node {
op = ir.OCONV op = ir.OCONV
} }
r := ir.Nod(op, n, nil) r := ir.NewConvExpr(base.Pos, op, t, n)
r.SetType(t)
r.SetTypecheck(1) r.SetTypecheck(1)
r.SetImplicit(true) r.SetImplicit(true)
return r return r
@ -1169,7 +1168,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
fn.PtrBody().Append(n) 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 // generate call
// It's not possible to use a tail call when dynamic linking on ppc64le. The // It's not possible to use a tail call when dynamic linking on ppc64le. The

View File

@ -766,8 +766,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
dowidth(l.Type()) dowidth(l.Type())
if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 { if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Width >= 1<<16 {
l = ir.Nod(aop, l, nil) l = ir.NewConvExpr(base.Pos, aop, r.Type(), l)
l.SetType(r.Type())
l.SetTypecheck(1) l.SetTypecheck(1)
n.SetLeft(l) n.SetLeft(l)
} }
@ -788,8 +787,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
dowidth(r.Type()) dowidth(r.Type())
if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 { if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Width >= 1<<16 {
r = ir.Nod(aop, r, nil) r = ir.NewConvExpr(base.Pos, aop, l.Type(), r)
r.SetType(l.Type())
r.SetTypecheck(1) r.SetTypecheck(1)
n.SetRight(r) n.SetRight(r)
} }
@ -1361,12 +1359,12 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
switch l.SubOp() { switch l.SubOp() {
default: default:
base.Fatalf("unknown builtin %v", l) base.Fatalf("unknown builtin %v", l)
return n
case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER: case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
n.SetOp(l.SubOp()) n.SetOp(l.SubOp())
n.SetLeft(nil) n.SetLeft(nil)
n.SetTypecheck(0) // re-typechecking new op is OK, not a loop 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: case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
typecheckargs(n) typecheckargs(n)
@ -1377,9 +1375,8 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
n.SetType(nil) n.SetType(nil)
return n return n
} }
old := n u := ir.NewUnaryExpr(n.Pos(), l.SubOp(), arg)
n = ir.NodAt(n.Pos(), l.SubOp(), arg, nil) return typecheck(initExpr(n.Init().Slice(), u), top) // typecheckargs can add to old.Init
n = initExpr(old.Init().Slice(), n) // typecheckargs can add to old.Init
case ir.OCOMPLEX, ir.OCOPY: case ir.OCOMPLEX, ir.OCOPY:
typecheckargs(n) typecheckargs(n)
@ -1388,11 +1385,10 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
n.SetType(nil) n.SetType(nil)
return n return n
} }
old := n b := ir.NewBinaryExpr(n.Pos(), l.SubOp(), arg1, arg2)
n = ir.NodAt(n.Pos(), l.SubOp(), arg1, arg2) return typecheck(initExpr(n.Init().Slice(), b), top) // typecheckargs can add to old.Init
n = initExpr(old.Init().Slice(), n) // typecheckargs can add to old.Init
} }
return typecheck(n, top) panic("unreachable")
} }
n.SetLeft(defaultlit(n.Left(), nil)) n.SetLeft(defaultlit(n.Left(), nil))

View File

@ -666,7 +666,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
if n.Op() == ir.OASOP { if n.Op() == ir.OASOP {
// Rewrite x op= y into x = x op y. // Rewrite x op= y into x = x op y.
n = ir.Nod(ir.OAS, n.Left(), 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) { if oaslit(n, init) {
@ -3232,16 +3232,16 @@ func walkcompare(n ir.Node, init *ir.Nodes) ir.Node {
if l.Type().IsEmptyInterface() { if l.Type().IsEmptyInterface() {
tab.SetType(types.NewPtr(types.Types[types.TUINT8])) tab.SetType(types.NewPtr(types.Types[types.TUINT8]))
tab.SetTypecheck(1) tab.SetTypecheck(1)
eqtype = ir.Nod(eq, tab, rtyp) eqtype = ir.NewBinaryExpr(base.Pos, eq, tab, rtyp)
} else { } else {
nonnil := ir.Nod(brcom(eq), nodnil(), tab) nonnil := ir.NewBinaryExpr(base.Pos, brcom(eq), nodnil(), tab)
match := ir.Nod(eq, itabType(tab), rtyp) match := ir.NewBinaryExpr(base.Pos, eq, itabType(tab), rtyp)
eqtype = ir.Nod(andor, nonnil, match) eqtype = ir.NewLogicalExpr(base.Pos, andor, nonnil, match)
} }
// Check for data equal. // 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. // Put it all together.
expr := ir.Nod(andor, eqtype, eqdata) expr := ir.NewLogicalExpr(base.Pos, andor, eqtype, eqdata)
n = finishcompare(n, expr, init) n = finishcompare(n, expr, init)
return n return n
} }
@ -3354,11 +3354,11 @@ func walkcompare(n ir.Node, init *ir.Nodes) ir.Node {
} }
var expr ir.Node var expr ir.Node
compare := func(el, er 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 { if expr == nil {
expr = a expr = a
} else { } else {
expr = ir.Nod(andor, expr, a) expr = ir.NewLogicalExpr(base.Pos, andor, expr, a)
} }
} }
cmpl = safeexpr(cmpl, init) cmpl = safeexpr(cmpl, init)
@ -3519,13 +3519,13 @@ func walkcompareString(n ir.Node, init *ir.Nodes) ir.Node {
if len(s) > 0 { if len(s) > 0 {
ncs = safeexpr(ncs, init) 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) remains := len(s)
for i := 0; remains > 0; { for i := 0; remains > 0; {
if remains == 1 || !canCombineLoads { if remains == 1 || !canCombineLoads {
cb := nodintconst(int64(s[i])) cb := nodintconst(int64(s[i]))
ncb := ir.Nod(ir.OINDEX, ncs, nodintconst(int64(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-- remains--
i++ i++
continue continue
@ -3556,7 +3556,7 @@ func walkcompareString(n ir.Node, init *ir.Nodes) ir.Node {
} }
csubstrPart := nodintconst(csubstr) csubstrPart := nodintconst(csubstr)
// Compare "step" bytes as once // 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 remains -= step
i += step i += step
} }
@ -3583,7 +3583,7 @@ func walkcompareString(n ir.Node, init *ir.Nodes) ir.Node {
} else { } else {
// sys_cmpstring(s1, s2) :: 0 // 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 = 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) return finishcompare(n, r, init)
@ -3909,17 +3909,13 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node {
if origArg == nil { if origArg == nil {
continue continue
} }
arg := ir.Nod(origArg.Op(), args[i], nil) args[i] = ir.NewConvExpr(base.Pos, origArg.Op(), origArg.Type(), args[i])
arg.SetType(origArg.Type())
args[i] = arg
} }
call := ir.Nod(n.Op(), nil, nil) call := ir.NewCallExpr(base.Pos, n.Op(), n.Left(), args)
if !isBuiltinCall { if !isBuiltinCall {
call.SetOp(ir.OCALL) call.SetOp(ir.OCALL)
call.SetLeft(n.Left())
call.SetIsDDD(n.IsDDD()) call.SetIsDDD(n.IsDDD())
} }
call.PtrList().Set(args)
fn.PtrBody().Set1(call) fn.PtrBody().Set1(call)
funcbody() funcbody()
@ -3928,12 +3924,8 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node {
typecheckslice(fn.Body().Slice(), ctxStmt) typecheckslice(fn.Body().Slice(), ctxStmt)
xtop = append(xtop, fn) xtop = append(xtop, fn)
call = ir.Nod(ir.OCALL, nil, nil) call = ir.NewCallExpr(base.Pos, ir.OCALL, fn.Nname, n.List().Slice())
call.SetLeft(fn.Nname) return walkexpr(typecheck(call, ctxStmt), init)
call.PtrList().Set(n.List().Slice())
call = typecheck(call, ctxStmt)
call = walkexpr(call, init)
return call
} }
// substArgTypes substitutes the given list of types for // substArgTypes substitutes the given list of types for