// 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 gc

import (
	"cmd/compile/internal/types"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"fmt"
	"strings"
)

// The constant is known to runtime.
const (
	tmpstringbufsize = 32
)

func walk(fn *Node) {
	Curfn = fn

	if Debug['W'] != 0 {
		s := fmt.Sprintf("\nbefore %v", Curfn.Func.Nname.Sym)
		dumplist(s, Curfn.Nbody)
	}

	lno := lineno

	// Final typecheck for any unused variables.
	for i, ln := range fn.Func.Dcl {
		if ln.Op == ONAME && (ln.Class() == PAUTO || ln.Class() == PAUTOHEAP) {
			ln = typecheck(ln, Erv|Easgn)
			fn.Func.Dcl[i] = ln
		}
	}

	// Propagate the used flag for typeswitch variables up to the NONAME in it's definition.
	for _, ln := range fn.Func.Dcl {
		if ln.Op == ONAME && (ln.Class() == PAUTO || ln.Class() == PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == OTYPESW && ln.Name.Used() {
			ln.Name.Defn.Left.Name.SetUsed(true)
		}
	}

	for _, ln := range fn.Func.Dcl {
		if ln.Op != ONAME || (ln.Class() != PAUTO && ln.Class() != PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Name.Used() {
			continue
		}
		if defn := ln.Name.Defn; defn != nil && defn.Op == OTYPESW {
			if defn.Left.Name.Used() {
				continue
			}
			yyerrorl(defn.Left.Pos, "%v declared and not used", ln.Sym)
			defn.Left.Name.SetUsed(true) // suppress repeats
		} else {
			yyerrorl(ln.Pos, "%v declared and not used", ln.Sym)
		}
	}

	lineno = lno
	if nerrors != 0 {
		return
	}
	walkstmtlist(Curfn.Nbody.Slice())
	if Debug['W'] != 0 {
		s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
		dumplist(s, Curfn.Nbody)
	}

	zeroResults()
	heapmoves()
	if Debug['W'] != 0 && Curfn.Func.Enter.Len() > 0 {
		s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
		dumplist(s, Curfn.Func.Enter)
	}
}

func walkstmtlist(s []*Node) {
	for i := range s {
		s[i] = walkstmt(s[i])
	}
}

func samelist(a, b []*Node) bool {
	if len(a) != len(b) {
		return false
	}
	for i, n := range a {
		if n != b[i] {
			return false
		}
	}
	return true
}

func paramoutheap(fn *Node) bool {
	for _, ln := range fn.Func.Dcl {
		switch ln.Class() {
		case PPARAMOUT:
			if ln.isParamStackCopy() || ln.Addrtaken() {
				return true
			}

		case PAUTO:
			// stop early - parameters are over
			return false
		}
	}

	return false
}

// adds "adjust" to all the argument locations for the call n.
// n must be a defer or go node that has already been walked.
func adjustargs(n *Node, adjust int) {
	var arg *Node
	var lhs *Node

	callfunc := n.Left
	for _, arg = range callfunc.List.Slice() {
		if arg.Op != OAS {
			Fatalf("call arg not assignment")
		}
		lhs = arg.Left
		if lhs.Op == ONAME {
			// This is a temporary introduced by reorder1.
			// The real store to the stack appears later in the arg list.
			continue
		}

		if lhs.Op != OINDREGSP {
			Fatalf("call argument store does not use OINDREGSP")
		}

		// can't really check this in machine-indep code.
		//if(lhs->val.u.reg != D_SP)
		//      Fatalf("call arg assign not indreg(SP)")
		lhs.Xoffset += int64(adjust)
	}
}

// The result of walkstmt MUST be assigned back to n, e.g.
// 	n.Left = walkstmt(n.Left)
func walkstmt(n *Node) *Node {
	if n == nil {
		return n
	}

	setlineno(n)

	walkstmtlist(n.Ninit.Slice())

	switch n.Op {
	default:
		if n.Op == ONAME {
			yyerror("%v is not a top level statement", n.Sym)
		} else {
			yyerror("%v is not a top level statement", n.Op)
		}
		Dump("nottop", n)

	case OAS,
		OASOP,
		OAS2,
		OAS2DOTTYPE,
		OAS2RECV,
		OAS2FUNC,
		OAS2MAPR,
		OCLOSE,
		OCOPY,
		OCALLMETH,
		OCALLINTER,
		OCALL,
		OCALLFUNC,
		ODELETE,
		OSEND,
		OPRINT,
		OPRINTN,
		OPANIC,
		OEMPTY,
		ORECOVER,
		OGETG:
		if n.Typecheck() == 0 {
			Fatalf("missing typecheck: %+v", n)
		}
		wascopy := n.Op == OCOPY
		init := n.Ninit
		n.Ninit.Set(nil)
		n = walkexpr(n, &init)
		n = addinit(n, init.Slice())
		if wascopy && n.Op == OCONVNOP {
			n.Op = OEMPTY // don't leave plain values as statements.
		}

	// special case for a receive where we throw away
	// the value received.
	case ORECV:
		if n.Typecheck() == 0 {
			Fatalf("missing typecheck: %+v", n)
		}
		init := n.Ninit
		n.Ninit.Set(nil)

		n.Left = walkexpr(n.Left, &init)
		n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, n.Left, nodnil())
		n = walkexpr(n, &init)

		n = addinit(n, init.Slice())

	case OBREAK,
		OCONTINUE,
		OFALL,
		OGOTO,
		OLABEL,
		ODCLCONST,
		ODCLTYPE,
		OCHECKNIL,
		OVARKILL,
		OVARLIVE:
		break

	case ODCL:
		v := n.Left
		if v.Class() == PAUTOHEAP {
			if compiling_runtime {
				yyerror("%v escapes to heap, not allowed in runtime.", v)
			}
			if prealloc[v] == nil {
				prealloc[v] = callnew(v.Type)
			}
			nn := nod(OAS, v.Name.Param.Heapaddr, prealloc[v])
			nn.SetColas(true)
			nn = typecheck(nn, Etop)
			return walkstmt(nn)
		}

	case OBLOCK:
		walkstmtlist(n.List.Slice())

	case OXCASE:
		yyerror("case statement out of place")
		n.Op = OCASE
		fallthrough

	case OCASE:
		n.Right = walkstmt(n.Right)

	case ODEFER:
		Curfn.Func.SetHasDefer(true)
		switch n.Left.Op {
		case OPRINT, OPRINTN:
			n.Left = walkprintfunc(n.Left, &n.Ninit)

		case OCOPY:
			n.Left = copyany(n.Left, &n.Ninit, true)

		default:
			n.Left = walkexpr(n.Left, &n.Ninit)
		}

		// make room for size & fn arguments.
		adjustargs(n, 2*Widthptr)

	case OFOR, OFORUNTIL:
		if n.Left != nil {
			walkstmtlist(n.Left.Ninit.Slice())
			init := n.Left.Ninit
			n.Left.Ninit.Set(nil)
			n.Left = walkexpr(n.Left, &init)
			n.Left = addinit(n.Left, init.Slice())
		}

		n.Right = walkstmt(n.Right)
		walkstmtlist(n.Nbody.Slice())

	case OIF:
		n.Left = walkexpr(n.Left, &n.Ninit)
		walkstmtlist(n.Nbody.Slice())
		walkstmtlist(n.Rlist.Slice())

	case OPROC:
		switch n.Left.Op {
		case OPRINT, OPRINTN:
			n.Left = walkprintfunc(n.Left, &n.Ninit)

		case OCOPY:
			n.Left = copyany(n.Left, &n.Ninit, true)

		default:
			n.Left = walkexpr(n.Left, &n.Ninit)
		}

		// make room for size & fn arguments.
		adjustargs(n, 2*Widthptr)

	case ORETURN:
		walkexprlist(n.List.Slice(), &n.Ninit)
		if n.List.Len() == 0 {
			break
		}
		if (Curfn.Type.FuncType().Outnamed && n.List.Len() > 1) || paramoutheap(Curfn) {
			// assign to the function out parameters,
			// so that reorder3 can fix up conflicts
			var rl []*Node

			var cl Class
			for _, ln := range Curfn.Func.Dcl {
				cl = ln.Class()
				if cl == PAUTO || cl == PAUTOHEAP {
					break
				}
				if cl == PPARAMOUT {
					if ln.isParamStackCopy() {
						ln = walkexpr(typecheck(nod(OIND, ln.Name.Param.Heapaddr, nil), Erv), nil)
					}
					rl = append(rl, ln)
				}
			}

			if got, want := n.List.Len(), len(rl); got != want {
				// order should have rewritten multi-value function calls
				// with explicit OAS2FUNC nodes.
				Fatalf("expected %v return arguments, have %v", want, got)
			}

			if samelist(rl, n.List.Slice()) {
				// special return in disguise
				n.List.Set(nil)

				break
			}

			// move function calls out, to make reorder3's job easier.
			walkexprlistsafe(n.List.Slice(), &n.Ninit)

			ll := ascompatee(n.Op, rl, n.List.Slice(), &n.Ninit)
			n.List.Set(reorder3(ll))
			break
		}

		ll := ascompatte(nil, false, Curfn.Type.Results(), n.List.Slice(), 1, &n.Ninit)
		n.List.Set(ll)

	case ORETJMP:
		break

	case OSELECT:
		walkselect(n)

	case OSWITCH:
		walkswitch(n)

	case ORANGE:
		n = walkrange(n)

	case OXFALL:
		yyerror("fallthrough statement out of place")
		n.Op = OFALL
	}

	if n.Op == ONAME {
		Fatalf("walkstmt ended up with name: %+v", n)
	}
	return n
}

func isSmallMakeSlice(n *Node) bool {
	if n.Op != OMAKESLICE {
		return false
	}
	l := n.Left
	r := n.Right
	if r == nil {
		r = l
	}
	t := n.Type

	return smallintconst(l) && smallintconst(r) && (t.Elem().Width == 0 || r.Int64() < (1<<16)/t.Elem().Width)
}

// walk the whole tree of the body of an
// expression or simple statement.
// the types expressions are calculated.
// compile-time constants are evaluated.
// complex side effects like statements are appended to init
func walkexprlist(s []*Node, init *Nodes) {
	for i := range s {
		s[i] = walkexpr(s[i], init)
	}
}

func walkexprlistsafe(s []*Node, init *Nodes) {
	for i, n := range s {
		s[i] = safeexpr(n, init)
		s[i] = walkexpr(s[i], init)
	}
}

func walkexprlistcheap(s []*Node, init *Nodes) {
	for i, n := range s {
		s[i] = cheapexpr(n, init)
		s[i] = walkexpr(s[i], init)
	}
}

// Build name of function for interface conversion.
// Not all names are possible
// (e.g., we'll never generate convE2E or convE2I or convI2E).
func convFuncName(from, to *types.Type) string {
	tkind := to.Tie()
	switch from.Tie() {
	case 'I':
		switch tkind {
		case 'I':
			return "convI2I"
		}
	case 'T':
		switch tkind {
		case 'E':
			switch {
			case from.Size() == 2 && from.Align == 2:
				return "convT2E16"
			case from.Size() == 4 && from.Align == 4 && !types.Haspointers(from):
				return "convT2E32"
			case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from):
				return "convT2E64"
			case from.IsString():
				return "convT2Estring"
			case from.IsSlice():
				return "convT2Eslice"
			case !types.Haspointers(from):
				return "convT2Enoptr"
			}
			return "convT2E"
		case 'I':
			switch {
			case from.Size() == 2 && from.Align == 2:
				return "convT2I16"
			case from.Size() == 4 && from.Align == 4 && !types.Haspointers(from):
				return "convT2I32"
			case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from):
				return "convT2I64"
			case from.IsString():
				return "convT2Istring"
			case from.IsSlice():
				return "convT2Islice"
			case !types.Haspointers(from):
				return "convT2Inoptr"
			}
			return "convT2I"
		}
	}
	Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie())
	panic("unreachable")
}

