From: christian Date: Sun, 28 Nov 2004 16:37:23 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=1fedc184e371b1f81a12529f5568063484419da9;p=cacao.git *** empty log message *** --- diff --git a/jit/lsra.h b/jit/lsra.h index f40ec07d9..e4b59d2d0 100644 --- a/jit/lsra.h +++ b/jit/lsra.h @@ -27,7 +27,7 @@ Authors: Christian Ullrich - $Id: lsra.h 1590 2004-11-25 13:24:49Z christian $ + $Id: lsra.h 1597 2004-11-28 16:37:23Z christian $ */ @@ -42,29 +42,19 @@ #define LSRA_POP -1 struct lifetime { - int index; /* unique index, LOCALVAR varnum or negative*/ - int b_start; /* bb of first use */ - int b_end; /* bb of last use */ int i_start; /* instruction number of first use */ int i_end; /* instruction number of last use */ - int length; /* lifetime in instructions */ - stackptr s; /* stackslot or NULL */ - int v_index; /* local variable index or -1 */ + int v_index; /* local variable index or negative for stackslots */ int type; - int usagecount; /* number of refernces*/ + int usagecount; /* number of references*/ int reg; /* regoffset durch lsra zugewiesen */ int savedvar; struct stackslot *passthrough; /* List of Stackslots in Lifetime, which are passed through a Basic Block */ - struct stackslot *local_ss; + struct stackslot *local_ss; /* Stackslots for this Lifetime or NULL (=="pure" Local Var) */ struct _i_list *i_list; /* list of instructions with references to var */ struct lifetime *next; }; -/* struct int_list { */ -/* int value; */ -/* int_list *next; */ -/* }; */ - struct active_lt { struct lifetime *lt; struct active_lt *next; @@ -116,10 +106,9 @@ struct freemem { struct freemem *next; }; -struct sss { - int bb; - bool out; - struct sss *next; +struct dup { + struct stackslot *ss; + struct dup *next; }; typedef struct lsradata lsradata; @@ -133,6 +122,8 @@ void lsra_clean_Graph( methodinfo *, codegendata *, lsradata *, loopdata *); #ifdef LSRA_DEBUG void lsra_dump_Graph(methodinfo *, struct depthElement **); void lsra_dump_stack(stackptr ); +#endif +#ifdef LSRA_PRINTLIFETIMES void print_lifetimes(registerdata *, struct lifetime *); #endif @@ -143,8 +134,9 @@ int lsra_getmaxblock(methodinfo *, loopdata *, int ); void lsra_calc_lifetime_length(methodinfo *, lsradata *, codegendata *, loopdata *); void lsra_merge_i_lists(struct lifetime *, struct lifetime *); +void lsra_merge_local_ss(struct lifetime *, struct lifetime *); -void _lsra_new_stack( lsradata *, stackptr , int , int , int); +void _lsra_new_stack( lsradata *, stackptr , int , int, int); void _lsra_from_stack(lsradata *, stackptr , int , int, int); void lsra_add_ss(struct lifetime *, stackptr ); void lsra_usage_local(lsradata *, s4 , int , int , int , int ); diff --git a/jit/lsra.inc b/jit/lsra.inc index 8202c285c..ba756aa7a 100644 --- a/jit/lsra.inc +++ b/jit/lsra.inc @@ -27,13 +27,19 @@ Authors: Christian Ullrich - $Id: lsra.inc 1590 2004-11-25 13:24:49Z christian $ + $Id: lsra.inc 1597 2004-11-28 16:37:23Z christian $ */ /* #define LSRA_DEBUG */ /* #define LSRA_SAVEDVAR */ /* #define LSRA_MEMORY */ +/* #define LSRA_PRINTLIFETIMES */ + + +#ifdef LSRA_DEBUG +#define LSRA_PRINTLIFETIMES +#endif #include "lsra.h" #include "loop/graph.h" @@ -63,7 +69,7 @@ void lsra(methodinfo *m, codegendata *cd, registerdata *rd, loopdata *ld, t_inli printf("LSRA Start for %s\n", name); - if (strcmp(name,"at/dms/kjc/CSourceClassgenCode(Lat/dms/kjc/BytecodeOptimizer;Ljava/lang/String;Lat/dms/kjc/TypeFactory;)V")==0) { + if (strcmp(name,"java/lang/SysteminitProperties()V")==0) { printf("-------------------\n"); } #endif @@ -95,7 +101,6 @@ void lsra_init(methodinfo *m, codegendata *cd, t_inlining_globals *id, lsradata for (i=0; i < cd->maxlocals; i++) ls->locals_lifetimes[i]=NULL; ls->lifetimes=NULL; ls->stackslots=NULL; - ls->var_index=-1; } void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, loopdata *ld) @@ -108,6 +113,7 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, struct lifetime *lt, *n; int v_index; struct stackslot *ss; + bool drop; /* Setup LSRA Data structures */ if (opt_loops) panic("lsra with -oloop not possible!\n"); @@ -168,8 +174,9 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, v_index=-1; + /* ls->lifetimes contains only the joined stackslotlifetimes */ for (lt=ls->lifetimes; lt != NULL; lt=lt->next) { - lt->index=v_index; + lt->v_index=v_index; #ifdef LSRA_SAVEDVAR lt->savedvar=SAVEDVAR; #endif @@ -179,15 +186,7 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, } } - for (i=0; i < cd->maxlocals; i++) { - for (lt=ls->locals_lifetimes[i]; lt != NULL; lt=lt->next) { -/* lt->local_ss=NULL; */ -#ifdef LSRA_SAVEDVAR - lt->savedvar=SAVEDVAR; -#endif - } - } - + /* add ss_lifetimes[i] to ls->lifetimes or local_lifetimes[lt->s->varnum] */ for (i=0; i < m->basicblockcount; i++) { if (m->basicblocks[i].flags >= BBREACHED) { for (; ls->ss_lifetimes[i] != NULL;) { @@ -195,48 +194,48 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, #ifdef LSRA_SAVEDVAR lt->savedvar=SAVEDVAR; #endif - if (lt->s->varkind == LOCALVAR) { - /* join with LOCALVAR */ - /* local Lifetime vom richtigen Type suchen */ - for (n=ls->locals_lifetimes[lt->s->varnum]; (n!=NULL) && (n->type!=lt->s->type);n=n->next); #ifdef LSRA_DEBUG - if (n == NULL) panic("lsra_setup: Local Var not found\n"); + if (lt->local_ss == NULL) panic("lsra_setup: normal Stackslot Lifetimes local_ss == NULL\n"); #endif - lsra_merge_i_lists(n, lt); - ss=DNEW(struct stackslot); - ss->s=lt->s; - ss->next=n->local_ss; - n->local_ss=ss; - - ls->ss_lifetimes[i]=lt->next; - } else { -#ifdef LSRA_DEBUG - if (lt->s == NULL) panic("lsra_setup: Wrong assumption about Stackslot Lifetimes -> s\n"); - -#endif - if ((lt->s != NULL) && (lt->s->varkind != ARGVAR)) { - if (lt->s->varkind != ARGVAR) { - lt->s->varkind=TEMPVAR; - lt->s->varnum=v_index; + drop=false; + for (ss=lt->local_ss; (ss!=NULL) && (!drop); ss=ss->next) { + if (lt->local_ss->next == NULL) { /* only one Stackslot in local_ss */ + /* Special Treatment for "lonely" LOCAL and ARGVARs */ + if (ss->s->varkind == LOCALVAR) { + /* join with LOCALVAR */ + /* local Lifetime vom richtigen Type suchen */ + for (n=ls->locals_lifetimes[lt->local_ss->s->varnum]; (n!=NULL) && (n->type!=lt->local_ss->s->type);n=n->next); + lsra_merge_i_lists(n, lt); + if (n->local_ss == NULL) /* "pure" Local without Stackslots */ + n->local_ss = lt->local_ss; + else + lsra_merge_local_ss(n, lt); + + drop = true; } - lt->index=lt->v_index=v_index; - for (ss=lt->local_ss; ss!=NULL; ss=ss->next) { - ss->s->varnum=v_index; - lt->s->varkind=TEMPVAR; + if (lt->local_ss->s->varkind == ARGVAR) { + drop = true; } - - ls->ss_lifetimes[i]=lt->next; - lt->next=ls->lifetimes; - ls->lifetimes=lt; - } else { - ls->ss_lifetimes[i]=lt->next; + } else { + /* no special treatment (only one Stackslot Lifetimes)? */ + ss->s->varnum=v_index; + ss->s->varkind=TEMPVAR; /* only TEMPVAR possible for now */ } - --v_index; - } + } + if (drop) + ls->ss_lifetimes[i]=lt->next; + else { + /* link into ls->lifetimes */ + ls->ss_lifetimes[i]=lt->next; + lt->next=ls->lifetimes; + ls->lifetimes=lt; + lt->v_index=v_index--; + } } /* for */ } /* if */ } + /* add local_lifetimes to lifetimes */ for (i=0; i < cd->maxlocals; i++) { if (ls->locals_lifetimes[i] != NULL) { for (lt=ls->locals_lifetimes[i]; lt->next != NULL; lt=lt->next); @@ -286,10 +285,7 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l exceptiontable *ex; struct depthElement **table; bool back_edge; -#ifdef LSRA_DEBUG struct LoopContainer *lc; - struct LoopElement *le; -#endif table=ld->c_dTable; @@ -304,16 +300,8 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l #endif for (; ex != NULL; ex = ex->down) { -#ifdef LSRA_DEBUG - if (ex->handler == NULL) { - panic("lsra_init_blocks EXCEPTIONTABLE without handler!\n"); - } -#endif -#ifdef LSRA_DEBUG - if ((ex->handler->debug_nr < 0) || (ex->handler->debug_nr >= m->basicblockcount)) { - panic("lsra_init_blocks EXCEPTIONTABLE Handler Blocknummer invalid! \n"); - } +#ifdef LSRA_DEBUG printf("%i ",ex->handler->debug_nr); #endif dF(m, ld, -1, ex->handler->debug_nr); @@ -336,24 +324,12 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l } back_edge=false; -#ifdef LSRA_DEBUG - printf("\n Cleaning c_dTable "); -#endif for(i=0; i < m->basicblockcount; i++) { -#ifdef LSRA_DEBUG - printf("\n %i-",i); -#endif if (m->basicblocks[i].flags < BBREACHED) { -#ifdef LSRA_DEBUG - printf("deleted\n"); -#endif table[i]=NULL; } else { for (de=table[i]; de != NULL; de=de->next) { if (de->value < i) back_edge=true; -#ifdef LSRA_DEBUG - printf("%i-%i ",de->value, bb_succ[de->value]); -#endif if (bb_succ[de->value] != de->value) de->value = bb_succ[de->value]; if (de->value == -1) panic("lsra_clean_Graph: Sprung ins nichts...."); @@ -369,37 +345,44 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l /* TODO bis dahin eine loop über die backedge eintragen */ /* anstatt back_edge_panic zu setzen und alle Lifetimes über die */ /* gesamt Methode auszudehnen */ - ls->back_edge_panic = true; - } - } +/* ls->back_edge_panic = true; */ + + /* create loops from all back edges */ + + for(i=0; i < m->basicblockcount; i++) { + if (m->basicblocks[i].flags >= BBREACHED) { + for (de=table[i]; de != NULL; de=de->next) { + if (de->value < i) { + if (ld->c_allLoops == NULL) { + ld->c_allLoops = lc = DNEW(struct LoopContainer); + } else { + lc->next=DNEW(struct LoopContainer); + lc=lc->next; + } + lc->nodes=DNEW(struct LoopElement); + lc->nodes->next=DNEW(struct LoopElement); + lc->nodes->next->next=NULL; + + lc->nodes->block=&(m->basicblocks[i]); + lc->nodes->next->block=&(m->basicblocks[de->value]); + lc->next = NULL; + } + } + } + } #ifdef LSRA_DEBUG - if (back_edge) { - if ( ld->c_allLoops == NULL ) { printf("-------------Warnung Back Edge + no LOOP..\n"); +#endif } - else - printf("Back-edges + Loops:\n"); - lc = ld->c_allLoops; - i = 0; - while (lc != NULL) { - printf("Loop [%d]: ", ++i); - le = lc->nodes; - while (le != NULL) { - printf("%d ", le->node); - printf("\n"); - le = le->next; - } - lc = lc->next; - } - printf("\n"); } -#endif bb_visited=DMNEW(int, m->basicblockcount); for (i=0; ibasicblockcount; i++) { bb_visited[i]=false; } + /* Add all return possibilities to subroutine returns! */ + /* --- subroutines will be inlined ---- -> then cancel this part */ #ifdef LSRA_DEBUG printf("LSRA Subroutine patching\n"); #endif @@ -490,7 +473,9 @@ void lsra_dump_Graph(methodinfo *m, struct depthElement **table) void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) { struct lifetime *lt, *lt_prev, *lt_temp, *int_lt, *int_lt_last, *flt_lt, *flt_lt_last; +#ifdef LSRA_DEBUG int lt_count,lt_int_count,lt_flt_count,lt_left_count; +#endif int i; int lsra_mem_use; int sav_reg_count, tmp_reg_count; @@ -501,24 +486,23 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) int flags; /* 0 INMEMORY->lifetimes, 1 INTREG->int_lt, 2 FLTREG->flt_lt */ int lsra_reg_use; + /* first split lifetimes for integer and float registers */ int_lt_last=int_lt=NULL; flt_lt_last=flt_lt=NULL; +#ifdef LSRA_DEBUG for (lt_count=0,lt=ls->lifetimes; lt!=NULL;lt=lt->next,lt_count++); - +#endif for (lt_prev=lt=ls->lifetimes;lt!=NULL;) { lt->reg = -1; if (lt->v_index < 0) { /* stackslot */ - if (lt->s != NULL) - type = lt->s->type; - else { + #ifdef LSRA_DEBUG - if (lt->local_ss == NULL) panic("lsra_main Lifetime for Stackslot invalid\n"); + if (lt->local_ss == NULL) panic("lsra_main Lifetime Stackslot invalid\n"); #endif - type = lt->local_ss->s->type; - } + type = lt->local_ss->s->type; } else { /* local var */ if (rd->locals[lt->v_index][lt->type].type>=0) { type = rd->locals[lt->v_index][lt->type].type; @@ -582,16 +566,16 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) lsra_sort_lt(&(ls->lifetimes)); lsra_sort_lt(&flt_lt); +#ifdef LSRA_DEBUG for (lt_int_count=0,lt=int_lt; lt!=NULL;lt=lt->next,lt_int_count++); for (lt_flt_count=0,lt=flt_lt; lt!=NULL;lt=lt->next,lt_flt_count++); for (lt_left_count=0,lt=ls->lifetimes; lt!=NULL;lt=lt->next,lt_left_count++); -#ifdef LSRA_DEBUG printf("\nLifetimes: %3i left: %3i Intlt: %3i Fltlt: %3i \n",lt_count,lt_left_count,lt_int_count,lt_flt_count); -#endif if (lt_count != lt_int_count + lt_flt_count + lt_left_count) { panic ("lifetimes missing\n"); } +#endif lsra_reg_use=rd->savintregcnt; if (int_lt!=NULL) { for (reg_count = 0; nregdescint[reg_count] != REG_END; reg_count++); @@ -618,7 +602,6 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) } _lsra_main(m, ls, int_lt, reg, tmp_reg_count, sav_reg_count, &lsra_mem_use, &lsra_reg_use); if (lsra_reg_use > rd->savintregcnt) lsra_reg_use=rd->savintregcnt; -/* r->maxsavintreguse=lsra_reg_use; */ } rd->maxsavintreguse= lsra_reg_use; lsra_reg_use=rd->savfltregcnt; @@ -629,7 +612,7 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) reg=DMNEW(struct lsra_reg,reg_count); sav_reg_count=0; for (i=0; iisleafmethod && (nregdescfloat[i]==REG_ARG))) { reg[sav_reg_count].reg_index=i; reg[sav_reg_count].use=0; sav_reg_count++; @@ -644,7 +627,6 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) } _lsra_main(m,ls, flt_lt, reg, tmp_reg_count, sav_reg_count, &lsra_mem_use, &lsra_reg_use); if (lsra_reg_use > rd->savfltregcnt) lsra_reg_use=rd->savfltregcnt; -/* r->maxsavfltreguse=0; */ } rd->maxsavfltreguse=lsra_reg_use; @@ -666,6 +648,9 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) else lsra_mem_use = 0; #endif +#ifdef SPECIALMEMUSE + lsra_mem_use = rd->ifmemuse; +#endif #ifdef LSRA_DEBUG printf("Alloc Rest\n"); @@ -680,7 +665,7 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) #endif lsra_alloc(m, rd, flt_lt,&lsra_mem_use); -#ifdef LSRA_DEBUG +#ifdef LSRA_PRINTLIFETIMES printf("Int RA complete \n"); printf("Lifetimes after splitting int: \n"); print_lifetimes(rd, int_lt); @@ -722,11 +707,6 @@ void lsra_alloc(methodinfo *m, registerdata *rd, struct lifetime *lifet, int *me } if (lt->v_index < 0) { - if (lt->s!=NULL) { - lsra_setflags( &(lt->s->flags), flags); - lt->s->regoff=regoff; - } - for (n=lt->local_ss; n!=NULL; n=n->next) { lsra_setflags( &(n->s->flags), flags); n->s->regoff=regoff; @@ -757,7 +737,7 @@ int lsra_getmem(struct lifetime *lt, struct freemem *fmem, int *mem_use) struct freemem *fm, *p; /* noch kein Speicher vergeben, oder alle Enden später */ - if ((fmem->next == NULL) || (fmem->next->end >= lt->i_start)) /* wirklich >= oder reicht > */ + if ((fmem->next == NULL) || (fmem->next->end > lt->i_start)) fm=lsra_getnewmem(mem_use); else { /* Speicherstelle frei */ @@ -786,7 +766,6 @@ struct freemem *lsra_getnewmem(int *mem_use) void _lsra_main( methodinfo *m, lsradata *ls, struct lifetime *lifet, struct lsra_reg *reg, int tmp_reg_count, int sav_reg_count, int *mem_use, int *reg_use) { struct lifetime *lt; -/* struct active_lt *a; */ int i; int _reg_use; int reg_count, active_count; @@ -871,7 +850,6 @@ void _lsra_expire_old_intervalls(struct lifetime *lt, struct lsra_reg *reg, stru for (i=0;reg[i].reg_index != alt->lt->reg;i++); reg[i].use=0; -/* FREE(alt,struct active_lt); */ (*active_count)--; } } @@ -894,12 +872,11 @@ void _spill_at_intervall(struct lifetime *lt, struct active_lt **active, int *ac if (*active == NULL) { lt->reg=-2; return; - panic("No Lifetime in Active List -> no free registers at all!\n"); } /* get last intervall from active */ for (alt1=alt=*active; alt->next != NULL; alt1=alt, alt=alt->next); - if (alt->lt->i_end > lt->i_end) { + if ((alt->lt->i_end > lt->i_end) && (alt->lt->usagecount < lt->usagecount)) { lt->reg=alt->lt->reg; alt->lt->reg=-1; @@ -1019,12 +996,11 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo } /* extend lifetime within loops */ - for (num_loops=0,lc =ld->c_allLoops;lc!=NULL;num_loops++,lc=lc->next); + /* set up loops[i].b_first .b_last to hold the first and last node of all loops */ loops=DMNEW(struct l_loop,num_loops); - for (i=0,lc=ld->c_allLoops;inext) { le = lc->nodes; @@ -1040,8 +1016,6 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo loops[i].nesting=0; } -/* for (i=0;i= loops[i+1].b_first !*/ @@ -1066,13 +1040,12 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo loops[i].b_first=-1; loops[i].b_last=-1; } else { - /* nested loops */ loops[i].nesting++; /* only boolean if nested... */ } } } -/* for (i=0;ibasicblockcount); for (i=0;ibasicblockcount; i++) { block_loop[i].loop=-1; @@ -1082,6 +1055,7 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo block_loop[i].instr=0; } + /* set block_loop[j].loop to loop index, if Basic Block is in this loop */ for (i=0; ilifetimes; while(lt!=NULL) { if (ls->back_edge_panic) { - lt->b_start=0; lt->i_start=0; - lt->b_end=m->basicblockcount-1; lt->i_end=block_loop[m->basicblockcount-1].instr+m->basicblocks[m->basicblockcount-1].icount; } else { - usage = 0; + usage = 1; il=lt->i_list; blast=il->b_index; ilast=il->instr; while (il->next!=NULL) { + if ((il->b_index != il->next->b_index) || ((il->b_index == il->next->b_index) && (il->instr != il->next->instr))) { + if (block_loop[il->b_index].loop == -1) + usage++; /* not in a loop */ + } il=il->next; - usage++; } bfirst=il->b_index; ifirst=il->instr; @@ -1127,8 +1103,8 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo } } - ilast+=block_loop[blast].instr; - ifirst+=block_loop[bfirst].instr; + ilast+=block_loop[blast].instr; /* add icount of previous Basic Blocks */ + ifirst+=block_loop[bfirst].instr; /* add icount of previous Basic Blocks */ if ((j=block_loop[bfirst].loop)==-1) j=block_loop[blast].loop; @@ -1146,12 +1122,10 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo } } - lt->length=ilast-ifirst; - - lt->b_start=bfirst; - lt->b_end=blast; lt->i_start=ifirst; lt->i_end=ilast; + i=ilast-ifirst; + if (i==0) i=1; lt->usagecount=usage; } lt=lt->next; @@ -1167,72 +1141,146 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo #endif } +/* void lsra_sort_lt(struct lifetime **lifet) */ +/* { */ +/* struct lifetime *lt, lt_new, *temp, *tmp; */ + +/* lt_new.next=NULL; */ + +/* for (lt=*lifet; lt!= NULL;) { */ +/* temp=lt->next; */ + +/* for(tmp=<_new; (tmp->next!= NULL) && (tmp->next->i_start < lt->i_start); tmp=tmp->next); */ +/* lt->next=tmp->next; */ +/* tmp->next=lt; */ +/* lt=temp; */ +/* } */ +/* *lifet=lt_new.next; */ +/* } */ + + +#define P_MAX 21 +void _lsra_merge_lt(struct lifetime **p, int i1, int i2) +{ + struct lifetime *iptr, *iptr1, *iptr2; + + if ( (iptr1=p[i2])==NULL) return; + if ( (iptr=p[i1])==NULL) return; + + iptr2=p[i1]=NULL; + p[i2]=NULL; + + while ((iptr != NULL) && (iptr1 != NULL)) { + if (iptr->i_start < iptr1->i_start) { + if (iptr2==NULL) { + p[i1]=iptr; + } else { + iptr2->next=iptr; + } + iptr2=iptr; + iptr=iptr->next; + } else { + if (iptr2==NULL) { + p[i1]=iptr1; + } else { + iptr2->next=iptr1; + } + iptr2=iptr1; + iptr1=iptr1->next; + } + } + if (iptr==NULL) + iptr2->next=iptr1; + if (iptr1==NULL) + iptr2->next=iptr; +} + +void lsra_merge_lt(struct lifetime **p, int top) +{ + int i,j; + + for (j=1; j just turn around */ - /* not really correct through exception and loop lifetime expansion! -> turn around and sort in*/ - lt_new.next=NULL; + p=DMNEW(struct lifetime *, P_MAX); + for (i=0; inext; + temp=lt; + lt=lt->next; + if (lt == NULL) { + p[top]=temp; + temp->next=NULL; + } else { + tmp=lt; + lt=lt->next; - for(tmp=<_new; (tmp->next!= NULL) && (tmp->next->i_start < lt->i_start); tmp=tmp->next); - lt->next=tmp->next; - tmp->next=lt; - lt=temp; + if (temp->i_start < tmp->i_start) { + p[top]=temp; + /* temp->next == tmp */ + tmp->next=NULL; + } else { + p[top]=tmp; + tmp->next=temp; + temp->next=NULL; + } + } + top++; + if (top == P_MAX) { + lsra_merge_lt(p, P_MAX); + top=1; + } } - *lifet=lt_new.next; + lsra_merge_lt(p, top); + *lifet=p[0]; } - +#ifdef LSRA_PRINTLIFETIMES void print_lifetimes(registerdata *rd, struct lifetime *lt) { struct lifetime *n; struct _i_list *ni; int type,flags,regoff,j,varkind; -/* int i; */ + /* int i; */ for (n=lt,j=0; n!=NULL; n=n->next,j++) { if (n->v_index < 0) { /* stackslot */ - if (n->s != 0) { /* stackslot */ - type = n->s->type; - flags=n->s->flags; - regoff=n->s->regoff; - varkind=n->s->varkind; - } else { - if (n->local_ss != 0) { - type = n->local_ss->s->type; - flags=n->local_ss->s->flags; - regoff=n->local_ss->s->regoff; - varkind=n->local_ss->s->varkind; - } - } + type = n->local_ss->s->type; + flags=n->local_ss->s->flags; + regoff=n->local_ss->s->regoff; + varkind=n->local_ss->s->varkind; } else { /* local var */ -/* for (i=TYPE_INT; i<=TYPE_ADR; i++) { */ - if (rd->locals[n->v_index][n->type].type>=0) { - type = rd->locals[n->v_index][n->type].type; - flags=rd->locals[n->v_index][n->type].flags; - regoff=rd->locals[n->v_index][n->type].regoff; - varkind=-1; - } else panic("Type Data mismatch 3\n"); -/* } */ + if (rd->locals[n->v_index][n->type].type>=0) { + type = rd->locals[n->v_index][n->type].type; + flags=rd->locals[n->v_index][n->type].flags; + regoff=rd->locals[n->v_index][n->type].regoff; + varkind=-1; + } else + panic("Type Data mismatch 3\n"); } - printf("i_Start: %3i i_stop: %3i reg: %3i Index: %3i VI: %3i Usage: %3i length: %3i type: %3i flags: %3i varkind: %3i ILst: ",n->i_start,n->i_end,regoff,n->index,n->v_index,n->usagecount, n->length,type,flags, varkind); + printf("i_Start: %3i i_stop: %3i reg: %3i VI: %3i Usage: %3i type: %3i flags: %3i varkind: %3i ILst: ",n->i_start,n->i_end,regoff,n->v_index,n->usagecount,type,flags, varkind); for (ni=n->i_list; ni!=NULL; ni=ni->next) { if (ni==ni->next) panic("loop in instruction list!\n"); printf( "(%3i,%3i) ",ni->b_index,ni->instr); } printf("\n"); -/* if (n->s!=NULL) */ -/* printf(" type: %1i flags: %1i varkind: %1i varnum: %3i regoff: %4i\n",n->s->type,n->s->flags,n->s->varkind,n->s->varnum,n->s->regoff); */ } printf( "%3i Lifetimes printed \n",j); } +#endif struct stackslot *lsra_make_ss(stackptr s, int bb_index) { @@ -1254,33 +1302,92 @@ void lsra_merge_i_lists(struct lifetime *lt, struct lifetime *lt1) iptr2=lt->i_list=NULL; iptr1=lt1->i_list; while ((iptr != NULL) && (iptr1 != NULL)) { - if ((iptr->b_index > iptr1->b_index)|| ((iptr->b_index == iptr1->b_index) && (iptr->instr > iptr1->instr))) { - if (lt->i_list==NULL) { - lt->i_list=iptr; -/* iptr2=lt->i_list; */ + if (iptr1->instr == -1) { + /* throw away, just for joining */ + iptr1=iptr1->next; + } else { + if ((iptr->b_index > iptr1->b_index)|| ((iptr->b_index == iptr1->b_index) && (iptr->instr > iptr1->instr))) { + if (lt->i_list==NULL) { + lt->i_list=iptr; + } else { + iptr2->next=iptr; + } + iptr2=iptr; + iptr=iptr->next; } else { - iptr2->next=iptr; + if (lt->i_list==NULL) { + lt->i_list=iptr1; + } else { + iptr2->next=iptr1; + } + iptr2=iptr1; + iptr1=iptr1->next; } - iptr2=iptr; - iptr=iptr->next; + } + } +#ifdef LSRA_DEBUG + if (iptr2 == NULL) + panic("lsra_merge_i_lists: Empty Instruction List in Lifetime\n"); +#endif + if (iptr==NULL) { + if (lt->i_list==NULL) + lt->i_list=iptr1; + else + iptr2->next=iptr1; + } + if (iptr1==NULL) { + if (lt->i_list==NULL) + lt->i_list=iptr; + else + iptr2->next=iptr; + } +} + +/* merge local_ss from lt1 to lt in order */ +void lsra_merge_local_ss(struct lifetime *lt, struct lifetime *lt1) +{ + struct stackslot *ssptr, *ssptr1, *ssptr2; + + /* merge stackslots in order */ + ssptr=lt->local_ss; + ssptr2=lt->local_ss=NULL; + ssptr1=lt1->local_ss; + while ((ssptr != NULL) && (ssptr1 != NULL)) { + + if (ssptr->s > ssptr1->s) { + if (lt->local_ss==NULL) { + lt->local_ss=ssptr; + } else { + ssptr2->next=ssptr; + } + ssptr2=ssptr; + ssptr=ssptr->next; } else { - if (lt->i_list==NULL) { - lt->i_list=iptr1; -/* iptr2=lt->i_list; */ + if (lt->local_ss==NULL) { + lt->local_ss=ssptr1; } else { - iptr2->next=iptr1; + ssptr2->next=ssptr1; } - iptr2=iptr1; - iptr1=iptr1->next; + ssptr2=ssptr1; + ssptr1=ssptr1->next; } } #ifdef LSRA_DEBUG - if (iptr2 == NULL) panic("lsra_merge_i_lists: Empty Instruction List in Lifetime\n"); + if (ssptr2 == NULL) + panic("lsra_merge_local_ss: Empty Stackslot List in Lifetime\n"); #endif - if (iptr==NULL) - iptr2->next=iptr1; - if (iptr1==NULL) - iptr2->next=iptr; + if (ssptr==NULL) { + if (lt->local_ss==NULL) + lt->local_ss=ssptr1; + else + ssptr2->next=ssptr1; + } + if (ssptr1==NULL) { + if (lt->local_ss==NULL) + lt->local_ss=ssptr; + else + ssptr2->next=ssptr; + } } #ifdef LSRA_DEBUG @@ -1293,10 +1400,10 @@ void dump_join( struct lifetime *lt_passing) for (lt=lt_passing,i=0; lt != NULL; lt=lt->next, ++i) { printf("Lifetime(%2i)\n PT: ",i); for ( ss=lt->passthrough; ss!=NULL; ss=ss->next) - printf("(%2i, %2i, %6p) ",ss->bb, ss->s->varnum, ss->s); + printf("(%2i, %2i, %6p) ",ss->bb, ss->s->varnum, (void *)ss->s); printf("\n SS: "); for (ss = lt->local_ss; ss!=NULL; ss=ss->next) - printf("(%2i, %2i, %6p) ", ss->bb, ss->s->varnum, ss->s); + printf("(%2i, %2i, %6p) ", ss->bb, ss->s->varnum, (void *)ss->s); printf("\n"); } } @@ -1310,10 +1417,10 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata int *in_stacks, *out_stacks; stackptr out, s; - struct stackslot **stacks, *ss, *ss_new; + struct stackslot **stacks, *ss, *ss1, *ss_new; struct lifetime *lt, *lt_prev, *lt_new, *lt_passing; struct stackslot *p, *q, *r; - bool drop; + bool drop, pt; #ifdef LSRA_DEBUG stackptr in; @@ -1390,7 +1497,10 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata for (ss=stacks[i]; ss!=NULL; ss=ss->next) { /* search stackslot ss->s lifetimelist of basicblock(ss->bb) (ss_lifetimes) */ /* remember the link before found lifetime, to remove it afterwards */ - for (lt_prev=lt=ls->ss_lifetimes[ss->bb]; (lt!=NULL) && (lt->s != ss->s); lt_prev=lt, lt=lt->next); + for (lt_prev=lt=ls->ss_lifetimes[ss->bb]; lt!=NULL; lt_prev=lt, lt=lt->next) { + for (ss1=lt->local_ss; (ss1!=NULL) && (ss1->s != ss->s); ss1 = ss1->next); + if (ss1 != NULL) break; /* found */ + } #ifdef LSRA_DEBUG if (lt==NULL) panic("lsra_join_lifetimes error in lifetimelist\n"); #endif @@ -1406,37 +1516,36 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata if (lt->i_list->instr==-1) { if (out_stacks[in_stacks[ss->bb]] == out_stacks[ss->bb]) { /* Throughpassing Basicblock is already in one "join Group" */ - /* If this stackslot (lt->s == ss->s) is already in lt_new->local_ss */ + /* If this stackslot ((lt->local_ss)ss1->s == ss->s) is already in lt_new->local_ss */ /* do not add it a second time! */ if (lt_new != NULL) { - for (ss_new=lt_new->local_ss; (ss_new != NULL) && (ss_new->s != lt->s); ss_new = ss_new->next); + for (ss_new=lt_new->local_ss; (ss_new != NULL) && (ss_new->s != ss1->s); ss_new = ss_new->next); if (ss_new != NULL) drop = true; } } } if (!drop) { - lt->s->varkind=TEMPVAR; /* no LOCALVAR, ARGVAR or STACKVAR with joined lifetimes */ + /* lt->s->varkind=TEMPVAR */; /* no LOCALVAR, ARGVAR or STACKVAR with joined lifetimes */ lt->v_index=-1; /* not a local var */ /* join Lifetime lt to lt_new */ if (lt_new == NULL) { lt_new = lt; lt_new->passthrough = NULL; - lt_new->s = NULL; /* Stackslots are all in local_ss for joined lifetimes */ - } else + } else { lsra_merge_i_lists( lt_new, lt); + lsra_merge_local_ss( lt_new, lt); + } + + + pt=(lt->i_list->instr==-1); /* remember this now, because merge_i_list could once destroy this link*/ /* add stackslot to local_ss of lt_new */ ss_new = DNEW(struct stackslot); - ss_new->s = ss->s; - ss_new->bb = ss->bb; /* for debugging only, has no further use */ - ss_new->next = lt_new->local_ss; - lt_new->local_ss = ss_new; lt_new->savedvar |= (lt->savedvar & SAVEDVAR); - - if (lt->i_list->instr==-1) { + if (pt) { /*lt->i_list->instr==-1) {*/ /* BB passes this stackslot through -> join later with other side!*/ if (out_stacks[in_stacks[ss->bb]] != out_stacks[ss->bb]) { /* Stackslot ist not passed through to same (this) "join group" */ @@ -1537,9 +1646,10 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata if (lt_new->next->local_ss == NULL) panic("lsra_join_lifetimes Lifetime without stackslot\n"); #endif - for (ss=lt_new->next->local_ss; (ss->next != NULL); ss=ss->next); - ss->next=lt->local_ss; - lt->local_ss=lt_new->next->local_ss; +/* for (ss=lt_new->next->local_ss; (ss->next != NULL); ss=ss->next); */ +/* ss->next=lt->local_ss; */ +/* lt->local_ss=lt_new->next->local_ss; */ + lsra_merge_local_ss(lt, lt_new->next); /* merge i_lists in order */ lsra_merge_i_lists(lt, lt_new->next); @@ -1636,16 +1746,15 @@ void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store) n=DNEW(struct lifetime); - n->index=s->varnum; n->savedvar = (s->flags & SAVEDVAR); - n->s=s; + n->local_ss=NULL; + lsra_add_ss( n, s); n->usagecount=1; - if (n->s->varkind == LOCALVAR) - n->v_index=n->s->varnum; + if (s->varkind == LOCALVAR) + n->v_index=s->varnum; else n->v_index=-1; n->i_list=NULL; - n->local_ss=NULL; n->next=ls->ss_lifetimes[block]; ls->ss_lifetimes[block]=n; @@ -1658,15 +1767,14 @@ void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store) void _lsra_from_stack(lsradata *ls, stackptr s, int block, int instr, int store) { struct lifetime *n; - - for (n=ls->ss_lifetimes[block]; (n!=NULL) && (n->s!=s);n=n->next); + /* ss_lifetimes[block]->local_ss have exactly one entry! */ + for (n=ls->ss_lifetimes[block]; (n!=NULL) && (n->local_ss->s!=s);n=n->next); if (n==NULL) { _lsra_new_stack(ls, s, block, instr, store); /* ist mit dem neuen joinen hinterher immer so, wenn ein Stackslot in einen BB "reinkommt" */ /* printf("type %i flags %i varkind %i varnum %i regoff %i \n",s->type,s->flags ,s->varkind ,s->varnum ,s->regoff); */ /* panic("lsra_from_stack: Var on Stack not found"); */ } else { - n->usagecount++; n->i_list=lsra_add_i_list(n->i_list, instr, block, store); } } @@ -1688,7 +1796,6 @@ void lsra_usage_local(lsradata *ls, s4 v_index, int type, int block, int instr, } /* add access at (block, instr) to intruction list */ n->i_list=lsra_add_i_list(n->i_list, instr, block, store); - n->usagecount++; } void lsra_new_local(lsradata *ls, s4 v_index, int type) @@ -1698,11 +1805,8 @@ void lsra_new_local(lsradata *ls, s4 v_index, int type) n=DNEW(struct lifetime); n->local_ss=NULL; n->i_list=NULL; - n->index=v_index; n->v_index=v_index; - n->s=NULL; n->type=type; - n->usagecount=0; n->savedvar = SAVEDVAR; n->next=ls->locals_lifetimes[v_index]; @@ -1720,6 +1824,81 @@ void lsra_dump_stack(stackptr s) } #endif +void dup_mark( struct dup *dup,stackptr s) +{ + struct stackslot *n; + n = DNEW(struct stackslot); + if (dup->ss == NULL) { + dup->ss = n; + n->next = NULL; + } else { + n->next=dup->ss; + dup->ss=n; + } + n->s=s; +} + +void dup_next( struct dup *dup) +{ + struct dup *n; + + n = DNEW(struct dup); + n->next = dup->next; + dup->next=n; + n->ss = dup->ss; + dup->ss = NULL; +} + +void dup_join( struct lsradata *ls, struct dup *dup, int block) +{ + struct dup *d; + struct stackslot *ss, *ss1; + bool pt; /* joins with passthrough lifetimes not yet possible! */ + struct lifetime *join_lt[3]; /* max three lifetimes to join */ + struct lifetime *join_lt_prev[3]; /* previous elements for unlinking */ + struct lifetime *lt, *lt_prev; + int i, join_lt_top, join_to; + + for (i=0; i<3; i++) join_lt[i]=join_lt_prev[i]=NULL; + /* walk through dup structure and clean it up for next block */ + /* the first dup entry is alway empty for the next group to come*/ + for (d=dup->next; d!= NULL; d = dup->next=dup->next->next) { + pt=false; + join_lt_top=0; + for (ss=d->ss; (ss != NULL) && (!pt); ss = ss->next) { + for (lt = lt_prev = ls->ss_lifetimes[block]; lt != NULL ; lt_prev=lt, lt=lt->next) { + for (ss1=lt->local_ss; (ss1!=NULL) && (ss1->s != ss->s); ss1 = ss1->next); + if (ss1 != NULL) break; /* found */ + } + if (lt == NULL) panic("dup_join Lifetimes not found\n"); + pt=(lt->i_list->instr == -1); /* joins with passthrough lifetimes not yet possible! */ + pt|=(lt->i_list->next == NULL); /* joins with "interface" Stackslots not yet possible! */ + if (!pt) { + join_lt_prev[join_lt_top]=lt_prev; + join_lt[join_lt_top++]=lt; + } + } + if (!pt) { /* now join */ + /* look if one element is the root of the list (joint_lt == join_lt_prev == ls->ss_lifetimes[block]) */ + for (join_to=0; (join_to < join_lt_top) && (join_lt[join_to] != join_lt_prev[join_to]); join_to++); + if (join_to == join_lt_top) /* no root element in join array */ + join_to=0; + join_lt[join_to]->v_index = -1; + for (i=0; isavedvar|=(join_lt[i]->savedvar & SAVEDVAR); + /* drop join_lt[i] from list */ + join_lt_prev[i]->next = join_lt[i]->next; + } + } + } + } + dup->next = NULL; +} + void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) { int i; @@ -1731,9 +1910,12 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) instruction *iptr; stackptr in,out; int id, od; - int b_index; - + struct dup dup; + + dup.ss=NULL; + dup.next=NULL; + b_index=0; while (b_index < m->basicblockcount ) { @@ -1766,7 +1948,6 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) /* Make 2 entries -> one for the instack, one for the out stack */ lsra_new_stack(ls, in, b_index, -1); lsra_new_stack(ls, in, b_index, -1); - /* } */ } } iptr = m->basicblocks[b_index].iinstr; @@ -1963,8 +2144,10 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) /* merge dupped vars??? */ case ICMD_DUP: /* lsra_from_stack(ls, src,b_index,iindex);*/ /* inc usage_count! */ -/* dup_alignstackslots(src, dst); */ lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_next(&dup); break; /* pop 0 push 2 dup */ @@ -1972,10 +2155,17 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) case ICMD_DUP2: lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ lsra_from_stack(ls, src,b_index,iindex); /* or inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /* inc usage_count! */ + + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); break; /* pop 2 push 3 dup */ @@ -1983,12 +2173,16 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) case ICMD_DUP_X1: lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src, dst->prev->prev); */ lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_next(&dup); break; /* pop 3 push 4 dup */ @@ -1997,14 +2191,20 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src->prev->prev, dst->prev->prev); */ -/* dup_alignstackslots(src, dst->prev->prev->prev); */ lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); break; /* pop 3 push 5 dup */ @@ -2013,16 +2213,22 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src->prev->prev, dst->prev->prev); */ -/* dup_alignstackslots(src, dst->prev->prev->prev); */ -/* dup_alignstackslots(src->prev, dst->prev->prev->prev->prev); */ lsra_new_stack(ls,dst->prev->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_mark(&dup, dst->prev->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); break; /* pop 4 push 6 dup */ @@ -2032,18 +2238,26 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src->prev->prev, dst->prev->prev); */ -/* dup_alignstackslots(src->prev->prev->prev, dst->prev->prev->prev); */ -/* dup_alignstackslots(src, dst->prev->prev->prev->prev); */ -/* dup_alignstackslots(src->prev, dst->prev->prev->prev->prev->prev); */ lsra_new_stack(ls,dst->prev->prev->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_mark(&dup, dst->prev->prev->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev->prev); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); break; /* pop 2 push 2 swap */ @@ -2051,10 +2265,14 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) case ICMD_SWAP: lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dst->varnum = src->varnum; */ -/* dst->varkind = src->varkind; */ lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst); + dup_next(&dup); break; /* pop 2 push 1 */ @@ -2232,7 +2450,7 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) } /* while instructions */ } /* if */ - + dup_join(ls, &dup, b_index); b_index++; } /* while blocks */ diff --git a/src/vm/jit/lsra.h b/src/vm/jit/lsra.h index f40ec07d9..e4b59d2d0 100644 --- a/src/vm/jit/lsra.h +++ b/src/vm/jit/lsra.h @@ -27,7 +27,7 @@ Authors: Christian Ullrich - $Id: lsra.h 1590 2004-11-25 13:24:49Z christian $ + $Id: lsra.h 1597 2004-11-28 16:37:23Z christian $ */ @@ -42,29 +42,19 @@ #define LSRA_POP -1 struct lifetime { - int index; /* unique index, LOCALVAR varnum or negative*/ - int b_start; /* bb of first use */ - int b_end; /* bb of last use */ int i_start; /* instruction number of first use */ int i_end; /* instruction number of last use */ - int length; /* lifetime in instructions */ - stackptr s; /* stackslot or NULL */ - int v_index; /* local variable index or -1 */ + int v_index; /* local variable index or negative for stackslots */ int type; - int usagecount; /* number of refernces*/ + int usagecount; /* number of references*/ int reg; /* regoffset durch lsra zugewiesen */ int savedvar; struct stackslot *passthrough; /* List of Stackslots in Lifetime, which are passed through a Basic Block */ - struct stackslot *local_ss; + struct stackslot *local_ss; /* Stackslots for this Lifetime or NULL (=="pure" Local Var) */ struct _i_list *i_list; /* list of instructions with references to var */ struct lifetime *next; }; -/* struct int_list { */ -/* int value; */ -/* int_list *next; */ -/* }; */ - struct active_lt { struct lifetime *lt; struct active_lt *next; @@ -116,10 +106,9 @@ struct freemem { struct freemem *next; }; -struct sss { - int bb; - bool out; - struct sss *next; +struct dup { + struct stackslot *ss; + struct dup *next; }; typedef struct lsradata lsradata; @@ -133,6 +122,8 @@ void lsra_clean_Graph( methodinfo *, codegendata *, lsradata *, loopdata *); #ifdef LSRA_DEBUG void lsra_dump_Graph(methodinfo *, struct depthElement **); void lsra_dump_stack(stackptr ); +#endif +#ifdef LSRA_PRINTLIFETIMES void print_lifetimes(registerdata *, struct lifetime *); #endif @@ -143,8 +134,9 @@ int lsra_getmaxblock(methodinfo *, loopdata *, int ); void lsra_calc_lifetime_length(methodinfo *, lsradata *, codegendata *, loopdata *); void lsra_merge_i_lists(struct lifetime *, struct lifetime *); +void lsra_merge_local_ss(struct lifetime *, struct lifetime *); -void _lsra_new_stack( lsradata *, stackptr , int , int , int); +void _lsra_new_stack( lsradata *, stackptr , int , int, int); void _lsra_from_stack(lsradata *, stackptr , int , int, int); void lsra_add_ss(struct lifetime *, stackptr ); void lsra_usage_local(lsradata *, s4 , int , int , int , int ); diff --git a/src/vm/jit/lsra.inc b/src/vm/jit/lsra.inc index 8202c285c..ba756aa7a 100644 --- a/src/vm/jit/lsra.inc +++ b/src/vm/jit/lsra.inc @@ -27,13 +27,19 @@ Authors: Christian Ullrich - $Id: lsra.inc 1590 2004-11-25 13:24:49Z christian $ + $Id: lsra.inc 1597 2004-11-28 16:37:23Z christian $ */ /* #define LSRA_DEBUG */ /* #define LSRA_SAVEDVAR */ /* #define LSRA_MEMORY */ +/* #define LSRA_PRINTLIFETIMES */ + + +#ifdef LSRA_DEBUG +#define LSRA_PRINTLIFETIMES +#endif #include "lsra.h" #include "loop/graph.h" @@ -63,7 +69,7 @@ void lsra(methodinfo *m, codegendata *cd, registerdata *rd, loopdata *ld, t_inli printf("LSRA Start for %s\n", name); - if (strcmp(name,"at/dms/kjc/CSourceClassgenCode(Lat/dms/kjc/BytecodeOptimizer;Ljava/lang/String;Lat/dms/kjc/TypeFactory;)V")==0) { + if (strcmp(name,"java/lang/SysteminitProperties()V")==0) { printf("-------------------\n"); } #endif @@ -95,7 +101,6 @@ void lsra_init(methodinfo *m, codegendata *cd, t_inlining_globals *id, lsradata for (i=0; i < cd->maxlocals; i++) ls->locals_lifetimes[i]=NULL; ls->lifetimes=NULL; ls->stackslots=NULL; - ls->var_index=-1; } void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, loopdata *ld) @@ -108,6 +113,7 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, struct lifetime *lt, *n; int v_index; struct stackslot *ss; + bool drop; /* Setup LSRA Data structures */ if (opt_loops) panic("lsra with -oloop not possible!\n"); @@ -168,8 +174,9 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, v_index=-1; + /* ls->lifetimes contains only the joined stackslotlifetimes */ for (lt=ls->lifetimes; lt != NULL; lt=lt->next) { - lt->index=v_index; + lt->v_index=v_index; #ifdef LSRA_SAVEDVAR lt->savedvar=SAVEDVAR; #endif @@ -179,15 +186,7 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, } } - for (i=0; i < cd->maxlocals; i++) { - for (lt=ls->locals_lifetimes[i]; lt != NULL; lt=lt->next) { -/* lt->local_ss=NULL; */ -#ifdef LSRA_SAVEDVAR - lt->savedvar=SAVEDVAR; -#endif - } - } - + /* add ss_lifetimes[i] to ls->lifetimes or local_lifetimes[lt->s->varnum] */ for (i=0; i < m->basicblockcount; i++) { if (m->basicblocks[i].flags >= BBREACHED) { for (; ls->ss_lifetimes[i] != NULL;) { @@ -195,48 +194,48 @@ void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, #ifdef LSRA_SAVEDVAR lt->savedvar=SAVEDVAR; #endif - if (lt->s->varkind == LOCALVAR) { - /* join with LOCALVAR */ - /* local Lifetime vom richtigen Type suchen */ - for (n=ls->locals_lifetimes[lt->s->varnum]; (n!=NULL) && (n->type!=lt->s->type);n=n->next); #ifdef LSRA_DEBUG - if (n == NULL) panic("lsra_setup: Local Var not found\n"); + if (lt->local_ss == NULL) panic("lsra_setup: normal Stackslot Lifetimes local_ss == NULL\n"); #endif - lsra_merge_i_lists(n, lt); - ss=DNEW(struct stackslot); - ss->s=lt->s; - ss->next=n->local_ss; - n->local_ss=ss; - - ls->ss_lifetimes[i]=lt->next; - } else { -#ifdef LSRA_DEBUG - if (lt->s == NULL) panic("lsra_setup: Wrong assumption about Stackslot Lifetimes -> s\n"); - -#endif - if ((lt->s != NULL) && (lt->s->varkind != ARGVAR)) { - if (lt->s->varkind != ARGVAR) { - lt->s->varkind=TEMPVAR; - lt->s->varnum=v_index; + drop=false; + for (ss=lt->local_ss; (ss!=NULL) && (!drop); ss=ss->next) { + if (lt->local_ss->next == NULL) { /* only one Stackslot in local_ss */ + /* Special Treatment for "lonely" LOCAL and ARGVARs */ + if (ss->s->varkind == LOCALVAR) { + /* join with LOCALVAR */ + /* local Lifetime vom richtigen Type suchen */ + for (n=ls->locals_lifetimes[lt->local_ss->s->varnum]; (n!=NULL) && (n->type!=lt->local_ss->s->type);n=n->next); + lsra_merge_i_lists(n, lt); + if (n->local_ss == NULL) /* "pure" Local without Stackslots */ + n->local_ss = lt->local_ss; + else + lsra_merge_local_ss(n, lt); + + drop = true; } - lt->index=lt->v_index=v_index; - for (ss=lt->local_ss; ss!=NULL; ss=ss->next) { - ss->s->varnum=v_index; - lt->s->varkind=TEMPVAR; + if (lt->local_ss->s->varkind == ARGVAR) { + drop = true; } - - ls->ss_lifetimes[i]=lt->next; - lt->next=ls->lifetimes; - ls->lifetimes=lt; - } else { - ls->ss_lifetimes[i]=lt->next; + } else { + /* no special treatment (only one Stackslot Lifetimes)? */ + ss->s->varnum=v_index; + ss->s->varkind=TEMPVAR; /* only TEMPVAR possible for now */ } - --v_index; - } + } + if (drop) + ls->ss_lifetimes[i]=lt->next; + else { + /* link into ls->lifetimes */ + ls->ss_lifetimes[i]=lt->next; + lt->next=ls->lifetimes; + ls->lifetimes=lt; + lt->v_index=v_index--; + } } /* for */ } /* if */ } + /* add local_lifetimes to lifetimes */ for (i=0; i < cd->maxlocals; i++) { if (ls->locals_lifetimes[i] != NULL) { for (lt=ls->locals_lifetimes[i]; lt->next != NULL; lt=lt->next); @@ -286,10 +285,7 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l exceptiontable *ex; struct depthElement **table; bool back_edge; -#ifdef LSRA_DEBUG struct LoopContainer *lc; - struct LoopElement *le; -#endif table=ld->c_dTable; @@ -304,16 +300,8 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l #endif for (; ex != NULL; ex = ex->down) { -#ifdef LSRA_DEBUG - if (ex->handler == NULL) { - panic("lsra_init_blocks EXCEPTIONTABLE without handler!\n"); - } -#endif -#ifdef LSRA_DEBUG - if ((ex->handler->debug_nr < 0) || (ex->handler->debug_nr >= m->basicblockcount)) { - panic("lsra_init_blocks EXCEPTIONTABLE Handler Blocknummer invalid! \n"); - } +#ifdef LSRA_DEBUG printf("%i ",ex->handler->debug_nr); #endif dF(m, ld, -1, ex->handler->debug_nr); @@ -336,24 +324,12 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l } back_edge=false; -#ifdef LSRA_DEBUG - printf("\n Cleaning c_dTable "); -#endif for(i=0; i < m->basicblockcount; i++) { -#ifdef LSRA_DEBUG - printf("\n %i-",i); -#endif if (m->basicblocks[i].flags < BBREACHED) { -#ifdef LSRA_DEBUG - printf("deleted\n"); -#endif table[i]=NULL; } else { for (de=table[i]; de != NULL; de=de->next) { if (de->value < i) back_edge=true; -#ifdef LSRA_DEBUG - printf("%i-%i ",de->value, bb_succ[de->value]); -#endif if (bb_succ[de->value] != de->value) de->value = bb_succ[de->value]; if (de->value == -1) panic("lsra_clean_Graph: Sprung ins nichts...."); @@ -369,37 +345,44 @@ void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *l /* TODO bis dahin eine loop über die backedge eintragen */ /* anstatt back_edge_panic zu setzen und alle Lifetimes über die */ /* gesamt Methode auszudehnen */ - ls->back_edge_panic = true; - } - } +/* ls->back_edge_panic = true; */ + + /* create loops from all back edges */ + + for(i=0; i < m->basicblockcount; i++) { + if (m->basicblocks[i].flags >= BBREACHED) { + for (de=table[i]; de != NULL; de=de->next) { + if (de->value < i) { + if (ld->c_allLoops == NULL) { + ld->c_allLoops = lc = DNEW(struct LoopContainer); + } else { + lc->next=DNEW(struct LoopContainer); + lc=lc->next; + } + lc->nodes=DNEW(struct LoopElement); + lc->nodes->next=DNEW(struct LoopElement); + lc->nodes->next->next=NULL; + + lc->nodes->block=&(m->basicblocks[i]); + lc->nodes->next->block=&(m->basicblocks[de->value]); + lc->next = NULL; + } + } + } + } #ifdef LSRA_DEBUG - if (back_edge) { - if ( ld->c_allLoops == NULL ) { printf("-------------Warnung Back Edge + no LOOP..\n"); +#endif } - else - printf("Back-edges + Loops:\n"); - lc = ld->c_allLoops; - i = 0; - while (lc != NULL) { - printf("Loop [%d]: ", ++i); - le = lc->nodes; - while (le != NULL) { - printf("%d ", le->node); - printf("\n"); - le = le->next; - } - lc = lc->next; - } - printf("\n"); } -#endif bb_visited=DMNEW(int, m->basicblockcount); for (i=0; ibasicblockcount; i++) { bb_visited[i]=false; } + /* Add all return possibilities to subroutine returns! */ + /* --- subroutines will be inlined ---- -> then cancel this part */ #ifdef LSRA_DEBUG printf("LSRA Subroutine patching\n"); #endif @@ -490,7 +473,9 @@ void lsra_dump_Graph(methodinfo *m, struct depthElement **table) void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) { struct lifetime *lt, *lt_prev, *lt_temp, *int_lt, *int_lt_last, *flt_lt, *flt_lt_last; +#ifdef LSRA_DEBUG int lt_count,lt_int_count,lt_flt_count,lt_left_count; +#endif int i; int lsra_mem_use; int sav_reg_count, tmp_reg_count; @@ -501,24 +486,23 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) int flags; /* 0 INMEMORY->lifetimes, 1 INTREG->int_lt, 2 FLTREG->flt_lt */ int lsra_reg_use; + /* first split lifetimes for integer and float registers */ int_lt_last=int_lt=NULL; flt_lt_last=flt_lt=NULL; +#ifdef LSRA_DEBUG for (lt_count=0,lt=ls->lifetimes; lt!=NULL;lt=lt->next,lt_count++); - +#endif for (lt_prev=lt=ls->lifetimes;lt!=NULL;) { lt->reg = -1; if (lt->v_index < 0) { /* stackslot */ - if (lt->s != NULL) - type = lt->s->type; - else { + #ifdef LSRA_DEBUG - if (lt->local_ss == NULL) panic("lsra_main Lifetime for Stackslot invalid\n"); + if (lt->local_ss == NULL) panic("lsra_main Lifetime Stackslot invalid\n"); #endif - type = lt->local_ss->s->type; - } + type = lt->local_ss->s->type; } else { /* local var */ if (rd->locals[lt->v_index][lt->type].type>=0) { type = rd->locals[lt->v_index][lt->type].type; @@ -582,16 +566,16 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) lsra_sort_lt(&(ls->lifetimes)); lsra_sort_lt(&flt_lt); +#ifdef LSRA_DEBUG for (lt_int_count=0,lt=int_lt; lt!=NULL;lt=lt->next,lt_int_count++); for (lt_flt_count=0,lt=flt_lt; lt!=NULL;lt=lt->next,lt_flt_count++); for (lt_left_count=0,lt=ls->lifetimes; lt!=NULL;lt=lt->next,lt_left_count++); -#ifdef LSRA_DEBUG printf("\nLifetimes: %3i left: %3i Intlt: %3i Fltlt: %3i \n",lt_count,lt_left_count,lt_int_count,lt_flt_count); -#endif if (lt_count != lt_int_count + lt_flt_count + lt_left_count) { panic ("lifetimes missing\n"); } +#endif lsra_reg_use=rd->savintregcnt; if (int_lt!=NULL) { for (reg_count = 0; nregdescint[reg_count] != REG_END; reg_count++); @@ -618,7 +602,6 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) } _lsra_main(m, ls, int_lt, reg, tmp_reg_count, sav_reg_count, &lsra_mem_use, &lsra_reg_use); if (lsra_reg_use > rd->savintregcnt) lsra_reg_use=rd->savintregcnt; -/* r->maxsavintreguse=lsra_reg_use; */ } rd->maxsavintreguse= lsra_reg_use; lsra_reg_use=rd->savfltregcnt; @@ -629,7 +612,7 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) reg=DMNEW(struct lsra_reg,reg_count); sav_reg_count=0; for (i=0; iisleafmethod && (nregdescfloat[i]==REG_ARG))) { reg[sav_reg_count].reg_index=i; reg[sav_reg_count].use=0; sav_reg_count++; @@ -644,7 +627,6 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) } _lsra_main(m,ls, flt_lt, reg, tmp_reg_count, sav_reg_count, &lsra_mem_use, &lsra_reg_use); if (lsra_reg_use > rd->savfltregcnt) lsra_reg_use=rd->savfltregcnt; -/* r->maxsavfltreguse=0; */ } rd->maxsavfltreguse=lsra_reg_use; @@ -666,6 +648,9 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) else lsra_mem_use = 0; #endif +#ifdef SPECIALMEMUSE + lsra_mem_use = rd->ifmemuse; +#endif #ifdef LSRA_DEBUG printf("Alloc Rest\n"); @@ -680,7 +665,7 @@ void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd) #endif lsra_alloc(m, rd, flt_lt,&lsra_mem_use); -#ifdef LSRA_DEBUG +#ifdef LSRA_PRINTLIFETIMES printf("Int RA complete \n"); printf("Lifetimes after splitting int: \n"); print_lifetimes(rd, int_lt); @@ -722,11 +707,6 @@ void lsra_alloc(methodinfo *m, registerdata *rd, struct lifetime *lifet, int *me } if (lt->v_index < 0) { - if (lt->s!=NULL) { - lsra_setflags( &(lt->s->flags), flags); - lt->s->regoff=regoff; - } - for (n=lt->local_ss; n!=NULL; n=n->next) { lsra_setflags( &(n->s->flags), flags); n->s->regoff=regoff; @@ -757,7 +737,7 @@ int lsra_getmem(struct lifetime *lt, struct freemem *fmem, int *mem_use) struct freemem *fm, *p; /* noch kein Speicher vergeben, oder alle Enden später */ - if ((fmem->next == NULL) || (fmem->next->end >= lt->i_start)) /* wirklich >= oder reicht > */ + if ((fmem->next == NULL) || (fmem->next->end > lt->i_start)) fm=lsra_getnewmem(mem_use); else { /* Speicherstelle frei */ @@ -786,7 +766,6 @@ struct freemem *lsra_getnewmem(int *mem_use) void _lsra_main( methodinfo *m, lsradata *ls, struct lifetime *lifet, struct lsra_reg *reg, int tmp_reg_count, int sav_reg_count, int *mem_use, int *reg_use) { struct lifetime *lt; -/* struct active_lt *a; */ int i; int _reg_use; int reg_count, active_count; @@ -871,7 +850,6 @@ void _lsra_expire_old_intervalls(struct lifetime *lt, struct lsra_reg *reg, stru for (i=0;reg[i].reg_index != alt->lt->reg;i++); reg[i].use=0; -/* FREE(alt,struct active_lt); */ (*active_count)--; } } @@ -894,12 +872,11 @@ void _spill_at_intervall(struct lifetime *lt, struct active_lt **active, int *ac if (*active == NULL) { lt->reg=-2; return; - panic("No Lifetime in Active List -> no free registers at all!\n"); } /* get last intervall from active */ for (alt1=alt=*active; alt->next != NULL; alt1=alt, alt=alt->next); - if (alt->lt->i_end > lt->i_end) { + if ((alt->lt->i_end > lt->i_end) && (alt->lt->usagecount < lt->usagecount)) { lt->reg=alt->lt->reg; alt->lt->reg=-1; @@ -1019,12 +996,11 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo } /* extend lifetime within loops */ - for (num_loops=0,lc =ld->c_allLoops;lc!=NULL;num_loops++,lc=lc->next); + /* set up loops[i].b_first .b_last to hold the first and last node of all loops */ loops=DMNEW(struct l_loop,num_loops); - for (i=0,lc=ld->c_allLoops;inext) { le = lc->nodes; @@ -1040,8 +1016,6 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo loops[i].nesting=0; } -/* for (i=0;i= loops[i+1].b_first !*/ @@ -1066,13 +1040,12 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo loops[i].b_first=-1; loops[i].b_last=-1; } else { - /* nested loops */ loops[i].nesting++; /* only boolean if nested... */ } } } -/* for (i=0;ibasicblockcount); for (i=0;ibasicblockcount; i++) { block_loop[i].loop=-1; @@ -1082,6 +1055,7 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo block_loop[i].instr=0; } + /* set block_loop[j].loop to loop index, if Basic Block is in this loop */ for (i=0; ilifetimes; while(lt!=NULL) { if (ls->back_edge_panic) { - lt->b_start=0; lt->i_start=0; - lt->b_end=m->basicblockcount-1; lt->i_end=block_loop[m->basicblockcount-1].instr+m->basicblocks[m->basicblockcount-1].icount; } else { - usage = 0; + usage = 1; il=lt->i_list; blast=il->b_index; ilast=il->instr; while (il->next!=NULL) { + if ((il->b_index != il->next->b_index) || ((il->b_index == il->next->b_index) && (il->instr != il->next->instr))) { + if (block_loop[il->b_index].loop == -1) + usage++; /* not in a loop */ + } il=il->next; - usage++; } bfirst=il->b_index; ifirst=il->instr; @@ -1127,8 +1103,8 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo } } - ilast+=block_loop[blast].instr; - ifirst+=block_loop[bfirst].instr; + ilast+=block_loop[blast].instr; /* add icount of previous Basic Blocks */ + ifirst+=block_loop[bfirst].instr; /* add icount of previous Basic Blocks */ if ((j=block_loop[bfirst].loop)==-1) j=block_loop[blast].loop; @@ -1146,12 +1122,10 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo } } - lt->length=ilast-ifirst; - - lt->b_start=bfirst; - lt->b_end=blast; lt->i_start=ifirst; lt->i_end=ilast; + i=ilast-ifirst; + if (i==0) i=1; lt->usagecount=usage; } lt=lt->next; @@ -1167,72 +1141,146 @@ void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loo #endif } +/* void lsra_sort_lt(struct lifetime **lifet) */ +/* { */ +/* struct lifetime *lt, lt_new, *temp, *tmp; */ + +/* lt_new.next=NULL; */ + +/* for (lt=*lifet; lt!= NULL;) { */ +/* temp=lt->next; */ + +/* for(tmp=<_new; (tmp->next!= NULL) && (tmp->next->i_start < lt->i_start); tmp=tmp->next); */ +/* lt->next=tmp->next; */ +/* tmp->next=lt; */ +/* lt=temp; */ +/* } */ +/* *lifet=lt_new.next; */ +/* } */ + + +#define P_MAX 21 +void _lsra_merge_lt(struct lifetime **p, int i1, int i2) +{ + struct lifetime *iptr, *iptr1, *iptr2; + + if ( (iptr1=p[i2])==NULL) return; + if ( (iptr=p[i1])==NULL) return; + + iptr2=p[i1]=NULL; + p[i2]=NULL; + + while ((iptr != NULL) && (iptr1 != NULL)) { + if (iptr->i_start < iptr1->i_start) { + if (iptr2==NULL) { + p[i1]=iptr; + } else { + iptr2->next=iptr; + } + iptr2=iptr; + iptr=iptr->next; + } else { + if (iptr2==NULL) { + p[i1]=iptr1; + } else { + iptr2->next=iptr1; + } + iptr2=iptr1; + iptr1=iptr1->next; + } + } + if (iptr==NULL) + iptr2->next=iptr1; + if (iptr1==NULL) + iptr2->next=iptr; +} + +void lsra_merge_lt(struct lifetime **p, int top) +{ + int i,j; + + for (j=1; j just turn around */ - /* not really correct through exception and loop lifetime expansion! -> turn around and sort in*/ - lt_new.next=NULL; + p=DMNEW(struct lifetime *, P_MAX); + for (i=0; inext; + temp=lt; + lt=lt->next; + if (lt == NULL) { + p[top]=temp; + temp->next=NULL; + } else { + tmp=lt; + lt=lt->next; - for(tmp=<_new; (tmp->next!= NULL) && (tmp->next->i_start < lt->i_start); tmp=tmp->next); - lt->next=tmp->next; - tmp->next=lt; - lt=temp; + if (temp->i_start < tmp->i_start) { + p[top]=temp; + /* temp->next == tmp */ + tmp->next=NULL; + } else { + p[top]=tmp; + tmp->next=temp; + temp->next=NULL; + } + } + top++; + if (top == P_MAX) { + lsra_merge_lt(p, P_MAX); + top=1; + } } - *lifet=lt_new.next; + lsra_merge_lt(p, top); + *lifet=p[0]; } - +#ifdef LSRA_PRINTLIFETIMES void print_lifetimes(registerdata *rd, struct lifetime *lt) { struct lifetime *n; struct _i_list *ni; int type,flags,regoff,j,varkind; -/* int i; */ + /* int i; */ for (n=lt,j=0; n!=NULL; n=n->next,j++) { if (n->v_index < 0) { /* stackslot */ - if (n->s != 0) { /* stackslot */ - type = n->s->type; - flags=n->s->flags; - regoff=n->s->regoff; - varkind=n->s->varkind; - } else { - if (n->local_ss != 0) { - type = n->local_ss->s->type; - flags=n->local_ss->s->flags; - regoff=n->local_ss->s->regoff; - varkind=n->local_ss->s->varkind; - } - } + type = n->local_ss->s->type; + flags=n->local_ss->s->flags; + regoff=n->local_ss->s->regoff; + varkind=n->local_ss->s->varkind; } else { /* local var */ -/* for (i=TYPE_INT; i<=TYPE_ADR; i++) { */ - if (rd->locals[n->v_index][n->type].type>=0) { - type = rd->locals[n->v_index][n->type].type; - flags=rd->locals[n->v_index][n->type].flags; - regoff=rd->locals[n->v_index][n->type].regoff; - varkind=-1; - } else panic("Type Data mismatch 3\n"); -/* } */ + if (rd->locals[n->v_index][n->type].type>=0) { + type = rd->locals[n->v_index][n->type].type; + flags=rd->locals[n->v_index][n->type].flags; + regoff=rd->locals[n->v_index][n->type].regoff; + varkind=-1; + } else + panic("Type Data mismatch 3\n"); } - printf("i_Start: %3i i_stop: %3i reg: %3i Index: %3i VI: %3i Usage: %3i length: %3i type: %3i flags: %3i varkind: %3i ILst: ",n->i_start,n->i_end,regoff,n->index,n->v_index,n->usagecount, n->length,type,flags, varkind); + printf("i_Start: %3i i_stop: %3i reg: %3i VI: %3i Usage: %3i type: %3i flags: %3i varkind: %3i ILst: ",n->i_start,n->i_end,regoff,n->v_index,n->usagecount,type,flags, varkind); for (ni=n->i_list; ni!=NULL; ni=ni->next) { if (ni==ni->next) panic("loop in instruction list!\n"); printf( "(%3i,%3i) ",ni->b_index,ni->instr); } printf("\n"); -/* if (n->s!=NULL) */ -/* printf(" type: %1i flags: %1i varkind: %1i varnum: %3i regoff: %4i\n",n->s->type,n->s->flags,n->s->varkind,n->s->varnum,n->s->regoff); */ } printf( "%3i Lifetimes printed \n",j); } +#endif struct stackslot *lsra_make_ss(stackptr s, int bb_index) { @@ -1254,33 +1302,92 @@ void lsra_merge_i_lists(struct lifetime *lt, struct lifetime *lt1) iptr2=lt->i_list=NULL; iptr1=lt1->i_list; while ((iptr != NULL) && (iptr1 != NULL)) { - if ((iptr->b_index > iptr1->b_index)|| ((iptr->b_index == iptr1->b_index) && (iptr->instr > iptr1->instr))) { - if (lt->i_list==NULL) { - lt->i_list=iptr; -/* iptr2=lt->i_list; */ + if (iptr1->instr == -1) { + /* throw away, just for joining */ + iptr1=iptr1->next; + } else { + if ((iptr->b_index > iptr1->b_index)|| ((iptr->b_index == iptr1->b_index) && (iptr->instr > iptr1->instr))) { + if (lt->i_list==NULL) { + lt->i_list=iptr; + } else { + iptr2->next=iptr; + } + iptr2=iptr; + iptr=iptr->next; } else { - iptr2->next=iptr; + if (lt->i_list==NULL) { + lt->i_list=iptr1; + } else { + iptr2->next=iptr1; + } + iptr2=iptr1; + iptr1=iptr1->next; } - iptr2=iptr; - iptr=iptr->next; + } + } +#ifdef LSRA_DEBUG + if (iptr2 == NULL) + panic("lsra_merge_i_lists: Empty Instruction List in Lifetime\n"); +#endif + if (iptr==NULL) { + if (lt->i_list==NULL) + lt->i_list=iptr1; + else + iptr2->next=iptr1; + } + if (iptr1==NULL) { + if (lt->i_list==NULL) + lt->i_list=iptr; + else + iptr2->next=iptr; + } +} + +/* merge local_ss from lt1 to lt in order */ +void lsra_merge_local_ss(struct lifetime *lt, struct lifetime *lt1) +{ + struct stackslot *ssptr, *ssptr1, *ssptr2; + + /* merge stackslots in order */ + ssptr=lt->local_ss; + ssptr2=lt->local_ss=NULL; + ssptr1=lt1->local_ss; + while ((ssptr != NULL) && (ssptr1 != NULL)) { + + if (ssptr->s > ssptr1->s) { + if (lt->local_ss==NULL) { + lt->local_ss=ssptr; + } else { + ssptr2->next=ssptr; + } + ssptr2=ssptr; + ssptr=ssptr->next; } else { - if (lt->i_list==NULL) { - lt->i_list=iptr1; -/* iptr2=lt->i_list; */ + if (lt->local_ss==NULL) { + lt->local_ss=ssptr1; } else { - iptr2->next=iptr1; + ssptr2->next=ssptr1; } - iptr2=iptr1; - iptr1=iptr1->next; + ssptr2=ssptr1; + ssptr1=ssptr1->next; } } #ifdef LSRA_DEBUG - if (iptr2 == NULL) panic("lsra_merge_i_lists: Empty Instruction List in Lifetime\n"); + if (ssptr2 == NULL) + panic("lsra_merge_local_ss: Empty Stackslot List in Lifetime\n"); #endif - if (iptr==NULL) - iptr2->next=iptr1; - if (iptr1==NULL) - iptr2->next=iptr; + if (ssptr==NULL) { + if (lt->local_ss==NULL) + lt->local_ss=ssptr1; + else + ssptr2->next=ssptr1; + } + if (ssptr1==NULL) { + if (lt->local_ss==NULL) + lt->local_ss=ssptr; + else + ssptr2->next=ssptr; + } } #ifdef LSRA_DEBUG @@ -1293,10 +1400,10 @@ void dump_join( struct lifetime *lt_passing) for (lt=lt_passing,i=0; lt != NULL; lt=lt->next, ++i) { printf("Lifetime(%2i)\n PT: ",i); for ( ss=lt->passthrough; ss!=NULL; ss=ss->next) - printf("(%2i, %2i, %6p) ",ss->bb, ss->s->varnum, ss->s); + printf("(%2i, %2i, %6p) ",ss->bb, ss->s->varnum, (void *)ss->s); printf("\n SS: "); for (ss = lt->local_ss; ss!=NULL; ss=ss->next) - printf("(%2i, %2i, %6p) ", ss->bb, ss->s->varnum, ss->s); + printf("(%2i, %2i, %6p) ", ss->bb, ss->s->varnum, (void *)ss->s); printf("\n"); } } @@ -1310,10 +1417,10 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata int *in_stacks, *out_stacks; stackptr out, s; - struct stackslot **stacks, *ss, *ss_new; + struct stackslot **stacks, *ss, *ss1, *ss_new; struct lifetime *lt, *lt_prev, *lt_new, *lt_passing; struct stackslot *p, *q, *r; - bool drop; + bool drop, pt; #ifdef LSRA_DEBUG stackptr in; @@ -1390,7 +1497,10 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata for (ss=stacks[i]; ss!=NULL; ss=ss->next) { /* search stackslot ss->s lifetimelist of basicblock(ss->bb) (ss_lifetimes) */ /* remember the link before found lifetime, to remove it afterwards */ - for (lt_prev=lt=ls->ss_lifetimes[ss->bb]; (lt!=NULL) && (lt->s != ss->s); lt_prev=lt, lt=lt->next); + for (lt_prev=lt=ls->ss_lifetimes[ss->bb]; lt!=NULL; lt_prev=lt, lt=lt->next) { + for (ss1=lt->local_ss; (ss1!=NULL) && (ss1->s != ss->s); ss1 = ss1->next); + if (ss1 != NULL) break; /* found */ + } #ifdef LSRA_DEBUG if (lt==NULL) panic("lsra_join_lifetimes error in lifetimelist\n"); #endif @@ -1406,37 +1516,36 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata if (lt->i_list->instr==-1) { if (out_stacks[in_stacks[ss->bb]] == out_stacks[ss->bb]) { /* Throughpassing Basicblock is already in one "join Group" */ - /* If this stackslot (lt->s == ss->s) is already in lt_new->local_ss */ + /* If this stackslot ((lt->local_ss)ss1->s == ss->s) is already in lt_new->local_ss */ /* do not add it a second time! */ if (lt_new != NULL) { - for (ss_new=lt_new->local_ss; (ss_new != NULL) && (ss_new->s != lt->s); ss_new = ss_new->next); + for (ss_new=lt_new->local_ss; (ss_new != NULL) && (ss_new->s != ss1->s); ss_new = ss_new->next); if (ss_new != NULL) drop = true; } } } if (!drop) { - lt->s->varkind=TEMPVAR; /* no LOCALVAR, ARGVAR or STACKVAR with joined lifetimes */ + /* lt->s->varkind=TEMPVAR */; /* no LOCALVAR, ARGVAR or STACKVAR with joined lifetimes */ lt->v_index=-1; /* not a local var */ /* join Lifetime lt to lt_new */ if (lt_new == NULL) { lt_new = lt; lt_new->passthrough = NULL; - lt_new->s = NULL; /* Stackslots are all in local_ss for joined lifetimes */ - } else + } else { lsra_merge_i_lists( lt_new, lt); + lsra_merge_local_ss( lt_new, lt); + } + + + pt=(lt->i_list->instr==-1); /* remember this now, because merge_i_list could once destroy this link*/ /* add stackslot to local_ss of lt_new */ ss_new = DNEW(struct stackslot); - ss_new->s = ss->s; - ss_new->bb = ss->bb; /* for debugging only, has no further use */ - ss_new->next = lt_new->local_ss; - lt_new->local_ss = ss_new; lt_new->savedvar |= (lt->savedvar & SAVEDVAR); - - if (lt->i_list->instr==-1) { + if (pt) { /*lt->i_list->instr==-1) {*/ /* BB passes this stackslot through -> join later with other side!*/ if (out_stacks[in_stacks[ss->bb]] != out_stacks[ss->bb]) { /* Stackslot ist not passed through to same (this) "join group" */ @@ -1537,9 +1646,10 @@ void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata if (lt_new->next->local_ss == NULL) panic("lsra_join_lifetimes Lifetime without stackslot\n"); #endif - for (ss=lt_new->next->local_ss; (ss->next != NULL); ss=ss->next); - ss->next=lt->local_ss; - lt->local_ss=lt_new->next->local_ss; +/* for (ss=lt_new->next->local_ss; (ss->next != NULL); ss=ss->next); */ +/* ss->next=lt->local_ss; */ +/* lt->local_ss=lt_new->next->local_ss; */ + lsra_merge_local_ss(lt, lt_new->next); /* merge i_lists in order */ lsra_merge_i_lists(lt, lt_new->next); @@ -1636,16 +1746,15 @@ void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store) n=DNEW(struct lifetime); - n->index=s->varnum; n->savedvar = (s->flags & SAVEDVAR); - n->s=s; + n->local_ss=NULL; + lsra_add_ss( n, s); n->usagecount=1; - if (n->s->varkind == LOCALVAR) - n->v_index=n->s->varnum; + if (s->varkind == LOCALVAR) + n->v_index=s->varnum; else n->v_index=-1; n->i_list=NULL; - n->local_ss=NULL; n->next=ls->ss_lifetimes[block]; ls->ss_lifetimes[block]=n; @@ -1658,15 +1767,14 @@ void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store) void _lsra_from_stack(lsradata *ls, stackptr s, int block, int instr, int store) { struct lifetime *n; - - for (n=ls->ss_lifetimes[block]; (n!=NULL) && (n->s!=s);n=n->next); + /* ss_lifetimes[block]->local_ss have exactly one entry! */ + for (n=ls->ss_lifetimes[block]; (n!=NULL) && (n->local_ss->s!=s);n=n->next); if (n==NULL) { _lsra_new_stack(ls, s, block, instr, store); /* ist mit dem neuen joinen hinterher immer so, wenn ein Stackslot in einen BB "reinkommt" */ /* printf("type %i flags %i varkind %i varnum %i regoff %i \n",s->type,s->flags ,s->varkind ,s->varnum ,s->regoff); */ /* panic("lsra_from_stack: Var on Stack not found"); */ } else { - n->usagecount++; n->i_list=lsra_add_i_list(n->i_list, instr, block, store); } } @@ -1688,7 +1796,6 @@ void lsra_usage_local(lsradata *ls, s4 v_index, int type, int block, int instr, } /* add access at (block, instr) to intruction list */ n->i_list=lsra_add_i_list(n->i_list, instr, block, store); - n->usagecount++; } void lsra_new_local(lsradata *ls, s4 v_index, int type) @@ -1698,11 +1805,8 @@ void lsra_new_local(lsradata *ls, s4 v_index, int type) n=DNEW(struct lifetime); n->local_ss=NULL; n->i_list=NULL; - n->index=v_index; n->v_index=v_index; - n->s=NULL; n->type=type; - n->usagecount=0; n->savedvar = SAVEDVAR; n->next=ls->locals_lifetimes[v_index]; @@ -1720,6 +1824,81 @@ void lsra_dump_stack(stackptr s) } #endif +void dup_mark( struct dup *dup,stackptr s) +{ + struct stackslot *n; + n = DNEW(struct stackslot); + if (dup->ss == NULL) { + dup->ss = n; + n->next = NULL; + } else { + n->next=dup->ss; + dup->ss=n; + } + n->s=s; +} + +void dup_next( struct dup *dup) +{ + struct dup *n; + + n = DNEW(struct dup); + n->next = dup->next; + dup->next=n; + n->ss = dup->ss; + dup->ss = NULL; +} + +void dup_join( struct lsradata *ls, struct dup *dup, int block) +{ + struct dup *d; + struct stackslot *ss, *ss1; + bool pt; /* joins with passthrough lifetimes not yet possible! */ + struct lifetime *join_lt[3]; /* max three lifetimes to join */ + struct lifetime *join_lt_prev[3]; /* previous elements for unlinking */ + struct lifetime *lt, *lt_prev; + int i, join_lt_top, join_to; + + for (i=0; i<3; i++) join_lt[i]=join_lt_prev[i]=NULL; + /* walk through dup structure and clean it up for next block */ + /* the first dup entry is alway empty for the next group to come*/ + for (d=dup->next; d!= NULL; d = dup->next=dup->next->next) { + pt=false; + join_lt_top=0; + for (ss=d->ss; (ss != NULL) && (!pt); ss = ss->next) { + for (lt = lt_prev = ls->ss_lifetimes[block]; lt != NULL ; lt_prev=lt, lt=lt->next) { + for (ss1=lt->local_ss; (ss1!=NULL) && (ss1->s != ss->s); ss1 = ss1->next); + if (ss1 != NULL) break; /* found */ + } + if (lt == NULL) panic("dup_join Lifetimes not found\n"); + pt=(lt->i_list->instr == -1); /* joins with passthrough lifetimes not yet possible! */ + pt|=(lt->i_list->next == NULL); /* joins with "interface" Stackslots not yet possible! */ + if (!pt) { + join_lt_prev[join_lt_top]=lt_prev; + join_lt[join_lt_top++]=lt; + } + } + if (!pt) { /* now join */ + /* look if one element is the root of the list (joint_lt == join_lt_prev == ls->ss_lifetimes[block]) */ + for (join_to=0; (join_to < join_lt_top) && (join_lt[join_to] != join_lt_prev[join_to]); join_to++); + if (join_to == join_lt_top) /* no root element in join array */ + join_to=0; + join_lt[join_to]->v_index = -1; + for (i=0; isavedvar|=(join_lt[i]->savedvar & SAVEDVAR); + /* drop join_lt[i] from list */ + join_lt_prev[i]->next = join_lt[i]->next; + } + } + } + } + dup->next = NULL; +} + void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) { int i; @@ -1731,9 +1910,12 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) instruction *iptr; stackptr in,out; int id, od; - int b_index; - + struct dup dup; + + dup.ss=NULL; + dup.next=NULL; + b_index=0; while (b_index < m->basicblockcount ) { @@ -1766,7 +1948,6 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) /* Make 2 entries -> one for the instack, one for the out stack */ lsra_new_stack(ls, in, b_index, -1); lsra_new_stack(ls, in, b_index, -1); - /* } */ } } iptr = m->basicblocks[b_index].iinstr; @@ -1963,8 +2144,10 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) /* merge dupped vars??? */ case ICMD_DUP: /* lsra_from_stack(ls, src,b_index,iindex);*/ /* inc usage_count! */ -/* dup_alignstackslots(src, dst); */ lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_next(&dup); break; /* pop 0 push 2 dup */ @@ -1972,10 +2155,17 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) case ICMD_DUP2: lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ lsra_from_stack(ls, src,b_index,iindex); /* or inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /* inc usage_count! */ + + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); break; /* pop 2 push 3 dup */ @@ -1983,12 +2173,16 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) case ICMD_DUP_X1: lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src, dst->prev->prev); */ lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_next(&dup); break; /* pop 3 push 4 dup */ @@ -1997,14 +2191,20 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src->prev->prev, dst->prev->prev); */ -/* dup_alignstackslots(src, dst->prev->prev->prev); */ lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); break; /* pop 3 push 5 dup */ @@ -2013,16 +2213,22 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src->prev->prev, dst->prev->prev); */ -/* dup_alignstackslots(src, dst->prev->prev->prev); */ -/* dup_alignstackslots(src->prev, dst->prev->prev->prev->prev); */ lsra_new_stack(ls,dst->prev->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_mark(&dup, dst->prev->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); break; /* pop 4 push 6 dup */ @@ -2032,18 +2238,26 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dup_alignstackslots(src, dst); */ -/* dup_alignstackslots(src->prev, dst->prev); */ -/* dup_alignstackslots(src->prev->prev, dst->prev->prev); */ -/* dup_alignstackslots(src->prev->prev->prev, dst->prev->prev->prev); */ -/* dup_alignstackslots(src, dst->prev->prev->prev->prev); */ -/* dup_alignstackslots(src->prev, dst->prev->prev->prev->prev->prev); */ lsra_new_stack(ls,dst->prev->prev->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev->prev,b_index,iindex); lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst); + dup_mark(&dup, dst->prev->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst->prev); + dup_mark(&dup, dst->prev->prev->prev->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev); + dup_mark(&dup, dst->prev->prev); + dup_next(&dup); + dup_mark(&dup, src->prev->prev->prev); + dup_mark(&dup, dst->prev->prev->prev); + dup_next(&dup); break; /* pop 2 push 2 swap */ @@ -2051,10 +2265,14 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) case ICMD_SWAP: lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */ lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */ -/* dst->varnum = src->varnum; */ -/* dst->varkind = src->varkind; */ lsra_new_stack(ls,dst->prev,b_index,iindex); lsra_new_stack(ls,dst,b_index,iindex); + dup_mark(&dup, src); + dup_mark(&dup, dst->prev); + dup_next(&dup); + dup_mark(&dup, src->prev); + dup_mark(&dup, dst); + dup_next(&dup); break; /* pop 2 push 1 */ @@ -2232,7 +2450,7 @@ void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls) } /* while instructions */ } /* if */ - + dup_join(ls, &dup, b_index); b_index++; } /* while blocks */