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