// The result of walkexpr MUST be assigned back to n, e.g.
// 	n.Left = walkexpr(n.Left, init)
func walkexpr(n *Node, init *Nodes) *Node {
	if n == nil {
		return n
	}

	// Eagerly checkwidth all expressions for the back end.
	if n.Type != nil && !n.Type.WidthCalculated() {
		switch n.Type.Etype {
		case TBLANK, TNIL, TIDEAL:
		default:
			checkwidth(n.Type)
		}
	}

	if init == &n.Ninit {
		// not okay to use n->ninit when walking n,
		// because we might replace n with some other node
		// and would lose the init list.
		Fatalf("walkexpr init == &n->ninit")
	}

	if n.Ninit.Len() != 0 {
		walkstmtlist(n.Ninit.Slice())
		init.AppendNodes(&n.Ninit)
	}

	lno := setlineno(n)

	if Debug['w'] > 1 {
		Dump("walk-before", n)
	}

	if n.Typecheck() != 1 {
		Fatalf("missed typecheck: %+v", n)
	}

	if n.Op == ONAME && n.Class() == PAUTOHEAP {
		nn := nod(OIND, n.Name.Param.Heapaddr, nil)
		nn = typecheck(nn, Erv)
		nn = walkexpr(nn, init)
		nn.Left.SetNonNil(true)
		return nn
	}

opswitch:
	switch n.Op {
	default:
		Dump("walk", n)
		Fatalf("walkexpr: switch 1 unknown op %+S", n)

	case ONONAME, OINDREGSP, OEMPTY, OGETG:

	case OTYPE, ONAME, OLITERAL:
		// TODO(mdempsky): Just return n; see discussion on CL 38655.
		// Perhaps refactor to use Node.mayBeShared for these instead.
		// If these return early, make sure to still call
		// stringsym for constant strings.

	case ONOT, OMINUS, OPLUS, OCOM, OREAL, OIMAG, ODOTMETH, ODOTINTER,
		OIND, OSPTR, OITAB, OIDATA, OADDR:
		n.Left = walkexpr(n.Left, init)

	case OEFACE, OAND, OSUB, OMUL, OLT, OLE, OGE, OGT, OADD, OOR, OXOR:
		n.Left = walkexpr(n.Left, init)
		n.Right = walkexpr(n.Right, init)

	case ODOT:
		usefield(n)
		n.Left = walkexpr(n.Left, init)

	case ODOTTYPE, ODOTTYPE2:
		n.Left = walkexpr(n.Left, init)
		// Set up interface type addresses for back end.
		n.Right = typename(n.Type)
		if n.Op == ODOTTYPE {
			n.Right.Right = typename(n.Left.Type)
		}
		if !n.Type.IsInterface() && !n.Left.Type.IsEmptyInterface() {
			n.List.Set1(itabname(n.Type, n.Left.Type))
		}

	case ODOTPTR:
		usefield(n)
		if n.Op == ODOTPTR && n.Left.Type.Elem().Width == 0 {
			// No actual copy will be generated, so emit an explicit nil check.
			n.Left = cheapexpr(n.Left, init)

			checknil(n.Left, init)
		}

		n.Left = walkexpr(n.Left, init)

	case OLEN, OCAP:
		n.Left = walkexpr(n.Left, init)

		// replace len(*[10]int) with 10.
		// delayed until now to preserve side effects.
		t := n.Left.Type

		if t.IsPtr() {
			t = t.Elem()
		}
		if t.IsArray() {
			safeexpr(n.Left, init)
			nodconst(n, n.Type, t.NumElem())
			n.SetTypecheck(1)
		}

	case OLSH, ORSH:
		n.Left = walkexpr(n.Left, init)
		n.Right = walkexpr(n.Right, init)
		t := n.Left.Type
		n.SetBounded(bounded(n.Right, 8*t.Width))
		if Debug['m'] != 0 && n.Etype != 0 && !Isconst(n.Right, CTINT) {
			Warn("shift bounds check elided")
		}

	case OCOMPLEX:
		// Use results from call expression as arguments for complex.
		if n.Left == nil && n.Right == nil {
			n.Left = n.List.First()
			n.Right = n.List.Second()
		}
		n.Left = walkexpr(n.Left, init)
		n.Right = walkexpr(n.Right, init)

	case OEQ, ONE:
		n.Left = walkexpr(n.Left, init)
		n.Right = walkexpr(n.Right, init)

		// Disable safemode while compiling this code: the code we
		// generate internally can refer to unsafe.Pointer.
		// In this case it can happen if we need to generate an ==
		// for a struct containing a reflect.Value, which itself has
		// an unexported field of type unsafe.Pointer.
		old_safemode := safemode
		safemode = false
		n = walkcompare(n, init)
		safemode = old_safemode

	case OANDAND, OOROR:
		n.Left = walkexpr(n.Left, init)

		// cannot put side effects from n.Right on init,
		// because they cannot run before n.Left is checked.
		// save elsewhere and store on the eventual n.Right.
		var ll Nodes

		n.Right = walkexpr(n.Right, &ll)
		n.Right = addinit(n.Right, ll.Slice())
		n = walkinrange(n, init)

	case OPRINT, OPRINTN:
		walkexprlist(n.List.Slice(), init)
		n = walkprint(n, init)

	case OPANIC:
		n = mkcall("gopanic", nil, init, n.Left)

	case ORECOVER:
		n = mkcall("gorecover", n.Type, init, nod(OADDR, nodfp, nil))

	case OCLOSUREVAR, OCFUNC:
		n.SetAddable(true)

	case OCALLINTER:
		usemethod(n)
		t := n.Left.Type
		if n.List.Len() != 0 && n.List.First().Op == OAS {
			break
		}
		n.Left = walkexpr(n.Left, init)
		walkexprlist(n.List.Slice(), init)
		ll := ascompatte(n, n.Isddd(), t.Params(), n.List.Slice(), 0, init)
		n.List.Set(reorder1(ll))

	case OCALLFUNC:
		if n.Left.Op == OCLOSURE {
			// Transform direct call of a closure to call of a normal function.
			// transformclosure already did all preparation work.

			// Prepend captured variables to argument list.
			n.List.Prepend(n.Left.Func.Enter.Slice()...)

			n.Left.Func.Enter.Set(nil)

			// Replace OCLOSURE with ONAME/PFUNC.
			n.Left = n.Left.Func.Closure.Func.Nname

			// Update type of OCALLFUNC node.
			// Output arguments had not changed, but their offsets could.
			if n.Left.Type.Results().NumFields() == 1 {
				n.Type = n.Left.Type.Results().Field(0).Type
			} else {
				n.Type = n.Left.Type.Results()
			}
		}

		t := n.Left.Type
		if n.List.Len() != 0 && n.List.First().Op == OAS {
			break
		}

		n.Left = walkexpr(n.Left, init)
		walkexprlist(n.List.Slice(), init)

		ll := ascompatte(n, n.Isddd(), t.Params(), n.List.Slice(), 0, init)
		n.List.Set(reorder1(ll))

	case OCALLMETH:
		t := n.Left.Type
		if n.List.Len() != 0 && n.List.First().Op == OAS {
			break
		}
		n.Left = walkexpr(n.Left, init)
		walkexprlist(n.List.Slice(), init)
		ll := ascompatte(n, false, t.Recvs(), []*Node{n.Left.Left}, 0, init)
		lr := ascompatte(n, n.Isddd(), t.Params(), n.List.Slice(), 0, init)
		ll = append(ll, lr...)
		n.Left.Left = nil
		updateHasCall(n.Left)
		n.List.Set(reorder1(ll))

	case OAS:
		init.AppendNodes(&n.Ninit)

		n.Left = walkexpr(n.Left, init)
		n.Left = safeexpr(n.Left, init)

		if oaslit(n, init) {
			break
		}

		if n.Right == nil {
			// TODO(austin): Check all "implicit zeroing"
			break
		}

		if !instrumenting && iszero(n.Right) {
			break
		}

		switch n.Right.Op {
		default:
			n.Right = walkexpr(n.Right, init)

		case ORECV:
			// x = <-c; n.Left is x, n.Right.Left is c.
			// orderstmt made sure x is addressable.
			n.Right.Left = walkexpr(n.Right.Left, init)

			n1 := nod(OADDR, n.Left, nil)
			r := n.Right.Left // the channel
			n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, r, n1)
			n = walkexpr(n, init)
			break opswitch

		case OAPPEND:
			// x = append(...)
			r := n.Right
			if r.Type.Elem().NotInHeap() {
				yyerror("%v is go:notinheap; heap allocation disallowed", r.Type.Elem())
			}
			if r.Isddd() {
				r = appendslice(r, init) // also works for append(slice, string).
			} else {
				r = walkappend(r, init, n)
			}
			n.Right = r
			if r.Op == OAPPEND {
				// Left in place for back end.
				// Do not add a new write barrier.
				// Set up address of type for back end.
				r.Left = typename(r.Type.Elem())
				break opswitch
			}
			// Otherwise, lowered for race detector.
			// Treat as ordinary assignment.
		}

		if n.Left != nil && n.Right != nil {
			n = convas(n, init)
		}

	case OAS2:
		init.AppendNodes(&n.Ninit)
		walkexprlistsafe(n.List.Slice(), init)
		walkexprlistsafe(n.Rlist.Slice(), init)
		ll := ascompatee(OAS, n.List.Slice(), n.Rlist.Slice(), init)
		ll = reorder3(ll)
		n = liststmt(ll)

	// a,b,... = fn()
	case OAS2FUNC:
		init.AppendNodes(&n.Ninit)

		r := n.Rlist.First()
		walkexprlistsafe(n.List.Slice(), init)
		r = walkexpr(r, init)

		if isIntrinsicCall(r) {
			n.Rlist.Set1(r)
			break
		}
		init.Append(r)

		ll := ascompatet(n.Op, n.List, r.Type)
		n = liststmt(ll)

	// x, y = <-c
	// orderstmt made sure x is addressable.
	case OAS2RECV:
		init.AppendNodes(&n.Ninit)

		r := n.Rlist.First()
		walkexprlistsafe(n.List.Slice(), init)
		r.Left = walkexpr(r.Left, init)
		var n1 *Node
		if isblank(n.List.First()) {
			n1 = nodnil()
		} else {
			n1 = nod(OADDR, n.List.First(), nil)
		}
		n1.Etype = 1 // addr does not escape
		fn := chanfn("chanrecv2", 2, r.Left.Type)
		ok := n.List.Second()
		call := mkcall1(fn, ok.Type, init, r.Left, n1)
		n = nod(OAS, ok, call)
		n = typecheck(n, Etop)

	// a,b = m[i]
	case OAS2MAPR:
		init.AppendNodes(&n.Ninit)

		r := n.Rlist.First()
		walkexprlistsafe(n.List.Slice(), init)
		r.Left = walkexpr(r.Left, init)
		r.Right = walkexpr(r.Right, init)
		t := r.Left.Type

		fast := mapfast(t)
		var key *Node
		if fast != mapslow {
			// fast versions take key by value
			key = r.Right
		} else {
			// standard version takes key by reference
			// orderexpr made sure key is addressable.
			key = nod(OADDR, r.Right, nil)
		}

		// from:
		//   a,b = m[i]
		// to:
		//   var,b = mapaccess2*(t, m, i)
		//   a = *var
		a := n.List.First()

		if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/hashmap.go:maxZero
			fn := mapfn(mapaccess2[fast], t)
			r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key)
		} else {
			fn := mapfn("mapaccess2_fat", t)
			z := zeroaddr(w)
			r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key, z)
		}

		// mapaccess2* returns a typed bool, but due to spec changes,
		// the boolean result of i.(T) is now untyped so we make it the
		// same type as the variable on the lhs.
		if ok := n.List.Second(); !isblank(ok) && ok.Type.IsBoolean() {
			r.Type.Field(1).Type = ok.Type
		}
		n.Rlist.Set1(r)
		n.Op = OAS2FUNC

		// don't generate a = *var if a is _
		if !isblank(a) {
			var_ := temp(types.NewPtr(t.Val()))
			var_.SetTypecheck(1)
			var_.SetNonNil(true) // mapaccess always returns a non-nil pointer
			n.List.SetFirst(var_)
			n = walkexpr(n, init)
			init.Append(n)
			n = nod(OAS, a, nod(OIND, var_, nil))
		}

		n = typecheck(n, Etop)
		n = walkexpr(n, init)

	case ODELETE:
		init.AppendNodes(&n.Ninit)
		map_ := n.List.First()
		key := n.List.Second()
		map_ = walkexpr(map_, init)
		key = walkexpr(key, init)

		t := map_.Type
		fast := mapfast(t)
		if fast == mapslow {
			// orderstmt made sure key is addressable.
			key = nod(OADDR, key, nil)
		}
		n = mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key)

	case OAS2DOTTYPE:
		walkexprlistsafe(n.List.Slice(), init)
		n.Rlist.SetFirst(walkexpr(n.Rlist.First(), init))

	case OCONVIFACE:
		n.Left = walkexpr(n.Left, init)

		// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
		if isdirectiface(n.Left.Type) {
			var t *Node
			if n.Type.IsEmptyInterface() {
				t = typename(n.Left.Type)
			} else {
				t = itabname(n.Left.Type, n.Type)
			}
			l := nod(OEFACE, t, n.Left)
			l.Type = n.Type
			l.SetTypecheck(n.Typecheck())
			n = l
			break
		}

		if staticbytes == nil {
			staticbytes = newname(Runtimepkg.Lookup("staticbytes"))
			staticbytes.SetClass(PEXTERN)
			staticbytes.Type = types.NewArray(types.Types[TUINT8], 256)
			zerobase = newname(Runtimepkg.Lookup("zerobase"))
			zerobase.SetClass(PEXTERN)
			zerobase.Type = types.Types[TUINTPTR]
		}

		// Optimize convT2{E,I} for many cases in which T is not pointer-shaped,
		// by using an existing addressable value identical to n.Left
		// or creating one on the stack.
		var value *Node
		switch {
		case n.Left.Type.Size() == 0:
			// n.Left is zero-sized. Use zerobase.
			cheapexpr(n.Left, init) // Evaluate n.Left for side-effects. See issue 19246.
			value = zerobase
		case n.Left.Type.IsBoolean() || (n.Left.Type.Size() == 1 && n.Left.Type.IsInteger()):
			// n.Left is a bool/byte. Use staticbytes[n.Left].
			n.Left = cheapexpr(n.Left, init)
			value = nod(OINDEX, staticbytes, byteindex(n.Left))
			value.SetBounded(true)
		case n.Left.Class() == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly():
			// n.Left is a readonly global; use it directly.
			value = n.Left
		case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024:
			// n.Left does not escape. Use a stack temporary initialized to n.Left.
			value = temp(n.Left.Type)
			init.Append(typecheck(nod(OAS, value, n.Left), Etop))
		}

		if value != nil {
			// Value is identical to n.Left.
			// Construct the interface directly: {type/itab, &value}.
			var t *Node
			if n.Type.IsEmptyInterface() {
				t = typename(n.Left.Type)
			} else {
				t = itabname(n.Left.Type, n.Type)
			}
			l := nod(OEFACE, t, typecheck(nod(OADDR, value, nil), Erv))
			l.Type = n.Type
			l.SetTypecheck(n.Typecheck())
			n = l
			break
		}

		// Implement interface to empty interface conversion.
		// tmp = i.itab
		// if tmp != nil {
		//    tmp = tmp.type
		// }
		// e = iface{tmp, i.data}
		if n.Type.IsEmptyInterface() && n.Left.Type.IsInterface() && !n.Left.Type.IsEmptyInterface() {
			// Evaluate the input interface.
			c := temp(n.Left.Type)
			init.Append(nod(OAS, c, n.Left))

			// Get the itab out of the interface.
			tmp := temp(types.NewPtr(types.Types[TUINT8]))
			init.Append(nod(OAS, tmp, typecheck(nod(OITAB, c, nil), Erv)))

			// Get the type out of the itab.
			nif := nod(OIF, typecheck(nod(ONE, tmp, nodnil()), Erv), nil)
			nif.Nbody.Set1(nod(OAS, tmp, itabType(tmp)))
			init.Append(nif)

			// Build the result.
			e := nod(OEFACE, tmp, ifaceData(c, types.NewPtr(types.Types[TUINT8])))
			e.Type = n.Type // assign type manually, typecheck doesn't understand OEFACE.
			e.SetTypecheck(1)
			n = e
			break
		}

		var ll []*Node
		if n.Type.IsEmptyInterface() {
			if !n.Left.Type.IsInterface() {
				ll = append(ll, typename(n.Left.Type))
			}
		} else {
			if n.Left.Type.IsInterface() {
				ll = append(ll, typename(n.Type))
			} else {
				ll = append(ll, itabname(n.Left.Type, n.Type))
			}
		}

		if n.Left.Type.IsInterface() {
			ll = append(ll, n.Left)
		} else {
			// regular types are passed by reference to avoid C vararg calls
			// orderexpr arranged for n.Left to be a temporary for all
			// the conversions it could see. comparison of an interface
			// with a non-interface, especially in a switch on interface value
			// with non-interface cases, is not visible to orderstmt, so we
			// have to fall back on allocating a temp here.
			if islvalue(n.Left) {
				ll = append(ll, nod(OADDR, n.Left, nil))
			} else {
				ll = append(ll, nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil))
			}
			dowidth(n.Left.Type)
		}

		fn := syslook(convFuncName(n.Left.Type, n.Type))
		fn = substArgTypes(fn, n.Left.Type, n.Type)
		dowidth(fn.Type)
		n = nod(OCALL, fn, nil)
		n.List.Set(ll)
		n = typecheck(n, Erv)
		n = walkexpr(n, init)

	case OCONV, OCONVNOP:
		if thearch.LinkArch.Family == sys.ARM || thearch.LinkArch.Family == sys.MIPS {
			if n.Left.Type.IsFloat() {
				if n.Type.Etype == TINT64 {
					n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
					break
				}

				if n.Type.Etype == TUINT64 {
					n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
					break
				}
			}

			if n.Type.IsFloat() {
				if n.Left.Type.Etype == TINT64 {
					n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
					break
				}

				if n.Left.Type.Etype == TUINT64 {
					n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
					break
				}
			}
		}

		if thearch.LinkArch.Family == sys.I386 {
			if n.Left.Type.IsFloat() {
				if n.Type.Etype == TINT64 {
					n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
					break
				}

				if n.Type.Etype == TUINT64 {
					n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
					break
				}
				if n.Type.Etype == TUINT32 || n.Type.Etype == TUINT || n.Type.Etype == TUINTPTR {
					n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
					break
				}
			}
			if n.Type.IsFloat() {
				if n.Left.Type.Etype == TINT64 {
					n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
					break
				}

				if n.Left.Type.Etype == TUINT64 {
					n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
					break
				}
				if n.Left.Type.Etype == TUINT32 || n.Left.Type.Etype == TUINT || n.Left.Type.Etype == TUINTPTR {
					n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type)
					break
				}
			}
		}

		n.Left = walkexpr(n.Left, init)

	case OANDNOT:
		n.Left = walkexpr(n.Left, init)
		n.Op = OAND
		n.Right = nod(OCOM, n.Right, nil)
		n.Right = typecheck(n.Right, Erv)
		n.Right = walkexpr(n.Right, init)

	case ODIV, OMOD:
		n.Left = walkexpr(n.Left, init)
		n.Right = walkexpr(n.Right, init)

		// rewrite complex div into function call.
		et := n.Left.Type.Etype

		if isComplex[et] && n.Op == ODIV {
			t := n.Type
			n = mkcall("complex128div", types.Types[TCOMPLEX128], init, conv(n.Left, types.Types[TCOMPLEX128]), conv(n.Right, types.Types[TCOMPLEX128]))
			n = conv(n, t)
			break
		}

		// Nothing to do for float divisions.
		if isFloat[et] {
			break
		}

		// rewrite 64-bit div and mod on 32-bit architectures.
		// TODO: Remove this code once we can introduce
		// runtime calls late in SSA processing.
		if Widthreg < 8 && (et == TINT64 || et == TUINT64) {
			if n.Right.Op == OLITERAL {
				// Leave div/mod by constant powers of 2.
				// The SSA backend will handle those.
				switch et {
				case TINT64:
					c := n.Right.Int64()
					if c < 0 {
						c = -c
					}
					if c != 0 && c&(c-1) == 0 {
						break opswitch
					}
				case TUINT64:
					c := uint64(n.Right.Int64())
					if c != 0 && c&(c-1) == 0 {
						break opswitch
					}
				}
			}
			var fn string
			if et == TINT64 {
				fn = "int64"
			} else {
				fn = "uint64"
			}
			if n.Op == ODIV {
				fn += "div"
			} else {
				fn += "mod"
			}
			n = mkcall(fn, n.Type, init, conv(n.Left, types.Types[et]), conv(n.Right, types.Types[et]))
		}

	case OINDEX:
		n.Left = walkexpr(n.Left, init)

		// save the original node for bounds checking elision.
		// If it was a ODIV/OMOD walk might rewrite it.
		r := n.Right

		n.Right = walkexpr(n.Right, init)

		// if range of type cannot exceed static array bound,
		// disable bounds check.
		if n.Bounded() {
			break
		}
		t := n.Left.Type
		if t != nil && t.IsPtr() {
			t = t.Elem()
		}
		if t.IsArray() {
			n.SetBounded(bounded(r, t.NumElem()))
			if Debug['m'] != 0 && n.Bounded() && !Isconst(n.Right, CTINT) {
				Warn("index bounds check elided")
			}
			if smallintconst(n.Right) && !n.Bounded() {
				yyerror("index out of bounds")
			}
		} else if Isconst(n.Left, CTSTR) {
			n.SetBounded(bounded(r, int64(len(n.Left.Val().U.(string)))))
			if Debug['m'] != 0 && n.Bounded() && !Isconst(n.Right, CTINT) {
				Warn("index bounds check elided")
			}
			if smallintconst(n.Right) && !n.Bounded() {
				yyerror("index out of bounds")
			}
		}

		if Isconst(n.Right, CTINT) {
			if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 {
				yyerror("index out of bounds")
			}
		}

	case OINDEXMAP:
		// Replace m[k] with *map{access1,assign}(maptype, m, &k)
		n.Left = walkexpr(n.Left, init)
		n.Right = walkexpr(n.Right, init)
		map_ := n.Left
		key := n.Right
		t := map_.Type
		if n.Etype == 1 {
			// This m[k] expression is on the left-hand side of an assignment.
			fast := mapfast(t)
			if fast == mapslow {
				// standard version takes key by reference.
				// orderexpr made sure key is addressable.
				key = nod(OADDR, key, nil)
			}
			n = mkcall1(mapfn(mapassign[fast], t), nil, init, typename(t), map_, key)
		} else {
			// m[k] is not the target of an assignment.
			fast := mapfast(t)
			if fast == mapslow {
				// standard version takes key by reference.
				// orderexpr made sure key is addressable.
				key = nod(OADDR, key, nil)
			}

			if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/hashmap.go:maxZero
				n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Val()), init, typename(t), map_, key)
			} else {
				z := zeroaddr(w)
				n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Val()), init, typename(t), map_, key, z)
			}
		}
		n.Type = types.NewPtr(t.Val())
		n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers.
		n = nod(OIND, n, nil)
		n.Type = t.Val()
		n.SetTypecheck(1)

	case ORECV:
		Fatalf("walkexpr ORECV") // should see inside OAS only

	case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
		n.Left = walkexpr(n.Left, init)
		low, high, max := n.SliceBounds()
		low = walkexpr(low, init)
		if low != nil && iszero(low) {
			// Reduce x[0:j] to x[:j] and x[0:j:k] to x[:j:k].
			low = nil
		}
		high = walkexpr(high, init)
		max = walkexpr(max, init)
		n.SetSliceBounds(low, high, max)
		if n.Op.IsSlice3() {
			if max != nil && max.Op == OCAP && samesafeexpr(n.Left, max.Left) {
				// Reduce x[i:j:cap(x)] to x[i:j].
				if n.Op == OSLICE3 {
					n.Op = OSLICE
				} else {
					n.Op = OSLICEARR
				}
				n = reduceSlice(n)
			}
		} else {
			n = reduceSlice(n)
		}

	case ONEW:
		if n.Esc == EscNone {
			if n.Type.Elem().Width >= 1<<16 {
				Fatalf("large ONEW with EscNone: %v", n)
			}
			r := temp(n.Type.Elem())
			r = nod(OAS, r, nil) // zero temp
			r = typecheck(r, Etop)
			init.Append(r)
			r = nod(OADDR, r.Left, nil)
			r = typecheck(r, Erv)
			n = r
		} else {
			n = callnew(n.Type.Elem())
		}

	case OCMPSTR:
		// s + "badgerbadgerbadger" == "badgerbadgerbadger"
		if (Op(n.Etype) == OEQ || Op(n.Etype) == ONE) && Isconst(n.Right, CTSTR) && n.Left.Op == OADDSTR && n.Left.List.Len() == 2 && Isconst(n.Left.List.Second(), CTSTR) && strlit(n.Right) == strlit(n.Left.List.Second()) {
			// TODO(marvin): Fix Node.EType type union.
			r := nod(Op(n.Etype), nod(OLEN, n.Left.List.First(), nil), nodintconst(0))
			r = typecheck(r, Erv)
			r = walkexpr(r, init)
			r.Type = n.Type
			n = r
			break
		}

		// Rewrite comparisons to short constant strings as length+byte-wise comparisons.
		var cs, ncs *Node // const string, non-const string
		switch {
		case Isconst(n.Left, CTSTR) && Isconst(n.Right, CTSTR):
			// ignore; will be constant evaluated
		case Isconst(n.Left, CTSTR):
			cs = n.Left
			ncs = n.Right
		case Isconst(n.Right, CTSTR):
			cs = n.Right
			ncs = n.Left
		}
		if cs != nil {
			cmp := Op(n.Etype)
			// Our comparison below assumes that the non-constant string
			// is on the left hand side, so rewrite "" cmp x to x cmp "".
			// See issue 24817.
			if Isconst(n.Left, CTSTR) {
				cmp = brrev(cmp)
			}

			// maxRewriteLen was chosen empirically.
			// It is the value that minimizes cmd/go file size
			// across most architectures.
			// See the commit description for CL 26758 for details.
			maxRewriteLen := 6
			// Some architectures can load unaligned byte sequence as 1 word.
			// So we can cover longer strings with the same amount of code.
			canCombineLoads := false
			combine64bit := false
			// TODO: does this improve performance on any other architectures?
			switch thearch.LinkArch.Family {
			case sys.AMD64:
				// Larger compare require longer instructions, so keep this reasonably low.
				// Data from CL 26758 shows that longer strings are rare.
				// If we really want we can do 16 byte SSE comparisons in the future.
				maxRewriteLen = 16
				canCombineLoads = true
				combine64bit = true
			case sys.I386:
				maxRewriteLen = 8
				canCombineLoads = true
			}
			var and Op
			switch cmp {
			case OEQ:
				and = OANDAND
			case ONE:
				and = OOROR
			default:
				// Don't do byte-wise comparisons for <, <=, etc.
				// They're fairly complicated.
				// Length-only checks are ok, though.
				maxRewriteLen = 0
			}
			if s := cs.Val().U.(string); len(s) <= maxRewriteLen {
				if len(s) > 0 {
					ncs = safeexpr(ncs, init)
				}
				// TODO(marvin): Fix Node.EType type union.
				r := nod(cmp, nod(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 := nod(OINDEX, ncs, nodintconst(int64(i)))
						r = nod(and, r, nod(cmp, ncb, cb))
						remains--
						i++
						continue
					}
					var step int
					var convType *types.Type
					switch {
					case remains >= 8 && combine64bit:
						convType = types.Types[TINT64]
						step = 8
					case remains >= 4:
						convType = types.Types[TUINT32]
						step = 4
					case remains >= 2:
						convType = types.Types[TUINT16]
						step = 2
					}
					ncsubstr := nod(OINDEX, ncs, nodintconst(int64(i)))
					ncsubstr = conv(ncsubstr, 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 := nod(OINDEX, ncs, nodintconst(int64(i+offset)))
						b = conv(b, convType)
						b = nod(OLSH, b, nodintconst(int64(8*offset)))
						ncsubstr = nod(OOR, ncsubstr, b)
						csubstr = csubstr | int64(s[i+offset])<<uint8(8*offset)
					}
					csubstrPart := nodintconst(csubstr)
					// Compare "step" bytes as once
					r = nod(and, r, nod(cmp, csubstrPart, ncsubstr))
					remains -= step
					i += step
				}
				r = typecheck(r, Erv)
				r = walkexpr(r, init)
				r.Type = n.Type
				n = r
				break
			}
		}

		var r *Node
		// TODO(marvin): Fix Node.EType type union.
		if Op(n.Etype) == OEQ || Op(n.Etype) == ONE {
			// prepare for rewrite below
			n.Left = cheapexpr(n.Left, init)
			n.Right = cheapexpr(n.Right, init)

			r = mkcall("eqstring", types.Types[TBOOL], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))

			// quick check of len before full compare for == or !=
			// eqstring assumes that the lengths are equal
			// TODO(marvin): Fix Node.EType type union.
			if Op(n.Etype) == OEQ {
				// len(left) == len(right) && eqstring(left, right)
				r = nod(OANDAND, nod(OEQ, nod(OLEN, n.Left, nil), nod(OLEN, n.Right, nil)), r)
			} else {
				// len(left) != len(right) || !eqstring(left, right)
				r = nod(ONOT, r, nil)
				r = nod(OOROR, nod(ONE, nod(OLEN, n.Left, nil), nod(OLEN, n.Right, nil)), r)
			}

			r = typecheck(r, Erv)
			r = walkexpr(r, nil)
		} else {
			// sys_cmpstring(s1, s2) :: 0
			r = mkcall("cmpstring", types.Types[TINT], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))
			// TODO(marvin): Fix Node.EType type union.
			r = nod(Op(n.Etype), r, nodintconst(0))
		}

		r = typecheck(r, Erv)
		if !n.Type.IsBoolean() {
			Fatalf("cmp %v", n.Type)
		}
		r.Type = n.Type
		n = r

	case OADDSTR:
		n = addstr(n, init)

	case OAPPEND:
		// order should make sure we only see OAS(node, OAPPEND), which we handle above.
		Fatalf("append outside assignment")

	case OCOPY:
		n = copyany(n, init, instrumenting && !compiling_runtime)

		// cannot use chanfn - closechan takes any, not chan any
	case OCLOSE:
		fn := syslook("closechan")

		fn = substArgTypes(fn, n.Left.Type)
		n = mkcall1(fn, nil, init, n.Left)

	case OMAKECHAN:
		n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]))

	case OMAKEMAP:
		t := n.Type

		a := nodnil() // hmap buffer
		r := nodnil() // bucket buffer
		if n.Esc == EscNone {
			// Allocate hmap buffer on stack.
			var_ := temp(hmap(t))

			a = nod(OAS, var_, nil) // zero temp
			a = typecheck(a, Etop)
			init.Append(a)
			a = nod(OADDR, var_, nil)

			// Allocate one bucket on stack.
			// Maximum key/value size is 128 bytes, larger objects
			// are stored with an indirection. So max bucket size is 2048+eps.
			var_ = temp(mapbucket(t))

			r = nod(OAS, var_, nil) // zero temp
			r = typecheck(r, Etop)
			init.Append(r)
			r = nod(OADDR, var_, nil)
		}

		fn := syslook("makemap")
		fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val())
		n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), a, r)

	case OMAKESLICE:
		l := n.Left
		r := n.Right
		if r == nil {
			r = safeexpr(l, init)
			l = r
		}
		t := n.Type
		if n.Esc == EscNone {
			if !isSmallMakeSlice(n) {
				Fatalf("non-small OMAKESLICE with EscNone: %v", n)
			}
			// var arr [r]T
			// n = arr[:l]
			t = types.NewArray(t.Elem(), nonnegintconst(r)) // [r]T
			var_ := temp(t)
			a := nod(OAS, var_, nil) // zero temp
			a = typecheck(a, Etop)
			init.Append(a)
			r := nod(OSLICE, var_, nil) // arr[:l]
			r.SetSliceBounds(nil, l, nil)
			r = conv(r, n.Type) // in case n.Type is named.
			r = typecheck(r, Erv)
			r = walkexpr(r, init)
			n = r
		} else {
			// n escapes; set up a call to makeslice.
			// When len and cap can fit into int, use makeslice instead of
			// makeslice64, which is faster and shorter on 32 bit platforms.

			if t.Elem().NotInHeap() {
				yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem())
			}

			len, cap := l, r

			fnname := "makeslice64"
			argtype := types.Types[TINT64]

			// typechecking guarantees that TIDEAL len/cap are positive and fit in an int.
			// The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
			// will be handled by the negative range checks in makeslice during runtime.
			if (len.Type.IsKind(TIDEAL) || maxintval[len.Type.Etype].Cmp(maxintval[TUINT]) <= 0) &&
				(cap.Type.IsKind(TIDEAL) || maxintval[cap.Type.Etype].Cmp(maxintval[TUINT]) <= 0) {
				fnname = "makeslice"
				argtype = types.Types[TINT]
			}

			fn := syslook(fnname)
			fn = substArgTypes(fn, t.Elem()) // any-1
			n = mkcall1(fn, t, init, typename(t.Elem()), conv(len, argtype), conv(cap, argtype))
		}

	case ORUNESTR:
		a := nodnil()
		if n.Esc == EscNone {
			t := types.NewArray(types.Types[TUINT8], 4)
			var_ := temp(t)
			a = nod(OADDR, var_, nil)
		}

		// intstring(*[4]byte, rune)
		n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[TINT64]))

	case OARRAYBYTESTR:
		a := nodnil()
		if n.Esc == EscNone {
			// Create temporary buffer for string on stack.
			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)

			a = nod(OADDR, temp(t), nil)
		}

		// slicebytetostring(*[32]byte, []byte) string;
		n = mkcall("slicebytetostring", n.Type, init, a, n.Left)

		// slicebytetostringtmp([]byte) string;
	case OARRAYBYTESTRTMP:
		n.Left = walkexpr(n.Left, init)

		if !instrumenting {
			// Let the backend handle OARRAYBYTESTRTMP directly
			// to avoid a function call to slicebytetostringtmp.
			break
		}

		n = mkcall("slicebytetostringtmp", n.Type, init, n.Left)

		// slicerunetostring(*[32]byte, []rune) string;
	case OARRAYRUNESTR:
		a := nodnil()

		if n.Esc == EscNone {
			// Create temporary buffer for string on stack.
			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)

			a = nod(OADDR, temp(t), nil)
		}

		n = mkcall("slicerunetostring", n.Type, init, a, n.Left)

		// stringtoslicebyte(*32[byte], string) []byte;
	case OSTRARRAYBYTE:
		a := nodnil()

		if n.Esc == EscNone {
			// Create temporary buffer for slice on stack.
			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)

			a = nod(OADDR, temp(t), nil)
		}

		n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, types.Types[TSTRING]))

	case OSTRARRAYBYTETMP:
		// []byte(string) conversion that creates a slice
		// referring to the actual string bytes.
		// This conversion is handled later by the backend and
		// is only for use by internal compiler optimizations
		// that know that the slice won't be mutated.
		// The only such case today is:
		// for i, c := range []byte(string)
		n.Left = walkexpr(n.Left, init)

		// stringtoslicerune(*[32]rune, string) []rune
	case OSTRARRAYRUNE:
		a := nodnil()

		if n.Esc == EscNone {
			// Create temporary buffer for slice on stack.
			t := types.NewArray(types.Types[TINT32], tmpstringbufsize)

			a = nod(OADDR, temp(t), nil)
		}

		n = mkcall("stringtoslicerune", n.Type, init, a, n.Left)

		// ifaceeq(i1 any-1, i2 any-2) (ret bool);
	case OCMPIFACE:
		if !eqtype(n.Left.Type, n.Right.Type) {
			Fatalf("ifaceeq %v %v %v", n.Op, n.Left.Type, n.Right.Type)
		}
		var fn *Node
		if n.Left.Type.IsEmptyInterface() {
			fn = syslook("efaceeq")
		} else {
			fn = syslook("ifaceeq")
		}

		n.Right = cheapexpr(n.Right, init)
		n.Left = cheapexpr(n.Left, init)
		lt := nod(OITAB, n.Left, nil)
		rt := nod(OITAB, n.Right, nil)
		ld := nod(OIDATA, n.Left, nil)
		rd := nod(OIDATA, n.Right, nil)
		ld.Type = types.Types[TUNSAFEPTR]
		rd.Type = types.Types[TUNSAFEPTR]
		ld.SetTypecheck(1)
		rd.SetTypecheck(1)
		call := mkcall1(fn, n.Type, init, lt, ld, rd)

		// Check itable/type before full compare.
		// Note: short-circuited because order matters.
		// TODO(marvin): Fix Node.EType type union.
		var cmp *Node
		if Op(n.Etype) == OEQ {
			cmp = nod(OANDAND, nod(OEQ, lt, rt), call)
		} else {
			cmp = nod(OOROR, nod(ONE, lt, rt), nod(ONOT, call, nil))
		}
		cmp = typecheck(cmp, Erv)
		cmp = walkexpr(cmp, init)
		cmp.Type = n.Type
		n = cmp

	case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
		if isStaticCompositeLiteral(n) && !canSSAType(n.Type) {
			// n can be directly represented in the read-only data section.
			// Make direct reference to the static data. See issue 12841.
			vstat := staticname(n.Type)
			vstat.Name.SetReadonly(true)
			fixedlit(inInitFunction, initKindStatic, n, vstat, init)
			n = vstat
			n = typecheck(n, Erv)
			break
		}
		var_ := temp(n.Type)
		anylit(n, var_, init)
		n = var_

	case OSEND:
		n1 := n.Right
		n1 = assignconv(n1, n.Left.Type.Elem(), "chan send")
		n1 = walkexpr(n1, init)
		n1 = nod(OADDR, n1, nil)
		n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, n.Left, n1)

	case OCLOSURE:
		n = walkclosure(n, init)

	case OCALLPART:
		n = walkpartialcall(n, init)
	}

	// Expressions that are constant at run time but not
	// considered const by the language spec are not turned into
	// constants until walk. For example, if n is y%1 == 0, the
	// walk of y%1 may have replaced it by 0.
	// Check whether n with its updated args is itself now a constant.
	t := n.Type
	evconst(n)
	if n.Type != t {
		Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type)
	}
	if n.Op == OLITERAL {
		n = typecheck(n, Erv)
		// Emit string symbol now to avoid emitting
		// any concurrently during the backend.
		if s, ok := n.Val().U.(string); ok {
			_ = stringsym(s)
		}
	}

	updateHasCall(n)

	if Debug['w'] != 0 && n != nil {
		Dump("walk", n)
	}

	lineno = lno
	return n
}

