// Copyright 2012 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.

// Rewrite tree to use separate statements to enforce
// order of evaluation.  Makes walk easier, because it
// can (after this runs) reorder at will within an expression.
//
// Rewrite x op= y into x = x op y.
//
// Introduce temporaries as needed by runtime routines.
// For example, the map runtime routines take the map key
// by reference, so make sure all map keys are addressable
// by copying them to temporaries as needed.
// The same is true for channel operations.
//
// Arrange that map index expressions only appear in direct
// assignments x = m[k] or m[k] = x, never in larger expressions.
//
// Arrange that receive expressions only appear in direct assignments
// x = <-c or as standalone statements <-c, never in larger expressions.

// TODO(rsc): The temporary introduction during multiple assignments
// should be moved into this file, so that the temporaries can be cleaned
// and so that conversions implicit in the OAS2FUNC and OAS2RECV
// nodes can be made explicit and then have their temporaries cleaned.

// TODO(rsc): Goto and multilevel break/continue can jump over
// inserted VARKILL annotations. Work out a way to handle these.
// The current implementation is safe, in that it will execute correctly.
// But it won't reuse temporaries as aggressively as it might, and
// it can result in unnecessary zeroing of those variables in the function
// prologue.

#include	<u.h>
#include	<libc.h>
#include	"go.h"

// Order holds state during the ordering process.
typedef struct Order Order;
struct Order
{
	NodeList *out; // list of generated statements
	NodeList *temp; // head of stack of temporary variables
	NodeList *free; // free list of NodeList* structs (for use in temp)
};

static void	orderstmt(Node*, Order*);
static void	orderstmtlist(NodeList*, Order*);
static void	orderblock(NodeList **l);
static void	orderexpr(Node**, Order*);
static void orderexprinplace(Node**, Order*);
static void	orderexprlist(NodeList*, Order*);
static void	orderexprlistinplace(NodeList*, Order*);

// Order rewrites fn->nbody to apply the ordering constraints
// described in the comment at the top of the file.
void
order(Node *fn)
{
	orderblock(&fn->nbody);
}

// Ordertemp allocates a new temporary with the given type,
// pushes it onto the temp stack, and returns it.
// If clear is true, ordertemp emits code to zero the temporary.
static Node*
ordertemp(Type *t, Order *order, int clear)
{
	Node *var, *a;
	NodeList *l;

	var = temp(t);
	if(clear) {
		a = nod(OAS, var, N);
		typecheck(&a, Etop);
		order->out = list(order->out, a);
	}
	if((l = order->free) == nil)
		l = mal(sizeof *l);
	order->free = l->next;
	l->next = order->temp;
	l->n = var;
	order->temp = l;
	return var;
}

// Ordercopyexpr behaves like ordertemp but also emits
// code to initialize the temporary to the value n.
//
// The clear argument is provided for use when the evaluation
// of tmp = n turns into a function call that is passed a pointer
// to the temporary as the output space. If the call blocks before
// tmp has been written, the garbage collector will still treat the
// temporary as live, so we must zero it before entering that call.
// Today, this only happens for channel receive operations.
// (The other candidate would be map access, but map access
// returns a pointer to the result data instead of taking a pointer
// to be filled in.)
static Node*
ordercopyexpr(Node *n, Type *t, Order *order, int clear)
{
	Node *a, *var;

	var = ordertemp(t, order, clear);
	a = nod(OAS, var, n);
	typecheck(&a, Etop);
	order->out = list(order->out, a);
	return var;
}

// Ordercheapexpr returns a cheap version of n.
// The definition of cheap is that n is a variable or constant.
// If not, ordercheapexpr allocates a new tmp, emits tmp = n,
// and then returns tmp.
static Node*
ordercheapexpr(Node *n, Order *order)
{
	switch(n->op) {
	case ONAME:
	case OLITERAL:
		return n;
	}
	return ordercopyexpr(n, n->type, order, 0);
}

