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