// TODO(josharian): combine this with its caller and simplify
func reduceSlice(n *Node) *Node {
	low, high, max := n.SliceBounds()
	if high != nil && high.Op == OLEN && samesafeexpr(n.Left, high.Left) {
		// Reduce x[i:len(x)] to x[i:].
		high = nil
	}
	n.SetSliceBounds(low, high, max)
	if (n.Op == OSLICE || n.Op == OSLICESTR) && low == nil && high == nil {
		// Reduce x[:] to x.
		if Debug_slice > 0 {
			Warn("slice: omit slice operation")
		}
		return n.Left
	}
	return n
}

func ascompatee1(op Op, l *Node, r *Node, init *Nodes) *Node {
	// convas will turn map assigns into function calls,
	// making it impossible for reorder3 to work.
	n := nod(OAS, l, r)

	if l.Op == OINDEXMAP {
		return n
	}

	return convas(n, init)
}

func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
	// check assign expression list to
	// a expression list. called in
	//	expr-list = expr-list

	// ensure order of evaluation for function calls
	for i := range nl {
		nl[i] = safeexpr(nl[i], init)
	}
	for i1 := range nr {
		nr[i1] = safeexpr(nr[i1], init)
	}

	var nn []*Node
	i := 0
	for ; i < len(nl); i++ {
		if i >= len(nr) {
			break
		}
		// Do not generate 'x = x' during return. See issue 4014.
		if op == ORETURN && samesafeexpr(nl[i], nr[i]) {
			continue
		}
		nn = append(nn, ascompatee1(op, nl[i], nr[i], init))
	}

	// cannot happen: caller checked that lists had same length
	if i < len(nl) || i < len(nr) {
		var nln, nrn Nodes
		nln.Set(nl)
		nrn.Set(nr)
		Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.funcname())
	}
	return nn
}