// Ordersafeexpr returns a safe version of n.
// The definition of safe is that n can appear multiple times
// without violating the semantics of the original program,
// and that assigning to the safe version has the same effect
// as assigning to the original n.
//
// The intended use is to apply to x when rewriting x += y into x = x + y.
static Node*
ordersafeexpr(Node *n, Order *order)
{
	Node *l, *r, *a;
	
	switch(n->op) {
	default:
		fatal("ordersafeexpr %O", n->op);

	case ONAME:
	case OLITERAL:
		return n;

	case ODOT:
		l = ordersafeexpr(n->left, order);
		if(l == n->left)
			return n;
		a = nod(OXXX, N, N);
		*a = *n;
		a->orig = a;
		a->left = l;
		typecheck(&a, Erv);
		return a;

	case ODOTPTR:
	case OIND:
		l = ordercheapexpr(n->left, order);
		if(l == n->left)
			return n;
		a = nod(OXXX, N, N);
		*a = *n;
		a->orig = a;
		a->left = l;
		typecheck(&a, Erv);
		return a;
		
	case OINDEX:
	case OINDEXMAP:
		if(isfixedarray(n->left->type))
			l = ordersafeexpr(n->left, order);
		else
			l = ordercheapexpr(n->left, order);
		r = ordercheapexpr(n->right, order);
		if(l == n->left && r == n->right)
			return n;
		a = nod(OXXX, N, N);
		*a = *n;
		a->orig = a;
		a->left = l;
		a->right = r;
		typecheck(&a, Erv);
		return a;
	}
}		

// Istemp reports whether n is a temporary variable.
static int
istemp(Node *n)
{
	if(n->op != ONAME)
		return 0;
	return strncmp(n->sym->name, "autotmp_", 8) == 0;
}

// Isaddrokay reports whether it is okay to pass n's address to runtime routines.
// Taking the address of a variable makes the liveness and optimization analyses
// lose track of where the variable's lifetime ends. To avoid hurting the analyses
// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
// because we emit explicit VARKILL instructions marking the end of those
// temporaries' lifetimes.
static int
isaddrokay(Node *n)
{
	return islvalue(n) && (n->op != ONAME || n->class == PEXTERN || istemp(n));
}

// Orderaddrtemp ensures that *np is okay to pass by address to runtime routines.
// If the original argument *np is not okay, orderaddrtemp creates a tmp, emits
// tmp = *np, and then sets *np to the tmp variable.
static void
orderaddrtemp(Node **np, Order *order)
{
	Node *n;
	
	n = *np;
	if(isaddrokay(n))
		return;
	*np = ordercopyexpr(n, n->type, order, 0);
}

// Marktemp returns the top of the temporary variable stack.
static NodeList*
marktemp(Order *order)
{
	return order->temp;
}

// Poptemp pops temporaries off the stack until reaching the mark,
// which must have been returned by marktemp.
static void
poptemp(NodeList *mark, Order *order)
{
	NodeList *l;

	while((l = order->temp) != mark) {
		order->temp = l->next;
		l->next = order->free;
		order->free = l;
	}
}

// Cleantempnopop emits to *out VARKILL instructions for each temporary
// above the mark on the temporary stack, but it does not pop them
// from the stack.
static void
cleantempnopop(NodeList *mark, Order *order, NodeList **out)
{
	NodeList *l;
	Node *kill;

	for(l=order->temp; l != mark; l=l->next) {
		kill = nod(OVARKILL, l->n, N);
		typecheck(&kill, Etop);
		*out = list(*out, kill);
	}
}

// Cleantemp emits VARKILL instructions for each temporary above the
// mark on the temporary stack and removes them from the stack.
static void
cleantemp(NodeList *top, Order *order)
{
	cleantempnopop(top, order, &order->out);
	poptemp(top, order);
}

// Orderstmtlist orders each of the statements in the list.
static void
orderstmtlist(NodeList *l, Order *order)
{
	for(; l; l=l->next)
		orderstmt(l->n, order);
}

