github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/gc/popt.c (about)

     1  // Derived from Inferno utils/6c/reg.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/reg.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  // "Portable" optimizations.
    32  // Compiled separately for 5g, 6g, and 8g, so allowed to use gg.h, opt.h.
    33  // Must code to the intersection of the three back ends.
    34  
    35  #include	<u.h>
    36  #include	<libc.h>
    37  #include	"gg.h"
    38  #include	"opt.h"
    39  
    40  // p is a call instruction. Does the call fail to return?
    41  int
    42  noreturn(Prog *p)
    43  {
    44  	Sym *s;
    45  	int i;
    46  	static Sym*	symlist[10];
    47  
    48  	if(symlist[0] == S) {
    49  		symlist[0] = pkglookup("panicindex", runtimepkg);
    50  		symlist[1] = pkglookup("panicslice", runtimepkg);
    51  		symlist[2] = pkglookup("throwinit", runtimepkg);
    52  		symlist[3] = pkglookup("panic", runtimepkg);
    53  		symlist[4] = pkglookup("panicwrap", runtimepkg);
    54  	}
    55  
    56  	s = p->to.sym;
    57  	if(s == S)
    58  		return 0;
    59  	for(i=0; symlist[i]!=S; i++)
    60  		if(s == symlist[i])
    61  			return 1;
    62  	return 0;
    63  }
    64  
    65  // JMP chasing and removal.
    66  //
    67  // The code generator depends on being able to write out jump
    68  // instructions that it can jump to now but fill in later.
    69  // the linker will resolve them nicely, but they make the code
    70  // longer and more difficult to follow during debugging.
    71  // Remove them.
    72  
    73  /* what instruction does a JMP to p eventually land on? */
    74  static Prog*
    75  chasejmp(Prog *p, int *jmploop)
    76  {
    77  	int n;
    78  
    79  	n = 0;
    80  	while(p != P && p->as == AJMP && p->to.type == D_BRANCH) {
    81  		if(++n > 10) {
    82  			*jmploop = 1;
    83  			break;
    84  		}
    85  		p = p->to.u.branch;
    86  	}
    87  	return p;
    88  }
    89  
    90  /*
    91   * reuse reg pointer for mark/sweep state.
    92   * leave reg==nil at end because alive==nil.
    93   */
    94  #define alive ((void*)0)
    95  #define dead ((void*)1)
    96  
    97  /* mark all code reachable from firstp as alive */
    98  static void
    99  mark(Prog *firstp)
   100  {
   101  	Prog *p;
   102  	
   103  	for(p=firstp; p; p=p->link) {
   104  		if(p->opt != dead)
   105  			break;
   106  		p->opt = alive;
   107  		if(p->as != ACALL && p->to.type == D_BRANCH && p->to.u.branch)
   108  			mark(p->to.u.branch);
   109  		if(p->as == AJMP || p->as == ARET || p->as == AUNDEF)
   110  			break;
   111  	}
   112  }
   113  
   114  void
   115  fixjmp(Prog *firstp)
   116  {
   117  	int jmploop;
   118  	Prog *p, *last;
   119  	
   120  	if(debug['R'] && debug['v'])
   121  		print("\nfixjmp\n");
   122  
   123  	// pass 1: resolve jump to jump, mark all code as dead.
   124  	jmploop = 0;
   125  	for(p=firstp; p; p=p->link) {
   126  		if(debug['R'] && debug['v'])
   127  			print("%P\n", p);
   128  		if(p->as != ACALL && p->to.type == D_BRANCH && p->to.u.branch && p->to.u.branch->as == AJMP) {
   129  			p->to.u.branch = chasejmp(p->to.u.branch, &jmploop);
   130  			if(debug['R'] && debug['v'])
   131  				print("->%P\n", p);
   132  		}
   133  		p->opt = dead;
   134  	}
   135  	if(debug['R'] && debug['v'])
   136  		print("\n");
   137  
   138  	// pass 2: mark all reachable code alive
   139  	mark(firstp);
   140  	
   141  	// pass 3: delete dead code (mostly JMPs).
   142  	last = nil;
   143  	for(p=firstp; p; p=p->link) {
   144  		if(p->opt == dead) {
   145  			if(p->link == P && p->as == ARET && last && last->as != ARET) {
   146  				// This is the final ARET, and the code so far doesn't have one.
   147  				// Let it stay.
   148  			} else {
   149  				if(debug['R'] && debug['v'])
   150  					print("del %P\n", p);
   151  				continue;
   152  			}
   153  		}
   154  		if(last)
   155  			last->link = p;
   156  		last = p;
   157  	}
   158  	last->link = P;
   159  	
   160  	// pass 4: elide JMP to next instruction.
   161  	// only safe if there are no jumps to JMPs anymore.
   162  	if(!jmploop) {
   163  		last = nil;
   164  		for(p=firstp; p; p=p->link) {
   165  			if(p->as == AJMP && p->to.type == D_BRANCH && p->to.u.branch == p->link) {
   166  				if(debug['R'] && debug['v'])
   167  					print("del %P\n", p);
   168  				continue;
   169  			}
   170  			if(last)
   171  				last->link = p;
   172  			last = p;
   173  		}
   174  		last->link = P;
   175  	}
   176  	
   177  	if(debug['R'] && debug['v']) {
   178  		print("\n");
   179  		for(p=firstp; p; p=p->link)
   180  			print("%P\n", p);
   181  		print("\n");
   182  	}
   183  }
   184  
   185  #undef alive
   186  #undef dead
   187  
   188  // Control flow analysis. The Flow structures hold predecessor and successor
   189  // information as well as basic loop analysis.
   190  //
   191  //	graph = flowstart(firstp, sizeof(Flow));
   192  //	... use flow graph ...
   193  //	flowend(graph); // free graph
   194  //
   195  // Typical uses of the flow graph are to iterate over all the flow-relevant instructions:
   196  //
   197  //	for(f = graph->start; f != nil; f = f->link)
   198  //
   199  // or, given an instruction f, to iterate over all the predecessors, which is
   200  // f->p1 and this list:
   201  //
   202  //	for(f2 = f->p2; f2 != nil; f2 = f2->p2link)
   203  //	
   204  // Often the Flow struct is embedded as the first field inside a larger struct S.
   205  // In that case casts are needed to convert Flow* to S* in many places but the
   206  // idea is the same. Pass sizeof(S) instead of sizeof(Flow) to flowstart.
   207  
   208  Graph*
   209  flowstart(Prog *firstp, int size)
   210  {
   211  	int nf;
   212  	Flow *f, *f1, *start, *last;
   213  	Graph *graph;
   214  	Prog *p;
   215  	ProgInfo info;
   216  
   217  	// Count and mark instructions to annotate.
   218  	nf = 0;
   219  	for(p = firstp; p != P; p = p->link) {
   220  		p->opt = nil; // should be already, but just in case
   221  		proginfo(&info, p);
   222  		if(info.flags & Skip)
   223  			continue;
   224  		p->opt = (void*)1;
   225  		nf++;
   226  	}
   227  	
   228  	if(nf == 0)
   229  		return nil;
   230  
   231  	if(nf >= 20000) {
   232  		// fatal("%S is too big (%d instructions)", curfn->nname->sym, nf);
   233  		return nil;
   234  	}
   235  
   236  	// Allocate annotations and assign to instructions.
   237  	graph = calloc(sizeof *graph + size*nf, 1);
   238  	if(graph == nil)
   239  		fatal("out of memory");
   240  	start = (Flow*)(graph+1);
   241  	last = nil;
   242  	f = start;
   243  	for(p = firstp; p != P; p = p->link) {
   244  		if(p->opt == nil)
   245  			continue;
   246  		p->opt = f;
   247  		f->prog = p;
   248  		if(last)
   249  			last->link = f;
   250  		last = f;
   251  		
   252  		f = (Flow*)((uchar*)f + size);
   253  	}
   254  
   255  	// Fill in pred/succ information.
   256  	for(f = start; f != nil; f = f->link) {
   257  		p = f->prog;
   258  		proginfo(&info, p);
   259  		if(!(info.flags & Break)) {
   260  			f1 = f->link;
   261  			f->s1 = f1;
   262  			f1->p1 = f;
   263  		}
   264  		if(p->to.type == D_BRANCH) {
   265  			if(p->to.u.branch == P)
   266  				fatal("pnil %P", p);
   267  			f1 = p->to.u.branch->opt;
   268  			if(f1 == nil)
   269  				fatal("fnil %P / %P", p, p->to.u.branch);
   270  			if(f1 == f) {
   271  				//fatal("self loop %P", p);
   272  				continue;
   273  			}
   274  			f->s2 = f1;
   275  			f->p2link = f1->p2;
   276  			f1->p2 = f;
   277  		}
   278  	}
   279  	
   280  	graph->start = start;
   281  	graph->num = nf;
   282  	return graph;
   283  }
   284  
   285  void
   286  flowend(Graph *graph)
   287  {
   288  	Flow *f;
   289  	
   290  	for(f = graph->start; f != nil; f = f->link)
   291  		f->prog->opt = nil;
   292  	free(graph);
   293  }
   294  
   295  /*
   296   * find looping structure
   297   *
   298   * 1) find reverse postordering
   299   * 2) find approximate dominators,
   300   *	the actual dominators if the flow graph is reducible
   301   *	otherwise, dominators plus some other non-dominators.
   302   *	See Matthew S. Hecht and Jeffrey D. Ullman,
   303   *	"Analysis of a Simple Algorithm for Global Data Flow Problems",
   304   *	Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
   305   *	Oct. 1-3, 1973, pp.  207-217.
   306   * 3) find all nodes with a predecessor dominated by the current node.
   307   *	such a node is a loop head.
   308   *	recursively, all preds with a greater rpo number are in the loop
   309   */
   310  static int32
   311  postorder(Flow *r, Flow **rpo2r, int32 n)
   312  {
   313  	Flow *r1;
   314  
   315  	r->rpo = 1;
   316  	r1 = r->s1;
   317  	if(r1 && !r1->rpo)
   318  		n = postorder(r1, rpo2r, n);
   319  	r1 = r->s2;
   320  	if(r1 && !r1->rpo)
   321  		n = postorder(r1, rpo2r, n);
   322  	rpo2r[n] = r;
   323  	n++;
   324  	return n;
   325  }
   326  
   327  static int32
   328  rpolca(int32 *idom, int32 rpo1, int32 rpo2)
   329  {
   330  	int32 t;
   331  
   332  	if(rpo1 == -1)
   333  		return rpo2;
   334  	while(rpo1 != rpo2){
   335  		if(rpo1 > rpo2){
   336  			t = rpo2;
   337  			rpo2 = rpo1;
   338  			rpo1 = t;
   339  		}
   340  		while(rpo1 < rpo2){
   341  			t = idom[rpo2];
   342  			if(t >= rpo2)
   343  				fatal("bad idom");
   344  			rpo2 = t;
   345  		}
   346  	}
   347  	return rpo1;
   348  }
   349  
   350  static int
   351  doms(int32 *idom, int32 r, int32 s)
   352  {
   353  	while(s > r)
   354  		s = idom[s];
   355  	return s == r;
   356  }
   357  
   358  static int
   359  loophead(int32 *idom, Flow *r)
   360  {
   361  	int32 src;
   362  
   363  	src = r->rpo;
   364  	if(r->p1 != nil && doms(idom, src, r->p1->rpo))
   365  		return 1;
   366  	for(r = r->p2; r != nil; r = r->p2link)
   367  		if(doms(idom, src, r->rpo))
   368  			return 1;
   369  	return 0;
   370  }
   371  
   372  static void
   373  loopmark(Flow **rpo2r, int32 head, Flow *r)
   374  {
   375  	if(r->rpo < head || r->active == head)
   376  		return;
   377  	r->active = head;
   378  	r->loop += LOOP;
   379  	if(r->p1 != nil)
   380  		loopmark(rpo2r, head, r->p1);
   381  	for(r = r->p2; r != nil; r = r->p2link)
   382  		loopmark(rpo2r, head, r);
   383  }
   384  
   385  void
   386  flowrpo(Graph *g)
   387  {
   388  	Flow *r1;
   389  	int32 i, d, me, nr, *idom;
   390  	Flow **rpo2r;
   391  
   392  	free(g->rpo);
   393  	g->rpo = calloc(g->num*sizeof g->rpo[0], 1);
   394  	idom = calloc(g->num*sizeof idom[0], 1);
   395  	if(g->rpo == nil || idom == nil)
   396  		fatal("out of memory");
   397  
   398  	for(r1 = g->start; r1 != nil; r1 = r1->link)
   399  		r1->active = 0;
   400  
   401  	rpo2r = g->rpo;
   402  	d = postorder(g->start, rpo2r, 0);
   403  	nr = g->num;
   404  	if(d > nr)
   405  		fatal("too many reg nodes %d %d", d, nr);
   406  	nr = d;
   407  	for(i = 0; i < nr / 2; i++) {
   408  		r1 = rpo2r[i];
   409  		rpo2r[i] = rpo2r[nr - 1 - i];
   410  		rpo2r[nr - 1 - i] = r1;
   411  	}
   412  	for(i = 0; i < nr; i++)
   413  		rpo2r[i]->rpo = i;
   414  
   415  	idom[0] = 0;
   416  	for(i = 0; i < nr; i++) {
   417  		r1 = rpo2r[i];
   418  		me = r1->rpo;
   419  		d = -1;
   420  		// rpo2r[r->rpo] == r protects against considering dead code,
   421  		// which has r->rpo == 0.
   422  		if(r1->p1 != nil && rpo2r[r1->p1->rpo] == r1->p1 && r1->p1->rpo < me)
   423  			d = r1->p1->rpo;
   424  		for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
   425  			if(rpo2r[r1->rpo] == r1 && r1->rpo < me)
   426  				d = rpolca(idom, d, r1->rpo);
   427  		idom[i] = d;
   428  	}
   429  
   430  	for(i = 0; i < nr; i++) {
   431  		r1 = rpo2r[i];
   432  		r1->loop++;
   433  		if(r1->p2 != nil && loophead(idom, r1))
   434  			loopmark(rpo2r, i, r1);
   435  	}
   436  	free(idom);
   437  
   438  	for(r1 = g->start; r1 != nil; r1 = r1->link)
   439  		r1->active = 0;
   440  }
   441  
   442  Flow*
   443  uniqp(Flow *r)
   444  {
   445  	Flow *r1;
   446  
   447  	r1 = r->p1;
   448  	if(r1 == nil) {
   449  		r1 = r->p2;
   450  		if(r1 == nil || r1->p2link != nil)
   451  			return nil;
   452  	} else
   453  		if(r->p2 != nil)
   454  			return nil;
   455  	return r1;
   456  }
   457  
   458  Flow*
   459  uniqs(Flow *r)
   460  {
   461  	Flow *r1;
   462  
   463  	r1 = r->s1;
   464  	if(r1 == nil) {
   465  		r1 = r->s2;
   466  		if(r1 == nil)
   467  			return nil;
   468  	} else
   469  		if(r->s2 != nil)
   470  			return nil;
   471  	return r1;
   472  }
   473  
   474  // The compilers assume they can generate temporary variables
   475  // as needed to preserve the right semantics or simplify code
   476  // generation and the back end will still generate good code.
   477  // This results in a large number of ephemeral temporary variables.
   478  // Merge temps with non-overlapping lifetimes and equal types using the
   479  // greedy algorithm in Poletto and Sarkar, "Linear Scan Register Allocation",
   480  // ACM TOPLAS 1999.
   481  
   482  typedef struct TempVar TempVar;
   483  typedef struct TempFlow TempFlow;
   484  
   485  struct TempVar
   486  {
   487  	Node *node;
   488  	TempFlow *def; // definition of temp var
   489  	TempFlow *use; // use list, chained through TempFlow.uselink
   490  	TempVar *freelink; // next free temp in Type.opt list
   491  	TempVar *merge; // merge var with this one
   492  	uint32 start; // smallest Prog.loc in live range
   493  	uint32 end; // largest Prog.loc in live range
   494  	uchar addr; // address taken - no accurate end
   495  	uchar removed; // removed from program
   496  };
   497  
   498  struct TempFlow
   499  {
   500  	Flow	f;
   501  	TempFlow *uselink;
   502  };
   503  
   504  static int
   505  startcmp(const void *va, const void *vb)
   506  {
   507  	TempVar *a, *b;
   508  	
   509  	a = *(TempVar**)va;
   510  	b = *(TempVar**)vb;
   511  
   512  	if(a->start < b->start)
   513  		return -1;
   514  	if(a->start > b->start)
   515  		return +1;
   516  	return 0;
   517  }
   518  
   519  // Is n available for merging?
   520  static int
   521  canmerge(Node *n)
   522  {
   523  	return n->class == PAUTO && !n->addrtaken && strncmp(n->sym->name, "autotmp", 7) == 0;
   524  }
   525  
   526  static void mergewalk(TempVar*, TempFlow*, uint32);
   527  
   528  void
   529  mergetemp(Prog *firstp)
   530  {
   531  	int i, j, nvar, ninuse, nfree, nkill;
   532  	TempVar *var, *v, *v1, **bystart, **inuse;
   533  	TempFlow *r;
   534  	NodeList *l, **lp;
   535  	Node *n;
   536  	Prog *p, *p1;
   537  	Type *t;
   538  	ProgInfo info, info1;
   539  	int32 gen;
   540  	Graph *g;
   541  
   542  	enum { Debug = 0 };
   543  
   544  	g = flowstart(firstp, sizeof(TempFlow));
   545  	if(g == nil)
   546  		return;
   547  
   548  	// Build list of all mergeable variables.
   549  	nvar = 0;
   550  	for(l = curfn->dcl; l != nil; l = l->next)
   551  		if(canmerge(l->n))
   552  			nvar++;
   553  	
   554  	var = calloc(nvar*sizeof var[0], 1);
   555  	nvar = 0;
   556  	for(l = curfn->dcl; l != nil; l = l->next) {
   557  		n = l->n;
   558  		if(canmerge(n)) {
   559  			v = &var[nvar++];
   560  			n->opt = v;
   561  			v->node = n;
   562  		}
   563  	}
   564  	
   565  	// Build list of uses.
   566  	// We assume that the earliest reference to a temporary is its definition.
   567  	// This is not true of variables in general but our temporaries are all
   568  	// single-use (that's why we have so many!).
   569  	for(r = (TempFlow*)g->start; r != nil; r = (TempFlow*)r->f.link) {
   570  		p = r->f.prog;
   571  		proginfo(&info, p);
   572  
   573  		if(p->from.node != N && p->from.node->opt && p->to.node != N && p->to.node->opt)
   574  			fatal("double node %P", p);
   575  		if((n = p->from.node) != N && (v = n->opt) != nil ||
   576  		   (n = p->to.node) != N && (v = n->opt) != nil) {
   577  		   	if(v->def == nil)
   578  		   		v->def = r;
   579  			r->uselink = v->use;
   580  			v->use = r;
   581  			if(n == p->from.node && (info.flags & LeftAddr))
   582  				v->addr = 1;
   583  		}
   584  	}
   585  	
   586  	if(Debug > 1)
   587  		dumpit("before", g->start, 0);
   588  	
   589  	nkill = 0;
   590  
   591  	// Special case.
   592  	for(v = var; v < var+nvar; v++) {
   593  		if(v->addr)
   594  			continue;
   595  		// Used in only one instruction, which had better be a write.
   596  		if((r = v->use) != nil && r->uselink == nil) {
   597  			p = r->f.prog;
   598  			proginfo(&info, p);
   599  			if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) {
   600  				p->as = ANOP;
   601  				p->to = zprog.to;
   602  				v->removed = 1;
   603  				if(Debug)
   604  					print("drop write-only %S\n", v->node->sym);
   605  			} else
   606  				fatal("temp used and not set: %P", p);
   607  			nkill++;
   608  			continue;
   609  		}
   610  		
   611  		// Written in one instruction, read in the next, otherwise unused,
   612  		// no jumps to the next instruction. Happens mainly in 386 compiler.
   613  		if((r = v->use) != nil && r->f.link == &r->uselink->f && r->uselink->uselink == nil && uniqp(r->f.link) == &r->f) {
   614  			p = r->f.prog;
   615  			proginfo(&info, p);
   616  			p1 = r->f.link->prog;
   617  			proginfo(&info1, p1);
   618  			enum {
   619  				SizeAny = SizeB | SizeW | SizeL | SizeQ | SizeF | SizeD,
   620  			};
   621  			if(p->from.node == v->node && p1->to.node == v->node && (info.flags & Move) &&
   622  			   !((info.flags|info1.flags) & (LeftAddr|RightAddr)) &&
   623  			   (info.flags & SizeAny) == (info1.flags & SizeAny)) {
   624  				p1->from = p->from;
   625  				excise(&r->f);
   626  				v->removed = 1;
   627  				if(Debug)
   628  					print("drop immediate-use %S\n", v->node->sym);
   629  			}
   630  			nkill++;
   631  			continue;
   632  		}			   
   633  	}
   634  
   635  	// Traverse live range of each variable to set start, end.
   636  	// Each flood uses a new value of gen so that we don't have
   637  	// to clear all the r->f.active words after each variable.
   638  	gen = 0;
   639  	for(v = var; v < var+nvar; v++) {
   640  		gen++;
   641  		for(r = v->use; r != nil; r = r->uselink)
   642  			mergewalk(v, r, gen);
   643  	}
   644  
   645  	// Sort variables by start.
   646  	bystart = malloc(nvar*sizeof bystart[0]);
   647  	for(i=0; i<nvar; i++)
   648  		bystart[i] = &var[i];
   649  	qsort(bystart, nvar, sizeof bystart[0], startcmp);
   650  
   651  	// List of in-use variables, sorted by end, so that the ones that
   652  	// will last the longest are the earliest ones in the array.
   653  	// The tail inuse[nfree:] holds no-longer-used variables.
   654  	// In theory we should use a sorted tree so that insertions are
   655  	// guaranteed O(log n) and then the loop is guaranteed O(n log n).
   656  	// In practice, it doesn't really matter.
   657  	inuse = malloc(nvar*sizeof inuse[0]);
   658  	ninuse = 0;
   659  	nfree = nvar;
   660  	for(i=0; i<nvar; i++) {
   661  		v = bystart[i];
   662  		if(v->addr || v->removed)
   663  			continue;
   664  
   665  		// Expire no longer in use.
   666  		while(ninuse > 0 && inuse[ninuse-1]->end < v->start) {
   667  			v1 = inuse[--ninuse];
   668  			inuse[--nfree] = v1;
   669  		}
   670  
   671  		// Find old temp to reuse if possible.
   672  		t = v->node->type;
   673  		for(j=nfree; j<nvar; j++) {
   674  			v1 = inuse[j];
   675  			if(eqtype(t, v1->node->type)) {
   676  				inuse[j] = inuse[nfree++];
   677  				if(v1->merge)
   678  					v->merge = v1->merge;
   679  				else
   680  					v->merge = v1;
   681  				nkill++;
   682  				break;
   683  			}
   684  		}
   685  
   686  		// Sort v into inuse.
   687  		j = ninuse++;
   688  		while(j > 0 && inuse[j-1]->end < v->end) {
   689  			inuse[j] = inuse[j-1];
   690  			j--;
   691  		}
   692  		inuse[j] = v;
   693  	}
   694  
   695  	if(Debug) {
   696  		print("%S [%d - %d]\n", curfn->nname->sym, nvar, nkill);
   697  		for(v=var; v<var+nvar; v++) {
   698  			print("var %#N %T %d-%d", v->node, v->node->type, v->start, v->end);
   699  			if(v->addr)
   700  				print(" addr=1");
   701  			if(v->removed)
   702  				print(" dead=1");
   703  			if(v->merge)
   704  				print(" merge %#N", v->merge->node);
   705  			if(v->start == v->end)
   706  				print(" %P", v->def->f.prog);
   707  			print("\n");
   708  		}
   709  	
   710  		if(Debug > 1)
   711  			dumpit("after", g->start, 0);
   712  	}
   713  
   714  	// Update node references to use merged temporaries.
   715  	for(r = (TempFlow*)g->start; r != nil; r = (TempFlow*)r->f.link) {
   716  		p = r->f.prog;
   717  		if((n = p->from.node) != N && (v = n->opt) != nil && v->merge != nil)
   718  			p->from.node = v->merge->node;
   719  		if((n = p->to.node) != N && (v = n->opt) != nil && v->merge != nil)
   720  			p->to.node = v->merge->node;
   721  	}
   722  
   723  	// Delete merged nodes from declaration list.
   724  	for(lp = &curfn->dcl; (l = *lp); ) {
   725  		curfn->dcl->end = l;
   726  		n = l->n;
   727  		v = n->opt;
   728  		if(v && (v->merge || v->removed)) {
   729  			*lp = l->next;
   730  			continue;
   731  		}
   732  		lp = &l->next;
   733  	}
   734  
   735  	// Clear aux structures.
   736  	for(v=var; v<var+nvar; v++)
   737  		v->node->opt = nil;
   738  	free(var);
   739  	free(bystart);
   740  	free(inuse);
   741  	flowend(g);
   742  }
   743  
   744  static void
   745  mergewalk(TempVar *v, TempFlow *r0, uint32 gen)
   746  {
   747  	Prog *p;
   748  	TempFlow *r1, *r, *r2;
   749  	
   750  	for(r1 = r0; r1 != nil; r1 = (TempFlow*)r1->f.p1) {
   751  		if(r1->f.active == gen)
   752  			break;
   753  		r1->f.active = gen;
   754  		p = r1->f.prog;
   755  		if(v->end < p->loc)
   756  			v->end = p->loc;
   757  		if(r1 == v->def) {
   758  			v->start = p->loc;
   759  			break;
   760  		}
   761  	}
   762  	
   763  	for(r = r0; r != r1; r = (TempFlow*)r->f.p1)
   764  		for(r2 = (TempFlow*)r->f.p2; r2 != nil; r2 = (TempFlow*)r2->f.p2link)
   765  			mergewalk(v, r2, gen);
   766  }
   767  
   768  // Eliminate redundant nil pointer checks.
   769  //
   770  // The code generation pass emits a CHECKNIL for every possibly nil pointer.
   771  // This pass removes a CHECKNIL if every predecessor path has already
   772  // checked this value for nil.
   773  //
   774  // Simple backwards flood from check to definition.
   775  // Run prog loop backward from end of program to beginning to avoid quadratic
   776  // behavior removing a run of checks.
   777  //
   778  // Assume that stack variables with address not taken can be loaded multiple times
   779  // from memory without being rechecked. Other variables need to be checked on
   780  // each load.
   781  	
   782  typedef struct NilVar NilVar;
   783  typedef struct NilFlow NilFlow;
   784  
   785  struct NilFlow {
   786  	Flow f;
   787  	int kill;
   788  };
   789  
   790  static void nilwalkback(NilFlow *rcheck);
   791  static void nilwalkfwd(NilFlow *rcheck);
   792  
   793  void
   794  nilopt(Prog *firstp)
   795  {
   796  	NilFlow *r;
   797  	Prog *p;
   798  	Graph *g;
   799  	int ncheck, nkill;
   800  
   801  	g = flowstart(firstp, sizeof(NilFlow));
   802  	if(g == nil)
   803  		return;
   804  
   805  	if(debug_checknil > 1 /* || strcmp(curfn->nname->sym->name, "f1") == 0 */)
   806  		dumpit("nilopt", g->start, 0);
   807  
   808  	ncheck = 0;
   809  	nkill = 0;
   810  	for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
   811  		p = r->f.prog;
   812  		if(p->as != ACHECKNIL || !regtyp(&p->from))
   813  			continue;
   814  		ncheck++;
   815  		if(stackaddr(&p->from)) {
   816  			if(debug_checknil && p->lineno > 1)
   817  				warnl(p->lineno, "removed nil check of SP address");
   818  			r->kill = 1;
   819  			continue;
   820  		}
   821  		nilwalkfwd(r);
   822  		if(r->kill) {
   823  			if(debug_checknil && p->lineno > 1)
   824  				warnl(p->lineno, "removed nil check before indirect");
   825  			continue;
   826  		}
   827  		nilwalkback(r);
   828  		if(r->kill) {
   829  			if(debug_checknil && p->lineno > 1)
   830  				warnl(p->lineno, "removed repeated nil check");
   831  			continue;
   832  		}
   833  	}
   834  	
   835  	for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
   836  		if(r->kill) {
   837  			nkill++;
   838  			excise(&r->f);
   839  		}
   840  	}
   841  
   842  	flowend(g);
   843  	
   844  	if(debug_checknil > 1)
   845  		print("%S: removed %d of %d nil checks\n", curfn->nname->sym, nkill, ncheck);
   846  }
   847  
   848  static void
   849  nilwalkback(NilFlow *rcheck)
   850  {
   851  	Prog *p;
   852  	ProgInfo info;
   853  	NilFlow *r;
   854  	
   855  	for(r = rcheck; r != nil; r = (NilFlow*)uniqp(&r->f)) {
   856  		p = r->f.prog;
   857  		proginfo(&info, p);
   858  		if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from)) {
   859  			// Found initialization of value we're checking for nil.
   860  			// without first finding the check, so this one is unchecked.
   861  			return;
   862  		}
   863  		if(r != rcheck && p->as == ACHECKNIL && sameaddr(&p->from, &rcheck->f.prog->from)) {
   864  			rcheck->kill = 1;
   865  			return;
   866  		}
   867  	}
   868  
   869  	// Here is a more complex version that scans backward across branches.
   870  	// It assumes rcheck->kill = 1 has been set on entry, and its job is to find a reason
   871  	// to keep the check (setting rcheck->kill = 0).
   872  	// It doesn't handle copying of aggregates as well as I would like,
   873  	// nor variables with their address taken,
   874  	// and it's too subtle to turn on this late in Go 1.2. Perhaps for Go 1.3.
   875  	/*
   876  	for(r1 = r0; r1 != nil; r1 = (NilFlow*)r1->f.p1) {
   877  		if(r1->f.active == gen)
   878  			break;
   879  		r1->f.active = gen;
   880  		p = r1->f.prog;
   881  		
   882  		// If same check, stop this loop but still check
   883  		// alternate predecessors up to this point.
   884  		if(r1 != rcheck && p->as == ACHECKNIL && sameaddr(&p->from, &rcheck->f.prog->from))
   885  			break;
   886  
   887  		proginfo(&info, p);
   888  		if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from)) {
   889  			// Found initialization of value we're checking for nil.
   890  			// without first finding the check, so this one is unchecked.
   891  			rcheck->kill = 0;
   892  			return;
   893  		}
   894  		
   895  		if(r1->f.p1 == nil && r1->f.p2 == nil) {
   896  			print("lost pred for %P\n", rcheck->f.prog);
   897  			for(r1=r0; r1!=nil; r1=(NilFlow*)r1->f.p1) {
   898  				proginfo(&info, r1->f.prog);
   899  				print("\t%P %d %d %D %D\n", r1->f.prog, info.flags&RightWrite, sameaddr(&r1->f.prog->to, &rcheck->f.prog->from), &r1->f.prog->to, &rcheck->f.prog->from);
   900  			}
   901  			fatal("lost pred trail");
   902  		}
   903  	}
   904  
   905  	for(r = r0; r != r1; r = (NilFlow*)r->f.p1)
   906  		for(r2 = (NilFlow*)r->f.p2; r2 != nil; r2 = (NilFlow*)r2->f.p2link)
   907  			nilwalkback(rcheck, r2, gen);
   908  	*/
   909  }
   910  
   911  static void
   912  nilwalkfwd(NilFlow *rcheck)
   913  {
   914  	NilFlow *r;
   915  	Prog *p;
   916  	ProgInfo info;
   917  	
   918  	// If the path down from rcheck dereferences the address
   919  	// (possibly with a small offset) before writing to memory
   920  	// and before any subsequent checks, it's okay to wait for
   921  	// that implicit check. Only consider this basic block to
   922  	// avoid problems like:
   923  	//	_ = *x // should panic
   924  	//	for {} // no writes but infinite loop may be considered visible
   925  	for(r = (NilFlow*)uniqs(&rcheck->f); r != nil; r = (NilFlow*)uniqs(&r->f)) {
   926  		p = r->f.prog;
   927  		proginfo(&info, p);
   928  		
   929  		if((info.flags & LeftRead) && smallindir(&p->from, &rcheck->f.prog->from)) {
   930  			rcheck->kill = 1;
   931  			return;
   932  		}
   933  		if((info.flags & (RightRead|RightWrite)) && smallindir(&p->to, &rcheck->f.prog->from)) {
   934  			rcheck->kill = 1;
   935  			return;
   936  		}
   937  		
   938  		// Stop if another nil check happens.
   939  		if(p->as == ACHECKNIL)
   940  			return;
   941  		// Stop if value is lost.
   942  		if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from))
   943  			return;
   944  		// Stop if memory write.
   945  		if((info.flags & RightWrite) && !regtyp(&p->to))
   946  			return;
   947  	}
   948  }