// l is an lv and rt is the type of an rv
// return 1 if this implies a function call
// evaluating the lv or a function call
// in the conversion of the types
func fncall(l *Node, rt *types.Type) bool {
	if l.HasCall() || l.Op == OINDEXMAP {
		return true
	}
	if needwritebarrier(l) {
		return true
	}
	if eqtype(l.Type, rt) {
		return false
	}
	return true
}

// check assign type list to
// a expression list. called in
//	expr-list = func()
func ascompatet(op Op, nl Nodes, nr *types.Type) []*Node {
	if nl.Len() != nr.NumFields() {
		Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
	}

	var nn, mm Nodes
	for i, l := range nl.Slice() {
		if isblank(l) {
			continue
		}
		r := nr.Field(i)

		// any lv that causes a fn call must be
		// deferred until all the return arguments
		// have been pulled from the output arguments
		if fncall(l, r.Type) {
			tmp := temp(r.Type)
			tmp = typecheck(tmp, Erv)
			a := nod(OAS, l, tmp)
			a = convas(a, &mm)
			mm.Append(a)
			l = tmp
		}

		a := nod(OAS, l, nodarg(r, 0))
		a = convas(a, &nn)
		updateHasCall(a)
		if a.HasCall() {
			Dump("ascompatet ucount", a)
			Fatalf("ascompatet: too many function calls evaluating parameters")
		}

		nn.Append(a)
	}
	return append(nn.Slice(), mm.Slice()...)
}

// nodarg returns a Node for the function argument denoted by t,
// which is either the entire function argument or result struct (t is a  struct *types.Type)
// or a specific argument (t is a *types.Field within a struct *types.Type).
//
// If fp is 0, the node is for use by a caller invoking the given
// function, preparing the arguments before the call
// or retrieving the results after the call.
// In this case, the node will correspond to an outgoing argument
// slot like 8(SP).
//
// If fp is 1, the node is for use by the function itself
// (the callee), to retrieve its arguments or write its results.
// In this case the node will be an ONAME with an appropriate
// type and offset.
func nodarg(t interface{}, fp int) *Node {
	var n *Node

	var funarg types.Funarg
	switch t := t.(type) {
	default:
		Fatalf("bad nodarg %T(%v)", t, t)

	case *types.Type:
		// Entire argument struct, not just one arg
		if !t.IsFuncArgStruct() {
			Fatalf("nodarg: bad type %v", t)
		}
		funarg = t.StructType().Funarg

		// Build fake variable name for whole arg struct.
		n = newname(lookup(".args"))
		n.Type = t
		first := t.Field(0)
		if first == nil {
			Fatalf("nodarg: bad struct")
		}
		if first.Offset == BADWIDTH {
			Fatalf("nodarg: offset not computed for %v", t)
		}
		n.Xoffset = first.Offset

	case *types.Field:
		funarg = t.Funarg
		if fp == 1 {
			// NOTE(rsc): This should be using t.Nname directly,
			// except in the case where t.Nname.Sym is the blank symbol and
			// so the assignment would be discarded during code generation.
			// In that case we need to make a new node, and there is no harm
			// in optimization passes to doing so. But otherwise we should
			// definitely be using the actual declaration and not a newly built node.
			// The extra Fatalf checks here are verifying that this is the case,
			// without changing the actual logic (at time of writing, it's getting
			// toward time for the Go 1.7 beta).
			// At some quieter time (assuming we've never seen these Fatalfs happen)
			// we could change this code to use "expect" directly.
			expect := asNode(t.Nname)
			if expect.isParamHeapCopy() {
				expect = expect.Name.Param.Stackcopy
			}

			for _, n := range Curfn.Func.Dcl {
				if (n.Class() == PPARAM || n.Class() == PPARAMOUT) && !t.Sym.IsBlank() && n.Sym == t.Sym {
					if n != expect {
						Fatalf("nodarg: unexpected node: %v (%p %v) vs %v (%p %v)", n, n, n.Op, asNode(t.Nname), asNode(t.Nname), asNode(t.Nname).Op)
					}
					return n
				}
			}

			if !expect.Sym.IsBlank() {
				Fatalf("nodarg: did not find node in dcl list: %v", expect)
			}
		}

		// Build fake name for individual variable.
		// This is safe because if there was a real declared name
		// we'd have used it above.
		n = newname(lookup("__"))
		n.Type = t.Type
		if t.Offset == BADWIDTH {
			Fatalf("nodarg: offset not computed for %v", t)
		}
		n.Xoffset = t.Offset
		n.Orig = asNode(t.Nname)
	}

	// Rewrite argument named _ to __,
	// or else the assignment to _ will be
	// discarded during code generation.
	if isblank(n) {
		n.Sym = lookup("__")
	}

	switch fp {
	default:
		Fatalf("bad fp")

	case 0: // preparing arguments for call
		n.Op = OINDREGSP
		n.Xoffset += Ctxt.FixedFrameSize()

	case 1: // reading arguments inside call
		n.SetClass(PPARAM)
		if funarg == types.FunargResults {
			n.SetClass(PPARAMOUT)
		}
	}

	n.SetTypecheck(1)
	n.SetAddrtaken(true) // keep optimizers at bay
	return n
}