// Orderblock orders the block of statements *l onto a new list,
// and then replaces *l with that list.
static void
orderblock(NodeList **l)
{
	Order order;
	NodeList *mark;
	
	memset(&order, 0, sizeof order);
	mark = marktemp(&order);
	orderstmtlist(*l, &order);
	cleantemp(mark, &order);
	*l = order.out;
}

// Orderexprinplace orders the side effects in *np and
// leaves them as the init list of the final *np.
static void
orderexprinplace(Node **np, Order *outer)
{
	Node *n;
	NodeList **lp;
	Order order;
	
	n = *np;
	memset(&order, 0, sizeof order);
	orderexpr(&n, &order);
	addinit(&n, order.out);
	
	// insert new temporaries from order
	// at head of outer list.
	lp = &order.temp;
	while(*lp != nil)
		lp = &(*lp)->next;
	*lp = outer->temp;
	outer->temp = order.temp;

	*np = n;
}

// Orderstmtinplace orders the side effects of the single statement *np
// and replaces it with the resulting statement list.
static void
orderstmtinplace(Node **np)
{
	Node *n;
	Order order;
	NodeList *mark;
	
	n = *np;
	memset(&order, 0, sizeof order);
	mark = marktemp(&order);
	orderstmt(n, &order);
	cleantemp(mark, &order);
	*np = liststmt(order.out);
}

// Orderinit moves n's init list to order->out.
static void
orderinit(Node *n, Order *order)
{
	orderstmtlist(n->ninit, order);
	n->ninit = nil;
}

// Ismulticall reports whether the list l is f() for a multi-value function.
// Such an f() could appear as the lone argument to a multi-arg function.
static int
ismulticall(NodeList *l)
{
	Node *n;
	
	// one arg only
	if(l == nil || l->next != nil)
		return 0;
	n = l->n;
	
	// must be call
	switch(n->op) {
	default:
		return 0;
	case OCALLFUNC:
	case OCALLMETH:
	case OCALLINTER:
		break;
	}
	
	// call must return multiple values
	return n->left->type->outtuple > 1;
}

// Copyret emits t1, t2, ... = n, where n is a function call,
// and then returns the list t1, t2, ....
static NodeList*
copyret(Node *n, Order *order)
{
	Type *t;
	Node *tmp, *as;
	NodeList *l1, *l2;
	Iter tl;
	
	if(n->type->etype != TSTRUCT || !n->type->funarg)
		fatal("copyret %T %d", n->type, n->left->type->outtuple);

	l1 = nil;
	l2 = nil;
	for(t=structfirst(&tl, &n->type); t; t=structnext(&tl)) {
		tmp = temp(t->type);
		l1 = list(l1, tmp);
		l2 = list(l2, tmp);
	}
	
	as = nod(OAS2, N, N);
	as->list = l1;
	as->rlist = list1(n);
	typecheck(&as, Etop);
	orderstmt(as, order);

	return l2;
}

// Ordercallargs orders the list of call arguments *l.
static void
ordercallargs(NodeList **l, Order *order)
{
	if(ismulticall(*l)) {
		// return f() where f() is multiple values.
		*l = copyret((*l)->n, order);
	} else {
		orderexprlist(*l, order);
	}
}

// Ordercall orders the call expression n.
// n->op is  OCALLMETH/OCALLFUNC/OCALLINTER.
static void
ordercall(Node *n, Order *order, int special)
{
	orderexpr(&n->left, order);
	ordercallargs(&n->list, order);
	if(!special)
		orderexpr(&n->right, order); // ODDDARG temp
}

