Home | History | Annotate | Download | only in gc
      1 // Copyright 2012 The Go Authors.  All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package gc
      6 
      7 import (
      8 	"fmt"
      9 	"strings"
     10 )
     11 
     12 // Rewrite tree to use separate statements to enforce
     13 // order of evaluation.  Makes walk easier, because it
     14 // can (after this runs) reorder at will within an expression.
     15 //
     16 // Rewrite x op= y into x = x op y.
     17 //
     18 // Introduce temporaries as needed by runtime routines.
     19 // For example, the map runtime routines take the map key
     20 // by reference, so make sure all map keys are addressable
     21 // by copying them to temporaries as needed.
     22 // The same is true for channel operations.
     23 //
     24 // Arrange that map index expressions only appear in direct
     25 // assignments x = m[k] or m[k] = x, never in larger expressions.
     26 //
     27 // Arrange that receive expressions only appear in direct assignments
     28 // x = <-c or as standalone statements <-c, never in larger expressions.
     29 
     30 // TODO(rsc): The temporary introduction during multiple assignments
     31 // should be moved into this file, so that the temporaries can be cleaned
     32 // and so that conversions implicit in the OAS2FUNC and OAS2RECV
     33 // nodes can be made explicit and then have their temporaries cleaned.
     34 
     35 // TODO(rsc): Goto and multilevel break/continue can jump over
     36 // inserted VARKILL annotations. Work out a way to handle these.
     37 // The current implementation is safe, in that it will execute correctly.
     38 // But it won't reuse temporaries as aggressively as it might, and
     39 // it can result in unnecessary zeroing of those variables in the function
     40 // prologue.
     41 
     42 // Order holds state during the ordering process.
     43 type Order struct {
     44 	out  *NodeList // list of generated statements
     45 	temp *NodeList // head of stack of temporary variables
     46 	free *NodeList // free list of NodeList* structs (for use in temp)
     47 }
     48 
     49 // Order rewrites fn->nbody to apply the ordering constraints
     50 // described in the comment at the top of the file.
     51 func order(fn *Node) {
     52 	if Debug['W'] > 1 {
     53 		s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym)
     54 		dumplist(s, fn.Nbody)
     55 	}
     56 
     57 	orderblock(&fn.Nbody)
     58 }
     59 
     60 // Ordertemp allocates a new temporary with the given type,
     61 // pushes it onto the temp stack, and returns it.
     62 // If clear is true, ordertemp emits code to zero the temporary.
     63 func ordertemp(t *Type, order *Order, clear bool) *Node {
     64 	var_ := temp(t)
     65 	if clear {
     66 		a := Nod(OAS, var_, nil)
     67 		typecheck(&a, Etop)
     68 		order.out = list(order.out, a)
     69 	}
     70 
     71 	l := order.free
     72 	if l == nil {
     73 		l = new(NodeList)
     74 	}
     75 	order.free = l.Next
     76 	l.Next = order.temp
     77 	l.N = var_
     78 	order.temp = l
     79 	return var_
     80 }
     81 
     82 // Ordercopyexpr behaves like ordertemp but also emits
     83 // code to initialize the temporary to the value n.
     84 //
     85 // The clear argument is provided for use when the evaluation
     86 // of tmp = n turns into a function call that is passed a pointer
     87 // to the temporary as the output space. If the call blocks before
     88 // tmp has been written, the garbage collector will still treat the
     89 // temporary as live, so we must zero it before entering that call.
     90 // Today, this only happens for channel receive operations.
     91 // (The other candidate would be map access, but map access
     92 // returns a pointer to the result data instead of taking a pointer
     93 // to be filled in.)
     94 func ordercopyexpr(n *Node, t *Type, order *Order, clear int) *Node {
     95 	var_ := ordertemp(t, order, clear != 0)
     96 	a := Nod(OAS, var_, n)
     97 	typecheck(&a, Etop)
     98 	order.out = list(order.out, a)
     99 	return var_
    100 }
    101 
    102 // Ordercheapexpr returns a cheap version of n.
    103 // The definition of cheap is that n is a variable or constant.
    104 // If not, ordercheapexpr allocates a new tmp, emits tmp = n,
    105 // and then returns tmp.
    106 func ordercheapexpr(n *Node, order *Order) *Node {
    107 	if n == nil {
    108 		return nil
    109 	}
    110 	switch n.Op {
    111 	case ONAME, OLITERAL:
    112 		return n
    113 	case OLEN, OCAP:
    114 		l := ordercheapexpr(n.Left, order)
    115 		if l == n.Left {
    116 			return n
    117 		}
    118 		a := Nod(OXXX, nil, nil)
    119 		*a = *n
    120 		a.Orig = a
    121 		a.Left = l
    122 		typecheck(&a, Erv)
    123 		return a
    124 	}
    125 
    126 	return ordercopyexpr(n, n.Type, order, 0)
    127 }
    128 
    129 // Ordersafeexpr returns a safe version of n.
    130 // The definition of safe is that n can appear multiple times
    131 // without violating the semantics of the original program,
    132 // and that assigning to the safe version has the same effect
    133 // as assigning to the original n.
    134 //
    135 // The intended use is to apply to x when rewriting x += y into x = x + y.
    136 func ordersafeexpr(n *Node, order *Order) *Node {
    137 	switch n.Op {
    138 	case ONAME, OLITERAL:
    139 		return n
    140 
    141 	case ODOT, OLEN, OCAP:
    142 		l := ordersafeexpr(n.Left, order)
    143 		if l == n.Left {
    144 			return n
    145 		}
    146 		a := Nod(OXXX, nil, nil)
    147 		*a = *n
    148 		a.Orig = a
    149 		a.Left = l
    150 		typecheck(&a, Erv)
    151 		return a
    152 
    153 	case ODOTPTR, OIND:
    154 		l := ordercheapexpr(n.Left, order)
    155 		if l == n.Left {
    156 			return n
    157 		}
    158 		a := Nod(OXXX, nil, nil)
    159 		*a = *n
    160 		a.Orig = a
    161 		a.Left = l
    162 		typecheck(&a, Erv)
    163 		return a
    164 
    165 	case OINDEX, OINDEXMAP:
    166 		var l *Node
    167 		if Isfixedarray(n.Left.Type) {
    168 			l = ordersafeexpr(n.Left, order)
    169 		} else {
    170 			l = ordercheapexpr(n.Left, order)
    171 		}
    172 		r := ordercheapexpr(n.Right, order)
    173 		if l == n.Left && r == n.Right {
    174 			return n
    175 		}
    176 		a := Nod(OXXX, nil, nil)
    177 		*a = *n
    178 		a.Orig = a
    179 		a.Left = l
    180 		a.Right = r
    181 		typecheck(&a, Erv)
    182 		return a
    183 	}
    184 
    185 	Fatal("ordersafeexpr %v", Oconv(int(n.Op), 0))
    186 	return nil // not reached
    187 }
    188 
    189 // Istemp reports whether n is a temporary variable.
    190 func istemp(n *Node) bool {
    191 	if n.Op != ONAME {
    192 		return false
    193 	}
    194 	return strings.HasPrefix(n.Sym.Name, "autotmp_")
    195 }
    196 
    197 // Isaddrokay reports whether it is okay to pass n's address to runtime routines.
    198 // Taking the address of a variable makes the liveness and optimization analyses
    199 // lose track of where the variable's lifetime ends. To avoid hurting the analyses
    200 // of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
    201 // because we emit explicit VARKILL instructions marking the end of those
    202 // temporaries' lifetimes.
    203 func isaddrokay(n *Node) bool {
    204 	return islvalue(n) && (n.Op != ONAME || n.Class == PEXTERN || istemp(n))
    205 }
    206 
    207 // Orderaddrtemp ensures that *np is okay to pass by address to runtime routines.
    208 // If the original argument *np is not okay, orderaddrtemp creates a tmp, emits
    209 // tmp = *np, and then sets *np to the tmp variable.
    210 func orderaddrtemp(np **Node, order *Order) {
    211 	n := *np
    212 	if isaddrokay(n) {
    213 		return
    214 	}
    215 	*np = ordercopyexpr(n, n.Type, order, 0)
    216 }
    217 
    218 // Marktemp returns the top of the temporary variable stack.
    219 func marktemp(order *Order) *NodeList {
    220 	return order.temp
    221 }
    222 
    223 // Poptemp pops temporaries off the stack until reaching the mark,
    224 // which must have been returned by marktemp.
    225 func poptemp(mark *NodeList, order *Order) {
    226 	var l *NodeList
    227 
    228 	for {
    229 		l = order.temp
    230 		if l == mark {
    231 			break
    232 		}
    233 		order.temp = l.Next
    234 		l.Next = order.free
    235 		order.free = l
    236 	}
    237 }
    238 
    239 // Cleantempnopop emits to *out VARKILL instructions for each temporary
    240 // above the mark on the temporary stack, but it does not pop them
    241 // from the stack.
    242 func cleantempnopop(mark *NodeList, order *Order, out **NodeList) {
    243 	var kill *Node
    244 
    245 	for l := order.temp; l != mark; l = l.Next {
    246 		kill = Nod(OVARKILL, l.N, nil)
    247 		typecheck(&kill, Etop)
    248 		*out = list(*out, kill)
    249 	}
    250 }
    251 
    252 // Cleantemp emits VARKILL instructions for each temporary above the
    253 // mark on the temporary stack and removes them from the stack.
    254 func cleantemp(top *NodeList, order *Order) {
    255 	cleantempnopop(top, order, &order.out)
    256 	poptemp(top, order)
    257 }
    258 
    259 // Orderstmtlist orders each of the statements in the list.
    260 func orderstmtlist(l *NodeList, order *Order) {
    261 	for ; l != nil; l = l.Next {
    262 		orderstmt(l.N, order)
    263 	}
    264 }
    265 
    266 // Orderblock orders the block of statements *l onto a new list,
    267 // and then replaces *l with that list.
    268 func orderblock(l **NodeList) {
    269 	var order Order
    270 	mark := marktemp(&order)
    271 	orderstmtlist(*l, &order)
    272 	cleantemp(mark, &order)
    273 	*l = order.out
    274 }
    275 
    276 // Orderexprinplace orders the side effects in *np and
    277 // leaves them as the init list of the final *np.
    278 func orderexprinplace(np **Node, outer *Order) {
    279 	n := *np
    280 	var order Order
    281 	orderexpr(&n, &order, nil)
    282 	addinit(&n, order.out)
    283 
    284 	// insert new temporaries from order
    285 	// at head of outer list.
    286 	lp := &order.temp
    287 
    288 	for *lp != nil {
    289 		lp = &(*lp).Next
    290 	}
    291 	*lp = outer.temp
    292 	outer.temp = order.temp
    293 
    294 	*np = n
    295 }
    296 
    297 // Orderstmtinplace orders the side effects of the single statement *np
    298 // and replaces it with the resulting statement list.
    299 func orderstmtinplace(np **Node) {
    300 	n := *np
    301 	var order Order
    302 	mark := marktemp(&order)
    303 	orderstmt(n, &order)
    304 	cleantemp(mark, &order)
    305 	*np = liststmt(order.out)
    306 }
    307 
    308 // Orderinit moves n's init list to order->out.
    309 func orderinit(n *Node, order *Order) {
    310 	orderstmtlist(n.Ninit, order)
    311 	n.Ninit = nil
    312 }
    313 
    314 // Ismulticall reports whether the list l is f() for a multi-value function.
    315 // Such an f() could appear as the lone argument to a multi-arg function.
    316 func ismulticall(l *NodeList) bool {
    317 	// one arg only
    318 	if l == nil || l.Next != nil {
    319 		return false
    320 	}
    321 	n := l.N
    322 
    323 	// must be call
    324 	switch n.Op {
    325 	default:
    326 		return false
    327 
    328 	case OCALLFUNC, OCALLMETH, OCALLINTER:
    329 		break
    330 	}
    331 
    332 	// call must return multiple values
    333 	return n.Left.Type.Outtuple > 1
    334 }
    335 
    336 // Copyret emits t1, t2, ... = n, where n is a function call,
    337 // and then returns the list t1, t2, ....
    338 func copyret(n *Node, order *Order) *NodeList {
    339 	if n.Type.Etype != TSTRUCT || n.Type.Funarg == 0 {
    340 		Fatal("copyret %v %d", n.Type, n.Left.Type.Outtuple)
    341 	}
    342 
    343 	var l1 *NodeList
    344 	var l2 *NodeList
    345 	var tl Iter
    346 	var tmp *Node
    347 	for t := Structfirst(&tl, &n.Type); t != nil; t = structnext(&tl) {
    348 		tmp = temp(t.Type)
    349 		l1 = list(l1, tmp)
    350 		l2 = list(l2, tmp)
    351 	}
    352 
    353 	as := Nod(OAS2, nil, nil)
    354 	as.List = l1
    355 	as.Rlist = list1(n)
    356 	typecheck(&as, Etop)
    357 	orderstmt(as, order)
    358 
    359 	return l2
    360 }
    361 
    362 // Ordercallargs orders the list of call arguments *l.
    363 func ordercallargs(l **NodeList, order *Order) {
    364 	if ismulticall(*l) {
    365 		// return f() where f() is multiple values.
    366 		*l = copyret((*l).N, order)
    367 	} else {
    368 		orderexprlist(*l, order)
    369 	}
    370 }
    371 
    372 // Ordercall orders the call expression n.
    373 // n->op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
    374 func ordercall(n *Node, order *Order) {
    375 	orderexpr(&n.Left, order, nil)
    376 	orderexpr(&n.Right, order, nil) // ODDDARG temp
    377 	ordercallargs(&n.List, order)
    378 }
    379 
    380 // Ordermapassign appends n to order->out, introducing temporaries
    381 // to make sure that all map assignments have the form m[k] = x,
    382 // where x is adressable.
    383 // (Orderexpr has already been called on n, so we know k is addressable.)
    384 //
    385 // If n is m[k] = x where x is not addressable, the rewrite is:
    386 //	tmp = x
    387 //	m[k] = tmp
    388 //
    389 // If n is the multiple assignment form ..., m[k], ... = ..., the rewrite is
    390 //	t1 = m
    391 //	t2 = k
    392 //	...., t3, ... = x
    393 //	t1[t2] = t3
    394 //
    395 // The temporaries t1, t2 are needed in case the ... being assigned
    396 // contain m or k. They are usually unnecessary, but in the unnecessary
    397 // cases they are also typically registerizable, so not much harm done.
    398 // And this only applies to the multiple-assignment form.
    399 // We could do a more precise analysis if needed, like in walk.c.
    400 //
    401 // Ordermapassign also inserts these temporaries if needed for
    402 // calling writebarrierfat with a pointer to n->right.
    403 func ordermapassign(n *Node, order *Order) {
    404 	switch n.Op {
    405 	default:
    406 		Fatal("ordermapassign %v", Oconv(int(n.Op), 0))
    407 
    408 	case OAS:
    409 		order.out = list(order.out, n)
    410 
    411 		// We call writebarrierfat only for values > 4 pointers long. See walk.c.
    412 		if (n.Left.Op == OINDEXMAP || (needwritebarrier(n.Left, n.Right) && n.Left.Type.Width > int64(4*Widthptr))) && !isaddrokay(n.Right) {
    413 			m := n.Left
    414 			n.Left = ordertemp(m.Type, order, false)
    415 			a := Nod(OAS, m, n.Left)
    416 			typecheck(&a, Etop)
    417 			order.out = list(order.out, a)
    418 		}
    419 
    420 	case OAS2, OAS2DOTTYPE, OAS2MAPR, OAS2FUNC:
    421 		var post *NodeList
    422 		var m *Node
    423 		var a *Node
    424 		for l := n.List; l != nil; l = l.Next {
    425 			if l.N.Op == OINDEXMAP {
    426 				m = l.N
    427 				if !istemp(m.Left) {
    428 					m.Left = ordercopyexpr(m.Left, m.Left.Type, order, 0)
    429 				}
    430 				if !istemp(m.Right) {
    431 					m.Right = ordercopyexpr(m.Right, m.Right.Type, order, 0)
    432 				}
    433 				l.N = ordertemp(m.Type, order, false)
    434 				a = Nod(OAS, m, l.N)
    435 				typecheck(&a, Etop)
    436 				post = list(post, a)
    437 			} else if flag_race != 0 && n.Op == OAS2FUNC && !isblank(l.N) {
    438 				m = l.N
    439 				l.N = ordertemp(m.Type, order, false)
    440 				a = Nod(OAS, m, l.N)
    441 				typecheck(&a, Etop)
    442 				post = list(post, a)
    443 			}
    444 		}
    445 
    446 		order.out = list(order.out, n)
    447 		order.out = concat(order.out, post)
    448 	}
    449 }
    450 
    451 // Orderstmt orders the statement n, appending to order->out.
    452 // Temporaries created during the statement are cleaned
    453 // up using VARKILL instructions as possible.
    454 func orderstmt(n *Node, order *Order) {
    455 	if n == nil {
    456 		return
    457 	}
    458 
    459 	lno := int(setlineno(n))
    460 
    461 	orderinit(n, order)
    462 
    463 	switch n.Op {
    464 	default:
    465 		Fatal("orderstmt %v", Oconv(int(n.Op), 0))
    466 
    467 	case OVARKILL:
    468 		order.out = list(order.out, n)
    469 
    470 	case OAS:
    471 		t := marktemp(order)
    472 		orderexpr(&n.Left, order, nil)
    473 		orderexpr(&n.Right, order, n.Left)
    474 		ordermapassign(n, order)
    475 		cleantemp(t, order)
    476 
    477 	case OAS2,
    478 		OCLOSE,
    479 		OCOPY,
    480 		OPRINT,
    481 		OPRINTN,
    482 		ORECOVER,
    483 		ORECV:
    484 		t := marktemp(order)
    485 		orderexpr(&n.Left, order, nil)
    486 		orderexpr(&n.Right, order, nil)
    487 		orderexprlist(n.List, order)
    488 		orderexprlist(n.Rlist, order)
    489 		switch n.Op {
    490 		case OAS2, OAS2DOTTYPE:
    491 			ordermapassign(n, order)
    492 		default:
    493 			order.out = list(order.out, n)
    494 		}
    495 		cleantemp(t, order)
    496 
    497 	case OASOP:
    498 		// Special: rewrite l op= r into l = l op r.
    499 		// This simplifies quite a few operations;
    500 		// most important is that it lets us separate
    501 		// out map read from map write when l is
    502 		// a map index expression.
    503 		t := marktemp(order)
    504 
    505 		orderexpr(&n.Left, order, nil)
    506 		n.Left = ordersafeexpr(n.Left, order)
    507 		tmp1 := treecopy(n.Left, 0)
    508 		if tmp1.Op == OINDEXMAP {
    509 			tmp1.Etype = 0 // now an rvalue not an lvalue
    510 		}
    511 		tmp1 = ordercopyexpr(tmp1, n.Left.Type, order, 0)
    512 		n.Right = Nod(int(n.Etype), tmp1, n.Right)
    513 		typecheck(&n.Right, Erv)
    514 		orderexpr(&n.Right, order, nil)
    515 		n.Etype = 0
    516 		n.Op = OAS
    517 		ordermapassign(n, order)
    518 		cleantemp(t, order)
    519 
    520 		// Special: make sure key is addressable,
    521 	// and make sure OINDEXMAP is not copied out.
    522 	case OAS2MAPR:
    523 		t := marktemp(order)
    524 
    525 		orderexprlist(n.List, order)
    526 		r := n.Rlist.N
    527 		orderexpr(&r.Left, order, nil)
    528 		orderexpr(&r.Right, order, nil)
    529 
    530 		// See case OINDEXMAP below.
    531 		if r.Right.Op == OARRAYBYTESTR {
    532 			r.Right.Op = OARRAYBYTESTRTMP
    533 		}
    534 		orderaddrtemp(&r.Right, order)
    535 		ordermapassign(n, order)
    536 		cleantemp(t, order)
    537 
    538 		// Special: avoid copy of func call n->rlist->n.
    539 	case OAS2FUNC:
    540 		t := marktemp(order)
    541 
    542 		orderexprlist(n.List, order)
    543 		ordercall(n.Rlist.N, order)
    544 		ordermapassign(n, order)
    545 		cleantemp(t, order)
    546 
    547 		// Special: use temporary variables to hold result,
    548 	// so that assertI2Tetc can take address of temporary.
    549 	// No temporary for blank assignment.
    550 	case OAS2DOTTYPE:
    551 		t := marktemp(order)
    552 
    553 		orderexprlist(n.List, order)
    554 		orderexpr(&n.Rlist.N.Left, order, nil) // i in i.(T)
    555 		if isblank(n.List.N) {
    556 			order.out = list(order.out, n)
    557 		} else {
    558 			typ := n.Rlist.N.Type
    559 			tmp1 := ordertemp(typ, order, haspointers(typ))
    560 			order.out = list(order.out, n)
    561 			r := Nod(OAS, n.List.N, tmp1)
    562 			typecheck(&r, Etop)
    563 			ordermapassign(r, order)
    564 			n.List = list(list1(tmp1), n.List.Next.N)
    565 		}
    566 
    567 		cleantemp(t, order)
    568 
    569 		// Special: use temporary variables to hold result,
    570 	// so that chanrecv can take address of temporary.
    571 	case OAS2RECV:
    572 		t := marktemp(order)
    573 
    574 		orderexprlist(n.List, order)
    575 		orderexpr(&n.Rlist.N.Left, order, nil) // arg to recv
    576 		ch := n.Rlist.N.Left.Type
    577 		tmp1 := ordertemp(ch.Type, order, haspointers(ch.Type))
    578 		var tmp2 *Node
    579 		if !isblank(n.List.Next.N) {
    580 			tmp2 = ordertemp(n.List.Next.N.Type, order, false)
    581 		} else {
    582 			tmp2 = ordertemp(Types[TBOOL], order, false)
    583 		}
    584 		order.out = list(order.out, n)
    585 		r := Nod(OAS, n.List.N, tmp1)
    586 		typecheck(&r, Etop)
    587 		ordermapassign(r, order)
    588 		r = Nod(OAS, n.List.Next.N, tmp2)
    589 		typecheck(&r, Etop)
    590 		ordermapassign(r, order)
    591 		n.List = list(list1(tmp1), tmp2)
    592 		cleantemp(t, order)
    593 
    594 		// Special: does not save n onto out.
    595 	case OBLOCK, OEMPTY:
    596 		orderstmtlist(n.List, order)
    597 
    598 		// Special: n->left is not an expression; save as is.
    599 	case OBREAK,
    600 		OCONTINUE,
    601 		ODCL,
    602 		ODCLCONST,
    603 		ODCLTYPE,
    604 		OFALL,
    605 		OXFALL,
    606 		OGOTO,
    607 		OLABEL,
    608 		ORETJMP:
    609 		order.out = list(order.out, n)
    610 
    611 		// Special: handle call arguments.
    612 	case OCALLFUNC, OCALLINTER, OCALLMETH:
    613 		t := marktemp(order)
    614 
    615 		ordercall(n, order)
    616 		order.out = list(order.out, n)
    617 		cleantemp(t, order)
    618 
    619 		// Special: order arguments to inner call but not call itself.
    620 	case ODEFER, OPROC:
    621 		t := marktemp(order)
    622 
    623 		switch n.Left.Op {
    624 		// Delete will take the address of the key.
    625 		// Copy key into new temp and do not clean it
    626 		// (it persists beyond the statement).
    627 		case ODELETE:
    628 			orderexprlist(n.Left.List, order)
    629 
    630 			t1 := marktemp(order)
    631 			np := &n.Left.List.Next.N // map key
    632 			*np = ordercopyexpr(*np, (*np).Type, order, 0)
    633 			poptemp(t1, order)
    634 
    635 		default:
    636 			ordercall(n.Left, order)
    637 		}
    638 
    639 		order.out = list(order.out, n)
    640 		cleantemp(t, order)
    641 
    642 	case ODELETE:
    643 		t := marktemp(order)
    644 		orderexpr(&n.List.N, order, nil)
    645 		orderexpr(&n.List.Next.N, order, nil)
    646 		orderaddrtemp(&n.List.Next.N, order) // map key
    647 		order.out = list(order.out, n)
    648 		cleantemp(t, order)
    649 
    650 		// Clean temporaries from condition evaluation at
    651 	// beginning of loop body and after for statement.
    652 	case OFOR:
    653 		t := marktemp(order)
    654 
    655 		orderexprinplace(&n.Left, order)
    656 		var l *NodeList
    657 		cleantempnopop(t, order, &l)
    658 		n.Nbody = concat(l, n.Nbody)
    659 		orderblock(&n.Nbody)
    660 		orderstmtinplace(&n.Right)
    661 		order.out = list(order.out, n)
    662 		cleantemp(t, order)
    663 
    664 		// Clean temporaries from condition at
    665 	// beginning of both branches.
    666 	case OIF:
    667 		t := marktemp(order)
    668 
    669 		orderexprinplace(&n.Left, order)
    670 		var l *NodeList
    671 		cleantempnopop(t, order, &l)
    672 		n.Nbody = concat(l, n.Nbody)
    673 		l = nil
    674 		cleantempnopop(t, order, &l)
    675 		n.Rlist = concat(l, n.Rlist)
    676 		poptemp(t, order)
    677 		orderblock(&n.Nbody)
    678 		orderblock(&n.Rlist)
    679 		order.out = list(order.out, n)
    680 
    681 		// Special: argument will be converted to interface using convT2E
    682 	// so make sure it is an addressable temporary.
    683 	case OPANIC:
    684 		t := marktemp(order)
    685 
    686 		orderexpr(&n.Left, order, nil)
    687 		if !Isinter(n.Left.Type) {
    688 			orderaddrtemp(&n.Left, order)
    689 		}
    690 		order.out = list(order.out, n)
    691 		cleantemp(t, order)
    692 
    693 		// n->right is the expression being ranged over.
    694 	// order it, and then make a copy if we need one.
    695 	// We almost always do, to ensure that we don't
    696 	// see any value changes made during the loop.
    697 	// Usually the copy is cheap (e.g., array pointer, chan, slice, string are all tiny).
    698 	// The exception is ranging over an array value (not a slice, not a pointer to array),
    699 	// which must make a copy to avoid seeing updates made during
    700 	// the range body. Ranging over an array value is uncommon though.
    701 	case ORANGE:
    702 		t := marktemp(order)
    703 
    704 		orderexpr(&n.Right, order, nil)
    705 		switch n.Type.Etype {
    706 		default:
    707 			Fatal("orderstmt range %v", n.Type)
    708 
    709 			// Mark []byte(str) range expression to reuse string backing storage.
    710 		// It is safe because the storage cannot be mutated.
    711 		case TARRAY:
    712 			if n.Right.Op == OSTRARRAYBYTE {
    713 				n.Right.Op = OSTRARRAYBYTETMP
    714 			}
    715 			if count(n.List) < 2 || isblank(n.List.Next.N) {
    716 				// for i := range x will only use x once, to compute len(x).
    717 				// No need to copy it.
    718 				break
    719 			}
    720 			fallthrough
    721 
    722 			// chan, string, slice, array ranges use value multiple times.
    723 		// make copy.
    724 		// fall through
    725 		case TCHAN, TSTRING:
    726 			r := n.Right
    727 
    728 			if r.Type.Etype == TSTRING && r.Type != Types[TSTRING] {
    729 				r = Nod(OCONV, r, nil)
    730 				r.Type = Types[TSTRING]
    731 				typecheck(&r, Erv)
    732 			}
    733 
    734 			n.Right = ordercopyexpr(r, r.Type, order, 0)
    735 
    736 			// copy the map value in case it is a map literal.
    737 		// TODO(rsc): Make tmp = literal expressions reuse tmp.
    738 		// For maps tmp is just one word so it hardly matters.
    739 		case TMAP:
    740 			r := n.Right
    741 
    742 			n.Right = ordercopyexpr(r, r.Type, order, 0)
    743 
    744 			// n->alloc is the temp for the iterator.
    745 			prealloc[n] = ordertemp(Types[TUINT8], order, true)
    746 		}
    747 
    748 		for l := n.List; l != nil; l = l.Next {
    749 			orderexprinplace(&l.N, order)
    750 		}
    751 		orderblock(&n.Nbody)
    752 		order.out = list(order.out, n)
    753 		cleantemp(t, order)
    754 
    755 	case ORETURN:
    756 		ordercallargs(&n.List, order)
    757 		order.out = list(order.out, n)
    758 
    759 		// Special: clean case temporaries in each block entry.
    760 	// Select must enter one of its blocks, so there is no
    761 	// need for a cleaning at the end.
    762 	// Doubly special: evaluation order for select is stricter
    763 	// than ordinary expressions. Even something like p.c
    764 	// has to be hoisted into a temporary, so that it cannot be
    765 	// reordered after the channel evaluation for a different
    766 	// case (if p were nil, then the timing of the fault would
    767 	// give this away).
    768 	case OSELECT:
    769 		t := marktemp(order)
    770 
    771 		var tmp1 *Node
    772 		var tmp2 *Node
    773 		var r *Node
    774 		for l := n.List; l != nil; l = l.Next {
    775 			if l.N.Op != OXCASE {
    776 				Fatal("order select case %v", Oconv(int(l.N.Op), 0))
    777 			}
    778 			r = l.N.Left
    779 			setlineno(l.N)
    780 
    781 			// Append any new body prologue to ninit.
    782 			// The next loop will insert ninit into nbody.
    783 			if l.N.Ninit != nil {
    784 				Fatal("order select ninit")
    785 			}
    786 			if r != nil {
    787 				switch r.Op {
    788 				default:
    789 					Yyerror("unknown op in select %v", Oconv(int(r.Op), 0))
    790 					Dump("select case", r)
    791 
    792 					// If this is case x := <-ch or case x, y := <-ch, the case has
    793 				// the ODCL nodes to declare x and y. We want to delay that
    794 				// declaration (and possible allocation) until inside the case body.
    795 				// Delete the ODCL nodes here and recreate them inside the body below.
    796 				case OSELRECV, OSELRECV2:
    797 					if r.Colas {
    798 						t = r.Ninit
    799 						if t != nil && t.N.Op == ODCL && t.N.Left == r.Left {
    800 							t = t.Next
    801 						}
    802 						if t != nil && t.N.Op == ODCL && r.List != nil && t.N.Left == r.List.N {
    803 							t = t.Next
    804 						}
    805 						if t == nil {
    806 							r.Ninit = nil
    807 						}
    808 					}
    809 
    810 					if r.Ninit != nil {
    811 						Yyerror("ninit on select recv")
    812 						dumplist("ninit", r.Ninit)
    813 					}
    814 
    815 					// case x = <-c
    816 					// case x, ok = <-c
    817 					// r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c.
    818 					// r->left == N means 'case <-c'.
    819 					// c is always evaluated; x and ok are only evaluated when assigned.
    820 					orderexpr(&r.Right.Left, order, nil)
    821 
    822 					if r.Right.Left.Op != ONAME {
    823 						r.Right.Left = ordercopyexpr(r.Right.Left, r.Right.Left.Type, order, 0)
    824 					}
    825 
    826 					// Introduce temporary for receive and move actual copy into case body.
    827 					// avoids problems with target being addressed, as usual.
    828 					// NOTE: If we wanted to be clever, we could arrange for just one
    829 					// temporary per distinct type, sharing the temp among all receives
    830 					// with that temp. Similarly one ok bool could be shared among all
    831 					// the x,ok receives. Not worth doing until there's a clear need.
    832 					if r.Left != nil && isblank(r.Left) {
    833 						r.Left = nil
    834 					}
    835 					if r.Left != nil {
    836 						// use channel element type for temporary to avoid conversions,
    837 						// such as in case interfacevalue = <-intchan.
    838 						// the conversion happens in the OAS instead.
    839 						tmp1 = r.Left
    840 
    841 						if r.Colas {
    842 							tmp2 = Nod(ODCL, tmp1, nil)
    843 							typecheck(&tmp2, Etop)
    844 							l.N.Ninit = list(l.N.Ninit, tmp2)
    845 						}
    846 
    847 						r.Left = ordertemp(r.Right.Left.Type.Type, order, haspointers(r.Right.Left.Type.Type))
    848 						tmp2 = Nod(OAS, tmp1, r.Left)
    849 						typecheck(&tmp2, Etop)
    850 						l.N.Ninit = list(l.N.Ninit, tmp2)
    851 					}
    852 
    853 					if r.List != nil && isblank(r.List.N) {
    854 						r.List = nil
    855 					}
    856 					if r.List != nil {
    857 						tmp1 = r.List.N
    858 						if r.Colas {
    859 							tmp2 = Nod(ODCL, tmp1, nil)
    860 							typecheck(&tmp2, Etop)
    861 							l.N.Ninit = list(l.N.Ninit, tmp2)
    862 						}
    863 
    864 						r.List = list1(ordertemp(tmp1.Type, order, false))
    865 						tmp2 = Nod(OAS, tmp1, r.List.N)
    866 						typecheck(&tmp2, Etop)
    867 						l.N.Ninit = list(l.N.Ninit, tmp2)
    868 					}
    869 
    870 					orderblock(&l.N.Ninit)
    871 
    872 				case OSEND:
    873 					if r.Ninit != nil {
    874 						Yyerror("ninit on select send")
    875 						dumplist("ninit", r.Ninit)
    876 					}
    877 
    878 					// case c <- x
    879 					// r->left is c, r->right is x, both are always evaluated.
    880 					orderexpr(&r.Left, order, nil)
    881 
    882 					if !istemp(r.Left) {
    883 						r.Left = ordercopyexpr(r.Left, r.Left.Type, order, 0)
    884 					}
    885 					orderexpr(&r.Right, order, nil)
    886 					if !istemp(r.Right) {
    887 						r.Right = ordercopyexpr(r.Right, r.Right.Type, order, 0)
    888 					}
    889 				}
    890 			}
    891 
    892 			orderblock(&l.N.Nbody)
    893 		}
    894 
    895 		// Now that we have accumulated all the temporaries, clean them.
    896 		// Also insert any ninit queued during the previous loop.
    897 		// (The temporary cleaning must follow that ninit work.)
    898 		for l := n.List; l != nil; l = l.Next {
    899 			cleantempnopop(t, order, &l.N.Ninit)
    900 			l.N.Nbody = concat(l.N.Ninit, l.N.Nbody)
    901 			l.N.Ninit = nil
    902 		}
    903 
    904 		order.out = list(order.out, n)
    905 		poptemp(t, order)
    906 
    907 		// Special: value being sent is passed as a pointer; make it addressable.
    908 	case OSEND:
    909 		t := marktemp(order)
    910 
    911 		orderexpr(&n.Left, order, nil)
    912 		orderexpr(&n.Right, order, nil)
    913 		orderaddrtemp(&n.Right, order)
    914 		order.out = list(order.out, n)
    915 		cleantemp(t, order)
    916 
    917 		// TODO(rsc): Clean temporaries more aggressively.
    918 	// Note that because walkswitch will rewrite some of the
    919 	// switch into a binary search, this is not as easy as it looks.
    920 	// (If we ran that code here we could invoke orderstmt on
    921 	// the if-else chain instead.)
    922 	// For now just clean all the temporaries at the end.
    923 	// In practice that's fine.
    924 	case OSWITCH:
    925 		t := marktemp(order)
    926 
    927 		orderexpr(&n.Left, order, nil)
    928 		for l := n.List; l != nil; l = l.Next {
    929 			if l.N.Op != OXCASE {
    930 				Fatal("order switch case %v", Oconv(int(l.N.Op), 0))
    931 			}
    932 			orderexprlistinplace(l.N.List, order)
    933 			orderblock(&l.N.Nbody)
    934 		}
    935 
    936 		order.out = list(order.out, n)
    937 		cleantemp(t, order)
    938 	}
    939 
    940 	lineno = int32(lno)
    941 }
    942 
    943 // Orderexprlist orders the expression list l into order.
    944 func orderexprlist(l *NodeList, order *Order) {
    945 	for ; l != nil; l = l.Next {
    946 		orderexpr(&l.N, order, nil)
    947 	}
    948 }
    949 
    950 // Orderexprlist orders the expression list l but saves
    951 // the side effects on the individual expression ninit lists.
    952 func orderexprlistinplace(l *NodeList, order *Order) {
    953 	for ; l != nil; l = l.Next {
    954 		orderexprinplace(&l.N, order)
    955 	}
    956 }
    957 
    958 // prealloc[x] records the allocation to use for x.
    959 var prealloc = map[*Node]*Node{}
    960 
    961 // Orderexpr orders a single expression, appending side
    962 // effects to order->out as needed.
    963 // If this is part of an assignment lhs = *np, lhs is given.
    964 // Otherwise lhs == nil. (When lhs != nil it may be possible
    965 // to avoid copying the result of the expression to a temporary.)
    966 func orderexpr(np **Node, order *Order, lhs *Node) {
    967 	n := *np
    968 	if n == nil {
    969 		return
    970 	}
    971 
    972 	lno := int(setlineno(n))
    973 	orderinit(n, order)
    974 
    975 	switch n.Op {
    976 	default:
    977 		orderexpr(&n.Left, order, nil)
    978 		orderexpr(&n.Right, order, nil)
    979 		orderexprlist(n.List, order)
    980 		orderexprlist(n.Rlist, order)
    981 
    982 		// Addition of strings turns into a function call.
    983 	// Allocate a temporary to hold the strings.
    984 	// Fewer than 5 strings use direct runtime helpers.
    985 	case OADDSTR:
    986 		orderexprlist(n.List, order)
    987 
    988 		if count(n.List) > 5 {
    989 			t := typ(TARRAY)
    990 			t.Bound = int64(count(n.List))
    991 			t.Type = Types[TSTRING]
    992 			prealloc[n] = ordertemp(t, order, false)
    993 		}
    994 
    995 		// Mark string(byteSlice) arguments to reuse byteSlice backing
    996 		// buffer during conversion. String concatenation does not
    997 		// memorize the strings for later use, so it is safe.
    998 		// However, we can do it only if there is at least one non-empty string literal.
    999 		// Otherwise if all other arguments are empty strings,
   1000 		// concatstrings will return the reference to the temp string
   1001 		// to the caller.
   1002 		hasbyte := false
   1003 
   1004 		haslit := false
   1005 		for l := n.List; l != nil; l = l.Next {
   1006 			hasbyte = hasbyte || l.N.Op == OARRAYBYTESTR
   1007 			haslit = haslit || l.N.Op == OLITERAL && len(l.N.Val().U.(string)) != 0
   1008 		}
   1009 
   1010 		if haslit && hasbyte {
   1011 			for l := n.List; l != nil; l = l.Next {
   1012 				if l.N.Op == OARRAYBYTESTR {
   1013 					l.N.Op = OARRAYBYTESTRTMP
   1014 				}
   1015 			}
   1016 		}
   1017 
   1018 	case OCMPSTR:
   1019 		orderexpr(&n.Left, order, nil)
   1020 		orderexpr(&n.Right, order, nil)
   1021 
   1022 		// Mark string(byteSlice) arguments to reuse byteSlice backing
   1023 		// buffer during conversion. String comparison does not
   1024 		// memorize the strings for later use, so it is safe.
   1025 		if n.Left.Op == OARRAYBYTESTR {
   1026 			n.Left.Op = OARRAYBYTESTRTMP
   1027 		}
   1028 		if n.Right.Op == OARRAYBYTESTR {
   1029 			n.Right.Op = OARRAYBYTESTRTMP
   1030 		}
   1031 
   1032 		// key must be addressable
   1033 	case OINDEXMAP:
   1034 		orderexpr(&n.Left, order, nil)
   1035 
   1036 		orderexpr(&n.Right, order, nil)
   1037 
   1038 		// For x = m[string(k)] where k is []byte, the allocation of
   1039 		// backing bytes for the string can be avoided by reusing
   1040 		// the []byte backing array. This is a special case that it
   1041 		// would be nice to handle more generally, but because
   1042 		// there are no []byte-keyed maps, this specific case comes
   1043 		// up in important cases in practice. See issue 3512.
   1044 		// Nothing can change the []byte we are not copying before
   1045 		// the map index, because the map access is going to
   1046 		// be forced to happen immediately following this
   1047 		// conversion (by the ordercopyexpr a few lines below).
   1048 		if n.Etype == 0 && n.Right.Op == OARRAYBYTESTR {
   1049 			n.Right.Op = OARRAYBYTESTRTMP
   1050 		}
   1051 
   1052 		orderaddrtemp(&n.Right, order)
   1053 		if n.Etype == 0 {
   1054 			// use of value (not being assigned);
   1055 			// make copy in temporary.
   1056 			n = ordercopyexpr(n, n.Type, order, 0)
   1057 		}
   1058 
   1059 		// concrete type (not interface) argument must be addressable
   1060 	// temporary to pass to runtime.
   1061 	case OCONVIFACE:
   1062 		orderexpr(&n.Left, order, nil)
   1063 
   1064 		if !Isinter(n.Left.Type) {
   1065 			orderaddrtemp(&n.Left, order)
   1066 		}
   1067 
   1068 	case OANDAND, OOROR:
   1069 		mark := marktemp(order)
   1070 		orderexpr(&n.Left, order, nil)
   1071 
   1072 		// Clean temporaries from first branch at beginning of second.
   1073 		// Leave them on the stack so that they can be killed in the outer
   1074 		// context in case the short circuit is taken.
   1075 		var l *NodeList
   1076 
   1077 		cleantempnopop(mark, order, &l)
   1078 		n.Right.Ninit = concat(l, n.Right.Ninit)
   1079 		orderexprinplace(&n.Right, order)
   1080 
   1081 	case OCALLFUNC,
   1082 		OCALLINTER,
   1083 		OCALLMETH,
   1084 		OCAP,
   1085 		OCOMPLEX,
   1086 		OCOPY,
   1087 		OIMAG,
   1088 		OLEN,
   1089 		OMAKECHAN,
   1090 		OMAKEMAP,
   1091 		OMAKESLICE,
   1092 		ONEW,
   1093 		OREAL,
   1094 		ORECOVER:
   1095 		ordercall(n, order)
   1096 		if lhs == nil || lhs.Op != ONAME || flag_race != 0 {
   1097 			n = ordercopyexpr(n, n.Type, order, 0)
   1098 		}
   1099 
   1100 	case OAPPEND:
   1101 		ordercallargs(&n.List, order)
   1102 		if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.List.N) {
   1103 			n = ordercopyexpr(n, n.Type, order, 0)
   1104 		}
   1105 
   1106 	case OSLICE, OSLICEARR, OSLICESTR:
   1107 		orderexpr(&n.Left, order, nil)
   1108 		orderexpr(&n.Right.Left, order, nil)
   1109 		n.Right.Left = ordercheapexpr(n.Right.Left, order)
   1110 		orderexpr(&n.Right.Right, order, nil)
   1111 		n.Right.Right = ordercheapexpr(n.Right.Right, order)
   1112 		if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.Left) {
   1113 			n = ordercopyexpr(n, n.Type, order, 0)
   1114 		}
   1115 
   1116 	case OSLICE3, OSLICE3ARR:
   1117 		orderexpr(&n.Left, order, nil)
   1118 		orderexpr(&n.Right.Left, order, nil)
   1119 		n.Right.Left = ordercheapexpr(n.Right.Left, order)
   1120 		orderexpr(&n.Right.Right.Left, order, nil)
   1121 		n.Right.Right.Left = ordercheapexpr(n.Right.Right.Left, order)
   1122 		orderexpr(&n.Right.Right.Right, order, nil)
   1123 		n.Right.Right.Right = ordercheapexpr(n.Right.Right.Right, order)
   1124 		if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.Left) {
   1125 			n = ordercopyexpr(n, n.Type, order, 0)
   1126 		}
   1127 
   1128 	case OCLOSURE:
   1129 		if n.Noescape && n.Func.Cvars != nil {
   1130 			prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
   1131 		}
   1132 
   1133 	case OARRAYLIT, OCALLPART:
   1134 		orderexpr(&n.Left, order, nil)
   1135 		orderexpr(&n.Right, order, nil)
   1136 		orderexprlist(n.List, order)
   1137 		orderexprlist(n.Rlist, order)
   1138 		if n.Noescape {
   1139 			prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
   1140 		}
   1141 
   1142 	case ODDDARG:
   1143 		if n.Noescape {
   1144 			// The ddd argument does not live beyond the call it is created for.
   1145 			// Allocate a temporary that will be cleaned up when this statement
   1146 			// completes. We could be more aggressive and try to arrange for it
   1147 			// to be cleaned up when the call completes.
   1148 			prealloc[n] = ordertemp(n.Type.Type, order, false)
   1149 		}
   1150 
   1151 	case ODOTTYPE, ODOTTYPE2:
   1152 		orderexpr(&n.Left, order, nil)
   1153 		// TODO(rsc): The Isfat is for consistency with componentgen and walkexpr.
   1154 		// It needs to be removed in all three places.
   1155 		// That would allow inlining x.(struct{*int}) the same as x.(*int).
   1156 		if !isdirectiface(n.Type) || Isfat(n.Type) || flag_race != 0 {
   1157 			n = ordercopyexpr(n, n.Type, order, 1)
   1158 		}
   1159 
   1160 	case ORECV:
   1161 		orderexpr(&n.Left, order, nil)
   1162 		n = ordercopyexpr(n, n.Type, order, 1)
   1163 
   1164 	case OEQ, ONE:
   1165 		orderexpr(&n.Left, order, nil)
   1166 		orderexpr(&n.Right, order, nil)
   1167 		t := n.Left.Type
   1168 		if t.Etype == TSTRUCT || Isfixedarray(t) {
   1169 			// for complex comparisons, we need both args to be
   1170 			// addressable so we can pass them to the runtime.
   1171 			orderaddrtemp(&n.Left, order)
   1172 			orderaddrtemp(&n.Right, order)
   1173 		}
   1174 	}
   1175 
   1176 	lineno = int32(lno)
   1177 
   1178 	*np = n
   1179 }
   1180