github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/gc/order.c (about)

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