// package all the arguments that match a ... T parameter into a []T.
func mkdotargslice(typ *types.Type, args []*Node, init *Nodes, ddd *Node) *Node {
	esc := uint16(EscUnknown)
	if ddd != nil {
		esc = ddd.Esc
	}

	if len(args) == 0 {
		n := nodnil()
		n.Type = typ
		return n
	}

	n := nod(OCOMPLIT, nil, typenod(typ))
	if ddd != nil && prealloc[ddd] != nil {
		prealloc[n] = prealloc[ddd] // temporary to use
	}
	n.List.Set(args)
	n.Esc = esc
	n = typecheck(n, Erv)
	if n.Type == nil {
		Fatalf("mkdotargslice: typecheck failed")
	}
	n = walkexpr(n, init)
	return n
}

// check assign expression list to
// a type list. called in
//	return expr-list
//	func(expr-list)
func ascompatte(call *Node, isddd bool, lhs *types.Type, rhs []*Node, fp int, init *Nodes) []*Node {
	var nn []*Node

	// f(g()) where g has multiple return values
	if len(rhs) == 1 && rhs[0].Type.IsFuncArgStruct() {
		// optimization - can do block copy
		if eqtypenoname(rhs[0].Type, lhs) {
			nl := nodarg(lhs, fp)
			nr := nod(OCONVNOP, rhs[0], nil)
			nr.Type = nl.Type
			nn = []*Node{convas(nod(OAS, nl, nr), init)}
			goto ret
		}

		// conversions involved.
		// copy into temporaries.
		var tmps []*Node
		for _, nr := range rhs[0].Type.FieldSlice() {
			tmps = append(tmps, temp(nr.Type))
		}

		a := nod(OAS2, nil, nil)
		a.List.Set(tmps)
		a.Rlist.Set(rhs)
		a = typecheck(a, Etop)
		a = walkstmt(a)
		init.Append(a)

		rhs = tmps
	}

	// For each parameter (LHS), assign its corresponding argument (RHS).
	// If there's a ... parameter (which is only valid as the final
	// parameter) and this is not a ... call expression,
	// then assign the remaining arguments as a slice.
	for i, nl := range lhs.FieldSlice() {
		var nr *Node
		if nl.Isddd() && !isddd {
			nr = mkdotargslice(nl.Type, rhs[i:], init, call.Right)
		} else {
			nr = rhs[i]
		}

		a := nod(OAS, nodarg(nl, fp), nr)
		a = convas(a, init)
		nn = append(nn, a)
	}

ret:
	for _, n := range nn {
		n.SetTypecheck(1)
	}
	return nn
}

// generate code for print
func walkprint(nn *Node, init *Nodes) *Node {
	var r *Node
	var n *Node
	var on *Node
	var t *types.Type
	var et types.EType

	op := nn.Op
	all := nn.List
	var calls []*Node
	notfirst := false

	// Hoist all the argument evaluation up before the lock.
	walkexprlistcheap(all.Slice(), init)

	calls = append(calls, mkcall("printlock", nil, init))
	for i1, n1 := range all.Slice() {
		if notfirst {
			calls = append(calls, mkcall("printsp", nil, init))
		}

		notfirst = op == OPRINTN

		n = n1
		if n.Op == OLITERAL {
			switch n.Val().Ctype() {
			case CTRUNE:
				n = defaultlit(n, types.Runetype)

			case CTINT:
				n = defaultlit(n, types.Types[TINT64])

			case CTFLT:
				n = defaultlit(n, types.Types[TFLOAT64])
			}
		}

		if n.Op != OLITERAL && n.Type != nil && n.Type.Etype == TIDEAL {
			n = defaultlit(n, types.Types[TINT64])
		}
		n = defaultlit(n, nil)
		all.SetIndex(i1, n)
		if n.Type == nil || n.Type.Etype == TFORW {
			continue
		}

		t = n.Type
		et = n.Type.Etype
		if n.Type.IsInterface() {
			if n.Type.IsEmptyInterface() {
				on = syslook("printeface")
			} else {
				on = syslook("printiface")
			}
			on = substArgTypes(on, n.Type) // any-1
		} else if n.Type.IsPtr() || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
			on = syslook("printpointer")
			on = substArgTypes(on, n.Type) // any-1
		} else if n.Type.IsSlice() {
			on = syslook("printslice")
			on = substArgTypes(on, n.Type) // any-1
		} else if isInt[et] {
			if et == TUINT64 {
				if isRuntimePkg(t.Sym.Pkg) && t.Sym.Name == "hex" {
					on = syslook("printhex")
				} else {
					on = syslook("printuint")
				}
			} else {
				on = syslook("printint")
			}
		} else if isFloat[et] {
			on = syslook("printfloat")
		} else if isComplex[et] {
			on = syslook("printcomplex")
		} else if et == TBOOL {
			on = syslook("printbool")
		} else if et == TSTRING {
			on = syslook("printstring")
		} else {
			badtype(OPRINT, n.Type, nil)
			continue
		}

		t = on.Type.Params().Field(0).Type

		if !eqtype(t, n.Type) {
			n = nod(OCONV, n, nil)
			n.Type = t
		}

		r = nod(OCALL, on, nil)
		r.List.Append(n)
		calls = append(calls, r)
	}

	if op == OPRINTN {
		calls = append(calls, mkcall("printnl", nil, nil))
	}

	calls = append(calls, mkcall("printunlock", nil, init))

	typecheckslice(calls, Etop)
	walkexprlist(calls, init)

	r = nod(OEMPTY, nil, nil)
	r = typecheck(r, Etop)
	r = walkexpr(r, init)
	r.Ninit.Set(calls)
	return r
}

func callnew(t *types.Type) *Node {
	if t.NotInHeap() {
		yyerror("%v is go:notinheap; heap allocation disallowed", t)
	}
	dowidth(t)
	fn := syslook("newobject")
	fn = substArgTypes(fn, t)
	v := mkcall1(fn, types.NewPtr(t), nil, typename(t))
	v.SetNonNil(true)
	return v
}

func iscallret(n *Node) bool {
	n = outervalue(n)
	return n.Op == OINDREGSP
}

func isstack(n *Node) bool {
	n = outervalue(n)

	// If n is *autotmp and autotmp = &foo, replace n with foo.
	// We introduce such temps when initializing struct literals.
	if n.Op == OIND && n.Left.Op == ONAME && n.Left.IsAutoTmp() {
		defn := n.Left.Name.Defn
		if defn != nil && defn.Op == OAS && defn.Right.Op == OADDR {
			n = defn.Right.Left
		}
	}

	switch n.Op {
	case OINDREGSP:
		return true

	case ONAME:
		switch n.Class() {
		case PAUTO, PPARAM, PPARAMOUT:
			return true
		}
	}

	return false
}

// 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[TUINTPTR] {
		return false
	}

	var tsym *types.Sym
	switch l.Op {
	case ODOT:
		tsym = l.Left.Type.Sym
	case ODOTPTR:
		tsym = l.Left.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"
}

// Do we need a write barrier for assigning to l?
func needwritebarrier(l *Node) bool {
	if !use_writebarrier {
		return false
	}

	if l == nil || isblank(l) {
		return false
	}

	// No write barrier for write to stack.
	if isstack(l) {
		return false
	}

	// 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).
	if isReflectHeaderDataField(l) {
		return true
	}

	// No write barrier for write of non-pointers.
	dowidth(l.Type)
	if !types.Haspointers(l.Type) {
		return false
	}

	// No write barrier if this is a pointer to a go:notinheap
	// type, since the write barrier's inheap(ptr) check will fail.
	if l.Type.IsPtr() && l.Type.Elem().NotInHeap() {
		return false
	}

	// TODO: We can eliminate write barriers if we know *both* the
	// current and new content of the slot must already be shaded.
	// We know a pointer is shaded if it's nil, or points to
	// static data, a global (variable or function), or the stack.
	// The nil optimization could be particularly useful for
	// writes to just-allocated objects. Unfortunately, knowing
	// the "current" value of the slot requires flow analysis.

	// Otherwise, be conservative and use write barrier.
	return true
}

func convas(n *Node, init *Nodes) *Node {
	if n.Op != OAS {
		Fatalf("convas: not OAS %v", n.Op)
	}

	n.SetTypecheck(1)

	var lt *types.Type
	var rt *types.Type
	if n.Left == nil || n.Right == nil {
		goto out
	}

	lt = n.Left.Type
	rt = n.Right.Type
	if lt == nil || rt == nil {
		goto out
	}

	if isblank(n.Left) {
		n.Right = defaultlit(n.Right, nil)
		goto out
	}

	if !eqtype(lt, rt) {
		n.Right = assignconv(n.Right, lt, "assignment")
		n.Right = walkexpr(n.Right, init)
	}
	dowidth(n.Right.Type)

out:
	updateHasCall(n)
	return n
}

// from ascompat[te]
// evaluating actual function arguments.
//	f(a,b)
// if there is exactly one function expr,
// then it is done first. otherwise must
// make temp variables
func reorder1(all []*Node) []*Node {
	c := 0 // function calls
	t := 0 // total parameters

	for _, n := range all {
		t++
		updateHasCall(n)
		if n.HasCall() {
			c++
		}
	}

	if c == 0 || t == 1 {
		return all
	}

	var g []*Node // fncalls assigned to tempnames
	var f *Node   // last fncall assigned to stack
	var r []*Node // non fncalls and tempnames assigned to stack
	d := 0
	var a *Node
	for _, n := range all {
		if !n.HasCall() {
			r = append(r, n)
			continue
		}

		d++
		if d == c {
			f = n
			continue
		}

		// make assignment of fncall to tempname
		a = temp(n.Right.Type)

		a = nod(OAS, a, n.Right)
		g = append(g, a)

		// put normal arg assignment on list
		// with fncall replaced by tempname
		n.Right = a.Left

		r = append(r, n)
	}

	if f != nil {
		g = append(g, f)
	}
	return append(g, r...)
}

// from ascompat[ee]
//	a,b = c,d
// simultaneous assignment. there cannot
// be later use of an earlier lvalue.
//
// function calls have been removed.
func reorder3(all []*Node) []*Node {
	var l *Node

	// If a needed expression may be affected by an
	// earlier assignment, make an early copy of that
	// expression and use the copy instead.
	var early []*Node

	var mapinit Nodes
	for i, n := range all {
		l = n.Left

		// Save subexpressions needed on left side.
		// Drill through non-dereferences.
		for {
			if l.Op == ODOT || l.Op == OPAREN {
				l = l.Left
				continue
			}

			if l.Op == OINDEX && l.Left.Type.IsArray() {
				l.Right = reorder3save(l.Right, all, i, &early)
				l = l.Left
				continue
			}

			break
		}

		switch l.Op {
		default:
			Fatalf("reorder3 unexpected lvalue %#v", l.Op)

		case ONAME:
			break

		case OINDEX, OINDEXMAP:
			l.Left = reorder3save(l.Left, all, i, &early)
			l.Right = reorder3save(l.Right, all, i, &early)
			if l.Op == OINDEXMAP {
				all[i] = convas(all[i], &mapinit)
			}

		case OIND, ODOTPTR:
			l.Left = reorder3save(l.Left, all, i, &early)
		}

		// Save expression on right side.
		all[i].Right = reorder3save(all[i].Right, all, i, &early)
	}

	early = append(mapinit.Slice(), early...)
	return append(early, all...)
}

// if the evaluation of *np would be affected by the
// assignments in all up to but not including the ith assignment,
// copy into a temporary during *early and
// replace *np with that temp.
// The result of reorder3save MUST be assigned back to n, e.g.
// 	n.Left = reorder3save(n.Left, all, i, early)
func reorder3save(n *Node, all []*Node, i int, early *[]*Node) *Node {
	if !aliased(n, all, i) {
		return n
	}

	q := temp(n.Type)
	q = nod(OAS, q, n)
	q = typecheck(q, Etop)
	*early = append(*early, q)
	return q.Left
}

// what's the outer value that a write to n affects?
// outer value means containing struct or array.
func outervalue(n *Node) *Node {
	for {
		if n.Op == OXDOT {
			Fatalf("OXDOT in walk")
		}
		if n.Op == ODOT || n.Op == OPAREN || n.Op == OCONVNOP {
			n = n.Left
			continue
		}

		if n.Op == OINDEX && n.Left.Type != nil && n.Left.Type.IsArray() {
			n = n.Left
			continue
		}

		break
	}

	return n
}