// Ordermapassign appends n to order->out, introducing temporaries
// to make sure that all map assignments have the form m[k] = x,
// where x is adressable.
// (Orderexpr has already been called on n, so we know k is addressable.)
//
// If n is m[k] = x where x is not addressable, the rewrite is:
//	tmp = x
//	m[k] = tmp
//
// If n is the multiple assignment form ..., m[k], ... = ..., the rewrite is
//	t1 = m
//	t2 = k
//	...., t3, ... = x
//	t1[t2] = t3
//
// The temporaries t1, t2 are needed in case the ... being assigned
// contain m or k. They are usually unnecessary, but in the unnecessary
// cases they are also typically registerizable, so not much harm done.
// And this only applies to the multiple-assignment form.
// We could do a more precise analysis if needed, like in walk.c.
static void
ordermapassign(Node *n, Order *order)
{
	Node *m, *a;
	NodeList *l;
	NodeList *post;

	switch(n->op) {
	default:
		fatal("ordermapassign %O", n->op);

	case OAS:
		order->out = list(order->out, n);
		if(n->left->op == OINDEXMAP && !isaddrokay(n->right)) {
			m = n->left;
			n->left = ordertemp(m->type, order, 0);
			a = nod(OAS, m, n->left);
			typecheck(&a, Etop);
			order->out = list(order->out, a);
		}
		break;

	case OAS2:
	case OAS2DOTTYPE:
	case OAS2MAPR:
	case OAS2FUNC:
		post = nil;
		for(l=n->list; l != nil; l=l->next) {
			if(l->n->op == OINDEXMAP) {
				m = l->n;
				if(!istemp(m->left))
					m->left = ordercopyexpr(m->left, m->left->type, order, 0);
				if(!istemp(m->right))
					m->right = ordercopyexpr(m->right, m->right->type, order, 0);
				l->n = ordertemp(m->type, order, 0);
				a = nod(OAS, m, l->n);
				typecheck(&a, Etop);
				post = list(post, a);
			}
		}
		order->out = list(order->out, n);
		order->out = concat(order->out, post);
		break;
	}
}

