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) } - return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y)) + + 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: 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