// Is it possible that the computation of n might be
// affected by writes in as up to but not including the ith element?
func aliased(n *Node, all []*Node, i int) bool {
	if n == nil {
		return false
	}

	// Treat all fields of a struct as referring to the whole struct.
	// We could do better but we would have to keep track of the fields.
	for n.Op == ODOT {
		n = n.Left
	}

	// Look for obvious aliasing: a variable being assigned
	// during the all list and appearing in n.
	// Also record whether there are any writes to main memory.
	// Also record whether there are any writes to variables
	// whose addresses have been taken.
	memwrite := 0

	varwrite := 0
	var a *Node
	for _, an := range all[:i] {
		a = outervalue(an.Left)

		for a.Op == ODOT {
			a = a.Left
		}

		if a.Op != ONAME {
			memwrite = 1
			continue
		}

		switch n.Class() {
		default:
			varwrite = 1
			continue

		case PAUTO, PPARAM, PPARAMOUT:
			if n.Addrtaken() {
				varwrite = 1
				continue
			}

			if vmatch2(a, n) {
				// Direct hit.
				return true
			}
		}
	}

	// The variables being written do not appear in n.
	// However, n might refer to computed addresses
	// that are being written.

	// If no computed addresses are affected by the writes, no aliasing.
	if memwrite == 0 && varwrite == 0 {
		return false
	}

	// If n does not refer to computed addresses
	// (that is, if n only refers to variables whose addresses
	// have not been taken), no aliasing.
	if varexpr(n) {
		return false
	}

	// Otherwise, both the writes and n refer to computed memory addresses.
	// Assume that they might conflict.
	return true
}

// does the evaluation of n only refer to variables
// whose addresses have not been taken?
// (and no other memory)
func varexpr(n *Node) bool {
	if n == nil {
		return true
	}

	switch n.Op {
	case OLITERAL:
		return true

	case ONAME:
		switch n.Class() {
		case PAUTO, PPARAM, PPARAMOUT:
			if !n.Addrtaken() {
				return true
			}
		}

		return false

	case OADD,
		OSUB,
		OOR,
		OXOR,
		OMUL,
		ODIV,
		OMOD,
		OLSH,
		ORSH,
		OAND,
		OANDNOT,
		OPLUS,
		OMINUS,
		OCOM,
		OPAREN,
		OANDAND,
		OOROR,
		OCONV,
		OCONVNOP,
		OCONVIFACE,
		ODOTTYPE:
		return varexpr(n.Left) && varexpr(n.Right)

	case ODOT: // but not ODOTPTR
		// Should have been handled in aliased.
		Fatalf("varexpr unexpected ODOT")
	}

	// Be conservative.
	return false
}

// is the name l mentioned in r?
func vmatch2(l *Node, r *Node) bool {
	if r == nil {
		return false
	}
	switch r.Op {
	// match each right given left
	case ONAME:
		return l == r

	case OLITERAL:
		return false
	}

	if vmatch2(l, r.Left) {
		return true
	}
	if vmatch2(l, r.Right) {
		return true
	}
	for _, n := range r.List.Slice() {
		if vmatch2(l, n) {
			return true
		}
	}
	return false
}

// is any name mentioned in l also mentioned in r?
// called by sinit.go
func vmatch1(l *Node, r *Node) bool {
	// isolate all left sides
	if l == nil || r == nil {
		return false
	}
	switch l.Op {
	case ONAME:
		switch l.Class() {
		case PPARAM, PAUTO:
			break

		default:
			// assignment to non-stack variable must be
			// delayed if right has function calls.
			if r.HasCall() {
				return true
			}
		}

		return vmatch2(l, r)

	case OLITERAL:
		return false
	}

	if vmatch1(l.Left, r) {
		return true
	}
	if vmatch1(l.Right, r) {
		return true
	}
	for _, n := range l.List.Slice() {
		if vmatch1(n, r) {
			return true
		}
	}
	return false
}

// paramstoheap returns code to allocate memory for heap-escaped parameters
// and to copy non-result parameters' values from the stack.
func paramstoheap(params *types.Type) []*Node {
	var nn []*Node
	for _, t := range params.Fields().Slice() {
		v := asNode(t.Nname)
		if v != nil && v.Sym != nil && strings.HasPrefix(v.Sym.Name, "~r") { // unnamed result
			v = nil
		}
		if v == nil {
			continue
		}

		if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil {
			nn = append(nn, walkstmt(nod(ODCL, v, nil)))
			if stackcopy.Class() == PPARAM {
				nn = append(nn, walkstmt(typecheck(nod(OAS, v, stackcopy), Etop)))
			}
		}
	}

	return nn
}

// zeroResults zeros the return values at the start of the function.
// We need to do this very early in the function.  Defer might stop a
// panic and show the return values as they exist at the time of
// panic.  For precise stacks, the garbage collector assumes results
// are always live, so we need to zero them before any allocations,
// even allocations to move params/results to the heap.
// The generated code is added to Curfn's Enter list.
func zeroResults() {
	lno := lineno
	lineno = Curfn.Pos
	for _, f := range Curfn.Type.Results().Fields().Slice() {
		if v := asNode(f.Nname); v != nil && v.Name.Param.Heapaddr != nil {
			// The local which points to the return value is the
			// thing that needs zeroing. This is already handled
			// by a Needzero annotation in plive.go:livenessepilogue.
			continue
		}
		// Zero the stack location containing f.
		Curfn.Func.Enter.Append(nod(OAS, nodarg(f, 1), nil))
	}
	lineno = lno
}

// returnsfromheap returns code to copy values for heap-escaped parameters
// back to the stack.
func returnsfromheap(params *types.Type) []*Node {
	var nn []*Node
	for _, t := range params.Fields().Slice() {
		v := asNode(t.Nname)
		if v == nil {
			continue
		}
		if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil && stackcopy.Class() == PPARAMOUT {
			nn = append(nn, walkstmt(typecheck(nod(OAS, stackcopy, v), Etop)))
		}
	}

	return nn
}

// heapmoves generates code to handle migrating heap-escaped parameters
// between the stack and the heap. The generated code is added to Curfn's
// Enter and Exit lists.
func heapmoves() {
	lno := lineno
	lineno = Curfn.Pos
	nn := paramstoheap(Curfn.Type.Recvs())
	nn = append(nn, paramstoheap(Curfn.Type.Params())...)
	nn = append(nn, paramstoheap(Curfn.Type.Results())...)
	Curfn.Func.Enter.Append(nn...)
	lineno = Curfn.Func.Endlineno
	Curfn.Func.Exit.Append(returnsfromheap(Curfn.Type.Results())...)
	lineno = lno
}

func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
	if fn.Type == nil || fn.Type.Etype != TFUNC {
		Fatalf("mkcall %v %v", fn, fn.Type)
	}

	n := fn.Type.Params().NumFields()

	r := nod(OCALL, fn, nil)
	r.List.Set(va[:n])
	if fn.Type.Results().NumFields() > 0 {
		r = typecheck(r, Erv|Efnstruct)
	} else {
		r = typecheck(r, Etop)
	}
	r = walkexpr(r, init)
	r.Type = t
	return r
}

func mkcall(name string, t *types.Type, init *Nodes, args ...*Node) *Node {
	return vmkcall(syslook(name), t, init, args)
}

func mkcall1(fn *Node, t *types.Type, init *Nodes, args ...*Node) *Node {
	return vmkcall(fn, t, init, args)
}

func conv(n *Node, t *types.Type) *Node {
	if eqtype(n.Type, t) {
		return n
	}
	n = nod(OCONV, n, nil)
	n.Type = t
	n = typecheck(n, Erv)
	return n
}

// byteindex converts n, which is byte-sized, to a uint8.
// We cannot use conv, because we allow converting bool to uint8 here,
// which is forbidden in user code.
func byteindex(n *Node) *Node {
	if eqtype(n.Type, types.Types[TUINT8]) {
		return n
	}
	n = nod(OCONV, n, nil)
	n.Type = types.Types[TUINT8]
	n.SetTypecheck(1)
	return n
}

func chanfn(name string, n int, t *types.Type) *Node {
	if !t.IsChan() {
		Fatalf("chanfn %v", t)
	}
	fn := syslook(name)
	switch n {
	default:
		Fatalf("chanfn %d", n)
	case 1:
		fn = substArgTypes(fn, t.Elem())
	case 2:
		fn = substArgTypes(fn, t.Elem(), t.Elem())
	}
	return fn
}

func mapfn(name string, t *types.Type) *Node {
	if !t.IsMap() {
		Fatalf("mapfn %v", t)
	}
	fn := syslook(name)
	fn = substArgTypes(fn, t.Key(), t.Val(), t.Key(), t.Val())
	return fn
}

func mapfndel(name string, t *types.Type) *Node {
	if !t.IsMap() {
		Fatalf("mapfn %v", t)
	}
	fn := syslook(name)
	fn = substArgTypes(fn, t.Key(), t.Val(), t.Key())
	return fn
}

const (
	mapslow = iota
	mapfast32
	mapfast32ptr
	mapfast64
	mapfast64ptr
	mapfaststr
	nmapfast
)

type mapnames [nmapfast]string

func mkmapnames(base string, ptr string) mapnames {
	return mapnames{base, base + "_fast32", base + "_fast32" + ptr, base + "_fast64", base + "_fast64" + ptr, base + "_faststr"}
}

var mapaccess1 mapnames = mkmapnames("mapaccess1", "")
var mapaccess2 mapnames = mkmapnames("mapaccess2", "")
var mapassign mapnames = mkmapnames("mapassign", "ptr")
var mapdelete mapnames = mkmapnames("mapdelete", "")

func mapfast(t *types.Type) int {
	// Check ../../runtime/hashmap.go:maxValueSize before changing.
	if t.Val().Width > 128 {
		return mapslow
	}
	switch algtype(t.Key()) {
	case AMEM32:
		if !t.Key().HasPointer() {
			return mapfast32
		}
		if Widthptr == 4 {
			return mapfast32ptr
		}
		Fatalf("small pointer %v", t.Key())
	case AMEM64:
		if !t.Key().HasPointer() {
			return mapfast64
		}
		if Widthptr == 8 {
			return mapfast64ptr
		}
		// Two-word object, at least one of which is a pointer.
		// Use the slow path.
	case ASTRING:
		return mapfaststr
	}
	return mapslow
}

func writebarrierfn(name string, l *types.Type, r *types.Type) *Node {
	fn := syslook(name)
	fn = substArgTypes(fn, l, r)
	return fn
}

func addstr(n *Node, init *Nodes) *Node {
	// orderexpr rewrote OADDSTR to have a list of strings.
	c := n.List.Len()

	if c < 2 {
		Fatalf("addstr count %d too small", c)
	}

	buf := nodnil()
	if n.Esc == EscNone {
		sz := int64(0)
		for _, n1 := range n.List.Slice() {
			if n1.Op == OLITERAL {
				sz += int64(len(n1.Val().U.(string)))
			}
		}

		// Don't allocate the buffer if the result won't fit.
		if sz < tmpstringbufsize {
			// Create temporary buffer for result string on stack.
			t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)

			buf = nod(OADDR, temp(t), nil)
		}
	}

	// build list of string arguments
	args := []*Node{buf}
	for _, n2 := range n.List.Slice() {
		args = append(args, conv(n2, types.Types[TSTRING]))
	}

	var fn string
	if c <= 5 {
		// small numbers of strings use direct runtime helpers.
		// note: orderexpr knows this cutoff too.
		fn = fmt.Sprintf("concatstring%d", c)
	} else {
		// large numbers of strings are passed to the runtime as a slice.
		fn = "concatstrings"

		t := types.NewSlice(types.Types[TSTRING])
		slice := nod(OCOMPLIT, nil, typenod(t))
		if prealloc[n] != nil {
			prealloc[slice] = prealloc[n]
		}
		slice.List.Set(args[1:]) // skip buf arg
		args = []*Node{buf, slice}
		slice.Esc = EscNone
	}

	cat := syslook(fn)
	r := nod(OCALL, cat, nil)
	r.List.Set(args)
	r = typecheck(r, Erv)
	r = walkexpr(r, init)
	r.Type = n.Type

	return r
}

// expand append(l1, l2...) to
//   init {
//     s := l1
//     n := len(s) + len(l2)
//     // Compare as uint so growslice can panic on overflow.
//     if uint(n) > uint(cap(s)) {
//       s = growslice(s, n)
//     }
//     s = s[:n]
//     memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
//   }
//   s
//
// l2 is allowed to be a string.
func appendslice(n *Node, init *Nodes) *Node {
	walkexprlistsafe(n.List.Slice(), init)

	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
	// and n are name or literal, but those may index the slice we're
	// modifying here. Fix explicitly.
	ls := n.List.Slice()
	for i1, n1 := range ls {
		ls[i1] = cheapexpr(n1, init)
	}

	l1 := n.List.First()
	l2 := n.List.Second()

	var l []*Node

	// var s []T
	s := temp(l1.Type)
	l = append(l, nod(OAS, s, l1)) // s = l1

	// n := len(s) + len(l2)
	nn := temp(types.Types[TINT])
	l = append(l, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))

	// if uint(n) > uint(cap(s))
	nif := nod(OIF, nil, nil)
	nif.Left = nod(OGT, nod(OCONV, nn, nil), nod(OCONV, nod(OCAP, s, nil), nil))
	nif.Left.Left.Type = types.Types[TUINT]
	nif.Left.Right.Type = types.Types[TUINT]

	// instantiate growslice(Type*, []any, int) []any
	fn := syslook("growslice")
	fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem())

	// s = growslice(T, s, n)
	nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type.Elem()), s, nn)))
	l = append(l, nif)

	// s = s[:n]
	nt := nod(OSLICE, s, nil)
	nt.SetSliceBounds(nil, nn, nil)
	nt.Etype = 1
	l = append(l, nod(OAS, s, nt))

	if types.Haspointers(l1.Type.Elem()) {
		// copy(s[len(l1):], l2)
		nptr1 := nod(OSLICE, s, nil)
		nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
		nptr1.Etype = 1
		nptr2 := l2
		fn := syslook("typedslicecopy")
		fn = substArgTypes(fn, l1.Type, l2.Type)
		var ln Nodes
		ln.Set(l)
		nt := mkcall1(fn, types.Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2)
		l = append(ln.Slice(), nt)
	} else if instrumenting && !compiling_runtime {
		// rely on runtime to instrument copy.
		// copy(s[len(l1):], l2)
		nptr1 := nod(OSLICE, s, nil)
		nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
		nptr1.Etype = 1
		nptr2 := l2
		var fn *Node
		if l2.Type.IsString() {
			fn = syslook("slicestringcopy")
		} else {
			fn = syslook("slicecopy")
		}
		fn = substArgTypes(fn, l1.Type, l2.Type)
		var ln Nodes
		ln.Set(l)
		nt := mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
		l = append(ln.Slice(), nt)
	} else {
		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
		nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
		nptr1.SetBounded(true)

		nptr1 = nod(OADDR, nptr1, nil)

		nptr2 := nod(OSPTR, l2, nil)

		fn := syslook("memmove")
		fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem())

		var ln Nodes
		ln.Set(l)
		nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &ln)

		nwid = nod(OMUL, nwid, nodintconst(s.Type.Elem().Width))
		nt := mkcall1(fn, nil, &ln, nptr1, nptr2, nwid)
		l = append(ln.Slice(), nt)
	}

	typecheckslice(l, Etop)
	walkstmtlist(l)
	init.Append(l...)
	return s
}

