2 static char rcsid[] = "$Id: codegen.c,v 2.14 1994/06/24 13:23:19 ceriel Exp $";
9 #include <cg_pattern.h>
17 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
18 * See the copyright notice in the ACK home directory, in the file "Copyright".
20 * Author: Hans van Staveren
23 #define SHORTCUT /* Stop searching at distance 0 */
28 #define MAXPOS MAXRULE
32 #define MAXREPLLEN 5 /* Max length of EM-replacement, should come from boot */
34 byte startupcode[] = { DO_NEXTEM };
46 #define DEBUG(string) {if(Debug) fprintf(stderr,"%-*d%s\n",4*level,level,string);}
49 #define BROKE() {assert(origcp!=startupcode);DEBUG("BROKE");goto doreturn;}
50 #define CHKCOST() {if (totalcost>=costlimit) BROKE();}
52 unsigned codegen(codep,ply,toplevel,costlimit,forced) byte *codep; unsigned costlimit; {
57 unsigned totalcost = 0;
60 unsigned mindistance,dist;
63 int npos,npos2,pos[MAXPOS],pos2[MAXPOS];
66 #define SAVEST savestatus(&state)
67 #define RESTST restorestatus(&state)
68 #define FREEST /* nothing */
71 #define SAVEST state=savestatus()
72 #define RESTST restorestatus(state)
73 #define FREEST freestatus(state)
80 register struct reginfo *rp;
82 token_t token,mtoken,token2;
90 int size,lsize,repllen;
91 int tokexp[MAXPATTERN];
93 token_p regtp[MAXCREG];
98 token_t reptoken[MAXREPLLEN];
99 int emrepllen,eminstr;
102 struct perm *tup,*ntup,*besttup,*tuples();
106 DEBUG("Entering codegen");
109 switch( (*codep++)&037 ) {
124 if (stackheight>MAXFSTACK-7)
125 totalcost += stackupto(&fakestack[6],ply,toplevel);
126 bp = nextem(toplevel);
129 * No pattern found, can be pseudo or error
143 ply -= emp-saveemp+1;
144 if (ply <= 0) ply = 1;
147 assert(n>0 && n<=MAXRULE);
149 mindistance = MAXINT; npos=0;
152 dist=distance(cindex);
155 fprintf(stderr,"distance of pos %d is %u\n",i,dist);
157 if (dist<=mindistance) {
158 if (dist<mindistance) {
166 pos[npos++] = cindex;
169 assert(mindistance<MAXINT);
172 * More than 1 tokenpattern is a candidate.
173 * Decision has to be made by lookahead.
176 mincost = costlimit-totalcost+1;
177 for(i=0;i<npos;i++) {
178 t=codegen(&coderules[pos[i]],ply,FALSE,
179 costlimit<MAXINT?mincost:MAXINT,0);
182 fprintf(stderr,"mincost %u,cost %u,pos %d\n",mincost,t,i);
191 if (totalcost+mincost>costlimit) {
192 totalcost += mincost;
204 * Now cindex contains the code-index of the best candidate
205 * so proceed to use it.
207 codep = &coderules[cindex];
219 tokpatlen=(codep[-1]>>5)&07;
220 for (i=0;i<tokpatlen;i++)
221 getint(tokexp[i],codep);
223 break; /* match already checked by distance() */
226 tokpatlen=(codep[-1]>>5)&07;
227 for(i=0;i<tokpatlen;i++)
228 getint(tokexp[i],codep);
230 tp = &fakestack[stackheight-1];
232 while (i<tokpatlen && tp>=fakestack) {
234 while (i<tokpatlen && (lsize=ssize(tokexp[i]))<=size) {
238 if (i<tokpatlen && size!=0) {
239 totalcost += stackupto(tp,ply,toplevel);
245 tp = &fakestack[stackheight-1];
247 while (i<tokpatlen && tp >= fakestack) {
249 lsize= ssize(tokexp[i]);
250 if (size != lsize) { /* find coercion */
252 sret = split(tp,&tokexp[i],ply,toplevel);
254 #endif /* MAXSPLIT */
255 totalcost += stackupto(tp,ply,toplevel);
261 #endif /* MAXSPLIT */
267 tp = &fakestack[stackheight-1];
269 while (i<tokpatlen && tp>=fakestack) {
270 if (!match(tp,&machsets[tokexp[i]],0)) {
271 register c3_p cp = findcoerc(tp, &machsets[tokexp[i]]);
273 for (j=0;j<nregneeded;j++)
274 regtp[j] -= (tp-fakestack+1);
275 totalcost += stackupto(tp,ply,toplevel);
279 if (cp->c3_prop==0) {
280 totalcost+=docoerc(tp,cp,ply,toplevel,0);
283 assert(nregneeded<MAXCREG);
284 regtp[nregneeded] = tp;
285 regcp[nregneeded] = cp;
286 regls[nregneeded] = curreglist;
293 if (tokpatlen>stackheight) {
295 stackpad = tokpatlen-stackheight;
296 for (j=stackheight-1, k = j + stackpad;j>=0;j--, k--) {
297 fakestack[k] = fakestack[j];
298 /* fakestack[j+stackpad] = fakestack[j]; does not
302 for (j=0;j<stackpad;j++)
303 fakestack[j].t_token=0;
304 stackheight += stackpad;
305 for (j=0;j<nregneeded;j++)
306 regtp[j] += stackpad;
307 tp = &fakestack[stackpad-1];
308 while (i<tokpatlen && tp>=fakestack) {
309 register c3_p cp = findcoerc((token_p) 0, &machsets[tokexp[i]]);
312 for (j=0;j<nregneeded;j++)
317 if (cp->c3_prop==0) {
318 totalcost+=docoerc(tp,cp,ply,toplevel,0);
321 assert(nregneeded<MAXCREG);
322 regtp[nregneeded] = tp;
323 regcp[nregneeded] = cp;
324 regls[nregneeded] = curreglist;
331 assert(i==tokpatlen);
335 mincost=costlimit-totalcost+1;
336 tup = tuples(regls,nregneeded);
338 for (; tup != 0; tup = ntup) {
340 if(Debug>1) { fprintf(stderr,"Next tuple %d,%d,%d,%d\n",
345 fprintf(stderr, "totalcost = %u, costlimit = %u, mincost = %u\n",
346 totalcost, costlimit, mincost);
350 for (i=0,t=0;i<nregneeded && t<mincost; i++)
351 t += docoerc(regtp[i],regcp[i],ply,FALSE,tup->p_rar[i]);
353 if (Debug > 1) fprintf(stderr, "cost after coercions: %u\n", t);
356 t += codegen(codep,ply,FALSE,mincost<MAXINT?mincost-t:MAXINT,0);
365 for (i=0;i<nregneeded;i++)
367 if (totalcost+mincost>costlimit) {
370 if (stackpad!=tokpatlen) {
372 if (costlimit<MAXINT) {
373 totalcost = costlimit+1;
376 for (i=0;i<stackheight-stackpad;i++)
377 fakestack[i] = fakestack[i+stackpad];
378 stackheight -= stackpad;
379 totalcost += stackupto(&fakestack[stackheight-1],ply,toplevel);
381 totalcost += stackupto(fakestack,ply,toplevel);
385 totalcost += mincost;
388 for (i=0;i<nregneeded;i++)
389 totalcost += docoerc(regtp[i],regcp[i],ply,toplevel,besttup->p_rar[i]);
395 getint(texpno,codep);
396 getint(nodeno,codep);
398 getint(texpno,codep);
401 for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--)
402 if (match(tp,&machsets[texpno],nodeno)) {
403 /* investigate possible coercion to register */
404 totalcost += stackupto(tp,ply,toplevel);
408 for (rp=machregs+2;rp<machregs+NREGS;rp++)
409 if (match(&rp->r_contents,&machsets[texpno],nodeno))
410 rp->r_contents.t_token=0;
412 case DO_RREMOVE: /* register remove */
414 getint(nodeno,codep);
415 result=compute(&enodes[nodeno]);
416 assert(result.e_typ==EV_REG);
417 for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--)
418 if (tp->t_token==-1) {
419 if(tp->t_att[0].ar==result.e_v.e_reg)
422 tdp = &tokens[tp->t_token];
423 for(i=0;i<TOKENSIZE;i++)
424 if (tdp->t_type[i]==EV_REG &&
425 tp->t_att[i].ar==result.e_v.e_reg)
430 /* investigate possible coercion to register */
431 totalcost += stackupto(tp,ply,toplevel);
436 getint(tinstno,codep);
437 instance(tinstno,&token);
438 if (token.t_token==-1)
439 chrefcount(token.t_att[0].ar,-1,TRUE);
441 tdp= &tokens[token.t_token];
442 for (i=0;i<TOKENSIZE;i++)
443 if (tdp->t_type[i]==EV_REG)
444 chrefcount(token.t_att[i].ar,-1,TRUE);
449 for(rp=machregs;rp<machregs+NREGS;rp++)
451 rp->r_refcount -= rp->r_tcount;
458 getint(propno,codep);
459 getint(tinstno,codep);
461 getint(propno,codep);
464 instance(tinstno,&token);
468 for(rpp=reglist[propno];rp= *rpp; rpp++)
469 if (getrefcount((int)(rp-machregs), FALSE)==0) {
470 pos[npos++] = rp-machregs;
471 if (eqtoken(&rp->r_contents,&token))
475 * Now pos[] contains all free registers with desired
476 * property. If none then some stacking has to take place.
479 if (stackheight<=tokpatlen) {
481 totalcost = INFINITY;
484 fatal("No regs available");
487 totalcost += stackupto( &fakestack[0],ply,toplevel);
497 * Now we are reducing the number of possible registers.
498 * We take only one equally likely register out of every
499 * equivalence class as given by set of properties.
504 if (eqtoken(&machregs[pos[i]].r_contents,&mtoken)) {
505 pos2[npos2++] = pos[i];
506 for(j=0;j<npos2-1;j++)
507 if (eqregclass(pos2[j],pos[i])) {
514 * Now pos2[] contains all possibilities to try, if more than
515 * one, lookahead is necessary.
518 for (i=1;i<TOKENSIZE;i++)
519 token2.t_att[i].aw=0;
524 mincost=costlimit-totalcost+1;
525 for(j=0;j<npos2;j++) {
526 chrefcount(pos2[j],1,FALSE);
527 token2.t_att[0].ar=pos2[j];
528 allreg[nallreg++] = pos2[j];
529 if (token.t_token != 0)
530 t=move(&token,&token2,ply,FALSE,mincost);
536 t += codegen(codep,ply,FALSE,mincost<MAXINT?mincost-t:MAXINT,0);
544 if (totalcost+mincost>costlimit) {
545 totalcost = INFINITY;
551 if (getrefcount(decision, FALSE)!=0) {
552 totalcost = INFINITY;
557 chrefcount(decision,1,FALSE);
558 token2.t_att[0].ar=decision;
559 if (token.t_token != 0) {
560 totalcost+=move(&token,&token2,ply,toplevel,MAXINT);
564 allreg[nallreg++]=decision;
568 getint(stringno,codep);
569 getint(nodeno,codep);
571 gencode(codestrings[stringno]);
577 i=((codep[-1]>>5)&07);
579 getint(stringno,codep);
581 gencode(codestrings[stringno]);
588 getint(tinstno,codep);
589 instance(tinstno,&token);
590 getint(tinstno,codep);
591 instance(tinstno,&token2);
592 totalcost += move(&token,&token2,ply,toplevel,costlimit-totalcost+1);
597 getint(nodeno,codep);
598 result=compute(&enodes[nodeno]);
599 assert(result.e_typ==EV_REG);
600 erasereg(result.e_v.e_reg);
604 assert(stackheight>=tokpatlen);
605 repllen=(codep[-1]>>5)&07;
606 for(i=0;i<repllen;i++) {
607 getint(tinstno,codep);
608 instance(tinstno,&reptoken[i]);
609 tref(&reptoken[i],1);
611 for(i=0;i<tokpatlen;i++) {
613 tref(&fakestack[stackheight-1],-1);
616 for (i=0;i<repllen;i++) {
617 assert(stackheight<MAXFSTACK);
618 fakestack[stackheight] = reptoken[i];
620 /* do not combine previous two statements; that does not
621 compile under Xenix V3.2
624 for(i=0;i<nallreg;i++)
625 chrefcount(allreg[i],-1,FALSE);
629 emrepllen=(codep[-1]>>5)&07;
632 int k = nemlines + emrepllen - j;
633 assert(k<MAXEMLINES);
634 for (i=nemlines;i>=0;i--, k--)
635 emlines[k] = emlines[i];
636 nemlines += emrepllen-j;
640 for (i=0;i<emrepllen;i++) {
641 getint(eminstr,codep);
642 getint(nodeno,codep);
643 emp[i].em_instr = eminstr;
644 result = compute(&enodes[nodeno]);
645 switch(result.e_typ) {
649 emp[i].em_optyp = OPNO;
653 emp[i].em_optyp = OPINT;
654 emp[i].em_soper = tostring(result.e_v.e_con);
655 emp[i].em_u.em_ioper = result.e_v.e_con;
658 emp[i].em_optyp = OPSYMBOL;
659 emp[i].em_soper = result.e_v.e_str;
669 getint(cost.c_size,codep);
670 getint(cost.c_time,codep);
671 totalcost += costcalc(cost);
678 regreturn(); /* in mach.c */
684 assert(origcp!=startupcode);