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