// Rewrite append(src, x, y, z) so that any side effects in
// x, y, z (including runtime panics) are evaluated in
// initialization statements before the append.
// For normal code generation, stop there and leave the
// rest to cgen_append.
//
// For race detector, expand append(src, a [, b]* ) to
//
//   init {
//     s := src
//     const argc = len(args) - 1
//     if cap(s) - len(s) < argc {
//	    s = growslice(s, len(s)+argc)
//     }
//     n := len(s)
//     s = s[:n+argc]
//     s[n] = a
//     s[n+1] = b
//     ...
//   }
//   s
func walkappend(n *Node, init *Nodes, dst *Node) *Node {
	if !samesafeexpr(dst, n.List.First()) {
		n.List.SetFirst(safeexpr(n.List.First(), init))
		n.List.SetFirst(walkexpr(n.List.First(), init))
	}
	walkexprlistsafe(n.List.Slice()[1:], init)

	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
	// and n are name or literal, but those may index the slice we're
	// modifying here. Fix explicitly.
	// Using cheapexpr also makes sure that the evaluation
	// of all arguments (and especially any panics) happen
	// before we begin to modify the slice in a visible way.
	ls := n.List.Slice()[1:]
	for i, n := range ls {
		ls[i] = cheapexpr(n, init)
	}

	nsrc := n.List.First()

	argc := n.List.Len() - 1
	if argc < 1 {
		return nsrc
	}

	// General case, with no function calls left as arguments.
	// Leave for gen, except that instrumentation requires old form.
	if !instrumenting || compiling_runtime {
		return n
	}

	var l []*Node

	ns := temp(nsrc.Type)
	l = append(l, nod(OAS, ns, nsrc)) // s = src

	na := nodintconst(int64(argc)) // const argc
	nx := nod(OIF, nil, nil)       // if cap(s) - len(s) < argc
	nx.Left = nod(OLT, nod(OSUB, nod(OCAP, ns, nil), nod(OLEN, ns, nil)), na)

	fn := syslook("growslice") //   growslice(<type>, old []T, mincap int) (ret []T)
	fn = substArgTypes(fn, ns.Type.Elem(), ns.Type.Elem())

	nx.Nbody.Set1(nod(OAS, ns,
		mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type.Elem()), ns,
			nod(OADD, nod(OLEN, ns, nil), na))))

	l = append(l, nx)

	nn := temp(types.Types[TINT])
	l = append(l, nod(OAS, nn, nod(OLEN, ns, nil))) // n = len(s)

	nx = nod(OSLICE, ns, nil) // ...s[:n+argc]
	nx.SetSliceBounds(nil, nod(OADD, nn, na), nil)
	nx.Etype = 1
	l = append(l, nod(OAS, ns, nx)) // s = s[:n+argc]

	ls = n.List.Slice()[1:]
	for i, n := range ls {
		nx = nod(OINDEX, ns, nn) // s[n] ...
		nx.SetBounded(true)
		l = append(l, nod(OAS, nx, n)) // s[n] = arg
		if i+1 < len(ls) {
			l = append(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))) // n = n + 1
		}
	}

	typecheckslice(l, Etop)
	walkstmtlist(l)
	init.Append(l...)
	return ns
}

// Lower copy(a, b) to a memmove call or a runtime call.
//
// init {
//   n := len(a)
//   if n > len(b) { n = len(b) }
//   memmove(a.ptr, b.ptr, n*sizeof(elem(a)))
// }
// n;
//
// Also works if b is a string.
//
func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
	if types.Haspointers(n.Left.Type.Elem()) {
		fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
		return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), n.Left, n.Right)
	}

	if runtimecall {
		var fn *Node
		if n.Right.Type.IsString() {
			fn = syslook("slicestringcopy")
		} else {
			fn = syslook("slicecopy")
		}
		fn = substArgTypes(fn, n.Left.Type, n.Right.Type)
		return mkcall1(fn, n.Type, init, n.Left, n.Right, nodintconst(n.Left.Type.Elem().Width))
	}

	n.Left = walkexpr(n.Left, init)
	n.Right = walkexpr(n.Right, init)
	nl := temp(n.Left.Type)
	nr := temp(n.Right.Type)
	var l []*Node
	l = append(l, nod(OAS, nl, n.Left))
	l = append(l, nod(OAS, nr, n.Right))

	nfrm := nod(OSPTR, nr, nil)
	nto := nod(OSPTR, nl, nil)

	nlen := temp(types.Types[TINT])

	// n = len(to)
	l = append(l, nod(OAS, nlen, nod(OLEN, nl, nil)))

	// if n > len(frm) { n = len(frm) }
	nif := nod(OIF, nil, nil)

	nif.Left = nod(OGT, nlen, nod(OLEN, nr, nil))
	nif.Nbody.Append(nod(OAS, nlen, nod(OLEN, nr, nil)))
	l = append(l, nif)

	// Call memmove.
	fn := syslook("memmove")

	fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem())
	nwid := temp(types.Types[TUINTPTR])
	l = append(l, nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR])))
	nwid = nod(OMUL, nwid, nodintconst(nl.Type.Elem().Width))
	l = append(l, mkcall1(fn, nil, init, nto, nfrm, nwid))

	typecheckslice(l, Etop)
	walkstmtlist(l)
	init.Append(l...)
	return nlen
}

func eqfor(t *types.Type, needsize *int) *Node {
	// Should only arrive here with large memory or
	// a struct/array containing a non-memory field/element.
	// Small memory is handled inline, and single non-memory
	// is handled during type check (OCMPSTR etc).
	switch a, _ := algtype1(t); a {
	case AMEM:
		n := syslook("memequal")
		n = substArgTypes(n, t, t)
		*needsize = 1
		return n
	case ASPECIAL:
		sym := typesymprefix(".eq", t)
		n := newname(sym)
		n.SetClass(PFUNC)
		ntype := nod(OTFUNC, nil, nil)
		ntype.List.Append(anonfield(types.NewPtr(t)))
		ntype.List.Append(anonfield(types.NewPtr(t)))
		ntype.Rlist.Append(anonfield(types.Types[TBOOL]))
		ntype = typecheck(ntype, Etype)
		n.Type = ntype.Type
		*needsize = 0
		return n
	}
	Fatalf("eqfor %v", t)
	return nil
}