// Orderstmt orders the statement n, appending to order->out.
// Temporaries created during the statement are cleaned
// up using VARKILL instructions as possible.
static void
orderstmt(Node *n, Order *order)
{
	int lno;
	NodeList *l, *t, *t1;
	Node *r, *tmp1, *tmp2, **np;
	Type *ch;

	if(n == N)
		return;

	lno = setlineno(n);

	orderinit(n, order);

	switch(n->op) {
	default:
		fatal("orderstmt %O", n->op);

	case OVARKILL:
		order->out = list(order->out, n);
		break;

	case OAS:
	case OAS2:
	case OAS2DOTTYPE:
	case OCLOSE:
	case OCOPY:
	case OPRINT:
	case OPRINTN:
	case ORECOVER:
	case ORECV:
		t = marktemp(order);
		orderexpr(&n->left, order);
		orderexpr(&n->right, order);
		orderexprlist(n->list, order);
		orderexprlist(n->rlist, order);
		switch(n->op) {
		case OAS:
		case OAS2:
		case OAS2DOTTYPE:
			ordermapassign(n, order);
			break;
		default:
			order->out = list(order->out, n);
			break;
		}
		cleantemp(t, order);
		break;

	case OASOP:
		// Special: rewrite l op= r into l = l op r.
		// This simplies quite a few operations;
		// most important is that it lets us separate
		// out map read from map write when l is
		// a map index expression.
		t = marktemp(order);
		orderexpr(&n->left, order);
		n->left = ordersafeexpr(n->left, order);
		tmp1 = treecopy(n->left);
		if(tmp1->op == OINDEXMAP)
			tmp1->etype = 0; // now an rvalue not an lvalue
		tmp1 = ordercopyexpr(tmp1, n->left->type, order, 0);
		n->right = nod(n->etype, tmp1, n->right);
		typecheck(&n->right, Erv);
		orderexpr(&n->right, order);
		n->etype = 0;
		n->op = OAS;
		ordermapassign(n, order);
		cleantemp(t, order);
		break;

	case OAS2MAPR:
		// Special: make sure key is addressable,
		// and make sure OINDEXMAP is not copied out.
		t = marktemp(order);
		orderexprlist(n->list, order);
		r = n->rlist->n;
		orderexpr(&r->left, order);
		orderexpr(&r->right, order);
		// See case OINDEXMAP below.
		if(r->right->op == OARRAYBYTESTR)
			r->right->op = OARRAYBYTESTRTMP;
		orderaddrtemp(&r->right, order);
		ordermapassign(n, order);
		cleantemp(t, order);
		break;

	case OAS2FUNC:
		// Special: avoid copy of func call n->rlist->n.
		t = marktemp(order);
		orderexprlist(n->list, order);
		ordercall(n->rlist->n, order, 0);
		ordermapassign(n, order);
		cleantemp(t, order);
		break;

	case OAS2RECV:
		// Special: avoid copy of receive.
		// Use temporary variables to hold result,
		// so that chanrecv can take address of temporary.
		t = marktemp(order);
		orderexprlist(n->list, order);
		orderexpr(&n->rlist->n->left, order);  // arg to recv
		ch = n->rlist->n->left->type;
		tmp1 = ordertemp(ch->type, order, haspointers(ch->type));
		tmp2 = ordertemp(types[TBOOL], order, 0);
		order->out = list(order->out, n);
		r = nod(OAS, n->list->n, tmp1);
		typecheck(&r, Etop);
		ordermapassign(r, order);
		r = nod(OAS, n->list->next->n, tmp2);
		typecheck(&r, Etop);
		ordermapassign(r, order);
		n->list = list(list1(tmp1), tmp2);
		cleantemp(t, order);
		break;

	case OBLOCK:
	case OEMPTY:
		// Special: does not save n onto out.
		orderstmtlist(n->list, order);
		break;

	case OBREAK:
	case OCONTINUE:
	case ODCL:
	case ODCLCONST:
	case ODCLTYPE:
	case OFALL:
	case OXFALL:
	case OGOTO:
	case OLABEL:
	case ORETJMP:
		// Special: n->left is not an expression; save as is.
		order->out = list(order->out, n);
		break;

	case OCALLFUNC:
	case OCALLINTER:
	case OCALLMETH:
		// Special: handle call arguments.
		t = marktemp(order);
		ordercall(n, order, 0);
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;

	case ODEFER:
	case OPROC:
		// Special: order arguments to inner call but not call itself.
		t = marktemp(order);
		switch(n->left->op) {
		case ODELETE:
			// Delete will take the address of the key.
			// Copy key into new temp and do not clean it
			// (it persists beyond the statement).
			orderexprlist(n->left->list, order);
			t1 = marktemp(order);
			np = &n->left->list->next->n; // map key
			*np = ordercopyexpr(*np, (*np)->type, order, 0);
			poptemp(t1, order);
			break;
		default:
			ordercall(n->left, order, 1);
			break;
		}
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;

	case ODELETE:
		t = marktemp(order);
		orderexpr(&n->list->n, order);
		orderexpr(&n->list->next->n, order);
		orderaddrtemp(&n->list->next->n, order); // map key
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;

	case OFOR:
		// Clean temporaries from condition evaluation at
		// beginning of loop body and after for statement.
		t = marktemp(order);
		orderexprinplace(&n->ntest, order);
		l = nil;
		cleantempnopop(t, order, &l);
		n->nbody = concat(l, n->nbody);
		orderblock(&n->nbody);
		orderstmtinplace(&n->nincr);
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;
		
	case OIF:
		// Clean temporaries from condition at
		// beginning of both branches.
		t = marktemp(order);
		orderexprinplace(&n->ntest, order);
		l = nil;
		cleantempnopop(t, order, &l);
		n->nbody = concat(l, n->nbody);
		l = nil;
		cleantempnopop(t, order, &l);
		n->nelse = concat(l, n->nelse);
		poptemp(t, order);
		orderblock(&n->nbody);
		orderblock(&n->nelse);
		order->out = list(order->out, n);
		break;

	case OPANIC:
		// Special: argument will be converted to interface using convT2E
		// so make sure it is an addressable temporary.
		t = marktemp(order);
		orderexpr(&n->left, order);
		if(!isinter(n->left->type))
			orderaddrtemp(&n->left, order);
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;

	case ORANGE:
		// n->right is the expression being ranged over.
		// order it, and then make a copy if we need one.
		// We almost always do, to ensure that we don't
		// see any value changes made during the loop.
		// Usually the copy is cheap (e.g., array pointer, chan, slice, string are all tiny).
		// The exception is ranging over an array value (not a slice, not a pointer to array),
		// which must make a copy to avoid seeing updates made during
		// the range body. Ranging over an array value is uncommon though.
		t = marktemp(order);
		orderexpr(&n->right, order);
		switch(n->type->etype) {
		default:
			fatal("orderstmt range %T", n->type);
		case TARRAY:
			if(count(n->list) < 2 || isblank(n->list->next->n)) {
				// for i := range x will only use x once, to compute len(x).
				// No need to copy it.
				break;
			}
			// fall through
		case TCHAN:
		case TSTRING:
			// chan, string, slice, array ranges use value multiple times.
			// make copy.
			r = n->right;
			if(r->type->etype == TSTRING && r->type != types[TSTRING]) {
				r = nod(OCONV, r, N);
				r->type = types[TSTRING];
				typecheck(&r, Erv);
			}
			n->right = ordercopyexpr(r, r->type, order, 0);
			break;
		case TMAP:
			// copy the map value in case it is a map literal.
			// TODO(rsc): Make tmp = literal expressions reuse tmp.
			// For maps tmp is just one word so it hardly matters.
			r = n->right;
			n->right = ordercopyexpr(r, r->type, order, 0);
			// n->alloc is the temp for the iterator.
			n->alloc = ordertemp(types[TUINT8], order, 1);
			break;
		}
		for(l=n->list; l; l=l->next)
			orderexprinplace(&l->n, order);
		orderblock(&n->nbody);
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;

	case ORETURN:
		ordercallargs(&n->list, order);
		order->out = list(order->out, n);
		break;
	
	case OSELECT:
		// Special: clean case temporaries in each block entry.
		// Select must enter one of its blocks, so there is no
		// need for a cleaning at the end.
		t = marktemp(order);
		for(l=n->list; l; l=l->next) {
			if(l->n->op != OXCASE)
				fatal("order select case %O", l->n->op);
			r = l->n->left;
			setlineno(l->n);
			// Append any new body prologue to ninit.
			// The next loop will insert ninit into nbody.
			if(l->n->ninit != nil)
				fatal("order select ninit");
			if(r != nil) {
				switch(r->op) {
				default:
					yyerror("unknown op in select %O", r->op);
					dump("select case", r);
					break;

				case OSELRECV:
				case OSELRECV2:
					// If this is case x := <-ch or case x, y := <-ch, the case has
					// the ODCL nodes to declare x and y. We want to delay that
					// declaration (and possible allocation) until inside the case body.
					// Delete the ODCL nodes here and recreate them inside the body below.
					if(r->colas) {
						t = r->ninit;
						if(t != nil && t->n->op == ODCL && t->n->left == r->left)
							t = t->next;
						if(t != nil && t->n->op == ODCL && t->n->left == r->ntest)
							t = t->next;
						if(t == nil)
							r->ninit = nil;
					}
					if(r->ninit != nil) {
						yyerror("ninit on select recv");
						dumplist("ninit", r->ninit);
					}
					// case x = <-c
					// case x, ok = <-c
					// r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c.
					// r->left == N means 'case <-c'.
					// c is always evaluated; x and ok are only evaluated when assigned.
					orderexpr(&r->right->left, order);

					// Introduce temporary for receive and move actual copy into case body.
					// avoids problems with target being addressed, as usual.
					// NOTE: If we wanted to be clever, we could arrange for just one
					// temporary per distinct type, sharing the temp among all receives
					// with that temp. Similarly one ok bool could be shared among all
					// the x,ok receives. Not worth doing until there's a clear need.
					if(r->left != N && isblank(r->left))
						r->left = N;
					if(r->left != N) {
						// use channel element type for temporary to avoid conversions,
						// such as in case interfacevalue = <-intchan.
						// the conversion happens in the OAS instead.
						tmp1 = r->left;
						if(r->colas) {
							tmp2 = nod(ODCL, tmp1, N);
							typecheck(&tmp2, Etop);
							l->n->ninit = list(l->n->ninit, tmp2);
						}
						r->left = ordertemp(r->right->left->type->type, order, haspointers(r->right->left->type->type));
						tmp2 = nod(OAS, tmp1, r->left);
						typecheck(&tmp2, Etop);
						l->n->ninit = list(l->n->ninit, tmp2);
					}
					if(r->ntest != N && isblank(r->ntest))
						r->ntest = N;
					if(r->ntest != N) {
						tmp1 = r->ntest;
						if(r->colas) {
							tmp2 = nod(ODCL, tmp1, N);
							typecheck(&tmp2, Etop);
							l->n->ninit = list(l->n->ninit, tmp2);
						}
						r->ntest = ordertemp(tmp1->type, order, 0);
						tmp2 = nod(OAS, tmp1, r->ntest);
						typecheck(&tmp2, Etop);
						l->n->ninit = list(l->n->ninit, tmp2);
					}
					orderblock(&l->n->ninit);
					break;

				case OSEND:
					if(r->ninit != nil) {
						yyerror("ninit on select send");
						dumplist("ninit", r->ninit);
					}
					// case c <- x
					// r->left is c, r->right is x, both are always evaluated.
					orderexpr(&r->left, order);
					if(!istemp(r->left))
						r->left = ordercopyexpr(r->left, r->left->type, order, 0);
					orderexpr(&r->right, order);
					if(!istemp(r->right))
						r->right = ordercopyexpr(r->right, r->right->type, order, 0);
					break;
				}
			}
			orderblock(&l->n->nbody);
		}
		// Now that we have accumulated all the temporaries, clean them.
		// Also insert any ninit queued during the previous loop.
		// (The temporary cleaning must follow that ninit work.)
		for(l=n->list; l; l=l->next) {
			cleantempnopop(t, order, &l->n->ninit);
			l->n->nbody = concat(l->n->ninit, l->n->nbody);
			l->n->ninit = nil;
		}
		order->out = list(order->out, n);
		poptemp(t, order);
		break;

	case OSEND:
		// Special: value being sent is passed as a pointer; make it addressable.
		t = marktemp(order);
		orderexpr(&n->left, order);
		orderexpr(&n->right, order);
		orderaddrtemp(&n->right, order);
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;

	case OSWITCH:
		// TODO(rsc): Clean temporaries more aggressively.
		// Note that because walkswitch will rewrite some of the
		// switch into a binary search, this is not as easy as it looks.
		// (If we ran that code here we could invoke orderstmt on
		// the if-else chain instead.)
		// For now just clean all the temporaries at the end.
		// In practice that's fine.
		t = marktemp(order);
		orderexpr(&n->ntest, order);
		for(l=n->list; l; l=l->next) {
			if(l->n->op != OXCASE)
				fatal("order switch case %O", l->n->op);
			orderexprlistinplace(l->n->list, order);
			orderblock(&l->n->nbody);
		}
		order->out = list(order->out, n);
		cleantemp(t, order);
		break;
	}
	
	lineno = lno;
}

