github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/src/cmd/gc/walk.c (about)

     1  // Copyright 2009 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  #include	<u.h>
     6  #include	<libc.h>
     7  #include	"go.h"
     8  #include	"../ld/textflag.h"
     9  #include	"../../runtime/mgc0.h"
    10  
    11  static	Node*	walkprint(Node*, NodeList**);
    12  static	Node*	writebarrierfn(char*, Type*, Type*);
    13  static	Node*	applywritebarrier(Node*, NodeList**);
    14  static	Node*	mapfn(char*, Type*);
    15  static	Node*	mapfndel(char*, Type*);
    16  static	Node*	ascompatee1(int, Node*, Node*, NodeList**);
    17  static	NodeList*	ascompatee(int, NodeList*, NodeList*, NodeList**);
    18  static	NodeList*	ascompatet(int, NodeList*, Type**, int, NodeList**);
    19  static	NodeList*	ascompatte(int, Node*, int, Type**, NodeList*, int, NodeList**);
    20  static	Node*	convas(Node*, NodeList**);
    21  static	void	heapmoves(void);
    22  static	NodeList*	paramstoheap(Type **argin, int out);
    23  static	NodeList*	reorder1(NodeList*);
    24  static	NodeList*	reorder3(NodeList*);
    25  static	Node*	addstr(Node*, NodeList**);
    26  static	Node*	appendslice(Node*, NodeList**);
    27  static	Node*	append(Node*, NodeList**);
    28  static	Node*	copyany(Node*, NodeList**, int);
    29  static	Node*	sliceany(Node*, NodeList**);
    30  static	void	walkcompare(Node**, NodeList**);
    31  static	void	walkrotate(Node**);
    32  static	void	walkmul(Node**, NodeList**);
    33  static	void	walkdiv(Node**, NodeList**);
    34  static	int	bounded(Node*, int64);
    35  static	Mpint	mpzero;
    36  static	void	walkprintfunc(Node**, NodeList**);
    37  
    38  void
    39  walk(Node *fn)
    40  {
    41  	char s[50];
    42  	NodeList *l;
    43  	int lno;
    44  
    45  	curfn = fn;
    46  
    47  	if(debug['W']) {
    48  		snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
    49  		dumplist(s, curfn->nbody);
    50  	}
    51  
    52  	lno = lineno;
    53  
    54  	// Final typecheck for any unused variables.
    55  	// It's hard to be on the heap when not-used, but best to be consistent about &~PHEAP here and below.
    56  	for(l=fn->dcl; l; l=l->next)
    57  		if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO)
    58  			typecheck(&l->n, Erv | Easgn);
    59  
    60  	// Propagate the used flag for typeswitch variables up to the NONAME in it's definition.
    61  	for(l=fn->dcl; l; l=l->next)
    62  		if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO && l->n->defn && l->n->defn->op == OTYPESW && l->n->used)
    63  			l->n->defn->left->used++;
    64  	
    65  	for(l=fn->dcl; l; l=l->next) {
    66  		if(l->n->op != ONAME || (l->n->class&~PHEAP) != PAUTO || l->n->sym->name[0] == '&' || l->n->used)
    67  			continue;
    68  		if(l->n->defn && l->n->defn->op == OTYPESW) {
    69  			if(l->n->defn->left->used)
    70  				continue;
    71  			lineno = l->n->defn->left->lineno;
    72  			yyerror("%S declared and not used", l->n->sym);
    73  			l->n->defn->left->used = 1; // suppress repeats
    74  		} else {
    75  			lineno = l->n->lineno;
    76  			yyerror("%S declared and not used", l->n->sym);
    77  		}
    78  	}	
    79  
    80  	lineno = lno;
    81  	if(nerrors != 0)
    82  		return;
    83  	walkstmtlist(curfn->nbody);
    84  	if(debug['W']) {
    85  		snprint(s, sizeof(s), "after walk %S", curfn->nname->sym);
    86  		dumplist(s, curfn->nbody);
    87  	}
    88  	heapmoves();
    89  	if(debug['W'] && curfn->enter != nil) {
    90  		snprint(s, sizeof(s), "enter %S", curfn->nname->sym);
    91  		dumplist(s, curfn->enter);
    92  	}
    93  }
    94  
    95  
    96  void
    97  walkstmtlist(NodeList *l)
    98  {
    99  	for(; l; l=l->next)
   100  		walkstmt(&l->n);
   101  }
   102  
   103  static int
   104  samelist(NodeList *a, NodeList *b)
   105  {
   106  	for(; a && b; a=a->next, b=b->next)
   107  		if(a->n != b->n)
   108  			return 0;
   109  	return a == b;
   110  }
   111  
   112  static int
   113  paramoutheap(Node *fn)
   114  {
   115  	NodeList *l;
   116  
   117  	for(l=fn->dcl; l; l=l->next) {
   118  		switch(l->n->class) {
   119  		case PPARAMOUT:
   120  		case PPARAMOUT|PHEAP:
   121  			return l->n->addrtaken;
   122  		case PAUTO:
   123  		case PAUTO|PHEAP:
   124  			// stop early - parameters are over
   125  			return 0;
   126  		}
   127  	}
   128  	return 0;
   129  }
   130  
   131  // adds "adjust" to all the argument locations for the call n.
   132  // n must be a defer or go node that has already been walked.
   133  static void
   134  adjustargs(Node *n, int adjust)
   135  {
   136  	Node *callfunc, *arg, *lhs;
   137  	NodeList *args;
   138  
   139  	callfunc = n->left;
   140  	for(args = callfunc->list; args != 0; args = args->next) {
   141  		arg = args->n;
   142  		if(arg->op != OAS)
   143  			yyerror("call arg not assignment");
   144  		lhs = arg->left;
   145  		if(lhs->op == ONAME) {
   146  			// This is a temporary introduced by reorder1.
   147  			// The real store to the stack appears later in the arg list.
   148  			continue;
   149  		}
   150  		if(lhs->op != OINDREG) {
   151  			yyerror("call argument store does not use OINDREG");
   152  		}
   153  		// can't really check this in machine-indep code.
   154  		//if(lhs->val.u.reg != D_SP)
   155  		//      yyerror("call arg assign not indreg(SP)");
   156  		lhs->xoffset += adjust;
   157  	}
   158  }
   159  
   160  void
   161  walkstmt(Node **np)
   162  {
   163  	NodeList *init;
   164  	NodeList *ll, *rl;
   165  	int cl;
   166  	Node *n, *f;
   167  
   168  	n = *np;
   169  	if(n == N)
   170  		return;
   171  	if(n->dodata == 2) // don't walk, generated by anylit.
   172  		return;
   173  
   174  	setlineno(n);
   175  
   176  	walkstmtlist(n->ninit);
   177  
   178  	switch(n->op) {
   179  	default:
   180  		if(n->op == ONAME)
   181  			yyerror("%S is not a top level statement", n->sym);
   182  		else
   183  			yyerror("%O is not a top level statement", n->op);
   184  		dump("nottop", n);
   185  		break;
   186  
   187  	case OAS:
   188  	case OASOP:
   189  	case OAS2:
   190  	case OAS2DOTTYPE:
   191  	case OAS2RECV:
   192  	case OAS2FUNC:
   193  	case OAS2MAPR:
   194  	case OCLOSE:
   195  	case OCOPY:
   196  	case OCALLMETH:
   197  	case OCALLINTER:
   198  	case OCALL:
   199  	case OCALLFUNC:
   200  	case ODELETE:
   201  	case OSEND:
   202  	case OPRINT:
   203  	case OPRINTN:
   204  	case OPANIC:
   205  	case OEMPTY:
   206  	case ORECOVER:
   207  		if(n->typecheck == 0)
   208  			fatal("missing typecheck: %+N", n);
   209  		init = n->ninit;
   210  		n->ninit = nil;
   211  		walkexpr(&n, &init);
   212  		addinit(&n, init);
   213  		if((*np)->op == OCOPY && n->op == OCONVNOP)
   214  			n->op = OEMPTY; // don't leave plain values as statements.
   215  		break;
   216  
   217  	case ORECV:
   218  		// special case for a receive where we throw away
   219  		// the value received.
   220  		if(n->typecheck == 0)
   221  			fatal("missing typecheck: %+N", n);
   222  		init = n->ninit;
   223  		n->ninit = nil;
   224  
   225  		walkexpr(&n->left, &init);
   226  		n = mkcall1(chanfn("chanrecv1", 2, n->left->type), T, &init, typename(n->left->type), n->left, nodnil());
   227  		walkexpr(&n, &init);
   228  
   229  		addinit(&n, init);
   230  		break;
   231  
   232  	case OBREAK:
   233  	case ODCL:
   234  	case OCONTINUE:
   235  	case OFALL:
   236  	case OGOTO:
   237  	case OLABEL:
   238  	case ODCLCONST:
   239  	case ODCLTYPE:
   240  	case OCHECKNIL:
   241  	case OVARKILL:
   242  		break;
   243  
   244  	case OBLOCK:
   245  		walkstmtlist(n->list);
   246  		break;
   247  
   248  	case OXCASE:
   249  		yyerror("case statement out of place");
   250  		n->op = OCASE;
   251  	case OCASE:
   252  		walkstmt(&n->right);
   253  		break;
   254  
   255  	case ODEFER:
   256  		hasdefer = 1;
   257  		switch(n->left->op) {
   258  		case OPRINT:
   259  		case OPRINTN:
   260  			walkprintfunc(&n->left, &n->ninit);
   261  			break;
   262  		case OCOPY:
   263  			n->left = copyany(n->left, &n->ninit, 1);
   264  			break;
   265  		default:
   266  			walkexpr(&n->left, &n->ninit);
   267  			break;
   268  		}
   269  		// make room for size & fn arguments.
   270  		adjustargs(n, 2 * widthptr);
   271  		break;
   272  
   273  	case OFOR:
   274  		if(n->ntest != N) {
   275  			walkstmtlist(n->ntest->ninit);
   276  			init = n->ntest->ninit;
   277  			n->ntest->ninit = nil;
   278  			walkexpr(&n->ntest, &init);
   279  			addinit(&n->ntest, init);
   280  		}
   281  		walkstmt(&n->nincr);
   282  		walkstmtlist(n->nbody);
   283  		break;
   284  
   285  	case OIF:
   286  		walkexpr(&n->ntest, &n->ninit);
   287  		walkstmtlist(n->nbody);
   288  		walkstmtlist(n->nelse);
   289  		break;
   290  
   291  	case OPROC:
   292  		switch(n->left->op) {
   293  		case OPRINT:
   294  		case OPRINTN:
   295  			walkprintfunc(&n->left, &n->ninit);
   296  			break;
   297  		case OCOPY:
   298  			n->left = copyany(n->left, &n->ninit, 1);
   299  			break;
   300  		default:
   301  			walkexpr(&n->left, &n->ninit);
   302  			break;
   303  		}
   304  		// make room for size & fn arguments.
   305  		adjustargs(n, 2 * widthptr);
   306  		break;
   307  
   308  	case ORETURN:
   309  		walkexprlist(n->list, &n->ninit);
   310  		if(n->list == nil)
   311  			break;
   312  		if((curfn->type->outnamed && count(n->list) > 1) || paramoutheap(curfn)) {
   313  			// assign to the function out parameters,
   314  			// so that reorder3 can fix up conflicts
   315  			rl = nil;
   316  			for(ll=curfn->dcl; ll != nil; ll=ll->next) {
   317  				cl = ll->n->class & ~PHEAP;
   318  				if(cl == PAUTO)
   319  					break;
   320  				if(cl == PPARAMOUT)
   321  					rl = list(rl, ll->n);
   322  			}
   323  			if(samelist(rl, n->list)) {
   324  				// special return in disguise
   325  				n->list = nil;
   326  				break;
   327  			}
   328  			if(count(n->list) == 1 && count(rl) > 1) {
   329  				// OAS2FUNC in disguise
   330  				f = n->list->n;
   331  				if(f->op != OCALLFUNC && f->op != OCALLMETH && f->op != OCALLINTER)
   332  					fatal("expected return of call, have %N", f);
   333  				n->list = concat(list1(f), ascompatet(n->op, rl, &f->type, 0, &n->ninit));
   334  				break;
   335  			}
   336  
   337  			// move function calls out, to make reorder3's job easier.
   338  			walkexprlistsafe(n->list, &n->ninit);
   339  			ll = ascompatee(n->op, rl, n->list, &n->ninit);
   340  			n->list = reorder3(ll);
   341  			break;
   342  		}
   343  		ll = ascompatte(n->op, nil, 0, getoutarg(curfn->type), n->list, 1, &n->ninit);
   344  		n->list = ll;
   345  		break;
   346  
   347  	case ORETJMP:
   348  		break;
   349  
   350  	case OSELECT:
   351  		walkselect(n);
   352  		break;
   353  
   354  	case OSWITCH:
   355  		walkswitch(n);
   356  		break;
   357  
   358  	case ORANGE:
   359  		walkrange(n);
   360  		break;
   361  
   362  	case OXFALL:
   363  		yyerror("fallthrough statement out of place");
   364  		n->op = OFALL;
   365  		break;
   366  	}
   367  
   368  	if(n->op == ONAME)
   369  		fatal("walkstmt ended up with name: %+N", n);
   370  	
   371  	*np = n;
   372  }
   373  
   374  
   375  /*
   376   * walk the whole tree of the body of an
   377   * expression or simple statement.
   378   * the types expressions are calculated.
   379   * compile-time constants are evaluated.
   380   * complex side effects like statements are appended to init
   381   */
   382  
   383  void
   384  walkexprlist(NodeList *l, NodeList **init)
   385  {
   386  	for(; l; l=l->next)
   387  		walkexpr(&l->n, init);
   388  }
   389  
   390  void
   391  walkexprlistsafe(NodeList *l, NodeList **init)
   392  {
   393  	for(; l; l=l->next) {
   394  		l->n = safeexpr(l->n, init);
   395  		walkexpr(&l->n, init);
   396  	}
   397  }
   398  
   399  void
   400  walkexprlistcheap(NodeList *l, NodeList **init)
   401  {
   402  	for(; l; l=l->next) {
   403  		l->n = cheapexpr(l->n, init);
   404  		walkexpr(&l->n, init);
   405  	}
   406  }
   407  
   408  void
   409  walkexpr(Node **np, NodeList **init)
   410  {
   411  	Node *r, *l, *var, *a, *ok;
   412  	Node *map, *key;
   413  	NodeList *ll, *lr;
   414  	Type *t;
   415  	int et, old_safemode;
   416  	int64 v;
   417  	int32 lno;
   418  	Node *n, *fn, *n1, *n2;
   419  	Sym *sym;
   420  	char buf[100], *p;
   421  
   422  	n = *np;
   423  
   424  	if(n == N)
   425  		return;
   426  
   427  	if(init == &n->ninit) {
   428  		// not okay to use n->ninit when walking n,
   429  		// because we might replace n with some other node
   430  		// and would lose the init list.
   431  		fatal("walkexpr init == &n->ninit");
   432  	}
   433  
   434  	if(n->ninit != nil) {
   435  		walkstmtlist(n->ninit);
   436  		*init = concat(*init, n->ninit);
   437  		n->ninit = nil;
   438  	}
   439  
   440  	// annoying case - not typechecked
   441  	if(n->op == OKEY) {
   442  		walkexpr(&n->left, init);
   443  		walkexpr(&n->right, init);
   444  		return;
   445  	}
   446  
   447  	lno = setlineno(n);
   448  
   449  	if(debug['w'] > 1)
   450  		dump("walk-before", n);
   451  
   452  	if(n->typecheck != 1)
   453  		fatal("missed typecheck: %+N\n", n);
   454  
   455  	switch(n->op) {
   456  	default:
   457  		dump("walk", n);
   458  		fatal("walkexpr: switch 1 unknown op %+hN", n);
   459  		break;
   460  
   461  	case OTYPE:
   462  	case ONONAME:
   463  	case OINDREG:
   464  	case OEMPTY:
   465  	case OPARAM:
   466  		goto ret;
   467  
   468  	case ONOT:
   469  	case OMINUS:
   470  	case OPLUS:
   471  	case OCOM:
   472  	case OREAL:
   473  	case OIMAG:
   474  	case ODOTMETH:
   475  	case ODOTINTER:
   476  		walkexpr(&n->left, init);
   477  		goto ret;
   478  
   479  	case OIND:
   480  		walkexpr(&n->left, init);
   481  		goto ret;
   482  
   483  	case ODOT:
   484  		usefield(n);
   485  		walkexpr(&n->left, init);
   486  		goto ret;
   487  
   488  	case ODOTPTR:
   489  		usefield(n);
   490  		if(n->op == ODOTPTR && n->left->type->type->width == 0) {
   491  			// No actual copy will be generated, so emit an explicit nil check.
   492  			n->left = cheapexpr(n->left, init);
   493  			checknil(n->left, init);
   494  		}
   495  		walkexpr(&n->left, init);
   496  		goto ret;
   497  
   498  	case OEFACE:
   499  		walkexpr(&n->left, init);
   500  		walkexpr(&n->right, init);
   501  		goto ret;
   502  
   503  	case OSPTR:
   504  	case OITAB:
   505  		walkexpr(&n->left, init);
   506  		goto ret;
   507  
   508  	case OLEN:
   509  	case OCAP:
   510  		walkexpr(&n->left, init);
   511  
   512  		// replace len(*[10]int) with 10.
   513  		// delayed until now to preserve side effects.
   514  		t = n->left->type;
   515  		if(isptr[t->etype])
   516  			t = t->type;
   517  		if(isfixedarray(t)) {
   518  			safeexpr(n->left, init);
   519  			nodconst(n, n->type, t->bound);
   520  			n->typecheck = 1;
   521  		}
   522  		goto ret;
   523  
   524  	case OLSH:
   525  	case ORSH:
   526  		walkexpr(&n->left, init);
   527  		walkexpr(&n->right, init);
   528  		t = n->left->type;
   529  		n->bounded = bounded(n->right, 8*t->width);
   530  		if(debug['m'] && n->etype && !isconst(n->right, CTINT))
   531  			warn("shift bounds check elided");
   532  		goto ret;
   533  
   534  	case OAND:
   535  	case OSUB:
   536  	case OHMUL:
   537  	case OLT:
   538  	case OLE:
   539  	case OGE:
   540  	case OGT:
   541  	case OADD:
   542  	case OCOMPLEX:
   543  	case OLROT:
   544  		// Use results from call expression as arguments for complex.
   545  		if(n->op == OCOMPLEX && n->left == N && n->right == N) {
   546  			n->left = n->list->n;
   547  			n->right = n->list->next->n;
   548  		}
   549  		walkexpr(&n->left, init);
   550  		walkexpr(&n->right, init);
   551  		goto ret;
   552  
   553  	case OOR:
   554  	case OXOR:
   555  		walkexpr(&n->left, init);
   556  		walkexpr(&n->right, init);
   557  		walkrotate(&n);
   558  		goto ret;
   559  
   560  	case OEQ:
   561  	case ONE:
   562  		walkexpr(&n->left, init);
   563  		walkexpr(&n->right, init);
   564  		// Disable safemode while compiling this code: the code we
   565  		// generate internally can refer to unsafe.Pointer.
   566  		// In this case it can happen if we need to generate an ==
   567  		// for a struct containing a reflect.Value, which itself has
   568  		// an unexported field of type unsafe.Pointer.
   569  		old_safemode = safemode;
   570  		safemode = 0;
   571  		walkcompare(&n, init);
   572  		safemode = old_safemode;
   573  		goto ret;
   574  
   575  	case OANDAND:
   576  	case OOROR:
   577  		walkexpr(&n->left, init);
   578  		// cannot put side effects from n->right on init,
   579  		// because they cannot run before n->left is checked.
   580  		// save elsewhere and store on the eventual n->right.
   581  		ll = nil;
   582  		walkexpr(&n->right, &ll);
   583  		addinit(&n->right, ll);
   584  		goto ret;
   585  
   586  	case OPRINT:
   587  	case OPRINTN:
   588  		walkexprlist(n->list, init);
   589  		n = walkprint(n, init);
   590  		goto ret;
   591  
   592  	case OPANIC:
   593  		n = mkcall("gopanic", T, init, n->left);
   594  		goto ret;
   595  
   596  	case ORECOVER:
   597  		n = mkcall("gorecover", n->type, init, nod(OADDR, nodfp, N));
   598  		goto ret;
   599  
   600  	case OLITERAL:
   601  		n->addable = 1;
   602  		goto ret;
   603  
   604  	case OCLOSUREVAR:
   605  	case OCFUNC:
   606  		n->addable = 1;
   607  		goto ret;
   608  
   609  	case ONAME:
   610  		if(!(n->class & PHEAP) && n->class != PPARAMREF)
   611  			n->addable = 1;
   612  		goto ret;
   613  
   614  	case OCALLINTER:
   615  		t = n->left->type;
   616  		if(n->list && n->list->n->op == OAS)
   617  			goto ret;
   618  		walkexpr(&n->left, init);
   619  		walkexprlist(n->list, init);
   620  		ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
   621  		n->list = reorder1(ll);
   622  		goto ret;
   623  
   624  	case OCALLFUNC:
   625  		t = n->left->type;
   626  		if(n->list && n->list->n->op == OAS)
   627  			goto ret;
   628  
   629  		walkexpr(&n->left, init);
   630  		walkexprlist(n->list, init);
   631  
   632  		ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
   633  		n->list = reorder1(ll);
   634  		goto ret;
   635  
   636  	case OCALLMETH:
   637  		t = n->left->type;
   638  		if(n->list && n->list->n->op == OAS)
   639  			goto ret;
   640  		walkexpr(&n->left, init);
   641  		walkexprlist(n->list, init);
   642  		ll = ascompatte(n->op, n, 0, getthis(t), list1(n->left->left), 0, init);
   643  		lr = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
   644  		ll = concat(ll, lr);
   645  		n->left->left = N;
   646  		ullmancalc(n->left);
   647  		n->list = reorder1(ll);
   648  		goto ret;
   649  
   650  	case OAS:
   651  		*init = concat(*init, n->ninit);
   652  		n->ninit = nil;
   653  
   654  		walkexpr(&n->left, init);
   655  		n->left = safeexpr(n->left, init);
   656  
   657  		if(oaslit(n, init))
   658  			goto ret;
   659  
   660  		if(n->right == N || iszero(n->right) && !flag_race)
   661  			goto ret;
   662  
   663  		switch(n->right->op) {
   664  		default:
   665  			walkexpr(&n->right, init);
   666  			break;
   667  		
   668  		case ODOTTYPE:
   669  			// x = i.(T); n->left is x, n->right->left is i.
   670  			// orderstmt made sure x is addressable.
   671  			walkexpr(&n->right->left, init);
   672  			n1 = nod(OADDR, n->left, N);
   673  			r = n->right; // i.(T)
   674  
   675  			strcpy(buf, "assertI2T");
   676  			if(isnilinter(r->left->type))
   677  				buf[6] = 'E';
   678  			if(isnilinter(r->type))
   679  				buf[8] = 'E';
   680  			else if(isinter(r->type))
   681  				buf[8] = 'I';
   682  			
   683  			fn = syslook(buf, 1);
   684  			argtype(fn, r->left->type);
   685  			argtype(fn, r->type);
   686  		
   687  			n = mkcall1(fn, T, init, typename(r->type), r->left, n1);
   688  			walkexpr(&n, init);
   689  			goto ret;
   690  
   691  		case ORECV:
   692  			// x = <-c; n->left is x, n->right->left is c.
   693  			// orderstmt made sure x is addressable.
   694  			walkexpr(&n->right->left, init);
   695  			n1 = nod(OADDR, n->left, N);
   696  			r = n->right->left; // the channel
   697  			n = mkcall1(chanfn("chanrecv1", 2, r->type), T, init, typename(r->type), r, n1);
   698  			walkexpr(&n, init);
   699  			goto ret;
   700  		}
   701  
   702  		if(n->left != N && n->right != N) {
   703  			r = convas(nod(OAS, n->left, n->right), init);
   704  			r->dodata = n->dodata;
   705  			n = r;
   706  			n = applywritebarrier(n, init);
   707  		}
   708  
   709  		goto ret;
   710  
   711  	case OAS2:
   712  		*init = concat(*init, n->ninit);
   713  		n->ninit = nil;
   714  		walkexprlistsafe(n->list, init);
   715  		walkexprlistsafe(n->rlist, init);
   716  		ll = ascompatee(OAS, n->list, n->rlist, init);
   717  		ll = reorder3(ll);
   718  		for(lr = ll; lr != nil; lr = lr->next)
   719  			lr->n = applywritebarrier(lr->n, init);
   720  		n = liststmt(ll);
   721  		goto ret;
   722  
   723  	case OAS2FUNC:
   724  		// a,b,... = fn()
   725  		*init = concat(*init, n->ninit);
   726  		n->ninit = nil;
   727  		r = n->rlist->n;
   728  		walkexprlistsafe(n->list, init);
   729  		walkexpr(&r, init);
   730  
   731  		ll = ascompatet(n->op, n->list, &r->type, 0, init);
   732  		for(lr = ll; lr != nil; lr = lr->next)
   733  			lr->n = applywritebarrier(lr->n, init);
   734  		n = liststmt(concat(list1(r), ll));
   735  		goto ret;
   736  
   737  	case OAS2RECV:
   738  		// x, y = <-c
   739  		// orderstmt made sure x is addressable.
   740  		*init = concat(*init, n->ninit);
   741  		n->ninit = nil;
   742  		r = n->rlist->n;
   743  		walkexprlistsafe(n->list, init);
   744  		walkexpr(&r->left, init);
   745  		if(isblank(n->list->n))
   746  			n1 = nodnil();
   747  		else
   748  			n1 = nod(OADDR, n->list->n, N);
   749  		n1->etype = 1; // addr does not escape
   750  		fn = chanfn("chanrecv2", 2, r->left->type);
   751  		r = mkcall1(fn, n->list->next->n->type, init, typename(r->left->type), r->left, n1);
   752  		n = nod(OAS, n->list->next->n, r);
   753  		typecheck(&n, Etop);
   754  		goto ret;
   755  
   756  	case OAS2MAPR:
   757  		// a,b = m[i];
   758  		*init = concat(*init, n->ninit);
   759  		n->ninit = nil;
   760  		r = n->rlist->n;
   761  		walkexprlistsafe(n->list, init);
   762  		walkexpr(&r->left, init);
   763  		walkexpr(&r->right, init);
   764  		t = r->left->type;
   765  		p = nil;
   766  		if(t->type->width <= 128) { // Check ../../runtime/hashmap.go:maxValueSize before changing.
   767  			switch(simsimtype(t->down)) {
   768  			case TINT32:
   769  			case TUINT32:
   770  				p = "mapaccess2_fast32";
   771  				break;
   772  			case TINT64:
   773  			case TUINT64:
   774  				p = "mapaccess2_fast64";
   775  				break;
   776  			case TSTRING:
   777  				p = "mapaccess2_faststr";
   778  				break;
   779  			}
   780  		}
   781  		if(p != nil) {
   782  			// fast versions take key by value
   783  			key = r->right;
   784  		} else {
   785  			// standard version takes key by reference
   786  			// orderexpr made sure key is addressable.
   787  			key = nod(OADDR, r->right, N);
   788  			p = "mapaccess2";
   789  		}
   790  
   791  		// from:
   792  		//   a,b = m[i]
   793  		// to:
   794  		//   var,b = mapaccess2*(t, m, i)
   795  		//   a = *var
   796  		a = n->list->n;
   797  		fn = mapfn(p, t);
   798  		r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key);
   799  
   800  		// mapaccess2* returns a typed bool, but due to spec changes,
   801  		// the boolean result of i.(T) is now untyped so we make it the
   802  		// same type as the variable on the lhs.
   803  		if(!isblank(n->list->next->n))
   804  			r->type->type->down->type = n->list->next->n->type;
   805  		n->rlist = list1(r);
   806  		n->op = OAS2FUNC;
   807  
   808  		// don't generate a = *var if a is _
   809  		if(!isblank(a)) {
   810  			var = temp(ptrto(t->type));
   811  			var->typecheck = 1;
   812  			n->list->n = var;
   813  			walkexpr(&n, init);
   814  			*init = list(*init, n);
   815  			n = nod(OAS, a, nod(OIND, var, N));
   816  		}
   817  
   818  		typecheck(&n, Etop);
   819  		walkexpr(&n, init);
   820  		// mapaccess needs a zero value to be at least this big.
   821  		if(zerosize < t->type->width)
   822  			zerosize = t->type->width;
   823  		// TODO: ptr is always non-nil, so disable nil check for this OIND op.
   824  		goto ret;
   825  
   826  	case ODELETE:
   827  		*init = concat(*init, n->ninit);
   828  		n->ninit = nil;
   829  		map = n->list->n;
   830  		key = n->list->next->n;
   831  		walkexpr(&map, init);
   832  		walkexpr(&key, init);
   833  		// orderstmt made sure key is addressable.
   834  		key = nod(OADDR, key, N);
   835  		t = map->type;
   836  		n = mkcall1(mapfndel("mapdelete", t), T, init, typename(t), map, key);
   837  		goto ret;
   838  
   839  	case OAS2DOTTYPE:
   840  		// a,b = i.(T)
   841  		// orderstmt made sure a is addressable.
   842  		*init = concat(*init, n->ninit);
   843  		n->ninit = nil;
   844  		r = n->rlist->n;
   845  		walkexprlistsafe(n->list, init);
   846  		walkexpr(&r->left, init);
   847  		if(isblank(n->list->n))
   848  			n1 = nodnil();
   849  		else
   850  			n1 = nod(OADDR, n->list->n, N);
   851  		n1->etype = 1; // addr does not escape
   852  
   853  		strcpy(buf, "assertI2T2");
   854  		if(isnilinter(r->left->type))
   855  			buf[6] = 'E';
   856  		if(isnilinter(r->type))
   857  			buf[8] = 'E';
   858  		else if(isinter(r->type))
   859  			buf[8] = 'I';
   860  		
   861  		fn = syslook(buf, 1);
   862  		argtype(fn, r->left->type);
   863  		argtype(fn, r->type);
   864  		
   865  		t = types[TBOOL];
   866  		ok = n->list->next->n;
   867  		if(!isblank(ok))
   868  			t = ok->type;
   869  		r = mkcall1(fn, t, init, typename(r->type), r->left, n1);
   870  		n = nod(OAS, ok, r);
   871  		typecheck(&n, Etop);
   872  		goto ret;
   873  
   874  	case ODOTTYPE:
   875  	case ODOTTYPE2:
   876  		fatal("walkexpr ODOTTYPE"); // should see inside OAS or OAS2 only
   877  
   878  	case OCONVIFACE:
   879  		walkexpr(&n->left, init);
   880  
   881  		// Optimize convT2E as a two-word copy when T is uintptr-shaped.
   882  		if(isnilinter(n->type) && isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
   883  			l = nod(OEFACE, typename(n->left->type), n->left);
   884  			l->type = n->type;
   885  			l->typecheck = n->typecheck;
   886  			n = l;
   887  			goto ret;
   888  		}
   889  
   890  		// Build name of function: convI2E etc.
   891  		// Not all names are possible
   892  		// (e.g., we'll never generate convE2E or convE2I).
   893  		strcpy(buf, "conv");
   894  		p = buf+strlen(buf);
   895  		if(isnilinter(n->left->type))
   896  			*p++ = 'E';
   897  		else if(isinter(n->left->type))
   898  			*p++ = 'I';
   899  		else
   900  			*p++ = 'T';
   901  		*p++ = '2';
   902  		if(isnilinter(n->type))
   903  			*p++ = 'E';
   904  		else
   905  			*p++ = 'I';
   906  		*p = '\0';
   907  
   908  		fn = syslook(buf, 1);
   909  		ll = nil;
   910  		if(!isinter(n->left->type))
   911  			ll = list(ll, typename(n->left->type));
   912  		if(!isnilinter(n->type))
   913  			ll = list(ll, typename(n->type));
   914  		if(!isinter(n->left->type) && !isnilinter(n->type)){
   915  			sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg);
   916  			if(sym->def == N) {
   917  				l = nod(ONAME, N, N);
   918  				l->sym = sym;
   919  				l->type = ptrto(types[TUINT8]);
   920  				l->addable = 1;
   921  				l->class = PEXTERN;
   922  				l->xoffset = 0;
   923  				sym->def = l;
   924  				ggloblsym(sym, widthptr, DUPOK|NOPTR);
   925  			}
   926  			l = nod(OADDR, sym->def, N);
   927  			l->addable = 1;
   928  			ll = list(ll, l);
   929  
   930  			if(isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
   931  				/* For pointer types, we can make a special form of optimization
   932  				 *
   933  				 * These statements are put onto the expression init list:
   934  				 * 	Itab *tab = atomicloadtype(&cache);
   935  				 * 	if(tab == nil)
   936  				 * 		tab = typ2Itab(type, itype, &cache);
   937  				 *
   938  				 * The CONVIFACE expression is replaced with this:
   939  				 * 	OEFACE{tab, ptr};
   940  				 */
   941  				l = temp(ptrto(types[TUINT8]));
   942  
   943  				n1 = nod(OAS, l, sym->def);
   944  				typecheck(&n1, Etop);
   945  				*init = list(*init, n1);
   946  
   947  				fn = syslook("typ2Itab", 1);
   948  				n1 = nod(OCALL, fn, N);
   949  				n1->list = ll;
   950  				typecheck(&n1, Erv);
   951  				walkexpr(&n1, init);
   952  
   953  				n2 = nod(OIF, N, N);
   954  				n2->ntest = nod(OEQ, l, nodnil());
   955  				n2->nbody = list1(nod(OAS, l, n1));
   956  				n2->likely = -1;
   957  				typecheck(&n2, Etop);
   958  				*init = list(*init, n2);
   959  
   960  				l = nod(OEFACE, l, n->left);
   961  				l->typecheck = n->typecheck; 
   962  				l->type = n->type;
   963  				n = l;
   964  				goto ret;
   965  			}
   966  		}
   967  		if(isinter(n->left->type)) {
   968  			ll = list(ll, n->left);
   969  		} else {
   970  			// regular types are passed by reference to avoid C vararg calls
   971  			// orderexpr arranged for n->left to be a temporary for all
   972  			// the conversions it could see. comparison of an interface
   973  			// with a non-interface, especially in a switch on interface value
   974  			// with non-interface cases, is not visible to orderstmt, so we
   975  			// have to fall back on allocating a temp here.
   976  			if(islvalue(n->left))
   977  				ll = list(ll, nod(OADDR, n->left, N));
   978  			else
   979  				ll = list(ll, nod(OADDR, copyexpr(n->left, n->left->type, init), N));
   980  		}
   981  		argtype(fn, n->left->type);
   982  		argtype(fn, n->type);
   983  		dowidth(fn->type);
   984  		n = nod(OCALL, fn, N);
   985  		n->list = ll;
   986  		typecheck(&n, Erv);
   987  		walkexpr(&n, init);
   988  		goto ret;
   989  
   990  	case OCONV:
   991  	case OCONVNOP:
   992  		if(thechar == '5') {
   993  			if(isfloat[n->left->type->etype]) {
   994  				if(n->type->etype == TINT64) {
   995  					n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
   996  					goto ret;
   997  				}
   998  				if(n->type->etype == TUINT64) {
   999  					n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64]));
  1000  					goto ret;
  1001  				}
  1002  			}
  1003  			if(isfloat[n->type->etype]) {
  1004  				if(n->left->type->etype == TINT64) {
  1005  					n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
  1006  					goto ret;
  1007  				}
  1008  				if(n->left->type->etype == TUINT64) {
  1009  					n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64]));
  1010  					goto ret;
  1011  				}
  1012  			}
  1013  		}
  1014  		walkexpr(&n->left, init);
  1015  		goto ret;
  1016  
  1017  	case OANDNOT:
  1018  		walkexpr(&n->left, init);
  1019  		n->op = OAND;
  1020  		n->right = nod(OCOM, n->right, N);
  1021  		typecheck(&n->right, Erv);
  1022  		walkexpr(&n->right, init);
  1023  		goto ret;
  1024  
  1025  	case OMUL:
  1026  		walkexpr(&n->left, init);
  1027  		walkexpr(&n->right, init);
  1028  		walkmul(&n, init);
  1029  		goto ret;
  1030  
  1031  	case ODIV:
  1032  	case OMOD:
  1033  		walkexpr(&n->left, init);
  1034  		walkexpr(&n->right, init);
  1035  		/*
  1036  		 * rewrite complex div into function call.
  1037  		 */
  1038  		et = n->left->type->etype;
  1039  		if(iscomplex[et] && n->op == ODIV) {
  1040  			t = n->type;
  1041  			n = mkcall("complex128div", types[TCOMPLEX128], init,
  1042  				conv(n->left, types[TCOMPLEX128]),
  1043  				conv(n->right, types[TCOMPLEX128]));
  1044  			n = conv(n, t);
  1045  			goto ret;
  1046  		}
  1047  		// Nothing to do for float divisions.
  1048  		if(isfloat[et])
  1049  			goto ret;
  1050  
  1051  		// Try rewriting as shifts or magic multiplies.
  1052  		walkdiv(&n, init);
  1053  
  1054  		/*
  1055  		 * rewrite 64-bit div and mod into function calls
  1056  		 * on 32-bit architectures.
  1057  		 */
  1058  		switch(n->op) {
  1059  		case OMOD:
  1060  		case ODIV:
  1061  			if(widthreg >= 8 || (et != TUINT64 && et != TINT64))
  1062  				goto ret;
  1063  			if(et == TINT64)
  1064  				strcpy(namebuf, "int64");
  1065  			else
  1066  				strcpy(namebuf, "uint64");
  1067  			if(n->op == ODIV)
  1068  				strcat(namebuf, "div");
  1069  			else
  1070  				strcat(namebuf, "mod");
  1071  			n = mkcall(namebuf, n->type, init,
  1072  				conv(n->left, types[et]), conv(n->right, types[et]));
  1073  			break;
  1074  		default:
  1075  			break;
  1076  		}
  1077  		goto ret;
  1078  
  1079  	case OINDEX:
  1080  		walkexpr(&n->left, init);
  1081  		// save the original node for bounds checking elision.
  1082  		// If it was a ODIV/OMOD walk might rewrite it.
  1083  		r = n->right;
  1084  		walkexpr(&n->right, init);
  1085  
  1086  		// if range of type cannot exceed static array bound,
  1087  		// disable bounds check.
  1088  		if(n->bounded)
  1089  			goto ret;
  1090  		t = n->left->type;
  1091  		if(t != T && isptr[t->etype])
  1092  			t = t->type;
  1093  		if(isfixedarray(t)) {
  1094  			n->bounded = bounded(r, t->bound);
  1095  			if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
  1096  				warn("index bounds check elided");
  1097  			if(smallintconst(n->right) && !n->bounded)
  1098  				yyerror("index out of bounds");
  1099  		} else if(isconst(n->left, CTSTR)) {
  1100  			n->bounded = bounded(r, n->left->val.u.sval->len);
  1101  			if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
  1102  				warn("index bounds check elided");
  1103  			if(smallintconst(n->right)) {
  1104  				if(!n->bounded)
  1105  					yyerror("index out of bounds");
  1106  				else {
  1107  					// replace "abc"[1] with 'b'.
  1108  					// delayed until now because "abc"[1] is not
  1109  					// an ideal constant.
  1110  					v = mpgetfix(n->right->val.u.xval);
  1111  					nodconst(n, n->type, n->left->val.u.sval->s[v]);
  1112  					n->typecheck = 1;
  1113  				}
  1114  			}
  1115  		}
  1116  
  1117  		if(isconst(n->right, CTINT))
  1118  		if(mpcmpfixfix(n->right->val.u.xval, &mpzero) < 0 ||
  1119  		   mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
  1120  			yyerror("index out of bounds");
  1121  		goto ret;
  1122  
  1123  	case OINDEXMAP:
  1124  		if(n->etype == 1)
  1125  			goto ret;
  1126  		walkexpr(&n->left, init);
  1127  		walkexpr(&n->right, init);
  1128  
  1129  		t = n->left->type;
  1130  		p = nil;
  1131  		if(t->type->width <= 128) {  // Check ../../runtime/hashmap.go:maxValueSize before changing.
  1132  			switch(simsimtype(t->down)) {
  1133  			case TINT32:
  1134  			case TUINT32:
  1135  				p = "mapaccess1_fast32";
  1136  				break;
  1137  			case TINT64:
  1138  			case TUINT64:
  1139  				p = "mapaccess1_fast64";
  1140  				break;
  1141  			case TSTRING:
  1142  				p = "mapaccess1_faststr";
  1143  				break;
  1144  			}
  1145  		}
  1146  		if(p != nil) {
  1147  			// fast versions take key by value
  1148  			key = n->right;
  1149  		} else {
  1150  			// standard version takes key by reference.
  1151  			// orderexpr made sure key is addressable.
  1152  			key = nod(OADDR, n->right, N);
  1153  			p = "mapaccess1";
  1154  		}
  1155  		n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, key);
  1156  		n = nod(OIND, n, N);
  1157  		n->type = t->type;
  1158  		n->typecheck = 1;
  1159  		// mapaccess needs a zero value to be at least this big.
  1160  		if(zerosize < t->type->width)
  1161  			zerosize = t->type->width;
  1162  		goto ret;
  1163  
  1164  	case ORECV:
  1165  		fatal("walkexpr ORECV"); // should see inside OAS only
  1166  
  1167  	case OSLICE:
  1168  		if(n->right != N && n->right->left == N && n->right->right == N) { // noop
  1169  			walkexpr(&n->left, init);
  1170  			n = n->left;
  1171  			goto ret;
  1172  		}
  1173  		// fallthrough
  1174  	case OSLICEARR:
  1175  	case OSLICESTR:
  1176  		if(n->right == N) // already processed
  1177  			goto ret;
  1178  
  1179  		walkexpr(&n->left, init);
  1180  		// cgen_slice can't handle string literals as source
  1181  		// TODO the OINDEX case is a bug elsewhere that needs to be traced.  it causes a crash on ([2][]int{ ... })[1][lo:hi]
  1182  		if((n->op == OSLICESTR && n->left->op == OLITERAL) || (n->left->op == OINDEX))
  1183  			n->left = copyexpr(n->left, n->left->type, init);
  1184  		else
  1185  			n->left = safeexpr(n->left, init);
  1186  		walkexpr(&n->right->left, init);
  1187  		n->right->left = safeexpr(n->right->left, init);
  1188  		walkexpr(&n->right->right, init);
  1189  		n->right->right = safeexpr(n->right->right, init);
  1190  		n = sliceany(n, init);  // chops n->right, sets n->list
  1191  		goto ret;
  1192  	
  1193  	case OSLICE3:
  1194  	case OSLICE3ARR:
  1195  		if(n->right == N) // already processed
  1196  			goto ret;
  1197  
  1198  		walkexpr(&n->left, init);
  1199  		// TODO the OINDEX case is a bug elsewhere that needs to be traced.  it causes a crash on ([2][]int{ ... })[1][lo:hi]
  1200  		// TODO the comment on the previous line was copied from case OSLICE. it might not even be true.
  1201  		if(n->left->op == OINDEX)
  1202  			n->left = copyexpr(n->left, n->left->type, init);
  1203  		else
  1204  			n->left = safeexpr(n->left, init);
  1205  		walkexpr(&n->right->left, init);
  1206  		n->right->left = safeexpr(n->right->left, init);
  1207  		walkexpr(&n->right->right->left, init);
  1208  		n->right->right->left = safeexpr(n->right->right->left, init);
  1209  		walkexpr(&n->right->right->right, init);
  1210  		n->right->right->right = safeexpr(n->right->right->right, init);
  1211  		n = sliceany(n, init);  // chops n->right, sets n->list
  1212  		goto ret;
  1213  
  1214  	case OADDR:
  1215  		walkexpr(&n->left, init);
  1216  		goto ret;
  1217  
  1218  	case ONEW:
  1219  		if(n->esc == EscNone && n->type->type->width < (1<<16)) {
  1220  			r = temp(n->type->type);
  1221  			r = nod(OAS, r, N);  // zero temp
  1222  			typecheck(&r, Etop);
  1223  			*init = list(*init, r);
  1224  			r = nod(OADDR, r->left, N);
  1225  			typecheck(&r, Erv);
  1226  			n = r;
  1227  		} else {
  1228  			n = callnew(n->type->type);
  1229  		}
  1230  		goto ret;
  1231  
  1232  	case OCMPSTR:
  1233  		// If one argument to the comparison is an empty string,
  1234  		// comparing the lengths instead will yield the same result
  1235  		// without the function call.
  1236  		if((isconst(n->left, CTSTR) && n->left->val.u.sval->len == 0) ||
  1237  		   (isconst(n->right, CTSTR) && n->right->val.u.sval->len == 0)) {
  1238  			r = nod(n->etype, nod(OLEN, n->left, N), nod(OLEN, n->right, N));
  1239  			typecheck(&r, Erv);
  1240  			walkexpr(&r, init);
  1241  			r->type = n->type;
  1242  			n = r;
  1243  			goto ret;
  1244  		}
  1245  
  1246  		// s + "badgerbadgerbadger" == "badgerbadgerbadger"
  1247  		if((n->etype == OEQ || n->etype == ONE) &&
  1248  		   isconst(n->right, CTSTR) &&
  1249  		   n->left->op == OADDSTR && count(n->left->list) == 2 &&
  1250  		   isconst(n->left->list->next->n, CTSTR) &&
  1251  		   cmpslit(n->right, n->left->list->next->n) == 0) {
  1252  			r = nod(n->etype, nod(OLEN, n->left->list->n, N), nodintconst(0));
  1253  			typecheck(&r, Erv);
  1254  			walkexpr(&r, init);
  1255  			r->type = n->type;
  1256  			n = r;
  1257  			goto ret;
  1258  		}
  1259  
  1260  		if(n->etype == OEQ || n->etype == ONE) {
  1261  			// prepare for rewrite below
  1262  			n->left = cheapexpr(n->left, init);
  1263  			n->right = cheapexpr(n->right, init);
  1264  
  1265  			r = mkcall("eqstring", types[TBOOL], init,
  1266  				conv(n->left, types[TSTRING]),
  1267  				conv(n->right, types[TSTRING]));
  1268  
  1269  			// quick check of len before full compare for == or !=
  1270  			if(n->etype == OEQ) {
  1271  				// len(left) == len(right) && eqstring(left, right)
  1272  				r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
  1273  			} else {
  1274  				// len(left) != len(right) || !eqstring(left, right)
  1275  				r = nod(ONOT, r, N);
  1276  				r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
  1277  			}
  1278  			typecheck(&r, Erv);
  1279  			walkexpr(&r, nil);
  1280  		} else {
  1281  			// sys_cmpstring(s1, s2) :: 0
  1282  			r = mkcall("cmpstring", types[TINT], init,
  1283  				conv(n->left, types[TSTRING]),
  1284  				conv(n->right, types[TSTRING]));
  1285  			r = nod(n->etype, r, nodintconst(0));
  1286  		}
  1287  
  1288  		typecheck(&r, Erv);
  1289  		if(n->type->etype != TBOOL) fatal("cmp %T", n->type);
  1290  		r->type = n->type;
  1291  		n = r;
  1292  		goto ret;
  1293  
  1294  	case OADDSTR:
  1295  		n = addstr(n, init);
  1296  		goto ret;
  1297  	
  1298  	case OAPPEND:
  1299  		if(n->isddd)
  1300  			n = appendslice(n, init); // also works for append(slice, string).
  1301  		else
  1302  			n = append(n, init);
  1303  		goto ret;
  1304  
  1305  	case OCOPY:
  1306  		n = copyany(n, init, flag_race);
  1307  		goto ret;
  1308  
  1309  	case OCLOSE:
  1310  		// cannot use chanfn - closechan takes any, not chan any
  1311  		fn = syslook("closechan", 1);
  1312  		argtype(fn, n->left->type);
  1313  		n = mkcall1(fn, T, init, n->left);
  1314  		goto ret;
  1315  
  1316  	case OMAKECHAN:
  1317  		n = mkcall1(chanfn("makechan", 1, n->type), n->type, init,
  1318  			typename(n->type),
  1319  			conv(n->left, types[TINT64]));
  1320  		goto ret;
  1321  
  1322  	case OMAKEMAP:
  1323  		t = n->type;
  1324  
  1325  		fn = syslook("makemap", 1);
  1326  		argtype(fn, t->down);	// any-1
  1327  		argtype(fn, t->type);	// any-2
  1328  
  1329  		n = mkcall1(fn, n->type, init,
  1330  			typename(n->type),
  1331  			conv(n->left, types[TINT64]));
  1332  		goto ret;
  1333  
  1334  	case OMAKESLICE:
  1335  		l = n->left;
  1336  		r = n->right;
  1337  		if(r == nil)
  1338  			l = r = safeexpr(l, init);
  1339  		t = n->type;
  1340  		if(n->esc == EscNone
  1341  			&& smallintconst(l) && smallintconst(r)
  1342  			&& (t->type->width == 0 || mpgetfix(r->val.u.xval) < (1ULL<<16) / t->type->width)) {
  1343  			// var arr [r]T
  1344  			// n = arr[:l]
  1345  			t = aindex(r, t->type); // [r]T
  1346  			var = temp(t);
  1347  			a = nod(OAS, var, N); // zero temp
  1348  			typecheck(&a, Etop);
  1349  			*init = list(*init, a);
  1350  			r = nod(OSLICE, var, nod(OKEY, N, l)); // arr[:l]
  1351  			r = conv(r, n->type); // in case n->type is named.
  1352  			typecheck(&r, Erv);
  1353  			walkexpr(&r, init);
  1354  			n = r;
  1355  		} else {
  1356  			// makeslice(t *Type, nel int64, max int64) (ary []any)
  1357  			fn = syslook("makeslice", 1);
  1358  			argtype(fn, t->type);			// any-1
  1359  			n = mkcall1(fn, n->type, init,
  1360  				typename(n->type),
  1361  				conv(l, types[TINT64]),
  1362  				conv(r, types[TINT64]));
  1363  		}
  1364  		goto ret;
  1365  
  1366  	case ORUNESTR:
  1367  		// sys_intstring(v)
  1368  		n = mkcall("intstring", n->type, init,
  1369  			conv(n->left, types[TINT64]));
  1370  		goto ret;
  1371  
  1372  	case OARRAYBYTESTR:
  1373  		// slicebytetostring([]byte) string;
  1374  		n = mkcall("slicebytetostring", n->type, init, n->left);
  1375  		goto ret;
  1376  
  1377  	case OARRAYBYTESTRTMP:
  1378  		// slicebytetostringtmp([]byte) string;
  1379  		n = mkcall("slicebytetostringtmp", n->type, init, n->left);
  1380  		goto ret;
  1381  
  1382  	case OARRAYRUNESTR:
  1383  		// slicerunetostring([]rune) string;
  1384  		n = mkcall("slicerunetostring", n->type, init, n->left);
  1385  		goto ret;
  1386  
  1387  	case OSTRARRAYBYTE:
  1388  		// stringtoslicebyte(string) []byte;
  1389  		n = mkcall("stringtoslicebyte", n->type, init, conv(n->left, types[TSTRING]));
  1390  		goto ret;
  1391  
  1392  	case OSTRARRAYRUNE:
  1393  		// stringtoslicerune(string) []rune
  1394  		n = mkcall("stringtoslicerune", n->type, init, n->left);
  1395  		goto ret;
  1396  
  1397  	case OCMPIFACE:
  1398  		// ifaceeq(i1 any-1, i2 any-2) (ret bool);
  1399  		if(!eqtype(n->left->type, n->right->type))
  1400  			fatal("ifaceeq %O %T %T", n->op, n->left->type, n->right->type);
  1401  		if(isnilinter(n->left->type))
  1402  			fn = syslook("efaceeq", 1);
  1403  		else
  1404  			fn = syslook("ifaceeq", 1);
  1405  
  1406  		n->right = cheapexpr(n->right, init);
  1407  		n->left = cheapexpr(n->left, init);
  1408  		argtype(fn, n->right->type);
  1409  		argtype(fn, n->left->type);
  1410  		r = mkcall1(fn, n->type, init, n->left, n->right);
  1411  		if(n->etype == ONE)
  1412  			r = nod(ONOT, r, N);
  1413  		
  1414  		// check itable/type before full compare.
  1415  		if(n->etype == OEQ)
  1416  			r = nod(OANDAND, nod(OEQ, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
  1417  		else
  1418  			r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
  1419  		typecheck(&r, Erv);
  1420  		walkexpr(&r, init);
  1421  		r->type = n->type;
  1422  		n = r;
  1423  		goto ret;
  1424  
  1425  	case OARRAYLIT:
  1426  	case OMAPLIT:
  1427  	case OSTRUCTLIT:
  1428  	case OPTRLIT:
  1429  		var = temp(n->type);
  1430  		anylit(0, n, var, init);
  1431  		n = var;
  1432  		goto ret;
  1433  
  1434  	case OSEND:
  1435  		n1 = n->right;
  1436  		n1 = assignconv(n1, n->left->type->type, "chan send");
  1437  		walkexpr(&n1, init);
  1438  		n1 = nod(OADDR, n1, N);
  1439  		n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n1);
  1440  		goto ret;
  1441  
  1442  	case OCLOSURE:
  1443  		n = walkclosure(n, init);
  1444  		goto ret;
  1445  	
  1446  	case OCALLPART:
  1447  		n = walkpartialcall(n, init);
  1448  		goto ret;
  1449  	}
  1450  	fatal("missing switch %O", n->op);
  1451  
  1452  ret:
  1453  	// Expressions that are constant at run time but not
  1454  	// considered const by the language spec are not turned into
  1455  	// constants until walk. For example, if n is y%1 == 0, the
  1456  	// walk of y%1 may have replaced it by 0.
  1457  	// Check whether n with its updated args is itself now a constant.
  1458  	t = n->type;
  1459  	evconst(n);
  1460  	n->type = t;
  1461  	if(n->op == OLITERAL)
  1462  		typecheck(&n, Erv);
  1463  
  1464  	ullmancalc(n);
  1465  
  1466  	if(debug['w'] && n != N)
  1467  		dump("walk", n);
  1468  
  1469  	lineno = lno;
  1470  	*np = n;
  1471  }
  1472  
  1473  static Node*
  1474  ascompatee1(int op, Node *l, Node *r, NodeList **init)
  1475  {
  1476  	Node *n;
  1477  	USED(op);
  1478  	
  1479  	// convas will turn map assigns into function calls,
  1480  	// making it impossible for reorder3 to work.
  1481  	n = nod(OAS, l, r);
  1482  	if(l->op == OINDEXMAP)
  1483  		return n;
  1484  
  1485  	return convas(n, init);
  1486  }
  1487  
  1488  static NodeList*
  1489  ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
  1490  {
  1491  	NodeList *ll, *lr, *nn;
  1492  
  1493  	/*
  1494  	 * check assign expression list to
  1495  	 * a expression list. called in
  1496  	 *	expr-list = expr-list
  1497  	 */
  1498  
  1499  	// ensure order of evaluation for function calls
  1500  	for(ll=nl; ll; ll=ll->next)
  1501  		ll->n = safeexpr(ll->n, init);
  1502  	for(lr=nr; lr; lr=lr->next)
  1503  		lr->n = safeexpr(lr->n, init);
  1504  
  1505  	nn = nil;
  1506  	for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) {
  1507  		// Do not generate 'x = x' during return. See issue 4014.
  1508  		if(op == ORETURN && ll->n == lr->n)
  1509  			continue;
  1510  		nn = list(nn, ascompatee1(op, ll->n, lr->n, init));
  1511  	}
  1512  
  1513  	// cannot happen: caller checked that lists had same length
  1514  	if(ll || lr)
  1515  		yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, count(nl), count(nr), curfn->nname->sym->name);
  1516  	return nn;
  1517  }
  1518  
  1519  /*
  1520   * l is an lv and rt is the type of an rv
  1521   * return 1 if this implies a function call
  1522   * evaluating the lv or a function call
  1523   * in the conversion of the types
  1524   */
  1525  static int
  1526  fncall(Node *l, Type *rt)
  1527  {
  1528  	Node r;
  1529  
  1530  	if(l->ullman >= UINF || l->op == OINDEXMAP)
  1531  		return 1;
  1532  	memset(&r, 0, sizeof r);
  1533  	if(needwritebarrier(l, &r))
  1534  		return 1;
  1535  	if(eqtype(l->type, rt))
  1536  		return 0;
  1537  	return 1;
  1538  }
  1539  
  1540  static NodeList*
  1541  ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
  1542  {
  1543  	Node *l, *tmp, *a;
  1544  	NodeList *ll;
  1545  	Type *r;
  1546  	Iter saver;
  1547  	int ucount;
  1548  	NodeList *nn, *mm;
  1549  
  1550  	USED(op);
  1551  
  1552  	/*
  1553  	 * check assign type list to
  1554  	 * a expression list. called in
  1555  	 *	expr-list = func()
  1556  	 */
  1557  	r = structfirst(&saver, nr);
  1558  	nn = nil;
  1559  	mm = nil;
  1560  	ucount = 0;
  1561  	for(ll=nl; ll; ll=ll->next) {
  1562  		if(r == T)
  1563  			break;
  1564  		l = ll->n;
  1565  		if(isblank(l)) {
  1566  			r = structnext(&saver);
  1567  			continue;
  1568  		}
  1569  
  1570  		// any lv that causes a fn call must be
  1571  		// deferred until all the return arguments
  1572  		// have been pulled from the output arguments
  1573  		if(fncall(l, r->type)) {
  1574  			tmp = temp(r->type);
  1575  			typecheck(&tmp, Erv);
  1576  			a = nod(OAS, l, tmp);
  1577  			a = convas(a, init);
  1578  			mm = list(mm, a);
  1579  			l = tmp;
  1580  		}
  1581  
  1582  		a = nod(OAS, l, nodarg(r, fp));
  1583  		a = convas(a, init);
  1584  		ullmancalc(a);
  1585  		if(a->ullman >= UINF) {
  1586  			dump("ascompatet ucount", a);
  1587  			ucount++;
  1588  		}
  1589  		nn = list(nn, a);
  1590  		r = structnext(&saver);
  1591  	}
  1592  
  1593  	if(ll != nil || r != T)
  1594  		yyerror("ascompatet: assignment count mismatch: %d = %d",
  1595  			count(nl), structcount(*nr));
  1596  
  1597  	if(ucount)
  1598  		fatal("ascompatet: too many function calls evaluating parameters");
  1599  	return concat(nn, mm);
  1600  }
  1601  
  1602   /*
  1603   * package all the arguments that match a ... T parameter into a []T.
  1604   */
  1605  static NodeList*
  1606  mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, Node *ddd)
  1607  {
  1608  	Node *a, *n;
  1609  	Type *tslice;
  1610  	int esc;
  1611  	
  1612  	esc = EscUnknown;
  1613  	if(ddd != nil)
  1614  		esc = ddd->esc;
  1615  	
  1616  	tslice = typ(TARRAY);
  1617  	tslice->type = l->type->type;
  1618  	tslice->bound = -1;
  1619  
  1620  	if(count(lr0) == 0) {
  1621  		n = nodnil();
  1622  		n->type = tslice;
  1623  	} else {
  1624  		n = nod(OCOMPLIT, N, typenod(tslice));
  1625  		if(ddd != nil)
  1626  			n->alloc = ddd->alloc; // temporary to use
  1627  		n->list = lr0;
  1628  		n->esc = esc;
  1629  		typecheck(&n, Erv);
  1630  		if(n->type == T)
  1631  			fatal("mkdotargslice: typecheck failed");
  1632  		walkexpr(&n, init);
  1633  	}
  1634  
  1635  	a = nod(OAS, nodarg(l, fp), n);
  1636  	nn = list(nn, convas(a, init));
  1637  	return nn;
  1638  }
  1639  
  1640  /*
  1641   * helpers for shape errors
  1642   */
  1643  static char*
  1644  dumptypes(Type **nl, char *what)
  1645  {
  1646  	int first;
  1647  	Type *l;
  1648  	Iter savel;
  1649  	Fmt fmt;
  1650  
  1651  	fmtstrinit(&fmt);
  1652  	fmtprint(&fmt, "\t");
  1653  	first = 1;
  1654  	for(l = structfirst(&savel, nl); l != T; l = structnext(&savel)) {
  1655  		if(first)
  1656  			first = 0;
  1657  		else
  1658  			fmtprint(&fmt, ", ");
  1659  		fmtprint(&fmt, "%T", l);
  1660  	}
  1661  	if(first)
  1662  		fmtprint(&fmt, "[no arguments %s]", what);
  1663  	return fmtstrflush(&fmt);
  1664  }
  1665  
  1666  static char*
  1667  dumpnodetypes(NodeList *l, char *what)
  1668  {
  1669  	int first;
  1670  	Node *r;
  1671  	Fmt fmt;
  1672  
  1673  	fmtstrinit(&fmt);
  1674  	fmtprint(&fmt, "\t");
  1675  	first = 1;
  1676  	for(; l; l=l->next) {
  1677  		r = l->n;
  1678  		if(first)
  1679  			first = 0;
  1680  		else
  1681  			fmtprint(&fmt, ", ");
  1682  		fmtprint(&fmt, "%T", r->type);
  1683  	}
  1684  	if(first)
  1685  		fmtprint(&fmt, "[no arguments %s]", what);
  1686  	return fmtstrflush(&fmt);
  1687  }
  1688  
  1689  /*
  1690   * check assign expression list to
  1691   * a type list. called in
  1692   *	return expr-list
  1693   *	func(expr-list)
  1694   */
  1695  static NodeList*
  1696  ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeList **init)
  1697  {
  1698  	Type *l, *ll;
  1699  	Node *r, *a;
  1700  	NodeList *nn, *lr0, *alist;
  1701  	Iter savel;
  1702  	char *l1, *l2;
  1703  
  1704  	lr0 = lr;
  1705  	l = structfirst(&savel, nl);
  1706  	r = N;
  1707  	if(lr)
  1708  		r = lr->n;
  1709  	nn = nil;
  1710  
  1711  	// f(g()) where g has multiple return values
  1712  	if(r != N && lr->next == nil && r->type->etype == TSTRUCT && r->type->funarg) {
  1713  		// optimization - can do block copy
  1714  		if(eqtypenoname(r->type, *nl)) {
  1715  			a = nodarg(*nl, fp);
  1716  			r = nod(OCONVNOP, r, N);
  1717  			r->type = a->type;
  1718  			nn = list1(convas(nod(OAS, a, r), init));
  1719  			goto ret;
  1720  		}
  1721  
  1722  		// conversions involved.
  1723  		// copy into temporaries.
  1724  		alist = nil;
  1725  		for(l=structfirst(&savel, &r->type); l; l=structnext(&savel)) {
  1726  			a = temp(l->type);
  1727  			alist = list(alist, a);
  1728  		}
  1729  		a = nod(OAS2, N, N);
  1730  		a->list = alist;
  1731  		a->rlist = lr;
  1732  		typecheck(&a, Etop);
  1733  		walkstmt(&a);
  1734  		*init = list(*init, a);
  1735  		lr = alist;
  1736  		r = lr->n;
  1737  		l = structfirst(&savel, nl);
  1738  	}
  1739  
  1740  loop:
  1741  	if(l != T && l->isddd) {
  1742  		// the ddd parameter must be last
  1743  		ll = structnext(&savel);
  1744  		if(ll != T)
  1745  			yyerror("... must be last argument");
  1746  
  1747  		// special case --
  1748  		// only if we are assigning a single ddd
  1749  		// argument to a ddd parameter then it is
  1750  		// passed thru unencapsulated
  1751  		if(r != N && lr->next == nil && isddd && eqtype(l->type, r->type)) {
  1752  			a = nod(OAS, nodarg(l, fp), r);
  1753  			a = convas(a, init);
  1754  			nn = list(nn, a);
  1755  			goto ret;
  1756  		}
  1757  
  1758  		// normal case -- make a slice of all
  1759  		// remaining arguments and pass it to
  1760  		// the ddd parameter.
  1761  		nn = mkdotargslice(lr, nn, l, fp, init, call->right);
  1762  		goto ret;
  1763  	}
  1764  
  1765  	if(l == T || r == N) {
  1766  		if(l != T || r != N) {
  1767  			l1 = dumptypes(nl, "expected");
  1768  			l2 = dumpnodetypes(lr0, "given");
  1769  			if(l != T)
  1770  				yyerror("not enough arguments to %O\n%s\n%s", op, l1, l2);
  1771  			else
  1772  				yyerror("too many arguments to %O\n%s\n%s", op, l1, l2);
  1773  		}
  1774  		goto ret;
  1775  	}
  1776  
  1777  	a = nod(OAS, nodarg(l, fp), r);
  1778  	a = convas(a, init);
  1779  	nn = list(nn, a);
  1780  
  1781  	l = structnext(&savel);
  1782  	r = N;
  1783  	lr = lr->next;
  1784  	if(lr != nil)
  1785  		r = lr->n;
  1786  	goto loop;
  1787  
  1788  ret:
  1789  	for(lr=nn; lr; lr=lr->next)
  1790  		lr->n->typecheck = 1;
  1791  	return nn;
  1792  }
  1793  
  1794  // generate code for print
  1795  static Node*
  1796  walkprint(Node *nn, NodeList **init)
  1797  {
  1798  	Node *r;
  1799  	Node *n;
  1800  	NodeList *l, *all;
  1801  	Node *on;
  1802  	Type *t;
  1803  	int notfirst, et, op;
  1804  	NodeList *calls;
  1805  
  1806  	op = nn->op;
  1807  	all = nn->list;
  1808  	calls = nil;
  1809  	notfirst = 0;
  1810  
  1811  	// Hoist all the argument evaluation up before the lock.
  1812  	walkexprlistcheap(all, init);
  1813  
  1814  	calls = list(calls, mkcall("printlock", T, init));
  1815  
  1816  	for(l=all; l; l=l->next) {
  1817  		if(notfirst) {
  1818  			calls = list(calls, mkcall("printsp", T, init));
  1819  		}
  1820  		notfirst = op == OPRINTN;
  1821  
  1822  		n = l->n;
  1823  		if(n->op == OLITERAL) {
  1824  			switch(n->val.ctype) {
  1825  			case CTRUNE:
  1826  				defaultlit(&n, runetype);
  1827  				break;
  1828  			case CTINT:
  1829  				defaultlit(&n, types[TINT64]);
  1830  				break;
  1831  			case CTFLT:
  1832  				defaultlit(&n, types[TFLOAT64]);
  1833  				break;
  1834  			}
  1835  		}
  1836  		if(n->op != OLITERAL && n->type && n->type->etype == TIDEAL)
  1837  			defaultlit(&n, types[TINT64]);
  1838  		defaultlit(&n, nil);
  1839  		l->n = n;
  1840  		if(n->type == T || n->type->etype == TFORW)
  1841  			continue;
  1842  
  1843  		t = n->type;
  1844  		et = n->type->etype;
  1845  		if(isinter(n->type)) {
  1846  			if(isnilinter(n->type))
  1847  				on = syslook("printeface", 1);
  1848  			else
  1849  				on = syslook("printiface", 1);
  1850  			argtype(on, n->type);		// any-1
  1851  		} else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) {
  1852  			on = syslook("printpointer", 1);
  1853  			argtype(on, n->type);	// any-1
  1854  		} else if(isslice(n->type)) {
  1855  			on = syslook("printslice", 1);
  1856  			argtype(on, n->type);	// any-1
  1857  		} else if(isint[et]) {
  1858  			if(et == TUINT64) {
  1859  				if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0)
  1860  					on = syslook("printhex", 0);
  1861  				else
  1862  					on = syslook("printuint", 0);
  1863  			} else
  1864  				on = syslook("printint", 0);
  1865  		} else if(isfloat[et]) {
  1866  			on = syslook("printfloat", 0);
  1867  		} else if(iscomplex[et]) {
  1868  			on = syslook("printcomplex", 0);
  1869  		} else if(et == TBOOL) {
  1870  			on = syslook("printbool", 0);
  1871  		} else if(et == TSTRING) {
  1872  			on = syslook("printstring", 0);
  1873  		} else {
  1874  			badtype(OPRINT, n->type, T);
  1875  			continue;
  1876  		}
  1877  
  1878  		t = *getinarg(on->type);
  1879  		if(t != nil)
  1880  			t = t->type;
  1881  		if(t != nil)
  1882  			t = t->type;
  1883  
  1884  		if(!eqtype(t, n->type)) {
  1885  			n = nod(OCONV, n, N);
  1886  			n->type = t;
  1887  		}
  1888  
  1889  		r = nod(OCALL, on, N);
  1890  		r->list = list1(n);
  1891  		calls = list(calls, r);
  1892  	}
  1893  
  1894  	if(op == OPRINTN)
  1895  		calls = list(calls, mkcall("printnl", T, nil));
  1896  
  1897  	calls = list(calls, mkcall("printunlock", T, init));
  1898  
  1899  	typechecklist(calls, Etop);
  1900  	walkexprlist(calls, init);
  1901  
  1902  	r = nod(OEMPTY, N, N);
  1903  	typecheck(&r, Etop);
  1904  	walkexpr(&r, init);
  1905  	r->ninit = calls;
  1906  	return r;
  1907  }
  1908  
  1909  Node*
  1910  callnew(Type *t)
  1911  {
  1912  	Node *fn;
  1913  
  1914  	dowidth(t);
  1915  	fn = syslook("newobject", 1);
  1916  	argtype(fn, t);
  1917  	return mkcall1(fn, ptrto(t), nil, typename(t));
  1918  }
  1919  
  1920  static int
  1921  isstack(Node *n)
  1922  {
  1923  	while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
  1924  		n = n->left;
  1925  	
  1926  	switch(n->op) {
  1927  	case OINDREG:
  1928  		// OINDREG only ends up in walk if it's indirect of SP.
  1929  		return 1;
  1930  
  1931  	case ONAME:
  1932  		switch(n->class) {
  1933  		case PAUTO:
  1934  		case PPARAM:
  1935  		case PPARAMOUT:
  1936  			return 1;
  1937  		}
  1938  		break;
  1939  	}
  1940  	
  1941  	return 0;
  1942  }
  1943  
  1944  static int
  1945  isglobal(Node *n)
  1946  {
  1947  	while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
  1948  		n = n->left;
  1949  	
  1950  	switch(n->op) {
  1951  	case ONAME:
  1952  		switch(n->class) {
  1953  		case PEXTERN:
  1954  			return 1;
  1955  		}
  1956  		break;
  1957  	}
  1958  	
  1959  	return 0;
  1960  }
  1961  
  1962  // Do we need a write barrier for the assignment l = r?
  1963  int
  1964  needwritebarrier(Node *l, Node *r)
  1965  {
  1966  	if(!use_writebarrier)
  1967  		return 0;
  1968  
  1969  	if(l == N || isblank(l))
  1970  		return 0;
  1971  
  1972  	// No write barrier for write of non-pointers.
  1973  	dowidth(l->type);
  1974  	if(!haspointers(l->type))
  1975  		return 0;
  1976  
  1977  	// No write barrier for write to stack.
  1978  	if(isstack(l))
  1979  		return 0;
  1980  
  1981  	// No write barrier for implicit or explicit zeroing.
  1982  	if(r == N || iszero(r))
  1983  		return 0;
  1984  
  1985  	// No write barrier for initialization to constant.
  1986  	if(r->op == OLITERAL)
  1987  		return 0;
  1988  
  1989  	// No write barrier for storing static (read-only) data.
  1990  	if(r->op == ONAME && strncmp(r->sym->name, "statictmp_", 10) == 0)
  1991  		return 0;
  1992  
  1993  	// No write barrier for storing address of stack values,
  1994  	// which are guaranteed only to be written to the stack.
  1995  	if(r->op == OADDR && isstack(r->left))
  1996  		return 0;
  1997  
  1998  	// No write barrier for storing address of global, which
  1999  	// is live no matter what.
  2000  	if(r->op == OADDR && isglobal(r->left))
  2001  		return 0;
  2002  
  2003  	// No write barrier for reslice: x = x[0:y] or x = append(x, ...).
  2004  	// Both are compiled to modify x directly.
  2005  	// In the case of append, a write barrier may still be needed
  2006  	// if the underlying array grows, but the append code can
  2007  	// generate the write barrier directly in that case.
  2008  	// (It does not yet, but the cost of the write barrier will be
  2009  	// small compared to the cost of the allocation.)
  2010  	if(r->reslice) {
  2011  		switch(r->op) {
  2012  		case OSLICE:
  2013  		case OSLICE3:
  2014  		case OSLICESTR:
  2015  		case OAPPEND:
  2016  			break;
  2017  		default:
  2018  			dump("bad reslice-l", l);
  2019  			dump("bad reslice-r", r);
  2020  			break;
  2021  		}
  2022  		return 0;
  2023  	}
  2024  
  2025  	// Otherwise, be conservative and use write barrier.
  2026  	return 1;
  2027  }
  2028  
  2029  // TODO(rsc): Perhaps componentgen should run before this.
  2030  static Node*
  2031  applywritebarrier(Node *n, NodeList **init)
  2032  {
  2033  	Node *l, *r;
  2034  	Type *t;
  2035  	vlong x;
  2036  	static Bvec *bv;
  2037  	char name[32];
  2038  
  2039  	if(n->left && n->right && needwritebarrier(n->left, n->right)) {
  2040  		if(curfn && curfn->nowritebarrier)
  2041  			yyerror("write barrier prohibited");
  2042  		t = n->left->type;
  2043  		l = nod(OADDR, n->left, N);
  2044  		l->etype = 1; // addr does not escape
  2045  		if(t->width == widthptr) {
  2046  			n = mkcall1(writebarrierfn("writebarrierptr", t, n->right->type), T, init,
  2047  				l, n->right);
  2048  		} else if(t->etype == TSTRING) {
  2049  			n = mkcall1(writebarrierfn("writebarrierstring", t, n->right->type), T, init,
  2050  				l, n->right);
  2051  		} else if(isslice(t)) {
  2052  			n = mkcall1(writebarrierfn("writebarrierslice", t, n->right->type), T, init,
  2053  				l, n->right);
  2054  		} else if(isinter(t)) {
  2055  			n = mkcall1(writebarrierfn("writebarrieriface", t, n->right->type), T, init,
  2056  				l, n->right);
  2057  		} else if(t->width <= 4*widthptr) {
  2058  			x = 0;
  2059  			if(bv == nil)
  2060  				bv = bvalloc(BitsPerPointer*4);
  2061  			bvresetall(bv);
  2062  			twobitwalktype1(t, &x, bv);
  2063  			// The bvgets are looking for BitsPointer in successive slots.
  2064  			enum {
  2065  				PtrBit = 1,
  2066  			};
  2067  			if(BitsPointer != (1<<PtrBit))
  2068  				fatal("wrong PtrBit");
  2069  			switch(t->width/widthptr) {
  2070  			default:
  2071  				fatal("found writebarrierfat for %d-byte object of type %T", (int)t->width, t);
  2072  			case 2:
  2073  				snprint(name, sizeof name, "writebarrierfat%d%d",
  2074  					bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit));
  2075  				break;
  2076  			case 3:
  2077  				snprint(name, sizeof name, "writebarrierfat%d%d%d",
  2078  					bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit));
  2079  				break;
  2080  			case 4:
  2081  				snprint(name, sizeof name, "writebarrierfat%d%d%d%d",
  2082  					bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit), bvget(bv, 3*BitsPerPointer+PtrBit));
  2083  				break;
  2084  			}
  2085  			n = mkcall1(writebarrierfn(name, t, n->right->type), T, init,
  2086  				l, nodnil(), n->right);
  2087  		} else {
  2088  			r = n->right;
  2089  			while(r->op == OCONVNOP)
  2090  				r = r->left;
  2091  			r = nod(OADDR, r, N);
  2092  			r->etype = 1; // addr does not escape
  2093  			//warnl(n->lineno, "typedmemmove %T %N", t, r);
  2094  			n = mkcall1(writebarrierfn("typedmemmove", t, r->left->type), T, init,
  2095  				typename(t), l, r);
  2096  		}
  2097  	}
  2098  	return n;
  2099  }
  2100  
  2101  static Node*
  2102  convas(Node *n, NodeList **init)
  2103  {
  2104  	Type *lt, *rt;
  2105  	Node *map, *key, *val;
  2106  
  2107  	if(n->op != OAS)
  2108  		fatal("convas: not OAS %O", n->op);
  2109  
  2110  	n->typecheck = 1;
  2111  
  2112  	if(n->left == N || n->right == N)
  2113  		goto out;
  2114  
  2115  	lt = n->left->type;
  2116  	rt = n->right->type;
  2117  	if(lt == T || rt == T)
  2118  		goto out;
  2119  
  2120  	if(isblank(n->left)) {
  2121  		defaultlit(&n->right, T);
  2122  		goto out;
  2123  	}
  2124  
  2125  	if(n->left->op == OINDEXMAP) {
  2126  		map = n->left->left;
  2127  		key = n->left->right;
  2128  		val = n->right;
  2129  		walkexpr(&map, init);
  2130  		walkexpr(&key, init);
  2131  		walkexpr(&val, init);
  2132  		// orderexpr made sure key and val are addressable.
  2133  		key = nod(OADDR, key, N);
  2134  		val = nod(OADDR, val, N);
  2135  		n = mkcall1(mapfn("mapassign1", map->type), T, init,
  2136  			typename(map->type), map, key, val);
  2137  		goto out;
  2138  	}
  2139  
  2140  	if(!eqtype(lt, rt)) {
  2141  		n->right = assignconv(n->right, lt, "assignment");
  2142  		walkexpr(&n->right, init);
  2143  	}
  2144  
  2145  out:
  2146  	ullmancalc(n);
  2147  	return n;
  2148  }
  2149  
  2150  /*
  2151   * from ascompat[te]
  2152   * evaluating actual function arguments.
  2153   *	f(a,b)
  2154   * if there is exactly one function expr,
  2155   * then it is done first. otherwise must
  2156   * make temp variables
  2157   */
  2158  static NodeList*
  2159  reorder1(NodeList *all)
  2160  {
  2161  	Node *f, *a, *n;
  2162  	NodeList *l, *r, *g;
  2163  	int c, d, t;
  2164  
  2165  	c = 0;	// function calls
  2166  	t = 0;	// total parameters
  2167  
  2168  	for(l=all; l; l=l->next) {
  2169  		n = l->n;
  2170  		t++;
  2171  		ullmancalc(n);
  2172  		if(n->ullman >= UINF)
  2173  			c++;
  2174  	}
  2175  	if(c == 0 || t == 1)
  2176  		return all;
  2177  
  2178  	g = nil;	// fncalls assigned to tempnames
  2179  	f = N;	// last fncall assigned to stack
  2180  	r = nil;	// non fncalls and tempnames assigned to stack
  2181  	d = 0;
  2182  	for(l=all; l; l=l->next) {
  2183  		n = l->n;
  2184  		if(n->ullman < UINF) {
  2185  			r = list(r, n);
  2186  			continue;
  2187  		}
  2188  		d++;
  2189  		if(d == c) {
  2190  			f = n;
  2191  			continue;
  2192  		}
  2193  
  2194  		// make assignment of fncall to tempname
  2195  		a = temp(n->right->type);
  2196  		a = nod(OAS, a, n->right);
  2197  		g = list(g, a);
  2198  
  2199  		// put normal arg assignment on list
  2200  		// with fncall replaced by tempname
  2201  		n->right = a->left;
  2202  		r = list(r, n);
  2203  	}
  2204  
  2205  	if(f != N)
  2206  		g = list(g, f);
  2207  	return concat(g, r);
  2208  }
  2209  
  2210  static void reorder3save(Node**, NodeList*, NodeList*, NodeList**);
  2211  static int aliased(Node*, NodeList*, NodeList*);
  2212  
  2213  /*
  2214   * from ascompat[ee]
  2215   *	a,b = c,d
  2216   * simultaneous assignment. there cannot
  2217   * be later use of an earlier lvalue.
  2218   *
  2219   * function calls have been removed.
  2220   */
  2221  static NodeList*
  2222  reorder3(NodeList *all)
  2223  {
  2224  	NodeList *list, *early, *mapinit;
  2225  	Node *l;
  2226  
  2227  	// If a needed expression may be affected by an
  2228  	// earlier assignment, make an early copy of that
  2229  	// expression and use the copy instead.
  2230  	early = nil;
  2231  	mapinit = nil;
  2232  	for(list=all; list; list=list->next) {
  2233  		l = list->n->left;
  2234  
  2235  		// Save subexpressions needed on left side.
  2236  		// Drill through non-dereferences.
  2237  		for(;;) {
  2238  			if(l->op == ODOT || l->op == OPAREN) {
  2239  				l = l->left;
  2240  				continue;
  2241  			}
  2242  			if(l->op == OINDEX && isfixedarray(l->left->type)) {
  2243  				reorder3save(&l->right, all, list, &early);
  2244  				l = l->left;
  2245  				continue;
  2246  			}
  2247  			break;
  2248  		}
  2249  		switch(l->op) {
  2250  		default:
  2251  			fatal("reorder3 unexpected lvalue %#O", l->op);
  2252  		case ONAME:
  2253  			break;
  2254  		case OINDEX:
  2255  		case OINDEXMAP:
  2256  			reorder3save(&l->left, all, list, &early);
  2257  			reorder3save(&l->right, all, list, &early);
  2258  			if(l->op == OINDEXMAP)
  2259  				list->n = convas(list->n, &mapinit);
  2260  			break;
  2261  		case OIND:
  2262  		case ODOTPTR:
  2263  			reorder3save(&l->left, all, list, &early);
  2264  		}
  2265  
  2266  		// Save expression on right side.
  2267  		reorder3save(&list->n->right, all, list, &early);
  2268  	}
  2269  
  2270  	early = concat(mapinit, early);
  2271  	return concat(early, all);
  2272  }
  2273  
  2274  static int vmatch2(Node*, Node*);
  2275  static int varexpr(Node*);
  2276  
  2277  /*
  2278   * if the evaluation of *np would be affected by the 
  2279   * assignments in all up to but not including stop,
  2280   * copy into a temporary during *early and
  2281   * replace *np with that temp.
  2282   */
  2283  static void
  2284  reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early)
  2285  {
  2286  	Node *n, *q;
  2287  
  2288  	n = *np;
  2289  	if(!aliased(n, all, stop))
  2290  		return;
  2291  	
  2292  	q = temp(n->type);
  2293  	q = nod(OAS, q, n);
  2294  	typecheck(&q, Etop);
  2295  	*early = list(*early, q);
  2296  	*np = q->left;
  2297  }
  2298  
  2299  /*
  2300   * what's the outer value that a write to n affects?
  2301   * outer value means containing struct or array.
  2302   */
  2303  Node*
  2304  outervalue(Node *n)
  2305  {	
  2306  	for(;;) {
  2307  		if(n->op == ODOT || n->op == OPAREN) {
  2308  			n = n->left;
  2309  			continue;
  2310  		}
  2311  		if(n->op == OINDEX && isfixedarray(n->left->type)) {
  2312  			n = n->left;
  2313  			continue;
  2314  		}
  2315  		break;
  2316  	}
  2317  	return n;
  2318  }
  2319  
  2320  /*
  2321   * Is it possible that the computation of n might be
  2322   * affected by writes in as up to but not including stop?
  2323   */
  2324  static int
  2325  aliased(Node *n, NodeList *all, NodeList *stop)
  2326  {
  2327  	int memwrite, varwrite;
  2328  	Node *a;
  2329  	NodeList *l;
  2330  
  2331  	if(n == N)
  2332  		return 0;
  2333  
  2334  	// Look for obvious aliasing: a variable being assigned
  2335  	// during the all list and appearing in n.
  2336  	// Also record whether there are any writes to main memory.
  2337  	// Also record whether there are any writes to variables
  2338  	// whose addresses have been taken.
  2339  	memwrite = 0;
  2340  	varwrite = 0;
  2341  	for(l=all; l!=stop; l=l->next) {
  2342  		a = outervalue(l->n->left);
  2343  		if(a->op != ONAME) {
  2344  			memwrite = 1;
  2345  			continue;
  2346  		}
  2347  		switch(n->class) {
  2348  		default:
  2349  			varwrite = 1;
  2350  			continue;
  2351  		case PAUTO:
  2352  		case PPARAM:
  2353  		case PPARAMOUT:
  2354  			if(n->addrtaken) {
  2355  				varwrite = 1;
  2356  				continue;
  2357  			}
  2358  			if(vmatch2(a, n)) {
  2359  				// Direct hit.
  2360  				return 1;
  2361  			}
  2362  		}
  2363  	}
  2364  
  2365  	// The variables being written do not appear in n.
  2366  	// However, n might refer to computed addresses
  2367  	// that are being written.
  2368  	
  2369  	// If no computed addresses are affected by the writes, no aliasing.
  2370  	if(!memwrite && !varwrite)
  2371  		return 0;
  2372  
  2373  	// If n does not refer to computed addresses
  2374  	// (that is, if n only refers to variables whose addresses
  2375  	// have not been taken), no aliasing.
  2376  	if(varexpr(n))
  2377  		return 0;
  2378  
  2379  	// Otherwise, both the writes and n refer to computed memory addresses.
  2380  	// Assume that they might conflict.
  2381  	return 1;
  2382  }
  2383  
  2384  /*
  2385   * does the evaluation of n only refer to variables
  2386   * whose addresses have not been taken?
  2387   * (and no other memory)
  2388   */
  2389  static int
  2390  varexpr(Node *n)
  2391  {
  2392  	if(n == N)
  2393  		return 1;
  2394  
  2395  	switch(n->op) {
  2396  	case OLITERAL:	
  2397  		return 1;
  2398  	case ONAME:
  2399  		switch(n->class) {
  2400  		case PAUTO:
  2401  		case PPARAM:
  2402  		case PPARAMOUT:
  2403  			if(!n->addrtaken)
  2404  				return 1;
  2405  		}
  2406  		return 0;
  2407  
  2408  	case OADD:
  2409  	case OSUB:
  2410  	case OOR:
  2411  	case OXOR:
  2412  	case OMUL:
  2413  	case ODIV:
  2414  	case OMOD:
  2415  	case OLSH:
  2416  	case ORSH:
  2417  	case OAND:
  2418  	case OANDNOT:
  2419  	case OPLUS:
  2420  	case OMINUS:
  2421  	case OCOM:
  2422  	case OPAREN:
  2423  	case OANDAND:
  2424  	case OOROR:
  2425  	case ODOT:  // but not ODOTPTR
  2426  	case OCONV:
  2427  	case OCONVNOP:
  2428  	case OCONVIFACE:
  2429  	case ODOTTYPE:
  2430  		return varexpr(n->left) && varexpr(n->right);
  2431  	}
  2432  
  2433  	// Be conservative.
  2434  	return 0;
  2435  }
  2436  
  2437  /*
  2438   * is the name l mentioned in r?
  2439   */
  2440  static int
  2441  vmatch2(Node *l, Node *r)
  2442  {
  2443  	NodeList *ll;
  2444  
  2445  	if(r == N)
  2446  		return 0;
  2447  	switch(r->op) {
  2448  	case ONAME:
  2449  		// match each right given left
  2450  		return l == r;
  2451  	case OLITERAL:
  2452  		return 0;
  2453  	}
  2454  	if(vmatch2(l, r->left))
  2455  		return 1;
  2456  	if(vmatch2(l, r->right))
  2457  		return 1;
  2458  	for(ll=r->list; ll; ll=ll->next)
  2459  		if(vmatch2(l, ll->n))
  2460  			return 1;
  2461  	return 0;
  2462  }
  2463  
  2464  /*
  2465   * is any name mentioned in l also mentioned in r?
  2466   * called by sinit.c
  2467   */
  2468  int
  2469  vmatch1(Node *l, Node *r)
  2470  {
  2471  	NodeList *ll;
  2472  
  2473  	/*
  2474  	 * isolate all left sides
  2475  	 */
  2476  	if(l == N || r == N)
  2477  		return 0;
  2478  	switch(l->op) {
  2479  	case ONAME:
  2480  		switch(l->class) {
  2481  		case PPARAM:
  2482  		case PPARAMREF:
  2483  		case PAUTO:
  2484  			break;
  2485  		default:
  2486  			// assignment to non-stack variable
  2487  			// must be delayed if right has function calls.
  2488  			if(r->ullman >= UINF)
  2489  				return 1;
  2490  			break;
  2491  		}
  2492  		return vmatch2(l, r);
  2493  	case OLITERAL:
  2494  		return 0;
  2495  	}
  2496  	if(vmatch1(l->left, r))
  2497  		return 1;
  2498  	if(vmatch1(l->right, r))
  2499  		return 1;
  2500  	for(ll=l->list; ll; ll=ll->next)
  2501  		if(vmatch1(ll->n, r))
  2502  			return 1;
  2503  	return 0;
  2504  }
  2505  
  2506  /*
  2507   * walk through argin parameters.
  2508   * generate and return code to allocate
  2509   * copies of escaped parameters to the heap.
  2510   */
  2511  static NodeList*
  2512  paramstoheap(Type **argin, int out)
  2513  {
  2514  	Type *t;
  2515  	Iter savet;
  2516  	Node *v, *as;
  2517  	NodeList *nn;
  2518  
  2519  	nn = nil;
  2520  	for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
  2521  		v = t->nname;
  2522  		if(v && v->sym && v->sym->name[0] == '~' && v->sym->name[1] == 'r') // unnamed result
  2523  			v = N;
  2524  		// In precisestack mode, the garbage collector assumes results
  2525  		// are always live, so zero them always.
  2526  		if(out && (precisestack_enabled || (v == N && hasdefer))) {
  2527  			// Defer might stop a panic and show the
  2528  			// return values as they exist at the time of panic.
  2529  			// Make sure to zero them on entry to the function.
  2530  			nn = list(nn, nod(OAS, nodarg(t, 1), N));
  2531  		}
  2532  		if(v == N || !(v->class & PHEAP))
  2533  			continue;
  2534  
  2535  		// generate allocation & copying code
  2536  		if(compiling_runtime)
  2537  			yyerror("%N escapes to heap, not allowed in runtime.", v);
  2538  		if(v->alloc == nil)
  2539  			v->alloc = callnew(v->type);
  2540  		nn = list(nn, nod(OAS, v->heapaddr, v->alloc));
  2541  		if((v->class & ~PHEAP) != PPARAMOUT) {
  2542  			as = nod(OAS, v, v->stackparam);
  2543  			v->stackparam->typecheck = 1;
  2544  			typecheck(&as, Etop);
  2545  			as = applywritebarrier(as, &nn);
  2546  			nn = list(nn, as);
  2547  		}
  2548  	}
  2549  	return nn;
  2550  }
  2551  
  2552  /*
  2553   * walk through argout parameters copying back to stack
  2554   */
  2555  static NodeList*
  2556  returnsfromheap(Type **argin)
  2557  {
  2558  	Type *t;
  2559  	Iter savet;
  2560  	Node *v;
  2561  	NodeList *nn;
  2562  
  2563  	nn = nil;
  2564  	for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
  2565  		v = t->nname;
  2566  		if(v == N || v->class != (PHEAP|PPARAMOUT))
  2567  			continue;
  2568  		nn = list(nn, nod(OAS, v->stackparam, v));
  2569  	}
  2570  	return nn;
  2571  }
  2572  
  2573  /*
  2574   * take care of migrating any function in/out args
  2575   * between the stack and the heap.  adds code to
  2576   * curfn's before and after lists.
  2577   */
  2578  static void
  2579  heapmoves(void)
  2580  {
  2581  	NodeList *nn;
  2582  	int32 lno;
  2583  
  2584  	lno = lineno;
  2585  	lineno = curfn->lineno;
  2586  	nn = paramstoheap(getthis(curfn->type), 0);
  2587  	nn = concat(nn, paramstoheap(getinarg(curfn->type), 0));
  2588  	nn = concat(nn, paramstoheap(getoutarg(curfn->type), 1));
  2589  	curfn->enter = concat(curfn->enter, nn);
  2590  	lineno = curfn->endlineno;
  2591  	curfn->exit = returnsfromheap(getoutarg(curfn->type));
  2592  	lineno = lno;
  2593  }
  2594  
  2595  static Node*
  2596  vmkcall(Node *fn, Type *t, NodeList **init, va_list va)
  2597  {
  2598  	int i, n;
  2599  	Node *r;
  2600  	NodeList *args;
  2601  
  2602  	if(fn->type == T || fn->type->etype != TFUNC)
  2603  		fatal("mkcall %N %T", fn, fn->type);
  2604  
  2605  	args = nil;
  2606  	n = fn->type->intuple;
  2607  	for(i=0; i<n; i++)
  2608  		args = list(args, va_arg(va, Node*));
  2609  
  2610  	r = nod(OCALL, fn, N);
  2611  	r->list = args;
  2612  	if(fn->type->outtuple > 0)
  2613  		typecheck(&r, Erv | Efnstruct);
  2614  	else
  2615  		typecheck(&r, Etop);
  2616  	walkexpr(&r, init);
  2617  	r->type = t;
  2618  	return r;
  2619  }
  2620  
  2621  Node*
  2622  mkcall(char *name, Type *t, NodeList **init, ...)
  2623  {
  2624  	Node *r;
  2625  	va_list va;
  2626  
  2627  	va_start(va, init);
  2628  	r = vmkcall(syslook(name, 0), t, init, va);
  2629  	va_end(va);
  2630  	return r;
  2631  }
  2632  
  2633  Node*
  2634  mkcall1(Node *fn, Type *t, NodeList **init, ...)
  2635  {
  2636  	Node *r;
  2637  	va_list va;
  2638  
  2639  	va_start(va, init);
  2640  	r = vmkcall(fn, t, init, va);
  2641  	va_end(va);
  2642  	return r;
  2643  }
  2644  
  2645  Node*
  2646  conv(Node *n, Type *t)
  2647  {
  2648  	if(eqtype(n->type, t))
  2649  		return n;
  2650  	n = nod(OCONV, n, N);
  2651  	n->type = t;
  2652  	typecheck(&n, Erv);
  2653  	return n;
  2654  }
  2655  
  2656  Node*
  2657  chanfn(char *name, int n, Type *t)
  2658  {
  2659  	Node *fn;
  2660  	int i;
  2661  
  2662  	if(t->etype != TCHAN)
  2663  		fatal("chanfn %T", t);
  2664  	fn = syslook(name, 1);
  2665  	for(i=0; i<n; i++)
  2666  		argtype(fn, t->type);
  2667  	return fn;
  2668  }
  2669  
  2670  static Node*
  2671  mapfn(char *name, Type *t)
  2672  {
  2673  	Node *fn;
  2674  
  2675  	if(t->etype != TMAP)
  2676  		fatal("mapfn %T", t);
  2677  	fn = syslook(name, 1);
  2678  	argtype(fn, t->down);
  2679  	argtype(fn, t->type);
  2680  	argtype(fn, t->down);
  2681  	argtype(fn, t->type);
  2682  	return fn;
  2683  }
  2684  
  2685  static Node*
  2686  mapfndel(char *name, Type *t)
  2687  {
  2688  	Node *fn;
  2689  
  2690  	if(t->etype != TMAP)
  2691  		fatal("mapfn %T", t);
  2692  	fn = syslook(name, 1);
  2693  	argtype(fn, t->down);
  2694  	argtype(fn, t->type);
  2695  	argtype(fn, t->down);
  2696  	return fn;
  2697  }
  2698  
  2699  static Node*
  2700  writebarrierfn(char *name, Type *l, Type *r)
  2701  {
  2702  	Node *fn;
  2703  
  2704  	fn = syslook(name, 1);
  2705  	argtype(fn, l);
  2706  	argtype(fn, r);
  2707  	return fn;
  2708  }
  2709  
  2710  static Node*
  2711  addstr(Node *n, NodeList **init)
  2712  {
  2713  	Node *r, *cat, *slice;
  2714  	NodeList *args, *l;
  2715  	int c;
  2716  	Type *t;
  2717  
  2718  	// orderexpr rewrote OADDSTR to have a list of strings.
  2719  	c = count(n->list);
  2720  	if(c < 2)
  2721  		yyerror("addstr count %d too small", c);
  2722  
  2723  	// build list of string arguments
  2724  	args = nil;
  2725  	for(l=n->list; l != nil; l=l->next)
  2726  		args = list(args, conv(l->n, types[TSTRING]));
  2727  
  2728  	if(c <= 5) {
  2729  		// small numbers of strings use direct runtime helpers.
  2730  		// note: orderexpr knows this cutoff too.
  2731  		snprint(namebuf, sizeof(namebuf), "concatstring%d", c);
  2732  	} else {
  2733  		// large numbers of strings are passed to the runtime as a slice.
  2734  		strcpy(namebuf, "concatstrings");
  2735  		t = typ(TARRAY);
  2736  		t->type = types[TSTRING];
  2737  		t->bound = -1;
  2738  		slice = nod(OCOMPLIT, N, typenod(t));
  2739  		slice->alloc = n->alloc;
  2740  		slice->list = args;
  2741  		slice->esc = EscNone;
  2742  		args = list1(slice);
  2743  	}
  2744  	cat = syslook(namebuf, 1);
  2745  	r = nod(OCALL, cat, N);
  2746  	r->list = args;
  2747  	typecheck(&r, Erv);
  2748  	walkexpr(&r, init);
  2749  	r->type = n->type;
  2750  
  2751  	return r;
  2752  }
  2753  
  2754  // expand append(l1, l2...) to
  2755  //   init {
  2756  //     s := l1
  2757  //     if n := len(l1) + len(l2) - cap(s); n > 0 {
  2758  //       s = growslice(s, n)
  2759  //     }
  2760  //     s = s[:len(l1)+len(l2)]
  2761  //     memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
  2762  //   }
  2763  //   s
  2764  //
  2765  // l2 is allowed to be a string.
  2766  static Node*
  2767  appendslice(Node *n, NodeList **init)
  2768  {
  2769  	NodeList *l;
  2770  	Node *l1, *l2, *nt, *nif, *fn;
  2771  	Node *nptr1, *nptr2, *nwid;
  2772  	Node *s;
  2773  
  2774  	walkexprlistsafe(n->list, init);
  2775  
  2776  	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
  2777  	// and n are name or literal, but those may index the slice we're
  2778  	// modifying here.  Fix explicitly.
  2779  	for(l=n->list; l; l=l->next)
  2780  		l->n = cheapexpr(l->n, init);
  2781  
  2782  	l1 = n->list->n;
  2783  	l2 = n->list->next->n;
  2784  
  2785  	s = temp(l1->type); // var s []T
  2786  	l = nil;
  2787  	l = list(l, nod(OAS, s, l1)); // s = l1
  2788  
  2789  	nt = temp(types[TINT]);
  2790  	nif = nod(OIF, N, N);
  2791  	// n := len(s) + len(l2) - cap(s)
  2792  	nif->ninit = list1(nod(OAS, nt,
  2793  		nod(OSUB, nod(OADD, nod(OLEN, s, N), nod(OLEN, l2, N)), nod(OCAP, s, N))));
  2794  	nif->ntest = nod(OGT, nt, nodintconst(0));
  2795  	// instantiate growslice(Type*, []any, int64) []any
  2796  	fn = syslook("growslice", 1);
  2797  	argtype(fn, s->type->type);
  2798  	argtype(fn, s->type->type);
  2799  
  2800  	// s = growslice(T, s, n)
  2801  	nif->nbody = list1(nod(OAS, s, mkcall1(fn, s->type, &nif->ninit,
  2802  					       typename(s->type),
  2803  					       s,
  2804  					       conv(nt, types[TINT64]))));
  2805  
  2806  	l = list(l, nif);
  2807  
  2808  	if(haspointers(l1->type->type)) {
  2809  		// copy(s[len(l1):len(l1)+len(l2)], l2)
  2810  		nptr1 = nod(OSLICE, s, nod(OKEY,
  2811  			nod(OLEN, l1, N),
  2812  			nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N))));
  2813  		nptr1->etype = 1;
  2814  		nptr2 = l2;
  2815  		fn = syslook("typedslicecopy", 1);
  2816  		argtype(fn, l1->type);
  2817  		argtype(fn, l2->type);
  2818  		nt = mkcall1(fn, types[TINT], &l,
  2819  				typename(l1->type->type),
  2820  				nptr1, nptr2);
  2821  		l = list(l, nt);
  2822  	} else if(flag_race) {
  2823  		// rely on runtime to instrument copy.
  2824  		// copy(s[len(l1):len(l1)+len(l2)], l2)
  2825  		nptr1 = nod(OSLICE, s, nod(OKEY,
  2826  			nod(OLEN, l1, N),
  2827  			nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N))));
  2828  		nptr1->etype = 1;
  2829  		nptr2 = l2;
  2830  		if(l2->type->etype == TSTRING)
  2831  			fn = syslook("slicestringcopy", 1);
  2832  		else
  2833  			fn = syslook("slicecopy", 1);
  2834  		argtype(fn, l1->type);
  2835  		argtype(fn, l2->type);
  2836  		nt = mkcall1(fn, types[TINT], &l,
  2837  				nptr1, nptr2,
  2838  				nodintconst(s->type->type->width));
  2839  		l = list(l, nt);
  2840  	} else {
  2841  		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
  2842  		nptr1 = nod(OINDEX, s, nod(OLEN, l1, N));
  2843  		nptr1->bounded = 1;
  2844  		nptr1 = nod(OADDR, nptr1, N);
  2845  
  2846  		nptr2 = nod(OSPTR, l2, N);
  2847  
  2848  		fn = syslook("memmove", 1);
  2849  		argtype(fn, s->type->type);	// 1 old []any
  2850  		argtype(fn, s->type->type);	// 2 ret []any
  2851  
  2852  		nwid = cheapexpr(conv(nod(OLEN, l2, N), types[TUINTPTR]), &l);
  2853  		nwid = nod(OMUL, nwid, nodintconst(s->type->type->width));
  2854  		nt = mkcall1(fn, T, &l, nptr1, nptr2, nwid);
  2855  		l = list(l, nt);
  2856  	}
  2857  
  2858  	// s = s[:len(l1)+len(l2)]
  2859  	nt = nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N));
  2860  	nt = nod(OSLICE, s, nod(OKEY, N, nt));
  2861  	nt->etype = 1;
  2862  	l = list(l, nod(OAS, s, nt));
  2863  
  2864  	typechecklist(l, Etop);
  2865  	walkstmtlist(l);
  2866  	*init = concat(*init, l);
  2867  	return s;
  2868  }
  2869  
  2870  // expand append(src, a [, b]* ) to
  2871  //
  2872  //   init {
  2873  //     s := src
  2874  //     const argc = len(args) - 1
  2875  //     if cap(s) - len(s) < argc {
  2876  //	    s = growslice(s, argc)
  2877  //     }
  2878  //     n := len(s)
  2879  //     s = s[:n+argc]
  2880  //     s[n] = a
  2881  //     s[n+1] = b
  2882  //     ...
  2883  //   }
  2884  //   s
  2885  static Node*
  2886  append(Node *n, NodeList **init)
  2887  {
  2888  	NodeList *l, *a;
  2889  	Node *nsrc, *ns, *nn, *na, *nx, *fn;
  2890  	int argc;
  2891  
  2892  	walkexprlistsafe(n->list, init);
  2893  
  2894  	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
  2895  	// and n are name or literal, but those may index the slice we're
  2896  	// modifying here.  Fix explicitly.
  2897  	for(l=n->list; l; l=l->next)
  2898  		l->n = cheapexpr(l->n, init);
  2899  
  2900  	nsrc = n->list->n;
  2901  
  2902  	// Resolve slice type of multi-valued return.
  2903  	if(istype(nsrc->type, TSTRUCT))
  2904  		nsrc->type = nsrc->type->type->type;
  2905  	argc = count(n->list) - 1;
  2906  	if (argc < 1) {
  2907  		return nsrc;
  2908  	}
  2909  
  2910  	l = nil;
  2911  
  2912  	ns = temp(nsrc->type);
  2913  	l = list(l, nod(OAS, ns, nsrc));  // s = src
  2914  
  2915  	na = nodintconst(argc);		// const argc
  2916  	nx = nod(OIF, N, N);		// if cap(s) - len(s) < argc
  2917  	nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na);
  2918  
  2919  	fn = syslook("growslice", 1);	//   growslice(<type>, old []T, n int64) (ret []T)
  2920  	argtype(fn, ns->type->type);	// 1 old []any
  2921  	argtype(fn, ns->type->type);	// 2 ret []any
  2922  
  2923  	nx->nbody = list1(nod(OAS, ns, mkcall1(fn,  ns->type, &nx->ninit,
  2924  					       typename(ns->type),
  2925  					       ns,
  2926  					       conv(na, types[TINT64]))));
  2927  	l = list(l, nx);
  2928  
  2929  	nn = temp(types[TINT]);
  2930  	l = list(l, nod(OAS, nn, nod(OLEN, ns, N)));	 // n = len(s)
  2931  
  2932  	nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na)));	 // ...s[:n+argc]
  2933  	nx->etype = 1;
  2934  	l = list(l, nod(OAS, ns, nx));			// s = s[:n+argc]
  2935  
  2936  	for (a = n->list->next;	 a != nil; a = a->next) {
  2937  		nx = nod(OINDEX, ns, nn);		// s[n] ...
  2938  		nx->bounded = 1;
  2939  		l = list(l, nod(OAS, nx, a->n));	// s[n] = arg
  2940  		if (a->next != nil)
  2941  			l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1))));  // n = n + 1
  2942  	}
  2943  
  2944  	typechecklist(l, Etop);
  2945  	walkstmtlist(l);
  2946  	*init = concat(*init, l);
  2947  	return ns;
  2948  }
  2949  
  2950  // Lower copy(a, b) to a memmove call or a runtime call.
  2951  //
  2952  // init {
  2953  //   n := len(a)
  2954  //   if n > len(b) { n = len(b) }
  2955  //   memmove(a.ptr, b.ptr, n*sizeof(elem(a)))
  2956  // }
  2957  // n;
  2958  //
  2959  // Also works if b is a string.
  2960  //
  2961  static Node*
  2962  copyany(Node *n, NodeList **init, int runtimecall)
  2963  {
  2964  	Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
  2965  	NodeList *l;
  2966  	
  2967  	if(haspointers(n->left->type->type)) {
  2968  		fn = writebarrierfn("typedslicecopy", n->left->type, n->right->type);
  2969  		return mkcall1(fn, n->type, init, typename(n->left->type->type), n->left, n->right);
  2970  	}
  2971  
  2972  	if(runtimecall) {
  2973  		if(n->right->type->etype == TSTRING)
  2974  			fn = syslook("slicestringcopy", 1);
  2975  		else
  2976  			fn = syslook("slicecopy", 1);
  2977  		argtype(fn, n->left->type);
  2978  		argtype(fn, n->right->type);
  2979  		return mkcall1(fn, n->type, init,
  2980  				n->left, n->right,
  2981  				nodintconst(n->left->type->type->width));
  2982  	}
  2983  	walkexpr(&n->left, init);
  2984  	walkexpr(&n->right, init);
  2985  	nl = temp(n->left->type);
  2986  	nr = temp(n->right->type);
  2987  	l = nil;
  2988  	l = list(l, nod(OAS, nl, n->left));
  2989  	l = list(l, nod(OAS, nr, n->right));
  2990  
  2991  	nfrm = nod(OSPTR, nr, N);
  2992  	nto = nod(OSPTR, nl, N);
  2993  
  2994  	nlen = temp(types[TINT]);
  2995  	// n = len(to)
  2996  	l = list(l, nod(OAS, nlen, nod(OLEN, nl, N)));
  2997  	// if n > len(frm) { n = len(frm) }
  2998  	nif = nod(OIF, N, N);
  2999  	nif->ntest = nod(OGT, nlen, nod(OLEN, nr, N));
  3000  	nif->nbody = list(nif->nbody,
  3001  		nod(OAS, nlen, nod(OLEN, nr, N)));
  3002  	l = list(l, nif);
  3003  
  3004  	// Call memmove.
  3005  	fn = syslook("memmove", 1);
  3006  	argtype(fn, nl->type->type);
  3007  	argtype(fn, nl->type->type);
  3008  	nwid = temp(types[TUINTPTR]);
  3009  	l = list(l, nod(OAS, nwid, conv(nlen, types[TUINTPTR])));
  3010  	nwid = nod(OMUL, nwid, nodintconst(nl->type->type->width));
  3011  	l = list(l, mkcall1(fn, T, init, nto, nfrm, nwid));
  3012  
  3013  	typechecklist(l, Etop);
  3014  	walkstmtlist(l);
  3015  	*init = concat(*init, l);
  3016  	return nlen;
  3017  }
  3018  
  3019  // Generate frontend part for OSLICE[3][ARR|STR]
  3020  // 
  3021  static	Node*
  3022  sliceany(Node* n, NodeList **init)
  3023  {
  3024  	int bounded, slice3;
  3025  	Node *src, *lb, *hb, *cb, *bound, *chk, *chk0, *chk1, *chk2;
  3026  	int64 lbv, hbv, cbv, bv, w;
  3027  	Type *bt;
  3028  
  3029  //	print("before sliceany: %+N\n", n);
  3030  
  3031  	src = n->left;
  3032  	lb = n->right->left;
  3033  	slice3 = n->op == OSLICE3 || n->op == OSLICE3ARR;
  3034  	if(slice3) {
  3035  		hb = n->right->right->left;
  3036  		cb = n->right->right->right;
  3037  	} else {
  3038  		hb = n->right->right;
  3039  		cb = N;
  3040  	}
  3041  
  3042  	bounded = n->etype;
  3043  	
  3044  	if(n->op == OSLICESTR)
  3045  		bound = nod(OLEN, src, N);
  3046  	else
  3047  		bound = nod(OCAP, src, N);
  3048  
  3049  	typecheck(&bound, Erv);
  3050  	walkexpr(&bound, init);  // if src is an array, bound will be a const now.
  3051  
  3052  	// static checks if possible
  3053  	bv = 1LL<<50;
  3054  	if(isconst(bound, CTINT)) {
  3055  		if(!smallintconst(bound))
  3056  			yyerror("array len too large");
  3057  		else
  3058  			bv = mpgetfix(bound->val.u.xval);
  3059  	}
  3060  
  3061  	if(isconst(cb, CTINT)) {
  3062  		cbv = mpgetfix(cb->val.u.xval);
  3063  		if(cbv < 0 || cbv > bv)
  3064  			yyerror("slice index out of bounds");
  3065  	}
  3066  	if(isconst(hb, CTINT)) {
  3067  		hbv = mpgetfix(hb->val.u.xval);
  3068  		if(hbv < 0 || hbv > bv)
  3069  			yyerror("slice index out of bounds");
  3070  	}
  3071  	if(isconst(lb, CTINT)) {
  3072  		lbv = mpgetfix(lb->val.u.xval);
  3073  		if(lbv < 0 || lbv > bv) {
  3074  			yyerror("slice index out of bounds");
  3075  			lbv = -1;
  3076  		}
  3077  		if(lbv == 0)
  3078  			lb = N;
  3079  	}
  3080  
  3081  	// Checking src[lb:hb:cb] or src[lb:hb].
  3082  	// if chk0 || chk1 || chk2 { panicslice() }
  3083  	chk = N;
  3084  	chk0 = N; // cap(src) < cb
  3085  	chk1 = N; // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
  3086  	chk2 = N; // hb < lb
  3087  
  3088  	// All comparisons are unsigned to avoid testing < 0.
  3089  	bt = types[simtype[TUINT]];
  3090  	if(cb != N && cb->type->width > 4)
  3091  		bt = types[TUINT64];
  3092  	if(hb != N && hb->type->width > 4)
  3093  		bt = types[TUINT64];
  3094  	if(lb != N && lb->type->width > 4)
  3095  		bt = types[TUINT64];
  3096  
  3097  	bound = cheapexpr(conv(bound, bt), init);
  3098  
  3099  	if(cb != N) {
  3100  		cb = cheapexpr(conv(cb, bt), init);
  3101  		if(!bounded)
  3102  			chk0 = nod(OLT, bound, cb);
  3103  	} else if(slice3) {
  3104  		// When we figure out what this means, implement it.
  3105  		fatal("slice3 with cb == N"); // rejected by parser
  3106  	}
  3107  		
  3108  	if(hb != N) {
  3109  		hb = cheapexpr(conv(hb, bt), init);
  3110  		if(!bounded) {
  3111  			if(cb != N)
  3112  				chk1 = nod(OLT, cb, hb);
  3113  			else
  3114  				chk1 = nod(OLT, bound, hb);
  3115  		}
  3116  	} else if(slice3) {
  3117  		// When we figure out what this means, implement it.
  3118  		fatal("slice3 with hb == N"); // rejected by parser
  3119  	} else if(n->op == OSLICEARR) {
  3120  		hb = bound;
  3121  	} else {
  3122  		hb = nod(OLEN, src, N);
  3123  		typecheck(&hb, Erv);
  3124  		walkexpr(&hb, init);
  3125  		hb = cheapexpr(conv(hb, bt), init);
  3126  	}
  3127  
  3128  	if(lb != N) {
  3129  		lb = cheapexpr(conv(lb, bt), init);
  3130  		if(!bounded)
  3131  			chk2 = nod(OLT, hb, lb);  
  3132  	}
  3133  
  3134  	if(chk0 != N || chk1 != N || chk2 != N) {
  3135  		chk = nod(OIF, N, N);
  3136  		chk->nbody = list1(mkcall("panicslice", T, init));
  3137  		chk->likely = -1;
  3138  		if(chk0 != N)
  3139  			chk->ntest = chk0;
  3140  		if(chk1 != N) {
  3141  			if(chk->ntest == N)
  3142  				chk->ntest = chk1;
  3143  			else
  3144  				chk->ntest = nod(OOROR, chk->ntest, chk1);
  3145  		}
  3146  		if(chk2 != N) {
  3147  			if(chk->ntest == N)
  3148  				chk->ntest = chk2;
  3149  			else
  3150  				chk->ntest = nod(OOROR, chk->ntest, chk2);
  3151  		}
  3152  		typecheck(&chk, Etop);
  3153  		walkstmt(&chk);
  3154  		*init = concat(*init, chk->ninit);
  3155  		chk->ninit = nil;
  3156  		*init = list(*init, chk);
  3157  	}
  3158  	
  3159  	// prepare new cap, len and offs for backend cgen_slice
  3160  	// cap = bound [ - lo ]
  3161  	n->right = N;
  3162  	n->list = nil;
  3163  	if(!slice3)
  3164  		cb = bound;
  3165  	if(lb == N)
  3166  		bound = conv(cb, types[simtype[TUINT]]);
  3167  	else
  3168  		bound = nod(OSUB, conv(cb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
  3169  	typecheck(&bound, Erv);
  3170  	walkexpr(&bound, init);
  3171  	n->list = list(n->list, bound);
  3172  
  3173  	// len = hi [ - lo]
  3174  	if(lb == N)
  3175  		hb = conv(hb, types[simtype[TUINT]]);
  3176  	else
  3177  		hb = nod(OSUB, conv(hb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
  3178  	typecheck(&hb, Erv);
  3179  	walkexpr(&hb, init);
  3180  	n->list = list(n->list, hb);
  3181  
  3182  	// offs = [width *] lo, but omit if zero
  3183  	if(lb != N) {
  3184  		if(n->op == OSLICESTR)
  3185  			w = 1;
  3186  		else
  3187  			w = n->type->type->width;
  3188  		lb = conv(lb, types[TUINTPTR]);
  3189  		if(w > 1)
  3190  			lb = nod(OMUL, nodintconst(w), lb);
  3191  		typecheck(&lb, Erv);
  3192  		walkexpr(&lb, init);
  3193  		n->list = list(n->list, lb);
  3194  	}
  3195  
  3196  //	print("after sliceany: %+N\n", n);
  3197  
  3198  	return n;
  3199  }
  3200  
  3201  static Node*
  3202  eqfor(Type *t, int *needsize)
  3203  {
  3204  	int a;
  3205  	Node *n;
  3206  	Node *ntype;
  3207  	Sym *sym;
  3208  
  3209  	// Should only arrive here with large memory or
  3210  	// a struct/array containing a non-memory field/element.
  3211  	// Small memory is handled inline, and single non-memory
  3212  	// is handled during type check (OCMPSTR etc).
  3213  	a = algtype1(t, nil);
  3214  	if(a != AMEM && a != -1)
  3215  		fatal("eqfor %T", t);
  3216  
  3217  	if(a == AMEM) {
  3218  		n = syslook("memequal", 1);
  3219  		argtype(n, t);
  3220  		argtype(n, t);
  3221  		*needsize = 1;
  3222  		return n;
  3223  	}
  3224  
  3225  	sym = typesymprefix(".eq", t);
  3226  	n = newname(sym);
  3227  	n->class = PFUNC;
  3228  	ntype = nod(OTFUNC, N, N);
  3229  	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
  3230  	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
  3231  	ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, N, typenod(types[TBOOL])));
  3232  	typecheck(&ntype, Etype);
  3233  	n->type = ntype->type;
  3234  	*needsize = 0;
  3235  	return n;
  3236  }
  3237  
  3238  static int
  3239  countfield(Type *t)
  3240  {
  3241  	Type *t1;
  3242  	int n;
  3243  	
  3244  	n = 0;
  3245  	for(t1=t->type; t1!=T; t1=t1->down)
  3246  		n++;
  3247  	return n;
  3248  }
  3249  
  3250  static void
  3251  walkcompare(Node **np, NodeList **init)
  3252  {
  3253  	Node *n, *l, *r, *call, *a, *li, *ri, *expr, *cmpl, *cmpr;
  3254  	int andor, i, needsize;
  3255  	Type *t, *t1;
  3256  	
  3257  	n = *np;
  3258  	
  3259  	// Must be comparison of array or struct.
  3260  	// Otherwise back end handles it.
  3261  	t = n->left->type;
  3262  	switch(t->etype) {
  3263  	default:
  3264  		return;
  3265  	case TARRAY:
  3266  		if(isslice(t))
  3267  			return;
  3268  		break;
  3269  	case TSTRUCT:
  3270  		break;
  3271  	}
  3272  	
  3273  	cmpl = n->left;
  3274  	while(cmpl != N && cmpl->op == OCONVNOP)
  3275  		cmpl = cmpl->left;
  3276  	cmpr = n->right;
  3277  	while(cmpr != N && cmpr->op == OCONVNOP)
  3278  		cmpr = cmpr->left;
  3279  	
  3280  	if(!islvalue(cmpl) || !islvalue(cmpr)) {
  3281  		fatal("arguments of comparison must be lvalues - %N %N", cmpl, cmpr);
  3282  	}
  3283  
  3284  	l = temp(ptrto(t));
  3285  	a = nod(OAS, l, nod(OADDR, cmpl, N));
  3286  	a->right->etype = 1;  // addr does not escape
  3287  	typecheck(&a, Etop);
  3288  	*init = list(*init, a);
  3289  
  3290  	r = temp(ptrto(t));
  3291  	a = nod(OAS, r, nod(OADDR, cmpr, N));
  3292  	a->right->etype = 1;  // addr does not escape
  3293  	typecheck(&a, Etop);
  3294  	*init = list(*init, a);
  3295  
  3296  	expr = N;
  3297  	andor = OANDAND;
  3298  	if(n->op == ONE)
  3299  		andor = OOROR;
  3300  
  3301  	if(t->etype == TARRAY &&
  3302  		t->bound <= 4 &&
  3303  		issimple[t->type->etype]) {
  3304  		// Four or fewer elements of a basic type.
  3305  		// Unroll comparisons.
  3306  		for(i=0; i<t->bound; i++) {
  3307  			li = nod(OINDEX, l, nodintconst(i));
  3308  			ri = nod(OINDEX, r, nodintconst(i));
  3309  			a = nod(n->op, li, ri);
  3310  			if(expr == N)
  3311  				expr = a;
  3312  			else
  3313  				expr = nod(andor, expr, a);
  3314  		}
  3315  		if(expr == N)
  3316  			expr = nodbool(n->op == OEQ);
  3317  		r = expr;
  3318  		goto ret;
  3319  	}
  3320  
  3321  	if(t->etype == TSTRUCT && countfield(t) <= 4) {
  3322  		// Struct of four or fewer fields.
  3323  		// Inline comparisons.
  3324  		for(t1=t->type; t1; t1=t1->down) {
  3325  			if(isblanksym(t1->sym))
  3326  				continue;
  3327  			li = nod(OXDOT, l, newname(t1->sym));
  3328  			ri = nod(OXDOT, r, newname(t1->sym));
  3329  			a = nod(n->op, li, ri);
  3330  			if(expr == N)
  3331  				expr = a;
  3332  			else
  3333  				expr = nod(andor, expr, a);
  3334  		}
  3335  		if(expr == N)
  3336  			expr = nodbool(n->op == OEQ);
  3337  		r = expr;
  3338  		goto ret;
  3339  	}
  3340  
  3341  	// Chose not to inline.  Call equality function directly.
  3342  	call = nod(OCALL, eqfor(t, &needsize), N);
  3343  	call->list = list(call->list, l);
  3344  	call->list = list(call->list, r);
  3345  	if(needsize)
  3346  		call->list = list(call->list, nodintconst(t->width));
  3347  	r = call;
  3348  	if(n->op != OEQ)
  3349  		r = nod(ONOT, r, N);
  3350  	goto ret;
  3351  
  3352  ret:
  3353  	typecheck(&r, Erv);
  3354  	walkexpr(&r, init);
  3355  	if(r->type != n->type) {
  3356  		r = nod(OCONVNOP, r, N);
  3357  		r->type = n->type;
  3358  		r->typecheck = 1;
  3359  	}
  3360  	*np = r;
  3361  	return;
  3362  }
  3363  
  3364  static int
  3365  samecheap(Node *a, Node *b)
  3366  {
  3367  	Node *ar, *br;
  3368  	while(a != N && b != N && a->op == b->op) {
  3369  		switch(a->op) {
  3370  		default:
  3371  			return 0;
  3372  		case ONAME:
  3373  			return a == b;
  3374  		case ODOT:
  3375  		case ODOTPTR:
  3376  			ar = a->right;
  3377  			br = b->right;
  3378  			if(ar->op != ONAME || br->op != ONAME || ar->sym != br->sym)
  3379  				return 0;
  3380  			break;
  3381  		case OINDEX:
  3382  			ar = a->right;
  3383  			br = b->right;
  3384  			if(!isconst(ar, CTINT) || !isconst(br, CTINT) || mpcmpfixfix(ar->val.u.xval, br->val.u.xval) != 0)
  3385  				return 0;
  3386  			break;
  3387  		}
  3388  		a = a->left;
  3389  		b = b->left;
  3390  	}
  3391  	return 0;
  3392  }
  3393  
  3394  static void
  3395  walkrotate(Node **np)
  3396  {
  3397  	int w, sl, sr, s;
  3398  	Node *l, *r;
  3399  	Node *n;
  3400  
  3401  	if(thechar == '9')
  3402  		return;
  3403  	
  3404  	n = *np;
  3405  
  3406  	// Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value.
  3407  	l = n->left;
  3408  	r = n->right;
  3409  	if((n->op != OOR && n->op != OXOR) ||
  3410  	   (l->op != OLSH && l->op != ORSH) ||
  3411  	   (r->op != OLSH && r->op != ORSH) ||
  3412  	   n->type == T || issigned[n->type->etype] ||
  3413  	   l->op == r->op) {
  3414  		return;
  3415  	}
  3416  
  3417  	// Want same, side effect-free expression on lhs of both shifts.
  3418  	if(!samecheap(l->left, r->left))
  3419  		return;
  3420  	
  3421  	// Constants adding to width?
  3422  	w = l->type->width * 8;
  3423  	if(smallintconst(l->right) && smallintconst(r->right)) {
  3424  		if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 0 && sl+sr == w)
  3425  			goto yes;
  3426  		return;
  3427  	}
  3428  	
  3429  	// TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
  3430  	return;
  3431  	
  3432  yes:
  3433  	// Rewrite left shift half to left rotate.
  3434  	if(l->op == OLSH)
  3435  		n = l;
  3436  	else
  3437  		n = r;
  3438  	n->op = OLROT;
  3439  	
  3440  	// Remove rotate 0 and rotate w.
  3441  	s = mpgetfix(n->right->val.u.xval);
  3442  	if(s == 0 || s == w)
  3443  		n = n->left;
  3444  
  3445  	*np = n;
  3446  	return;
  3447  }
  3448  
  3449  /*
  3450   * walkmul rewrites integer multiplication by powers of two as shifts.
  3451   */
  3452  static void
  3453  walkmul(Node **np, NodeList **init)
  3454  {
  3455  	Node *n, *nl, *nr;
  3456  	int pow, neg, w;
  3457  	
  3458  	n = *np;
  3459  	if(!isint[n->type->etype])
  3460  		return;
  3461  
  3462  	if(n->right->op == OLITERAL) {
  3463  		nl = n->left;
  3464  		nr = n->right;
  3465  	} else if(n->left->op == OLITERAL) {
  3466  		nl = n->right;
  3467  		nr = n->left;
  3468  	} else
  3469  		return;
  3470  
  3471  	neg = 0;
  3472  
  3473  	// x*0 is 0 (and side effects of x).
  3474  	if(mpgetfix(nr->val.u.xval) == 0) {
  3475  		cheapexpr(nl, init);
  3476  		nodconst(n, n->type, 0);
  3477  		goto ret;
  3478  	}
  3479  
  3480  	// nr is a constant.
  3481  	pow = powtwo(nr);
  3482  	if(pow < 0)
  3483  		return;
  3484  	if(pow >= 1000) {
  3485  		// negative power of 2, like -16
  3486  		neg = 1;
  3487  		pow -= 1000;
  3488  	}
  3489  
  3490  	w = nl->type->width*8;
  3491  	if(pow+1 >= w)// too big, shouldn't happen
  3492  		return;
  3493  
  3494  	nl = cheapexpr(nl, init);
  3495  
  3496  	if(pow == 0) {
  3497  		// x*1 is x
  3498  		n = nl;
  3499  		goto ret;
  3500  	}
  3501  	
  3502  	n = nod(OLSH, nl, nodintconst(pow));
  3503  
  3504  ret:
  3505  	if(neg)
  3506  		n = nod(OMINUS, n, N);
  3507  
  3508  	typecheck(&n, Erv);
  3509  	walkexpr(&n, init);
  3510  	*np = n;
  3511  }
  3512  
  3513  /*
  3514   * walkdiv rewrites division by a constant as less expensive
  3515   * operations.
  3516   */
  3517  static void
  3518  walkdiv(Node **np, NodeList **init)
  3519  {
  3520  	Node *n, *nl, *nr, *nc;
  3521  	Node *n1, *n2, *n3, *n4;
  3522  	int pow; // if >= 0, nr is 1<<pow
  3523  	int s; // 1 if nr is negative.
  3524  	int w;
  3525  	Type *twide;
  3526  	Magic m;
  3527  
  3528  	// TODO(minux)
  3529  	if(thechar == '9')
  3530  		return;
  3531  
  3532  	n = *np;
  3533  	if(n->right->op != OLITERAL)
  3534  		return;
  3535  	// nr is a constant.
  3536  	nl = cheapexpr(n->left, init);
  3537  	nr = n->right;
  3538  
  3539  	// special cases of mod/div
  3540  	// by a constant
  3541  	w = nl->type->width*8;
  3542  	s = 0;
  3543  	pow = powtwo(nr);
  3544  	if(pow >= 1000) {
  3545  		// negative power of 2
  3546  		s = 1;
  3547  		pow -= 1000;
  3548  	}
  3549  
  3550  	if(pow+1 >= w) {
  3551  		// divisor too large.
  3552  		return;
  3553  	}
  3554  	if(pow < 0) {
  3555  		goto divbymul;
  3556  	}
  3557  
  3558  	switch(pow) {
  3559  	case 0:
  3560  		if(n->op == OMOD) {
  3561  			// nl % 1 is zero.
  3562  			nodconst(n, n->type, 0);
  3563  		} else if(s) {
  3564  			// divide by -1
  3565  			n->op = OMINUS;
  3566  			n->right = N;
  3567  		} else {
  3568  			// divide by 1
  3569  			n = nl;
  3570  		}
  3571  		break;
  3572  	default:
  3573  		if(issigned[n->type->etype]) {
  3574  			if(n->op == OMOD) {
  3575  				// signed modulo 2^pow is like ANDing
  3576  				// with the last pow bits, but if nl < 0,
  3577  				// nl & (2^pow-1) is (nl+1)%2^pow - 1.
  3578  				nc = nod(OXXX, N, N);
  3579  				nodconst(nc, types[simtype[TUINT]], w-1);
  3580  				n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
  3581  				if(pow == 1) {
  3582  					typecheck(&n1, Erv);
  3583  					n1 = cheapexpr(n1, init);
  3584  					// n = (nl+ε)&1 -ε where ε=1 iff nl<0.
  3585  					n2 = nod(OSUB, nl, n1);
  3586  					nc = nod(OXXX, N, N);
  3587  					nodconst(nc, nl->type, 1);
  3588  					n3 = nod(OAND, n2, nc);
  3589  					n = nod(OADD, n3, n1);
  3590  				} else {
  3591  					// n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0.
  3592  					nc = nod(OXXX, N, N);
  3593  					nodconst(nc, nl->type, (1LL<<pow)-1);
  3594  					n2 = nod(OAND, n1, nc); // n2 = 2^pow-1 iff nl<0.
  3595  					typecheck(&n2, Erv);
  3596  					n2 = cheapexpr(n2, init);
  3597  
  3598  					n3 = nod(OADD, nl, n2);
  3599  					n4 = nod(OAND, n3, nc);
  3600  					n = nod(OSUB, n4, n2);
  3601  				}
  3602  				break;
  3603  			} else {
  3604  				// arithmetic right shift does not give the correct rounding.
  3605  				// if nl >= 0, nl >> n == nl / nr
  3606  				// if nl < 0, we want to add 2^n-1 first.
  3607  				nc = nod(OXXX, N, N);
  3608  				nodconst(nc, types[simtype[TUINT]], w-1);
  3609  				n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
  3610  				if(pow == 1) {
  3611  					// nl+1 is nl-(-1)
  3612  					n->left = nod(OSUB, nl, n1);
  3613  				} else {
  3614  					// Do a logical right right on -1 to keep pow bits.
  3615  					nc = nod(OXXX, N, N);
  3616  					nodconst(nc, types[simtype[TUINT]], w-pow);
  3617  					n2 = nod(ORSH, conv(n1, tounsigned(nl->type)), nc);
  3618  					n->left = nod(OADD, nl, conv(n2, nl->type));
  3619  				}
  3620  				// n = (nl + 2^pow-1) >> pow
  3621  				n->op = ORSH;
  3622  				nc = nod(OXXX, N, N);
  3623  				nodconst(nc, types[simtype[TUINT]], pow);
  3624  				n->right = nc;
  3625  				n->typecheck = 0;
  3626  			}
  3627  			if(s)
  3628  				n = nod(OMINUS, n, N);
  3629  			break;
  3630  		}
  3631  		nc = nod(OXXX, N, N);
  3632  		if(n->op == OMOD) {
  3633  			// n = nl & (nr-1)
  3634  			n->op = OAND;
  3635  			nodconst(nc, nl->type, mpgetfix(nr->val.u.xval)-1);
  3636  		} else {
  3637  			// n = nl >> pow
  3638  			n->op = ORSH;
  3639  			nodconst(nc, types[simtype[TUINT]], pow);
  3640  		}
  3641  		n->typecheck = 0;
  3642  		n->right = nc;
  3643  		break;
  3644  	}
  3645  	goto ret;
  3646  
  3647  divbymul:
  3648  	// try to do division by multiply by (2^w)/d
  3649  	// see hacker's delight chapter 10
  3650  	// TODO: support 64-bit magic multiply here.
  3651  	m.w = w;
  3652  	if(issigned[nl->type->etype]) {
  3653  		m.sd = mpgetfix(nr->val.u.xval);
  3654  		smagic(&m);
  3655  	} else {
  3656  		m.ud = mpgetfix(nr->val.u.xval);
  3657  		umagic(&m);
  3658  	}
  3659  	if(m.bad)
  3660  		return;
  3661  
  3662  	// We have a quick division method so use it
  3663  	// for modulo too.
  3664  	if(n->op == OMOD)
  3665  		goto longmod;
  3666  
  3667  	switch(simtype[nl->type->etype]) {
  3668  	default:
  3669  		return;
  3670  
  3671  	case TUINT8:
  3672  	case TUINT16:
  3673  	case TUINT32:
  3674  		// n1 = nl * magic >> w (HMUL)
  3675  		nc = nod(OXXX, N, N);
  3676  		nodconst(nc, nl->type, m.um);
  3677  		n1 = nod(OMUL, nl, nc);
  3678  		typecheck(&n1, Erv);
  3679  		n1->op = OHMUL;
  3680  		if(m.ua) {
  3681  			// Select a Go type with (at least) twice the width.
  3682  			switch(simtype[nl->type->etype]) {
  3683  			default:
  3684  				return;
  3685  			case TUINT8:
  3686  			case TUINT16:
  3687  				twide = types[TUINT32];
  3688  				break;
  3689  			case TUINT32:
  3690  				twide = types[TUINT64];
  3691  				break;
  3692  			case TINT8:
  3693  			case TINT16:
  3694  				twide = types[TINT32];
  3695  				break;
  3696  			case TINT32:
  3697  				twide = types[TINT64];
  3698  				break;
  3699  			}
  3700  
  3701  			// add numerator (might overflow).
  3702  			// n2 = (n1 + nl)
  3703  			n2 = nod(OADD, conv(n1, twide), conv(nl, twide));
  3704  
  3705  			// shift by m.s
  3706  			nc = nod(OXXX, N, N);
  3707  			nodconst(nc, types[TUINT], m.s);
  3708  			n = conv(nod(ORSH, n2, nc), nl->type);
  3709  		} else {
  3710  			// n = n1 >> m.s
  3711  			nc = nod(OXXX, N, N);
  3712  			nodconst(nc, types[TUINT], m.s);
  3713  			n = nod(ORSH, n1, nc);
  3714  		}
  3715  		break;
  3716  
  3717  	case TINT8:
  3718  	case TINT16:
  3719  	case TINT32:
  3720  		// n1 = nl * magic >> w
  3721  		nc = nod(OXXX, N, N);
  3722  		nodconst(nc, nl->type, m.sm);
  3723  		n1 = nod(OMUL, nl, nc);
  3724  		typecheck(&n1, Erv);
  3725  		n1->op = OHMUL;
  3726  		if(m.sm < 0) {
  3727  			// add the numerator.
  3728  			n1 = nod(OADD, n1, nl);
  3729  		}
  3730  		// shift by m.s
  3731  		nc = nod(OXXX, N, N);
  3732  		nodconst(nc, types[TUINT], m.s);
  3733  		n2 = conv(nod(ORSH, n1, nc), nl->type);
  3734  		// add 1 iff n1 is negative.
  3735  		nc = nod(OXXX, N, N);
  3736  		nodconst(nc, types[TUINT], w-1);
  3737  		n3 = nod(ORSH, nl, nc); // n4 = -1 iff n1 is negative.
  3738  		n = nod(OSUB, n2, n3);
  3739  		// apply sign.
  3740  		if(m.sd < 0)
  3741  			n = nod(OMINUS, n, N);
  3742  		break;
  3743  	}
  3744  	goto ret;
  3745  
  3746  longmod:
  3747  	// rewrite as A%B = A - (A/B*B).
  3748  	n1 = nod(ODIV, nl, nr);
  3749  	n2 = nod(OMUL, n1, nr);
  3750  	n = nod(OSUB, nl, n2);
  3751  	goto ret;
  3752  
  3753  ret:
  3754  	typecheck(&n, Erv);
  3755  	walkexpr(&n, init);
  3756  	*np = n;
  3757  }
  3758  
  3759  // return 1 if integer n must be in range [0, max), 0 otherwise
  3760  static int
  3761  bounded(Node *n, int64 max)
  3762  {
  3763  	int64 v;
  3764  	int32 bits;
  3765  	int sign;
  3766  
  3767  	if(n->type == T || !isint[n->type->etype])
  3768  		return 0;
  3769  
  3770  	sign = issigned[n->type->etype];
  3771  	bits = 8*n->type->width;
  3772  
  3773  	if(smallintconst(n)) {
  3774  		v = mpgetfix(n->val.u.xval);
  3775  		return 0 <= v && v < max;
  3776  	}
  3777  
  3778  	switch(n->op) {
  3779  	case OAND:
  3780  		v = -1;
  3781  		if(smallintconst(n->left)) {
  3782  			v = mpgetfix(n->left->val.u.xval);
  3783  		} else if(smallintconst(n->right)) {
  3784  			v = mpgetfix(n->right->val.u.xval);
  3785  		}
  3786  		if(0 <= v && v < max)
  3787  			return 1;
  3788  		break;
  3789  
  3790  	case OMOD:
  3791  		if(!sign && smallintconst(n->right)) {
  3792  			v = mpgetfix(n->right->val.u.xval);
  3793  			if(0 <= v && v <= max)
  3794  				return 1;
  3795  		}
  3796  		break;
  3797  	
  3798  	case ODIV:
  3799  		if(!sign && smallintconst(n->right)) {
  3800  			v = mpgetfix(n->right->val.u.xval);
  3801  			while(bits > 0 && v >= 2) {
  3802  				bits--;
  3803  				v >>= 1;
  3804  			}
  3805  		}
  3806  		break;
  3807  	
  3808  	case ORSH:
  3809  		if(!sign && smallintconst(n->right)) {
  3810  			v = mpgetfix(n->right->val.u.xval);
  3811  			if(v > bits)
  3812  				return 1;
  3813  			bits -= v;
  3814  		}
  3815  		break;
  3816  	}
  3817  	
  3818  	if(!sign && bits <= 62 && (1LL<<bits) <= max)
  3819  		return 1;
  3820  	
  3821  	return 0;
  3822  }
  3823  
  3824  void
  3825  usefield(Node *n)
  3826  {
  3827  	Type *field, *l;
  3828  
  3829  	if(!fieldtrack_enabled)
  3830  		return;
  3831  
  3832  	switch(n->op) {
  3833  	default:
  3834  		fatal("usefield %O", n->op);
  3835  	case ODOT:
  3836  	case ODOTPTR:
  3837  		break;
  3838  	}
  3839  	
  3840  	field = n->paramfld;
  3841  	if(field == T)
  3842  		fatal("usefield %T %S without paramfld", n->left->type, n->right->sym);
  3843  	if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil)
  3844  		return;
  3845  
  3846  	// dedup on list
  3847  	if(field->lastfn == curfn)
  3848  		return;
  3849  	field->lastfn = curfn;
  3850  	field->outer = n->left->type;
  3851  	if(isptr[field->outer->etype])
  3852  		field->outer = field->outer->type;
  3853  	if(field->outer->sym == S)
  3854  		yyerror("tracked field must be in named struct type");
  3855  	if(!exportname(field->sym->name))
  3856  		yyerror("tracked field must be exported (upper case)");
  3857  
  3858  	l = typ(0);
  3859  	l->type = field;
  3860  	l->down = curfn->paramfld;
  3861  	curfn->paramfld = l;
  3862  }
  3863  
  3864  static int
  3865  candiscardlist(NodeList *l)
  3866  {
  3867  	for(; l; l=l->next)
  3868  		if(!candiscard(l->n))
  3869  			return 0;
  3870  	return 1;
  3871  }
  3872  
  3873  int
  3874  candiscard(Node *n)
  3875  {
  3876  	if(n == N)
  3877  		return 1;
  3878  	
  3879  	switch(n->op) {
  3880  	default:
  3881  		return 0;
  3882  
  3883  	case ONAME:
  3884  	case ONONAME:
  3885  	case OTYPE:
  3886  	case OPACK:
  3887  	case OLITERAL:
  3888  	case OADD:
  3889  	case OSUB:
  3890  	case OOR:
  3891  	case OXOR:
  3892  	case OADDSTR:
  3893  	case OADDR:
  3894  	case OANDAND:
  3895  	case OARRAYBYTESTR:
  3896  	case OARRAYRUNESTR:
  3897  	case OSTRARRAYBYTE:
  3898  	case OSTRARRAYRUNE:
  3899  	case OCAP:
  3900  	case OCMPIFACE:
  3901  	case OCMPSTR:
  3902  	case OCOMPLIT:
  3903  	case OMAPLIT:
  3904  	case OSTRUCTLIT:
  3905  	case OARRAYLIT:
  3906  	case OPTRLIT:
  3907  	case OCONV:
  3908  	case OCONVIFACE:
  3909  	case OCONVNOP:
  3910  	case ODOT:
  3911  	case OEQ:
  3912  	case ONE:
  3913  	case OLT:
  3914  	case OLE:
  3915  	case OGT:
  3916  	case OGE:
  3917  	case OKEY:
  3918  	case OLEN:
  3919  	case OMUL:
  3920  	case OLSH:
  3921  	case ORSH:
  3922  	case OAND:
  3923  	case OANDNOT:
  3924  	case ONEW:
  3925  	case ONOT:
  3926  	case OCOM:
  3927  	case OPLUS:
  3928  	case OMINUS:
  3929  	case OOROR:
  3930  	case OPAREN:
  3931  	case ORUNESTR:
  3932  	case OREAL:
  3933  	case OIMAG:
  3934  	case OCOMPLEX:
  3935  		// Discardable as long as the subpieces are.
  3936  		break;
  3937  
  3938  	case ODIV:
  3939  	case OMOD:
  3940  		// Discardable as long as we know it's not division by zero.
  3941  		if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0)
  3942  			break;
  3943  		if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0)
  3944  			break;
  3945  		return 0;
  3946  
  3947  	case OMAKECHAN:
  3948  	case OMAKEMAP:
  3949  		// Discardable as long as we know it won't fail because of a bad size.
  3950  		if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0)
  3951  			break;
  3952  		return 0;
  3953  	
  3954  	case OMAKESLICE:
  3955  		// Difficult to tell what sizes are okay.
  3956  		return 0;		
  3957  	}
  3958  	
  3959  	if(!candiscard(n->left) ||
  3960  	   !candiscard(n->right) ||
  3961  	   !candiscard(n->ntest) ||
  3962  	   !candiscard(n->nincr) ||
  3963  	   !candiscardlist(n->ninit) ||
  3964  	   !candiscardlist(n->nbody) ||
  3965  	   !candiscardlist(n->nelse) ||
  3966  	   !candiscardlist(n->list) ||
  3967  	   !candiscardlist(n->rlist)) {
  3968  		return 0;
  3969  	}
  3970  	
  3971  	return 1;
  3972  }
  3973  
  3974  // rewrite
  3975  //	print(x, y, z)
  3976  // into
  3977  //	func(a1, a2, a3) {
  3978  //		print(a1, a2, a3)
  3979  //	}(x, y, z)
  3980  // and same for println.
  3981  static void
  3982  walkprintfunc(Node **np, NodeList **init)
  3983  {
  3984  	Node *n;
  3985  	Node *a, *fn, *t, *oldfn;
  3986  	NodeList *l, *printargs;
  3987  	int num;
  3988  	char buf[100];
  3989  	static int prgen;
  3990  	
  3991  	n = *np;
  3992  
  3993  	if(n->ninit != nil) {
  3994  		walkstmtlist(n->ninit);
  3995  		*init = concat(*init, n->ninit);
  3996  		n->ninit = nil;
  3997  	}
  3998  
  3999  	t = nod(OTFUNC, N, N);
  4000  	num = 0;
  4001  	printargs = nil;
  4002  	for(l=n->list; l != nil; l=l->next) {
  4003  		snprint(buf, sizeof buf, "a%d", num++);
  4004  		a = nod(ODCLFIELD, newname(lookup(buf)), typenod(l->n->type));
  4005  		t->list = list(t->list, a);
  4006  		printargs = list(printargs, a->left);
  4007  	}
  4008  
  4009  	fn = nod(ODCLFUNC, N, N);
  4010  	snprint(buf, sizeof buf, "print·%d", ++prgen);
  4011  	fn->nname = newname(lookup(buf));
  4012  	fn->nname->defn = fn;
  4013  	fn->nname->ntype = t;
  4014  	declare(fn->nname, PFUNC);
  4015  
  4016  	oldfn = curfn;
  4017  	curfn = nil;
  4018  	funchdr(fn);
  4019  	
  4020  	a = nod(n->op, N, N);
  4021  	a->list = printargs;
  4022  	typecheck(&a, Etop);
  4023  	walkstmt(&a);
  4024  	
  4025  	fn->nbody = list1(a);
  4026  
  4027  	funcbody(fn);
  4028  	
  4029  	typecheck(&fn, Etop);
  4030  	typechecklist(fn->nbody, Etop);
  4031  	xtop = list(xtop, fn);
  4032  	curfn = oldfn;
  4033  
  4034  	a = nod(OCALL, N, N);
  4035  	a->left = fn->nname;
  4036  	a->list = n->list;
  4037  	typecheck(&a, Etop);
  4038  	walkexpr(&a, init);
  4039  	*np = a;
  4040  }