// The result of walkcompare MUST be assigned back to n, e.g.
// 	n.Left = walkcompare(n.Left, init)
func walkcompare(n *Node, init *Nodes) *Node {
	// Given interface value l and concrete value r, rewrite
	//   l == r
	// into types-equal && data-equal.
	// This is efficient, avoids allocations, and avoids runtime calls.
	var l, r *Node
	if n.Left.Type.IsInterface() && !n.Right.Type.IsInterface() {
		l = n.Left
		r = n.Right
	} else if !n.Left.Type.IsInterface() && n.Right.Type.IsInterface() {
		l = n.Right
		r = n.Left
	}

	if l != nil {
		// Handle both == and !=.
		eq := n.Op
		var andor Op
		if eq == OEQ {
			andor = OANDAND
		} else {
			andor = OOROR
		}
		// Check for types equal.
		// For empty interface, this is:
		//   l.tab == type(r)
		// For non-empty interface, this is:
		//   l.tab != nil && l.tab._type == type(r)
		var eqtype *Node
		tab := nod(OITAB, l, nil)
		rtyp := typename(r.Type)
		if l.Type.IsEmptyInterface() {
			tab.Type = types.NewPtr(types.Types[TUINT8])
			tab.SetTypecheck(1)
			eqtype = nod(eq, tab, rtyp)
		} else {
			nonnil := nod(brcom(eq), nodnil(), tab)
			match := nod(eq, itabType(tab), rtyp)
			eqtype = nod(andor, nonnil, match)
		}
		// Check for data equal.
		eqdata := nod(eq, ifaceData(l, r.Type), r)
		// Put it all together.
		expr := nod(andor, eqtype, eqdata)
		n = finishcompare(n, expr, init)
		return n
	}

	// Must be comparison of array or struct.
	// Otherwise back end handles it.
	// While we're here, decide whether to
	// inline or call an eq alg.
	t := n.Left.Type
	var inline bool

	maxcmpsize := int64(4)
	unalignedLoad := false
	switch thearch.LinkArch.Family {
	case sys.AMD64, sys.ARM64, sys.S390X:
		// Keep this low enough, to generate less code than function call.
		maxcmpsize = 16
		unalignedLoad = true
	case sys.I386:
		maxcmpsize = 8
		unalignedLoad = true
	}

	switch t.Etype {
	default:
		return n
	case TARRAY:
		// We can compare several elements at once with 2/4/8 byte integer compares
		inline = t.NumElem() <= 1 || (issimple[t.Elem().Etype] && (t.NumElem() <= 4 || t.Elem().Width*t.NumElem() <= maxcmpsize))
	case TSTRUCT:
		inline = t.NumFields() <= 4
	}

	cmpl := n.Left
	for cmpl != nil && cmpl.Op == OCONVNOP {
		cmpl = cmpl.Left
	}
	cmpr := n.Right
	for cmpr != nil && cmpr.Op == OCONVNOP {
		cmpr = cmpr.Left
	}

	// Chose not to inline. Call equality function directly.
	if !inline {
		if isvaluelit(cmpl) {
			var_ := temp(cmpl.Type)
			anylit(cmpl, var_, init)
			cmpl = var_
		}
		if isvaluelit(cmpr) {
			var_ := temp(cmpr.Type)
			anylit(cmpr, var_, init)
			cmpr = var_
		}
		if !islvalue(cmpl) || !islvalue(cmpr) {
			Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
		}

		// eq algs take pointers
		pl := temp(types.NewPtr(t))
		al := nod(OAS, pl, nod(OADDR, cmpl, nil))
		al.Right.Etype = 1 // addr does not escape
		al = typecheck(al, Etop)
		init.Append(al)

		pr := temp(types.NewPtr(t))
		ar := nod(OAS, pr, nod(OADDR, cmpr, nil))
		ar.Right.Etype = 1 // addr does not escape
		ar = typecheck(ar, Etop)
		init.Append(ar)

		var needsize int
		call := nod(OCALL, eqfor(t, &needsize), nil)
		call.List.Append(pl)
		call.List.Append(pr)
		if needsize != 0 {
			call.List.Append(nodintconst(t.Width))
		}
		res := call
		if n.Op != OEQ {
			res = nod(ONOT, res, nil)
		}
		n = finishcompare(n, res, init)
		return n
	}

	// inline: build boolean expression comparing element by element
	andor := OANDAND
	if n.Op == ONE {
		andor = OOROR
	}
	var expr *Node
	compare := func(el, er *Node) {
		a := nod(n.Op, el, er)
		if expr == nil {
			expr = a
		} else {
			expr = nod(andor, expr, a)
		}
	}
	cmpl = safeexpr(cmpl, init)
	cmpr = safeexpr(cmpr, init)
	if t.IsStruct() {
		for _, f := range t.Fields().Slice() {
			sym := f.Sym
			if sym.IsBlank() {
				continue
			}
			compare(
				nodSym(OXDOT, cmpl, sym),
				nodSym(OXDOT, cmpr, sym),
			)
		}
	} else {
		step := int64(1)
		remains := t.NumElem() * t.Elem().Width
		combine64bit := unalignedLoad && Widthreg == 8 && t.Elem().Width <= 4 && t.Elem().IsInteger()
		combine32bit := unalignedLoad && t.Elem().Width <= 2 && t.Elem().IsInteger()
		combine16bit := unalignedLoad && t.Elem().Width == 1 && t.Elem().IsInteger()
		for i := int64(0); remains > 0; {
			var convType *types.Type
			switch {
			case remains >= 8 && combine64bit:
				convType = types.Types[TINT64]
				step = 8 / t.Elem().Width
			case remains >= 4 && combine32bit:
				convType = types.Types[TUINT32]
				step = 4 / t.Elem().Width
			case remains >= 2 && combine16bit:
				convType = types.Types[TUINT16]
				step = 2 / t.Elem().Width
			default:
				step = 1
			}
			if step == 1 {
				compare(
					nod(OINDEX, cmpl, nodintconst(int64(i))),
					nod(OINDEX, cmpr, nodintconst(int64(i))),
				)
				i++
				remains -= t.Elem().Width
			} else {
				elemType := t.Elem().ToUnsigned()
				cmplw := nod(OINDEX, cmpl, nodintconst(int64(i)))
				cmplw = conv(cmplw, elemType) // convert to unsigned
				cmplw = conv(cmplw, convType) // widen
				cmprw := nod(OINDEX, cmpr, nodintconst(int64(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 := nod(OINDEX, cmpl, nodintconst(int64(i+offset)))
					lb = conv(lb, elemType)
					lb = conv(lb, convType)
					lb = nod(OLSH, lb, nodintconst(int64(8*t.Elem().Width*offset)))
					cmplw = nod(OOR, cmplw, lb)
					rb := nod(OINDEX, cmpr, nodintconst(int64(i+offset)))
					rb = conv(rb, elemType)
					rb = conv(rb, convType)
					rb = nod(OLSH, rb, nodintconst(int64(8*t.Elem().Width*offset)))
					cmprw = nod(OOR, cmprw, rb)
				}
				compare(cmplw, cmprw)
				i += step
				remains -= step * t.Elem().Width
			}
		}
	}
	if expr == nil {
		expr = nodbool(n.Op == OEQ)
	}
	n = finishcompare(n, expr, init)
	return n
}

// The result of finishcompare MUST be assigned back to n, e.g.
// 	n.Left = finishcompare(n.Left, x, r, init)
func finishcompare(n, r *Node, init *Nodes) *Node {
	// Use nn here to avoid passing r to typecheck.
	nn := r
	nn = typecheck(nn, Erv)
	nn = walkexpr(nn, init)
	r = nn
	if r.Type != n.Type {
		r = nod(OCONVNOP, r, nil)
		r.Type = n.Type
		r.SetTypecheck(1)
		nn = r
	}
	return nn
}

// isIntOrdering reports whether n is a <, ≤, >, or ≥ ordering between integers.
func (n *Node) isIntOrdering() bool {
	switch n.Op {
	case OLE, OLT, OGE, OGT:
	default:
		return false
	}
	return n.Left.Type.IsInteger() && n.Right.Type.IsInteger()
}

// walkinrange optimizes integer-in-range checks, such as 4 <= x && x < 10.
// n must be an OANDAND or OOROR node.
// The result of walkinrange MUST be assigned back to n, e.g.
// 	n.Left = walkinrange(n.Left)
func walkinrange(n *Node, init *Nodes) *Node {
	// We are looking for something equivalent to a opl b OP b opr c, where:
	// * a, b, and c have integer type
	// * b is side-effect-free
	// * opl and opr are each < or ≤
	// * OP is &&
	l := n.Left
	r := n.Right
	if !l.isIntOrdering() || !r.isIntOrdering() {
		return n
	}

	// Find b, if it exists, and rename appropriately.
	// Input is: l.Left l.Op l.Right ANDAND/OROR r.Left r.Op r.Right
	// Output is: a opl b(==x) ANDAND/OROR b(==x) opr c
	a, opl, b := l.Left, l.Op, l.Right
	x, opr, c := r.Left, r.Op, r.Right
	for i := 0; ; i++ {
		if samesafeexpr(b, x) {
			break
		}
		if i == 3 {
			// Tried all permutations and couldn't find an appropriate b == x.
			return n
		}
		if i&1 == 0 {
			a, opl, b = b, brrev(opl), a
		} else {
			x, opr, c = c, brrev(opr), x
		}
	}

	// If n.Op is ||, apply de Morgan.
	// Negate the internal ops now; we'll negate the top level op at the end.
	// Henceforth assume &&.
	negateResult := n.Op == OOROR
	if negateResult {
		opl = brcom(opl)
		opr = brcom(opr)
	}

	cmpdir := func(o Op) int {
		switch o {
		case OLE, OLT:
			return -1
		case OGE, OGT:
			return +1
		}
		Fatalf("walkinrange cmpdir %v", o)
		return 0
	}
	if cmpdir(opl) != cmpdir(opr) {
		// Not a range check; something like b < a && b < c.
		return n
	}

	switch opl {
	case OGE, OGT:
		// We have something like a > b && b ≥ c.
		// Switch and reverse ops and rename constants,
		// to make it look like a ≤ b && b < c.
		a, c = c, a
		opl, opr = brrev(opr), brrev(opl)
	}

	// We must ensure that c-a is non-negative.
	// For now, require a and c to be constants.
	// In the future, we could also support a == 0 and c == len/cap(...).
	// Unfortunately, by this point, most len/cap expressions have been
	// stored into temporary variables.
	if !Isconst(a, CTINT) || !Isconst(c, CTINT) {
		return n
	}

	if opl == OLT {
		// We have a < b && ...
		// We need a ≤ b && ... to safely use unsigned comparison tricks.
		// If a is not the maximum constant for b's type,
		// we can increment a and switch to ≤.
		if a.Int64() >= maxintval[b.Type.Etype].Int64() {
			return n
		}
		a = nodintconst(a.Int64() + 1)
		opl = OLE
	}

	bound := c.Int64() - a.Int64()
	if bound < 0 {
		// Bad news. Something like 5 <= x && x < 3.
		// Rare in practice, and we still need to generate side-effects,
		// so just leave it alone.
		return n
	}

	// We have a ≤ b && b < c (or a ≤ b && b ≤ c).
	// This is equivalent to (a-a) ≤ (b-a) && (b-a) < (c-a),
	// which is equivalent to 0 ≤ (b-a) && (b-a) < (c-a),
	// which is equivalent to uint(b-a) < uint(c-a).
	ut := b.Type.ToUnsigned()
	lhs := conv(nod(OSUB, b, a), ut)
	rhs := nodintconst(bound)
	if negateResult {
		// Negate top level.
		opr = brcom(opr)
	}
	cmp := nod(opr, lhs, rhs)
	cmp.Pos = n.Pos
	cmp = addinit(cmp, l.Ninit.Slice())
	cmp = addinit(cmp, r.Ninit.Slice())
	// Typecheck the AST rooted at cmp...
	cmp = typecheck(cmp, Erv)
	// ...but then reset cmp's type to match n's type.
	cmp.Type = n.Type
	cmp = walkexpr(cmp, init)
	return cmp
}

// return 1 if integer n must be in range [0, max), 0 otherwise
func bounded(n *Node, max int64) bool {
	if n.Type == nil || !n.Type.IsInteger() {
		return false
	}

	sign := n.Type.IsSigned()
	bits := int32(8 * n.Type.Width)

	if smallintconst(n) {
		v := n.Int64()
		return 0 <= v && v < max
	}

	switch n.Op {
	case OAND:
		v := int64(-1)
		if smallintconst(n.Left) {
			v = n.Left.Int64()
		} else if smallintconst(n.Right) {
			v = n.Right.Int64()
		}

		if 0 <= v && v < max {
			return true
		}

	case OMOD:
		if !sign && smallintconst(n.Right) {
			v := n.Right.Int64()
			if 0 <= v && v <= max {
				return true
			}
		}

	case ODIV:
		if !sign && smallintconst(n.Right) {
			v := n.Right.Int64()
			for bits > 0 && v >= 2 {
				bits--
				v >>= 1
			}
		}

	case ORSH:
		if !sign && smallintconst(n.Right) {
			v := n.Right.Int64()
			if v > int64(bits) {
				return true
			}
			bits -= int32(v)
		}
	}

	if !sign && bits <= 62 && 1<<uint(bits) <= max {
		return true
	}

	return false
}

// usemethod checks interface method calls for uses of reflect.Type.Method.
func usemethod(n *Node) {
	t := n.Left.Type

	// Looking for either of:
	//	Method(int) reflect.Method
	//	MethodByName(string) (reflect.Method, bool)
	//
	// TODO(crawshaw): improve precision of match by working out
	//                 how to check the method name.
	if n := t.Params().NumFields(); n != 1 {
		return
	}
	if n := t.Results().NumFields(); n != 1 && n != 2 {
		return
	}
	p0 := t.Params().Field(0)
	res0 := t.Results().Field(0)
	var res1 *types.Field
	if t.Results().NumFields() == 2 {
		res1 = t.Results().Field(1)
	}

	if res1 == nil {
		if p0.Type.Etype != TINT {
			return
		}
	} else {
		if !p0.Type.IsString() {
			return
		}
		if !res1.Type.IsBoolean() {
			return
		}
	}

	// Note: Don't rely on res0.Type.String() since its formatting depends on multiple factors
	//       (including global variables such as numImports - was issue #19028).
	if s := res0.Type.Sym; s != nil && s.Name == "Method" && s.Pkg != nil && s.Pkg.Path == "reflect" {
		Curfn.Func.SetReflectMethod(true)
	}
}

func usefield(n *Node) {
	if objabi.Fieldtrack_enabled == 0 {
		return
	}

	switch n.Op {
	default:
		Fatalf("usefield %v", n.Op)

	case ODOT, ODOTPTR:
		break
	}
	if n.Sym == nil {
		// No field name.  This DOTPTR was built by the compiler for access
		// to runtime data structures.  Ignore.
		return
	}

	t := n.Left.Type
	if t.IsPtr() {
		t = t.Elem()
	}
	field := dotField[typeSymKey{t.Orig, n.Sym}]
	if field == nil {
		Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym)
	}
	if !strings.Contains(field.Note, "go:\"track\"") {
		return
	}

	outer := n.Left.Type
	if outer.IsPtr() {
		outer = outer.Elem()
	}
	if outer.Sym == nil {
		yyerror("tracked field must be in named struct type")
	}
	if !exportname(field.Sym.Name) {
		yyerror("tracked field must be exported (upper case)")
	}

	sym := tracksym(outer, field)
	if Curfn.Func.FieldTrack == nil {
		Curfn.Func.FieldTrack = make(map[*types.Sym]struct{})
	}
	Curfn.Func.FieldTrack[sym] = struct{}{}
}

func candiscardlist(l Nodes) bool {
	for _, n := range l.Slice() {
		if !candiscard(n) {
			return false
		}
	}
	return true
}

func candiscard(n *Node) bool {
	if n == nil {
		return true
	}

	switch n.Op {
	default:
		return false

		// Discardable as long as the subpieces are.
	case ONAME,
		ONONAME,
		OTYPE,
		OPACK,
		OLITERAL,
		OADD,
		OSUB,
		OOR,
		OXOR,
		OADDSTR,
		OADDR,
		OANDAND,
		OARRAYBYTESTR,
		OARRAYRUNESTR,
		OSTRARRAYBYTE,
		OSTRARRAYRUNE,
		OCAP,
		OCMPIFACE,
		OCMPSTR,
		OCOMPLIT,
		OMAPLIT,
		OSTRUCTLIT,
		OARRAYLIT,
		OSLICELIT,
		OPTRLIT,
		OCONV,
		OCONVIFACE,
		OCONVNOP,
		ODOT,
		OEQ,
		ONE,
		OLT,
		OLE,
		OGT,
		OGE,
		OKEY,
		OSTRUCTKEY,
		OLEN,
		OMUL,
		OLSH,
		ORSH,
		OAND,
		OANDNOT,
		ONEW,
		ONOT,
		OCOM,
		OPLUS,
		OMINUS,
		OOROR,
		OPAREN,
		ORUNESTR,
		OREAL,
		OIMAG,
		OCOMPLEX:
		break

		// Discardable as long as we know it's not division by zero.
	case ODIV, OMOD:
		if Isconst(n.Right, CTINT) && n.Right.Val().U.(*Mpint).CmpInt64(0) != 0 {
			break
		}
		if Isconst(n.Right, CTFLT) && n.Right.Val().U.(*Mpflt).CmpFloat64(0) != 0 {
			break
		}
		return false

		// Discardable as long as we know it won't fail because of a bad size.
	case OMAKECHAN, OMAKEMAP:
		if Isconst(n.Left, CTINT) && n.Left.Val().U.(*Mpint).CmpInt64(0) == 0 {
			break
		}
		return false

		// Difficult to tell what sizes are okay.
	case OMAKESLICE:
		return false
	}

	if !candiscard(n.Left) || !candiscard(n.Right) || !candiscardlist(n.Ninit) || !candiscardlist(n.Nbody) || !candiscardlist(n.List) || !candiscardlist(n.Rlist) {
		return false
	}

	return true
}

// rewrite
//	print(x, y, z)
// into
//	func(a1, a2, a3) {
//		print(a1, a2, a3)
//	}(x, y, z)
// and same for println.

var walkprintfunc_prgen int

// The result of walkprintfunc MUST be assigned back to n, e.g.
// 	n.Left = walkprintfunc(n.Left, init)
func walkprintfunc(n *Node, init *Nodes) *Node {
	if n.Ninit.Len() != 0 {
		walkstmtlist(n.Ninit.Slice())
		init.AppendNodes(&n.Ninit)
	}

	t := nod(OTFUNC, nil, nil)
	num := 0
	var printargs []*Node
	var a *Node
	var buf string
	for _, n1 := range n.List.Slice() {
		buf = fmt.Sprintf("a%d", num)
		num++
		a = namedfield(buf, n1.Type)
		t.List.Append(a)
		printargs = append(printargs, a.Left)
	}

	oldfn := Curfn
	Curfn = nil

	walkprintfunc_prgen++
	sym := lookupN("print·%d", walkprintfunc_prgen)
	fn := dclfunc(sym, t)

	a = nod(n.Op, nil, nil)
	a.List.Set(printargs)
	a = typecheck(a, Etop)
	a = walkstmt(a)

	fn.Nbody.Set1(a)

	funcbody(fn)

	fn = typecheck(fn, Etop)
	typecheckslice(fn.Nbody.Slice(), Etop)
	xtop = append(xtop, fn)
	Curfn = oldfn

	a = nod(OCALL, nil, nil)
	a.Left = fn.Func.Nname
	a.List.Set(n.List.Slice())
	a = typecheck(a, Etop)
	a = walkexpr(a, init)
	return a
}

// substArgTypes substitutes the given list of types for
// successive occurrences of the "any" placeholder in the
// type syntax expression n.Type.
// The result of substArgTypes MUST be assigned back to old, e.g.
// 	n.Left = substArgTypes(n.Left, t1, t2)
func substArgTypes(old *Node, types_ ...*types.Type) *Node {
	n := *old // make shallow copy

	for _, t := range types_ {
		dowidth(t)
	}
	n.Type = types.SubstAny(n.Type, &types_)
	if len(types_) > 0 {
		Fatalf("substArgTypes: too many argument types")
	}
	return &n
}