// Orderexprlist orders the expression list l into order.
static void
orderexprlist(NodeList *l, Order *order)
{
	for(; l; l=l->next)
		orderexpr(&l->n, order);
}

// Orderexprlist orders the expression list l but saves
// the side effects on the individual expression ninit lists.
static void
orderexprlistinplace(NodeList *l, Order *order)
{
	for(; l; l=l->next)
		orderexprinplace(&l->n, order);
}

// Orderexpr orders a single expression, appending side
// effects to order->out as needed.
static void
orderexpr(Node **np, Order *order)
{
	Node *n;
	NodeList *mark, *l;
	Type *t;
	int lno;

	n = *np;
	if(n == N)
		return;

	lno = setlineno(n);
	orderinit(n, order);

	switch(n->op) {
	default:
		orderexpr(&n->left, order);
		orderexpr(&n->right, order);
		orderexprlist(n->list, order);
		orderexprlist(n->rlist, order);
		break;
	
	case OADDSTR:
		// Addition of strings turns into a function call.
		// Allocate a temporary to hold the strings.
		// Fewer than 5 strings use direct runtime helpers.
		orderexprlist(n->list, order);
		if(count(n->list) > 5) {
			t = typ(TARRAY);
			t->bound = count(n->list);
			t->type = types[TSTRING];
			n->alloc = ordertemp(t, order, 0);
		}
		break;

	case OINDEXMAP:
		// key must be addressable
		orderexpr(&n->left, order);
		orderexpr(&n->right, order);

		// For x = m[string(k)] where k is []byte, the allocation of
		// backing bytes for the string can be avoided by reusing
		// the []byte backing array. This is a special case that it
		// would be nice to handle more generally, but because
		// there are no []byte-keyed maps, this specific case comes
		// up in important cases in practice. See issue 3512.
		// Nothing can change the []byte we are not copying before
		// the map index, because the map access is going to
		// be forced to happen immediately following this
		// conversion (by the ordercopyexpr a few lines below).
		if(n->etype == 0 && n->right->op == OARRAYBYTESTR)
			n->right->op = OARRAYBYTESTRTMP;

		orderaddrtemp(&n->right, order);
		if(n->etype == 0) {
			// use of value (not being assigned);
			// make copy in temporary.
			n = ordercopyexpr(n, n->type, order, 0);
		}
		break;
	
	case OCONVIFACE:
		// concrete type (not interface) argument must be addressable
		// temporary to pass to runtime.
		orderexpr(&n->left, order);
		if(!isinter(n->left->type))
			orderaddrtemp(&n->left, order);
		break;
	
	case OANDAND:
	case OOROR:
		mark = marktemp(order);
		orderexpr(&n->left, order);
		// Clean temporaries from first branch at beginning of second.
		// Leave them on the stack so that they can be killed in the outer
		// context in case the short circuit is taken.
		l = nil;
		cleantempnopop(mark, order, &l);
		n->right->ninit = concat(l, n->right->ninit);
		orderexprinplace(&n->right, order);
		break;
	
	case OCALLFUNC:
	case OCALLMETH:
	case OCALLINTER:
	case OAPPEND:
	case OCOMPLEX:
		ordercall(n, order, 0);
		n = ordercopyexpr(n, n->type, order, 0);
		break;

	case OCLOSURE:
		if(n->noescape && n->cvars != nil)
			n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type
		break;

	case OARRAYLIT:
	case OCALLPART:
		orderexpr(&n->left, order);
		orderexpr(&n->right, order);
		orderexprlist(n->list, order);
		orderexprlist(n->rlist, order);
		if(n->noescape)
			n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type
		break;

	case ODDDARG:
		if(n->noescape) {
			// The ddd argument does not live beyond the call it is created for.
			// Allocate a temporary that will be cleaned up when this statement
			// completes. We could be more aggressive and try to arrange for it
			// to be cleaned up when the call completes.
			n->alloc = ordertemp(n->type->type, order, 0);
		}
		break;

	case ORECV:
		orderexpr(&n->left, order);
		n = ordercopyexpr(n, n->type, order, 1);
		break;
	}
	
	lineno = lno;

	*np = n;
}
