1 /* jit/lsra.inc - linear scan register allocator
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7 J. Wenninger, C. Ullrich
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Christian Ullrich
30 $Id: lsra.inc 1590 2004-11-25 13:24:49Z christian $
34 /* #define LSRA_DEBUG */
35 /* #define LSRA_SAVEDVAR */
36 /* #define LSRA_MEMORY */
39 #include "loop/graph.h"
40 #include "loop/loop.h"
41 #include "toolbox/memory.h"
49 void lsra(methodinfo *m, codegendata *cd, registerdata *rd, loopdata *ld, t_inlining_globals *id)
55 char name[1256], name1[1256];
57 utf_sprint(name, m->class->name);
58 utf_sprint(name1, m->name);
60 utf_sprint(name1, m->descriptor);
64 printf("LSRA Start for %s\n", name);
66 if (strcmp(name,"at/dms/kjc/CSourceClassgenCode(Lat/dms/kjc/BytecodeOptimizer;Ljava/lang/String;Lat/dms/kjc/TypeFactory;)V")==0) {
67 printf("-------------------\n");
72 lsra_init(m, cd, id, ls);
73 lsra_setup(m, cd, rd, ls, ld);
82 void lsra_init(methodinfo *m, codegendata *cd, t_inlining_globals *id, lsradata *ls)
86 /* Init LSRA Data Structures */
87 ls->back_edge_panic=false;
88 /* lifetimes für alle Basicblocks allokieren */
89 ls->ss_lifetimes=DMNEW(struct lifetime *, m->basicblockcount);
90 for (i=0; i<m->basicblockcount; i++) ls->ss_lifetimes[i]=NULL;
92 if (cd->maxlocals != id->cumlocals) panic("lsra: Welche locals nehmen?\n");
94 ls->locals_lifetimes=DMNEW(struct lifetime *, cd->maxlocals);
95 for (i=0; i < cd->maxlocals; i++) ls->locals_lifetimes[i]=NULL;
101 void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls, loopdata *ld)
108 struct lifetime *lt, *n;
110 struct stackslot *ss;
112 /* Setup LSRA Data structures */
113 if (opt_loops) panic("lsra with -oloop not possible!\n");
119 /* BBDELETED Blöcke aus loopdata->c_dTable rausschmeissen! */
120 /* Exceptionhandler in loopdata->c_dTable hinzufügen */
122 printf("LSRA lsra_clean_Graph\n");
124 lsra_clean_Graph(m, cd, ls, ld);
127 /* sicherheitshalber Konsistenz von m->basicblocks[..] mit basicblocks->next (Liste) überprüfen */
128 printf("LSRA bb prüfen\n");
130 bptr = m->basicblocks;
131 while (bptr != NULL) {
132 if (i > m->basicblockcount){
133 panic("linked bb list does not correspond with bb array(1)\n");
135 if (bptr != &(m->basicblocks[i])){
136 panic("linked bb list does not correspond with bb array(2)\n");
142 if (i<m->basicblockcount){
143 panic("linked bb list does not correspond with bb array(3)\n");
146 printf("LSRA lsra_dump_Graph\n");
147 lsra_dump_Graph(m, ld->c_dTable);
151 /* Parameter initialisieren = local Vars schreibzugriff bei 0,0*/
153 for (p = 0, i = 0; p < m->paramcount; p++) {
154 t = m->paramtypes[p];
156 if (rd->locals[i][t].type >= 0)
157 lsra_usage_local(ls, i, t, 0, 0, LSRA_STORE);
159 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
164 printf("LSRA lsra_scan_register_canditates\n");
166 lsra_scan_registers_canditates(m, ls);
167 lsra_join_lifetimes(m, cd, ls, ld);
171 for (lt=ls->lifetimes; lt != NULL; lt=lt->next) {
174 lt->savedvar=SAVEDVAR;
176 for (ss=lt->local_ss; ss != NULL; ss=ss->next) {
177 ss->s->varnum=v_index;
178 ss->s->varkind=TEMPVAR; /* just another time */
182 for (i=0; i < cd->maxlocals; i++) {
183 for (lt=ls->locals_lifetimes[i]; lt != NULL; lt=lt->next) {
184 /* lt->local_ss=NULL; */
186 lt->savedvar=SAVEDVAR;
191 for (i=0; i < m->basicblockcount; i++) {
192 if (m->basicblocks[i].flags >= BBREACHED) {
193 for (; ls->ss_lifetimes[i] != NULL;) {
194 lt=ls->ss_lifetimes[i];
196 lt->savedvar=SAVEDVAR;
198 if (lt->s->varkind == LOCALVAR) {
199 /* join with LOCALVAR */
200 /* local Lifetime vom richtigen Type suchen */
201 for (n=ls->locals_lifetimes[lt->s->varnum]; (n!=NULL) && (n->type!=lt->s->type);n=n->next);
203 if (n == NULL) panic("lsra_setup: Local Var not found\n");
205 lsra_merge_i_lists(n, lt);
206 ss=DNEW(struct stackslot);
208 ss->next=n->local_ss;
211 ls->ss_lifetimes[i]=lt->next;
214 if (lt->s == NULL) panic("lsra_setup: Wrong assumption about Stackslot Lifetimes -> s\n");
217 if ((lt->s != NULL) && (lt->s->varkind != ARGVAR)) {
218 if (lt->s->varkind != ARGVAR) {
219 lt->s->varkind=TEMPVAR;
220 lt->s->varnum=v_index;
222 lt->index=lt->v_index=v_index;
223 for (ss=lt->local_ss; ss!=NULL; ss=ss->next) {
224 ss->s->varnum=v_index;
225 lt->s->varkind=TEMPVAR;
228 ls->ss_lifetimes[i]=lt->next;
229 lt->next=ls->lifetimes;
232 ls->ss_lifetimes[i]=lt->next;
240 for (i=0; i < cd->maxlocals; i++) {
241 if (ls->locals_lifetimes[i] != NULL) {
242 for (lt=ls->locals_lifetimes[i]; lt->next != NULL; lt=lt->next);
243 lt->next=ls->lifetimes;
244 ls->lifetimes=ls->locals_lifetimes[i];
248 /* calc lifetime length */
250 printf("Lifetimes before calc_lifetime_length: \n");
251 print_lifetimes(rd, ls->lifetimes);
252 printf("LSRA lsra_calc_lifetime_lengthe\n");
254 lsra_calc_lifetime_length(m, ls, cd, ld);
257 int lsra_get_sbr_end(methodinfo *m, loopdata *ld, int bb, int *bb_visited)
260 struct depthElement *de;
264 ip = m->basicblocks[bb].iinstr + m->basicblocks[bb].icount -1;/* set ip to last instruction */
265 if (ip->opc == ICMD_RET)
267 /* This Block is not the end -> search all following Blocks */
269 for (de=ld->c_dTable[bb]; de != NULL; de=de->next) {
270 if (!bb_visited[de->value]) {
271 j=lsra_get_sbr_end(m, ld, de->value, bb_visited);
272 if (j!=-1) { /* No new return path found */
273 if ((bb_end != -1) && (j!=bb_end)) panic("SBR has more than one exit Blocks\n");
281 void lsra_clean_Graph( methodinfo *m, codegendata *cd, lsradata *ls, loopdata *ld)
284 struct depthElement *de, *n;
285 int *bb_succ, *bb_visited, *ptr, index;
287 struct depthElement **table;
290 struct LoopContainer *lc;
291 struct LoopElement *le;
300 /* Exceptionhandler noch in c_dTable aufnehmen */
301 ex=cd->exceptiontable;
303 printf("ExTable(%i): ", cd->exceptiontablelength);
306 for (; ex != NULL; ex = ex->down) {
308 if (ex->handler == NULL) {
309 panic("lsra_init_blocks EXCEPTIONTABLE without handler!\n");
313 if ((ex->handler->debug_nr < 0) || (ex->handler->debug_nr >= m->basicblockcount)) {
314 panic("lsra_init_blocks EXCEPTIONTABLE Handler Blocknummer invalid! \n");
317 printf("%i ",ex->handler->debug_nr);
319 dF(m, ld, -1, ex->handler->debug_nr);
323 /* Setting up successors of deleted Basic Blocks, in case c_dTable has an edge */
324 /* to a deleted block, so it can be replaced with the next "normal" Block */
325 bb_succ= DMNEW(int, m->basicblockcount);
326 for (i=0; i < m->basicblockcount; i++) {
327 if (m->basicblocks[i].flags >= BBREACHED)
330 for(j=i; ((j < m->basicblockcount) && (m->basicblocks[j].flags < BBREACHED)); j++);
331 if (j < m->basicblockcount)
340 printf("\n Cleaning c_dTable ");
342 for(i=0; i < m->basicblockcount; i++) {
346 if (m->basicblocks[i].flags < BBREACHED) {
352 for (de=table[i]; de != NULL; de=de->next) {
353 if (de->value < i) back_edge=true;
355 printf("%i-%i ",de->value, bb_succ[de->value]);
357 if (bb_succ[de->value] != de->value)
358 de->value = bb_succ[de->value];
359 if (de->value == -1) panic("lsra_clean_Graph: Sprung ins nichts....");
365 if ( ld->c_allLoops == NULL ) {
366 /* Keine Loops in Datenstruktur aber backedge! */
367 /* sollte nach BasicBlock umsortieren (revererse Depth First sort) */
368 /* und überprüfen von jit/loop/loop.c nicht mehr nötig sein */
369 /* TODO bis dahin eine loop über die backedge eintragen */
370 /* anstatt back_edge_panic zu setzen und alle Lifetimes über die */
371 /* gesamt Methode auszudehnen */
372 ls->back_edge_panic = true;
377 if ( ld->c_allLoops == NULL ) {
378 printf("-------------Warnung Back Edge + no LOOP..\n");
381 printf("Back-edges + Loops:\n");
385 printf("Loop [%d]: ", ++i);
388 printf("%d ", le->node);
398 bb_visited=DMNEW(int, m->basicblockcount);
399 for (i=0; i<m->basicblockcount; i++) {
404 printf("LSRA Subroutine patching\n");
406 for (i=0; i < m->basicblockcount; i++ ) {
407 /* Search all Subroutine Headers */
408 if (m->basicblocks[i].type == BBTYPE_SBR) {
410 printf("Subroutine at BB %3i num pred: %3i Pred: ",i, ld->c_numPre[i]);
411 for (ptr=ld->c_pre[i], index=0; index < ld->c_numPre[i]; ++index, ++ptr)
412 printf("%3i ", *ptr);
415 if (ld->c_numPre[i] > 1) { /* only if more than one call */
417 printf("Searching End of Subroutine: ");
419 j=lsra_get_sbr_end(m, ld, i, bb_visited); /* get Ending Block of Subroutine */
423 /* ensure, that all Predecessors+1 of the Subroutine Header are in the list */
424 /* in the List is only one Predecessor */
426 if (ld->c_dTable[j] == NULL) panic("No SBR Return in c_dTable\n");
427 if (ld->c_dTable[j]->next != NULL) panic("More than one SBR Return in c_dTable\n");
430 for (ptr=ld->c_pre[i], index=0; index < ld->c_numPre[i]; ++index, ++ptr) {
431 if (*ptr+1!=de->value) { /* Make new Entry */
432 n=DNEW(struct depthElement);
440 printf( "(%3i)table[%3i %3i]: ",m->basicblocks[j].flags,j,m->basicblocks[j].debug_nr);
441 for (de=ld->c_dTable[j]; de != NULL; de=de->next) {
442 printf( "%3i ", de->value);
451 void lsra_dump_Graph(methodinfo *m, struct depthElement **table)
454 struct depthElement *de;
457 printf ("table == NULL\n");
461 for(i=0; i < m->basicblockcount; i++) {
463 switch (m->basicblocks[i].type) {
476 printf("%3i ", m->basicblocks[i].flags);
480 printf( "(F%3i)table[%3i %3i]: ",m->basicblocks[i].flags,i,m->basicblocks[i].debug_nr);
481 for (de=table[i]; de != NULL; de=de->next) {
482 printf( "%3i ", de->value);
486 printf( "table dump end\n");
490 void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd)
492 struct lifetime *lt, *lt_prev, *lt_temp, *int_lt, *int_lt_last, *flt_lt, *flt_lt_last;
493 int lt_count,lt_int_count,lt_flt_count,lt_left_count;
496 int sav_reg_count, tmp_reg_count;
497 struct lsra_reg *reg;
501 int flags; /* 0 INMEMORY->lifetimes, 1 INTREG->int_lt, 2 FLTREG->flt_lt */
504 int_lt_last=int_lt=NULL;
505 flt_lt_last=flt_lt=NULL;
507 for (lt_count=0,lt=ls->lifetimes; lt!=NULL;lt=lt->next,lt_count++);
510 for (lt_prev=lt=ls->lifetimes;lt!=NULL;) {
513 if (lt->v_index < 0) { /* stackslot */
518 if (lt->local_ss == NULL) panic("lsra_main Lifetime for Stackslot invalid\n");
520 type = lt->local_ss->s->type;
522 } else { /* local var */
523 if (rd->locals[lt->v_index][lt->type].type>=0) {
524 type = rd->locals[lt->v_index][lt->type].type;
525 } else panic("Type Data Mismatch 2\n");
530 #if defined(__I386__)
532 * for i386 put all longs in memory
546 panic("Unknown Type\n");
551 case 1: /* l->lifetimes -> int_lt */
552 if (int_lt == NULL) {
553 int_lt_last=int_lt=lt;
555 int_lt_last->next=lt;
559 case 2: /* l->lifetimes -> flt_lt */
561 flt_lt_last=flt_lt=lt;
563 flt_lt_last->next=lt;
569 if (lt == ls->lifetimes) {
570 lt=lt_prev=ls->lifetimes=ls->lifetimes->next;
572 lt_prev->next=lt->next;
581 lsra_sort_lt(&int_lt);
582 lsra_sort_lt(&(ls->lifetimes));
583 lsra_sort_lt(&flt_lt);
585 for (lt_int_count=0,lt=int_lt; lt!=NULL;lt=lt->next,lt_int_count++);
586 for (lt_flt_count=0,lt=flt_lt; lt!=NULL;lt=lt->next,lt_flt_count++);
587 for (lt_left_count=0,lt=ls->lifetimes; lt!=NULL;lt=lt->next,lt_left_count++);
590 printf("\nLifetimes: %3i left: %3i Intlt: %3i Fltlt: %3i \n",lt_count,lt_left_count,lt_int_count,lt_flt_count);
592 if (lt_count != lt_int_count + lt_flt_count + lt_left_count) {
593 panic ("lifetimes missing\n");
595 lsra_reg_use=rd->savintregcnt;
597 for (reg_count = 0; nregdescint[reg_count] != REG_END; reg_count++);
599 reg=DMNEW(struct lsra_reg,reg_count);
601 for (i=0; i<reg_count ; i++)
602 if (nregdescint[i]==REG_SAV) {
603 reg[sav_reg_count].reg_index=i;
604 reg[sav_reg_count].use=0;
607 tmp_reg_count=sav_reg_count;
608 for (i=0; i<reg_count ; i++) {
609 #if defined(__I386__)
610 if ((method_uses_ecx) && (i==ECX)) continue;
611 if ((method_uses_edx) && (i==EDX)) continue;
613 if (nregdescint[i]==REG_TMP) {
614 reg[tmp_reg_count].reg_index=i;
615 reg[tmp_reg_count].use=0;
619 _lsra_main(m, ls, int_lt, reg, tmp_reg_count, sav_reg_count, &lsra_mem_use, &lsra_reg_use);
620 if (lsra_reg_use > rd->savintregcnt) lsra_reg_use=rd->savintregcnt;
621 /* r->maxsavintreguse=lsra_reg_use; */
623 rd->maxsavintreguse= lsra_reg_use;
624 lsra_reg_use=rd->savfltregcnt;
627 for (reg_count = 0; nregdescfloat[reg_count] != REG_END; reg_count++);
629 reg=DMNEW(struct lsra_reg,reg_count);
631 for (i=0; i<reg_count ; i++)
632 if (nregdescfloat[i]==REG_SAV) {
633 reg[sav_reg_count].reg_index=i;
634 reg[sav_reg_count].use=0;
638 tmp_reg_count=sav_reg_count;
639 for (i=0; i<reg_count ; i++)
640 if (nregdescfloat[i]==REG_TMP) {
641 reg[tmp_reg_count].reg_index=i;
642 reg[tmp_reg_count].use=0;
645 _lsra_main(m,ls, flt_lt, reg, tmp_reg_count, sav_reg_count, &lsra_mem_use, &lsra_reg_use);
646 if (lsra_reg_use > rd->savfltregcnt) lsra_reg_use=rd->savfltregcnt;
647 /* r->maxsavfltreguse=0; */
650 rd->maxsavfltreguse=lsra_reg_use;
652 #ifndef SPECIALMEMUSE
653 #if defined(__X86_64__)
655 * XXX: we have a problem here, but allocating a little more stack space
656 * is better than having a bug
658 /* if (arguments_num > (intreg_argnum + fltreg_argnum)) */
659 /* ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
660 if (rd->arguments_num > rd->fltreg_argnum)
661 lsra_mem_use = rd->arguments_num - rd->fltreg_argnum;
663 if (rd->arguments_num > rd->intreg_argnum)
664 lsra_mem_use = rd->arguments_num - rd->intreg_argnum;
671 printf("Alloc Rest\n");
673 lsra_alloc(m, rd, ls->lifetimes,&lsra_mem_use);
675 printf("Alloc Int\n");
677 lsra_alloc(m, rd, int_lt,&lsra_mem_use);
679 printf("Alloc Flt\n");
681 lsra_alloc(m, rd, flt_lt,&lsra_mem_use);
684 printf("Int RA complete \n");
685 printf("Lifetimes after splitting int: \n");
686 print_lifetimes(rd, int_lt);
688 printf("Flt RA complete \n");
689 printf("Lifetimes after splitting flt:\n");
690 print_lifetimes(rd, flt_lt);
692 printf("Rest RA complete \n");
693 printf("Lifetimes after leftt:\n");
694 print_lifetimes(rd, ls->lifetimes);
697 rd->maxmemuse=lsra_mem_use;
700 void lsra_alloc(methodinfo *m, registerdata *rd, struct lifetime *lifet, int *mem_use)
704 struct freemem *fmem;
707 fmem=DNEW(struct freemem);
711 for (lt=lifet;lt!=NULL;lt=lt->next) {
718 regoff=lsra_getmem(lt, fmem, mem_use);
724 if (lt->v_index < 0) {
726 lsra_setflags( &(lt->s->flags), flags);
727 lt->s->regoff=regoff;
730 for (n=lt->local_ss; n!=NULL; n=n->next) {
731 lsra_setflags( &(n->s->flags), flags);
734 } else { /* local var */
735 if (rd->locals[lt->v_index][lt->type].type>=0) {
736 /* lsra_setflags( &(rd->locals[lt->v_index][lt->type].flags), flags); */
737 rd->locals[lt->v_index][lt->type].flags= flags;
738 rd->locals[lt->v_index][lt->type].regoff=regoff;
739 } else panic("Type Data mismatch 1\n");
744 void lsra_setflags(int *flags, int newflags)
746 if ( newflags & INMEMORY)
751 if (newflags & SAVEDVAR)
755 int lsra_getmem(struct lifetime *lt, struct freemem *fmem, int *mem_use)
757 struct freemem *fm, *p;
759 /* noch kein Speicher vergeben, oder alle Enden später */
760 if ((fmem->next == NULL) || (fmem->next->end >= lt->i_start)) /* wirklich >= oder reicht > */
761 fm=lsra_getnewmem(mem_use);
763 /* Speicherstelle frei */
769 for (p=fmem; (p->next!=NULL) && (p->next->end < fm->end); p=p->next);
775 struct freemem *lsra_getnewmem(int *mem_use)
779 fm=DNEW(struct freemem);
786 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)
789 /* struct active_lt *a; */
792 int reg_count, active_count;
794 if ((tmp_reg_count+sav_reg_count) == 0) {
795 for (lt=lifet; lt != NULL; lt=lt->next)
800 ls->active_tmp = NULL;
801 ls->active_sav = NULL;
802 ls->active_tmp_count=0;
803 ls->active_sav_count=0;
804 for (lt=lifet; lt != NULL; lt=lt->next) {
805 lsra_expire_old_intervalls(ls, lt,reg);
806 if (lt->savedvar && (!m->isleafmethod)) {
807 reg_count=sav_reg_count;
808 active_count=ls->active_sav_count;
811 reg_count=tmp_reg_count;
812 active_count=ls->active_sav_count+ls->active_tmp_count;
814 if (active_count == reg_count)
815 spill_at_intervall(ls, lt);
817 for (i=reg_count-1;i>=0;i--) {
820 lt->reg=reg[i].reg_index;
822 if (_reg_use<*reg_use) *reg_use=_reg_use;
826 if (i < sav_reg_count)
827 lsra_add_active(lt, &(ls->active_sav), &(ls->active_sav_count));
829 lsra_add_active(lt, &(ls->active_tmp), &(ls->active_tmp_count));
834 void lsra_add_active(struct lifetime *lt, struct active_lt **active, int *active_count)
836 struct active_lt *alt,*alt1,*alt2;
837 alt=DNEW(struct active_lt);
840 for(alt1=alt2=*active; alt1 != NULL; alt2=alt1, alt1=alt1->next)
841 if (alt1->lt->i_end > lt->i_end) break;
843 if (alt1 == *active) {
847 alt->next = alt2->next;
854 void lsra_expire_old_intervalls(lsradata *ls, struct lifetime *lt, struct lsra_reg *reg)
856 _lsra_expire_old_intervalls(lt, reg, &(ls->active_tmp), &(ls->active_tmp_count));
857 _lsra_expire_old_intervalls(lt, reg, &(ls->active_sav), &(ls->active_sav_count));
860 void _lsra_expire_old_intervalls(struct lifetime *lt, struct lsra_reg *reg, struct active_lt **active, int *active_count)
862 struct active_lt *alt,*alt1;
865 for (alt1=alt=*active; alt != NULL; alt1=alt, alt=alt->next) {
866 if (alt->lt->i_end >= lt->i_start) return;
868 *active = (*active)->next;
870 alt1->next=alt->next;
872 for (i=0;reg[i].reg_index != alt->lt->reg;i++);
874 /* FREE(alt,struct active_lt); */
879 void spill_at_intervall(lsradata *ls, struct lifetime *lt )
882 _spill_at_intervall(lt, &(ls->active_sav), &(ls->active_sav_count));
884 _spill_at_intervall(lt, &(ls->active_tmp), &(ls->active_tmp_count));
885 if (lt->reg == -1) /* kein tmp mehr frei gewesen */
886 _spill_at_intervall(lt, &(ls->active_sav), &(ls->active_sav_count));
888 if (lt->reg == -2) panic("spill_at_intervall: Keine Register mehr frei gewesen!\n");
891 void _spill_at_intervall(struct lifetime *lt, struct active_lt **active, int *active_count)
893 struct active_lt *alt,*alt1;
894 if (*active == NULL) {
897 panic("No Lifetime in Active List -> no free registers at all!\n");
899 /* get last intervall from active */
900 for (alt1=alt=*active; alt->next != NULL; alt1=alt, alt=alt->next);
902 if (alt->lt->i_end > lt->i_end) {
903 lt->reg=alt->lt->reg;
907 *active=(*active)->next;
909 alt1->next=alt->next;
910 /* FREE(alt,struct active_lt); */
912 lsra_add_active(lt, active, active_count);
918 int lsra_getmaxblock(methodinfo *m, loopdata *ld, int bb_start)
922 struct depthElement *hp;
925 blocks=DMNEW(int, m->basicblockcount);
926 /* ExTable Ablauf kann in die STD Code BB wieder "hineinspringen" */
928 /* TODO vorher alle "normalen" BB mit 2=bereits besucht initialisieren */
931 for (i=0; i<m->basicblockcount; i++) blocks[i]=-1;
938 for (i=0; i<m->basicblockcount; i++) {
940 if (blocks[i] == 1) {
941 if (i > bb_max) bb_max = i;
942 blocks[i]=2; /* visited */
943 for (hp=ld->c_dTable[i]; hp!=NULL; hp=hp->next) {
944 if (blocks[hp->value] != 2) {
945 blocks[hp->value]=1; /* to visit */
953 printf("ExTable searching: BB_MAX %3i ",bb_max);
954 for (i=0; i<m->basicblockcount; i++)
955 if (blocks[i] != -1) printf("%3i ",i);
962 void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd, loopdata *ld)
966 struct l_loop *loops;
967 struct b_loop *block_loop;
969 int *exh_max; /* Exception Handler End BB */
970 int *exh_min; /* Exception Handler Start BB */
971 int *ex_max; /* Exception guarded Area End BB */
972 int *ex_min; /* Exception guarded Area Start BB */
974 int blast,bfirst,ilast,ifirst,usage;
977 struct LoopContainer *lc;
978 struct LoopElement *le;
982 /* Für Exceptionhandler Blocks wurde keine Loop Analyse durchgeführt! */
983 /* -> deshalb vorerst die einzelnen Handler als eine Loop eintragen */
984 /* oder loop analyse extra für jeden Handler aufrufen */
986 /* lifetime der Vars des ExHandlers über guarded Bereich ausdehnen! */
988 /* Falls die einzelnen Blöcke einer Loop nicht durchgehend nummeriert sind */
989 /* auch nicht alle in block_loop eintragen! */
991 exh_max = DMNEW(int, cd->exceptiontablelength);
992 exh_min = DMNEW(int, cd->exceptiontablelength);
993 ex_max = DMNEW(int, cd->exceptiontablelength);
994 ex_min = DMNEW(int, cd->exceptiontablelength);
996 /* BB der Exhandler bestimmen + BB der guarded Area hinzu */
997 ex = cd->exceptiontable;
998 for (i=0; ex != NULL; i++,ex = ex->down) {
999 if (ex->handler == NULL) {
1001 printf("lsra_init_blocks EXCEPTIONTABLE without handler!\n");
1004 if ((ex->handler->debug_nr < 0) || (ex->handler->debug_nr >= m->basicblockcount)) {
1006 printf("lsra_init_blocks EXCEPTIONTABLE Handler Blocknummer invalid! %i\n", ex->handler->debug_nr);
1009 exh_min[i]=ex->handler->debug_nr;
1010 exh_max[i]=lsra_getmaxblock(m, ld, ex->handler->debug_nr);
1012 ex_min[i]=ex->start->debug_nr;
1013 ex_max[i]=ex->end->debug_nr;
1015 printf("EX %3i exmin %3i exmax %3i exhmin %3i exhmax %3i\n",i,ex_min[i],ex_max[i],exh_min[i],exh_max[i]);
1021 /* extend lifetime within loops */
1024 for (num_loops=0,lc =ld->c_allLoops;lc!=NULL;num_loops++,lc=lc->next);
1026 loops=DMNEW(struct l_loop,num_loops);
1028 for (i=0,lc=ld->c_allLoops;i<num_loops;i++,lc=lc->next) {
1031 bfirst=m->basicblockcount;
1033 while (le != NULL) {
1034 if (le->node<bfirst) bfirst=le->node;
1035 if (le->node>blast) blast=le->node;
1038 loops[i].b_first=bfirst;
1039 loops[i].b_last=blast;
1043 /* for (i=0;i<num_loops;i++) printf("loops[%2i] bfirst: %3i blast %3i nesting %3i\n",i,loops[i].b_first,loops[i].b_last,loops[i].nesting); */
1045 /* sort loops by b_first desc*/
1046 for (i=0; i<num_loops-1;i++) {
1047 for (j=i+1; j<num_loops;j++) {
1048 if (loops[i].b_first < loops[j].b_first) {
1049 bfirst=loops[j].b_first;
1050 blast=loops[j].b_last;
1051 loops[j].b_first=loops[i].b_first;
1052 loops[j].b_last=loops[i].b_last;
1053 loops[i].b_first=bfirst;
1054 loops[i].b_last=blast;
1058 /* for (i=0;i<num_loops;i++) printf("loops[%2i] bfirst: %3i blast %3i nesting %3i\n",i,loops[i].b_first,loops[i].b_last,loops[i].nesting); */
1059 /* check for nesting_level, overlapping */
1060 for (i=0; i<num_loops-1;i++) {
1061 /*! loops[i].b_first >= loops[i+1].b_first !*/
1062 if (loops[i+1].b_last>=loops[i].b_first) {
1063 if (loops[i+1].b_last<loops[i].b_last) {
1064 /* overlapping -> make one loop of both */
1065 loops[i+1].b_last=loops[i].b_last;
1066 loops[i].b_first=-1;
1070 loops[i].nesting++; /* only boolean if nested... */
1074 /* for (i=0;i<num_loops;i++) printf("loops[%2i] bfirst: %3i blast %3i nesting %3i\n",i,loops[i].b_first,loops[i].b_last,loops[i].nesting); */
1076 block_loop=DMNEW(struct b_loop, m->basicblockcount);
1077 for (i=0;i<m->basicblockcount; i++) {
1078 block_loop[i].loop=-1;
1080 block_loop[i].instr=block_loop[i-1].instr+m->basicblocks[i-1].icount;
1082 block_loop[i].instr=0;
1085 for (i=0; i<num_loops;i++) {
1086 if (loops[i].b_first!=-1) {
1088 for (j=loops[i].b_first;j<=loops[i].b_last;j++) block_loop[j].loop=i;
1095 if (ls->back_edge_panic) {
1098 lt->b_end=m->basicblockcount-1;
1099 lt->i_end=block_loop[m->basicblockcount-1].instr+m->basicblocks[m->basicblockcount-1].icount;
1105 while (il->next!=NULL) {
1111 /* expand lifetimes in a exceptionhandler to at least the whole handler */
1112 /* TODO do a loop analyze for the exceptionhandler, too*/
1113 for (i=0; i < cd->exceptiontablelength; i++) {
1115 if ( !((bfirst > exh_max[i]) || ( blast < exh_min[i])) ) {
1116 /* Überschneidung mit exh_???[i]-> lt liegt in Exceptionhandler */
1117 /* -> Start auf mindestens die erste Instruktion des geschützten Bereiches legen */
1118 if (bfirst >= exh_min[i]) {
1122 /* -> Ende auf mindestens die letzte Instruktion des geschützten Bereiches legen */
1123 if (blast <= exh_max[i]) {
1125 ilast= m->basicblocks[exh_max[i]].icount-1;
1130 ilast+=block_loop[blast].instr;
1131 ifirst+=block_loop[bfirst].instr;
1133 if ((j=block_loop[bfirst].loop)==-1)
1134 j=block_loop[blast].loop;
1137 if (loops[j].b_first<=bfirst) {
1138 bfirst=loops[j].b_first;
1139 ifirst=block_loop[bfirst].instr;
1140 usage+=loops[j].nesting*100;
1142 if (blast <= loops[j].b_last) {
1143 blast=loops[j].b_last;
1144 ilast=block_loop[blast].instr+m->basicblocks[blast].icount;
1145 usage+=loops[j].nesting*100;
1149 lt->length=ilast-ifirst;
1155 lt->usagecount=usage;
1161 for (i=0; i<num_loops;i++) {
1162 printf("LoopNR: %3i Start: %3i End: %3i Nesting: %3i Block_loop[%3i]:",i,loops[i].b_first,loops[i].b_last,loops[i].nesting,i);
1163 for (j=0;j<m->basicblockcount;j++)
1164 if (block_loop[j].loop==i) printf(" %3i",j);
1170 void lsra_sort_lt(struct lifetime **lifet)
1172 /* sort lifetimes by increasing start point */
1173 /* struct lifetime **plt,**plt1; */
1174 struct lifetime *lt, lt_new, *temp, *tmp;
1177 /* lifetimes are sorted by decreasing start point -> just turn around */
1178 /* not really correct through exception and loop lifetime expansion! -> turn around and sort in*/
1181 for (lt=*lifet; lt!= NULL;) {
1184 for(tmp=<_new; (tmp->next!= NULL) && (tmp->next->i_start < lt->i_start); tmp=tmp->next);
1193 void print_lifetimes(registerdata *rd, struct lifetime *lt)
1197 int type,flags,regoff,j,varkind;
1200 for (n=lt,j=0; n!=NULL; n=n->next,j++) {
1201 if (n->v_index < 0) { /* stackslot */
1202 if (n->s != 0) { /* stackslot */
1205 regoff=n->s->regoff;
1206 varkind=n->s->varkind;
1208 if (n->local_ss != 0) {
1209 type = n->local_ss->s->type;
1210 flags=n->local_ss->s->flags;
1211 regoff=n->local_ss->s->regoff;
1212 varkind=n->local_ss->s->varkind;
1215 } else { /* local var */
1216 /* for (i=TYPE_INT; i<=TYPE_ADR; i++) { */
1217 if (rd->locals[n->v_index][n->type].type>=0) {
1218 type = rd->locals[n->v_index][n->type].type;
1219 flags=rd->locals[n->v_index][n->type].flags;
1220 regoff=rd->locals[n->v_index][n->type].regoff;
1222 } else panic("Type Data mismatch 3\n");
1225 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);
1226 for (ni=n->i_list; ni!=NULL; ni=ni->next) {
1227 if (ni==ni->next) panic("loop in instruction list!\n");
1228 printf( "(%3i,%3i) ",ni->b_index,ni->instr);
1231 /* if (n->s!=NULL) */
1232 /* 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); */
1234 printf( "%3i Lifetimes printed \n",j);
1237 struct stackslot *lsra_make_ss(stackptr s, int bb_index)
1239 struct stackslot *ss;
1241 ss=DNEW(struct stackslot);
1247 /* merge i_list from lt1 to lt in order */
1248 void lsra_merge_i_lists(struct lifetime *lt, struct lifetime *lt1)
1250 struct _i_list *iptr, *iptr1, *iptr2;
1252 /* merge i_lists in order */
1254 iptr2=lt->i_list=NULL;
1256 while ((iptr != NULL) && (iptr1 != NULL)) {
1257 if ((iptr->b_index > iptr1->b_index)|| ((iptr->b_index == iptr1->b_index) && (iptr->instr > iptr1->instr))) {
1258 if (lt->i_list==NULL) {
1260 /* iptr2=lt->i_list; */
1267 if (lt->i_list==NULL) {
1269 /* iptr2=lt->i_list; */
1278 if (iptr2 == NULL) panic("lsra_merge_i_lists: Empty Instruction List in Lifetime\n");
1287 void dump_join( struct lifetime *lt_passing)
1289 struct lifetime *lt;
1290 struct stackslot *ss;
1293 for (lt=lt_passing,i=0; lt != NULL; lt=lt->next, ++i) {
1294 printf("Lifetime(%2i)\n PT: ",i);
1295 for ( ss=lt->passthrough; ss!=NULL; ss=ss->next)
1296 printf("(%2i, %2i, %6p) ",ss->bb, ss->s->varnum, ss->s);
1298 for (ss = lt->local_ss; ss!=NULL; ss=ss->next)
1299 printf("(%2i, %2i, %6p) ", ss->bb, ss->s->varnum, ss->s);
1305 void lsra_join_lifetimes(methodinfo *m, codegendata *cd, lsradata *ls, loopdata *ld)
1307 int i, j, index, stacks_top;
1308 int in1, out1, in2, out2, temp;
1309 struct depthElement *de;
1311 int *in_stacks, *out_stacks;
1313 struct stackslot **stacks, *ss, *ss_new;
1314 struct lifetime *lt, *lt_prev, *lt_new, *lt_passing;
1315 struct stackslot *p, *q, *r;
1321 in=m->basicblocks[0].instack; /* ?falls Instack des Startblocks != leer ?*/
1322 if (in != NULL) printf("------------ Instack von BB0 nicht leer! -------\n");
1325 /* join copies of dup/swap? or let just codegen copy the contents? */
1326 /* -> ?TODO? save at ICMD_DUP* and ICMD_SWAP Copy Info */
1328 /* out_stacks hold an index to stacks, which holds the joined stacks */
1329 /* in_stacks hold an index to out_stacks, with which they are joined */
1330 /* an initial index of -1 mark, that they where not visited yet */
1331 in_stacks = DMNEW(int, m->basicblockcount);
1332 out_stacks = DMNEW(int, m->basicblockcount);
1333 stacks = DMNEW(struct stackslot *, m->basicblockcount);
1334 /* for (i=0; i< m->basicblockcount; i++) stacks[i]=NULL; */
1335 for (i=0; i < m->basicblockcount; i++ ) in_stacks[i]=out_stacks[i]=-1;
1338 for (i=0; i < m->basicblockcount; i++)
1339 if (m->basicblocks[i].flags >= BBREACHED) {
1340 if ((out=m->basicblocks[i].outstack) != NULL) {
1341 ss=lsra_make_ss(out, i);
1343 stacks[stacks_top]=ss;
1344 out_stacks[i]=stacks_top++;
1345 for (de=ld->c_dTable[i]; de != NULL; de=de->next) {
1346 if (in_stacks[de->value] == -1) { /* not visited==joined yet */
1347 in_stacks[de->value] = i;
1348 ss=lsra_make_ss(m->basicblocks[de->value].instack, de->value);
1349 ss->next=stacks[out_stacks[i]];
1350 stacks[out_stacks[i]]=ss;
1351 } else { /* in stacks already joined -> join with others */
1352 /* join this outstack to index in_stack[de->value] points to */
1353 for (ss=stacks[out_stacks[i]]; ss->next != NULL; ss=ss->next); /* get last element */
1354 ss->next=stacks[out_stacks[in_stacks[de->value]]];
1355 stacks[out_stacks[in_stacks[de->value]]]=stacks[out_stacks[i]];
1356 stacks[out_stacks[i]]=NULL;
1357 /* update all prior out_stacks indexes to this new join */
1358 for (j=0; j <= i; j++) {
1359 if (out_stacks[j] == out_stacks[i]) {
1360 out_stacks[j]=out_stacks[in_stacks[de->value]];
1368 /* leere einträge aus stacks entfernen */
1369 for (i=index=0; i< stacks_top;) {
1370 if (stacks[index]!=NULL) { /* nächsten freien Platz suchen */
1374 if (stacks[i]==NULL) { /* nächsten bestetzten Platz zum verschieben suchen*/
1376 } else { /* von i nach index umhängen */
1377 stacks[index]=stacks[i];
1385 /* 0 <= i < index | join all corresponding stackslots of in- and outstacks of stacks[i] to lt_new */
1386 /* and put lt_new in lt_passing (if passthrough ss exist in them) or ls->lifetimes */
1387 for (i=0; i < index; i++) {
1388 while (stacks[i]->s != NULL) {
1390 for (ss=stacks[i]; ss!=NULL; ss=ss->next) {
1391 /* search stackslot ss->s lifetimelist of basicblock(ss->bb) (ss_lifetimes) */
1392 /* remember the link before found lifetime, to remove it afterwards */
1393 for (lt_prev=lt=ls->ss_lifetimes[ss->bb]; (lt!=NULL) && (lt->s != ss->s); lt_prev=lt, lt=lt->next);
1395 if (lt==NULL) panic("lsra_join_lifetimes error in lifetimelist\n");
1397 /* Remove found lifetime from Block Stackslot Lifetimelist */
1398 if (lt==ls->ss_lifetimes[ss->bb]) {
1399 ls->ss_lifetimes[ss->bb]=lt->next;
1401 lt_prev->next=lt->next;
1406 if (lt->i_list->instr==-1) {
1407 if (out_stacks[in_stacks[ss->bb]] == out_stacks[ss->bb]) {
1408 /* Throughpassing Basicblock is already in one "join Group" */
1409 /* If this stackslot (lt->s == ss->s) is already in lt_new->local_ss */
1410 /* do not add it a second time! */
1411 if (lt_new != NULL) {
1412 for (ss_new=lt_new->local_ss; (ss_new != NULL) && (ss_new->s != lt->s); ss_new = ss_new->next);
1413 if (ss_new != NULL) drop = true;
1418 lt->s->varkind=TEMPVAR; /* no LOCALVAR, ARGVAR or STACKVAR with joined lifetimes */
1419 lt->v_index=-1; /* not a local var */
1421 /* join Lifetime lt to lt_new */
1422 if (lt_new == NULL) {
1424 lt_new->passthrough = NULL;
1425 lt_new->s = NULL; /* Stackslots are all in local_ss for joined lifetimes */
1427 lsra_merge_i_lists( lt_new, lt);
1429 /* add stackslot to local_ss of lt_new */
1430 ss_new = DNEW(struct stackslot);
1432 ss_new->bb = ss->bb; /* for debugging only, has no further use */
1433 ss_new->next = lt_new->local_ss;
1434 lt_new->local_ss = ss_new;
1436 lt_new->savedvar |= (lt->savedvar & SAVEDVAR);
1439 if (lt->i_list->instr==-1) {
1440 /* BB passes this stackslot through -> join later with other side!*/
1441 if (out_stacks[in_stacks[ss->bb]] != out_stacks[ss->bb]) {
1442 /* Stackslot ist not passed through to same (this) "join group" */
1444 p = DNEW(struct stackslot);
1445 p->bb = ss->bb; /* Basic Block index of joined Lifetime */
1447 /* sort p in lt_new->passthrough list by increasing stackslot adress */
1448 /* there are no two stackslots allowed, which "join" the same "join groups" */
1449 /* in case one has to be dropped, keep the one with the "greater" address */
1452 in2=out_stacks[in_stacks[p->bb]];
1453 out2=out_stacks[p->bb];
1454 if (in2 > out2) { temp=in2; in2=out2; out2=temp; }
1455 for (q=lt_new->passthrough; (q != NULL);) {
1456 in1=out_stacks[in_stacks[q->bb]];
1457 out1=out_stacks[q->bb];
1458 if (in1 > out1) { temp=in1; in1=out1; out1=temp; }
1460 if ((in1 == in2) && (out1 == out2)) { /* p->s would join to same group -> drop the one with the lower address */
1461 if (p->s < q->s) /* drop p->s, it has the lower address */
1463 else { /* drop q from the list, since it has the lower address */
1464 if (q == lt_new->passthrough ) {
1465 lt_new->passthrough=q->next;
1467 } else { /* r points to the previous element */
1474 r=q; /* remember position for sorting p in */
1480 /* List Empty or all elements greater than p->s */
1481 p->next=lt_new->passthrough;
1482 lt_new->passthrough=p;
1491 ss->s=ss->s->prev; /* Next Stackslot for next Iteration */
1493 if (lt_new->passthrough != NULL) {
1494 lt_new->next=lt_passing;
1497 lt_new->next=ls->lifetimes;
1498 ls->lifetimes=lt_new;
1503 /* join lifetimes with same stackslots in ->passthrough in lt_passing */
1504 for (lt=lt_passing; lt != NULL; lt=lt->next) {
1505 while (lt->passthrough != NULL) {
1507 printf("before \n");
1508 dump_join(lt_passing);
1510 s=lt->passthrough->s;
1511 lt->passthrough=lt->passthrough->next; /* drop this stackslot from lt_passthrough list */
1512 /* search for next lifetime, which has the same stackslot in passthrough */
1513 /* lt_new->next will point to it */
1514 /* there has to be another lifetime after lt with same s in passthrough */
1515 for (lt_new=lt; (lt_new->next != NULL); lt_new=lt_new->next) {
1516 /* passthrough is sorted by increasing address of s */
1517 /* remember in q the list element before p with p->s == s */
1518 for (p=lt_new->next->passthrough; (p!=NULL) && (p->s < s); q=p,p=p->next);
1519 if ((p != NULL) && (p->s == s)) {
1520 /* found -> now drop this stackslot from lt_new's passtrough list */
1521 if (p == lt_new->next->passthrough) { /* first element in list */
1522 lt_new->next->passthrough = lt_new->next->passthrough->next;
1529 if (lt_new->next==NULL)
1530 panic("lsra_join_lifetimes error in lt_passing lifetimelist\n");
1532 /* join lt and lt_new->next to lt */
1533 lt->savedvar |= (lt_new->next->savedvar & SAVEDVAR);
1535 /* join local_ss lists */
1537 if (lt_new->next->local_ss == NULL)
1538 panic("lsra_join_lifetimes Lifetime without stackslot\n");
1540 for (ss=lt_new->next->local_ss; (ss->next != NULL); ss=ss->next);
1541 ss->next=lt->local_ss;
1542 lt->local_ss=lt_new->next->local_ss;
1544 /* merge i_lists in order */
1545 lsra_merge_i_lists(lt, lt_new->next);
1547 /* join passthrough lists in ascending order */
1548 /* if there are duplicates, it happened that a join was done through the */
1549 /* other joins till now, so just drop both of them */
1551 q=lt_new->next->passthrough;
1552 lt->passthrough=NULL;
1553 ss=NULL; /* pointer to the end of lt->passthrough */
1554 while ( (p!=NULL) && (q!=NULL) ) {
1565 /* Drop both stackslots -> they where just joined through some other joins */
1581 if (lt->passthrough == NULL)
1587 if (lt->passthrough == NULL)
1592 lt_new->next=lt_new->next->next; /* throw away joined lifetime lt_new->next */
1595 dump_join(lt_passing);
1600 if (lt_passing!=NULL) {
1601 for (lt=lt_passing; (lt->next!=NULL); lt=lt->next);
1602 lt->next=ls->lifetimes;
1603 ls->lifetimes=lt_passing;
1608 struct _i_list *lsra_add_i_list(struct _i_list *i_list, int instr, int b_index, int store)
1612 n=DNEW(struct _i_list);
1620 void lsra_add_ss(struct lifetime *lt, stackptr s) {
1621 struct stackslot *ss;
1622 /* Stackslot noch nicht eingetragen? */
1623 if ((lt->local_ss==NULL) || (lt->local_ss->s != s)) {
1624 ss = DNEW(struct stackslot);
1626 ss->next = lt->local_ss;
1628 if (s != NULL) lt->savedvar |= s->flags & SAVEDVAR;
1632 #define lsra_new_stack(ls, s, block, instr) _lsra_new_stack(ls, s, block, instr, LSRA_STORE)
1633 void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store)
1637 n=DNEW(struct lifetime);
1640 n->savedvar = (s->flags & SAVEDVAR);
1643 if (n->s->varkind == LOCALVAR)
1644 n->v_index=n->s->varnum;
1650 n->next=ls->ss_lifetimes[block];
1651 ls->ss_lifetimes[block]=n;
1653 n->i_list=lsra_add_i_list(n->i_list, instr, block, store);
1656 #define lsra_from_stack(ls, s, block, instr) _lsra_from_stack(ls, s, block, instr, LSRA_LOAD)
1657 #define lsra_pop_from_stack(ls, s, block, instr) _lsra_from_stack(ls, s, block, instr, LSRA_POP)
1658 void _lsra_from_stack(lsradata *ls, stackptr s, int block, int instr, int store)
1662 for (n=ls->ss_lifetimes[block]; (n!=NULL) && (n->s!=s);n=n->next);
1664 _lsra_new_stack(ls, s, block, instr, store);
1665 /* ist mit dem neuen joinen hinterher immer so, wenn ein Stackslot in einen BB "reinkommt" */
1666 /* printf("type %i flags %i varkind %i varnum %i regoff %i \n",s->type,s->flags ,s->varkind ,s->varnum ,s->regoff); */
1667 /* panic("lsra_from_stack: Var on Stack not found"); */
1670 n->i_list=lsra_add_i_list(n->i_list, instr, block, store);
1674 void lsra_usage_local(lsradata *ls, s4 v_index, int type, int block, int instr, int store)
1678 /* Lifetime vom richtigen Type suchen */
1679 for (n=ls->locals_lifetimes[v_index]; (n!=NULL) && (n->type!=type);n=n->next);
1683 if (store != LSRA_STORE) printf("lsra_local_store: Read before write Local var: %i paramcount: ?\n", v_index);
1685 lsra_new_local(ls, v_index, type);
1686 /* neue Lifetimes werden immer am Anfang der Liste eingehängt */
1687 n=ls->locals_lifetimes[v_index];
1689 /* add access at (block, instr) to intruction list */
1690 n->i_list=lsra_add_i_list(n->i_list, instr, block, store);
1694 void lsra_new_local(lsradata *ls, s4 v_index, int type)
1698 n=DNEW(struct lifetime);
1706 n->savedvar = SAVEDVAR;
1708 n->next=ls->locals_lifetimes[v_index];
1709 ls->locals_lifetimes[v_index]=n;
1713 void lsra_dump_stack(stackptr s)
1716 printf("%p(R%3i N%3i K%3i T%3i F%3i) ",(void *)s,s->regoff, s->varnum, s->varkind, s->type, s->flags);
1723 void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls)
1738 while (b_index < m->basicblockcount ) {
1740 if (m->basicblocks[b_index].flags >= BBREACHED) {
1741 dst = m->basicblocks[b_index].instack;
1742 if (dst != NULL) { /* create Lifetimes for pass-through Stackslots */
1743 in=m->basicblocks[b_index].instack;
1744 id=m->basicblocks[b_index].indepth;
1745 if (m->basicblocks[b_index].type != BBTYPE_STD) {
1746 /* Pay attention to the top Stackslot in BBTYPE_EXH and BBTYPE_SBR Basicblocks */
1747 /* this is not a passthrough, but set from the "system" to the exception object or */
1748 /* the return adress -> just create a lifetime with a write at instr==0 */
1749 lsra_new_stack(ls, in, b_index, 0);
1754 out=m->basicblocks[b_index].outstack;
1755 od=m->basicblocks[b_index].outdepth;
1757 /* ignore all in-stackslots not in outstack */
1758 for (;id>od; in=in->prev, --id);
1759 /* ignore all out-stackslots not in instack */
1760 for (;od>id; out=out->prev, --od);
1761 /* ignore all non equal stackslots from in and outstack */
1762 for (;in != out; in=in->prev, out=out->prev, --id);
1763 /* set up a lifetime for the rest: */
1764 /* stackslot adress equal, stackslot"number" equal */
1765 for (;in!=NULL; in=in->prev) {
1766 /* Make 2 entries -> one for the instack, one for the out stack */
1767 lsra_new_stack(ls, in, b_index, -1);
1768 lsra_new_stack(ls, in, b_index, -1);
1772 iptr = m->basicblocks[b_index].iinstr;
1773 len = m->basicblocks[b_index].icount;
1776 while (iindex<len) {
1781 printf("bb: %3i bcount: %3i iindex: %3i ilen: %3i opcode: %3i %s\n",b_index,m->basicblockcount,iindex,len,opcode,icmd_names[opcode]);
1782 lsra_dump_stack(src);
1783 lsra_dump_stack(dst);
1788 lsra_usage_local(ls,iptr->op1,TYPE_ADR, b_index,iindex,LSRA_LOAD); /* local read (return adress) */
1793 case ICMD_ELSE_ICONST:
1794 case ICMD_CHECKEXCEPTION:
1795 case ICMD_CHECKASIZE:
1800 case ICMD_INLINE_START:
1801 case ICMD_INLINE_END:
1804 /* pop 0 push 1 const */
1812 /* new stack slot */
1813 lsra_new_stack(ls,dst,b_index,iindex); /* const->stack */
1816 /* pop 0 push 1 load */
1824 lsra_usage_local(ls,iptr->op1,opcode-ICMD_ILOAD, b_index,iindex,LSRA_LOAD); /* local->value */
1825 lsra_new_stack(ls,dst,b_index,iindex); /* value->stack */
1826 /* ?Reference to local var?-> attention if local var is changed */
1830 /* Stack(arrayref,index)->stack */
1842 lsra_new_stack(ls,dst,b_index,iindex); /* arrayref[index]->stack */
1843 lsra_from_stack(ls, src,b_index,iindex); /* stack->index */
1844 lsra_from_stack(ls, src->prev,b_index,iindex); /* stack->arrayref */
1848 /* stack(arrayref,index,value)->arrayref[index]=value */
1860 lsra_from_stack(ls, src,b_index,iindex); /* stack -> value */
1861 lsra_from_stack(ls, src->prev,b_index,iindex); /* stack -> index */
1862 lsra_from_stack(ls, src->prev->prev,b_index,iindex); /* stack -> arrayref */
1865 case ICMD_POP: /* throw away a stackslot -> check if used anyway! */
1866 lsra_pop_from_stack(ls,src,b_index,iindex);
1869 /* pop 1 push 0 store */
1870 /* stack -> local */
1877 lsra_from_stack(ls, src,b_index,iindex); /* stack -> value */
1878 lsra_usage_local(ls,iptr->op1,opcode-ICMD_ISTORE, b_index,iindex,LSRA_STORE); /* local->value */
1887 case ICMD_ARETURN: /*stack(value) -> [empty] */
1889 case ICMD_ATHROW: /* stack(objref) -> undefined */
1891 case ICMD_PUTSTATIC: /* stack(value) -> static_field */
1892 /* pop 1 push 0 branch */
1894 case ICMD_IFNULL: /* stack(value) -> branch? */
1895 case ICMD_IFNONNULL:
1911 /* pop 1 push 0 table branch */
1913 case ICMD_TABLESWITCH:
1914 case ICMD_LOOKUPSWITCH:
1916 case ICMD_NULLCHECKPOP: /****** ????? -1 -> stack *********/
1917 case ICMD_MONITORENTER:
1918 case ICMD_MONITOREXIT:
1919 lsra_from_stack(ls, src,b_index,iindex); /* stack -> value */
1924 case ICMD_POP2: /* throw away 2 stackslots -> check if used anyway! */
1925 lsra_pop_from_stack(ls,src,b_index,iindex);
1926 lsra_pop_from_stack(ls,src->prev,b_index,iindex);
1929 /* pop 2 push 0 branch */
1931 case ICMD_IF_ICMPEQ: /* stack (v1,v2) -> branch(v1,v2) */
1932 case ICMD_IF_ICMPNE:
1933 case ICMD_IF_ICMPLT:
1934 case ICMD_IF_ICMPGE:
1935 case ICMD_IF_ICMPGT:
1936 case ICMD_IF_ICMPLE:
1938 case ICMD_IF_LCMPEQ:
1939 case ICMD_IF_LCMPNE:
1940 case ICMD_IF_LCMPLT:
1941 case ICMD_IF_LCMPGE:
1942 case ICMD_IF_LCMPGT:
1943 case ICMD_IF_LCMPLE:
1945 case ICMD_IF_ACMPEQ:
1946 case ICMD_IF_ACMPNE:
1950 case ICMD_PUTFIELD: /* stack(objref,value) -> objref->method=value */
1952 case ICMD_IASTORECONST:
1953 case ICMD_LASTORECONST:
1954 case ICMD_AASTORECONST:
1955 case ICMD_BASTORECONST:
1956 case ICMD_CASTORECONST:
1957 case ICMD_SASTORECONST:
1958 lsra_from_stack(ls, src,b_index,iindex); /* stack -> value*/
1959 lsra_from_stack(ls, src->prev,b_index,iindex); /* stack -> objref*/
1962 /* pop 0 push 1 dup */
1963 /* merge dupped vars??? */
1965 /* lsra_from_stack(ls, src,b_index,iindex);*/ /* inc usage_count! */
1966 /* dup_alignstackslots(src, dst); */
1967 lsra_new_stack(ls,dst,b_index,iindex);
1970 /* pop 0 push 2 dup */
1973 lsra_new_stack(ls,dst->prev,b_index,iindex);
1974 lsra_new_stack(ls,dst,b_index,iindex);
1975 /* dup_alignstackslots(src, dst); */
1976 /* dup_alignstackslots(src->prev, dst->prev); */
1977 lsra_from_stack(ls, src,b_index,iindex); /* or inc usage_count! */
1978 lsra_from_stack(ls, src->prev,b_index,iindex); /* inc usage_count! */
1981 /* pop 2 push 3 dup */
1984 lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */
1985 lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
1986 /* dup_alignstackslots(src, dst); */
1987 /* dup_alignstackslots(src->prev, dst->prev); */
1988 /* dup_alignstackslots(src, dst->prev->prev); */
1989 lsra_new_stack(ls,dst->prev->prev,b_index,iindex);
1990 lsra_new_stack(ls,dst->prev,b_index,iindex);
1991 lsra_new_stack(ls,dst,b_index,iindex);
1994 /* pop 3 push 4 dup */
1997 lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */
1998 lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
1999 lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2000 /* dup_alignstackslots(src, dst); */
2001 /* dup_alignstackslots(src->prev, dst->prev); */
2002 /* dup_alignstackslots(src->prev->prev, dst->prev->prev); */
2003 /* dup_alignstackslots(src, dst->prev->prev->prev); */
2004 lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex);
2005 lsra_new_stack(ls,dst->prev->prev,b_index,iindex);
2006 lsra_new_stack(ls,dst->prev,b_index,iindex);
2007 lsra_new_stack(ls,dst,b_index,iindex);
2010 /* pop 3 push 5 dup */
2013 lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */
2014 lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2015 lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2016 /* dup_alignstackslots(src, dst); */
2017 /* dup_alignstackslots(src->prev, dst->prev); */
2018 /* dup_alignstackslots(src->prev->prev, dst->prev->prev); */
2019 /* dup_alignstackslots(src, dst->prev->prev->prev); */
2020 /* dup_alignstackslots(src->prev, dst->prev->prev->prev->prev); */
2021 lsra_new_stack(ls,dst->prev->prev->prev->prev,b_index,iindex);
2022 lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex);
2023 lsra_new_stack(ls,dst->prev->prev,b_index,iindex);
2024 lsra_new_stack(ls,dst->prev,b_index,iindex);
2025 lsra_new_stack(ls,dst,b_index,iindex);
2028 /* pop 4 push 6 dup */
2031 lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */
2032 lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2033 lsra_from_stack(ls, src->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2034 lsra_from_stack(ls, src->prev->prev->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2035 /* dup_alignstackslots(src, dst); */
2036 /* dup_alignstackslots(src->prev, dst->prev); */
2037 /* dup_alignstackslots(src->prev->prev, dst->prev->prev); */
2038 /* dup_alignstackslots(src->prev->prev->prev, dst->prev->prev->prev); */
2039 /* dup_alignstackslots(src, dst->prev->prev->prev->prev); */
2040 /* dup_alignstackslots(src->prev, dst->prev->prev->prev->prev->prev); */
2041 lsra_new_stack(ls,dst->prev->prev->prev->prev->prev,b_index,iindex);
2042 lsra_new_stack(ls,dst->prev->prev->prev->prev,b_index,iindex);
2043 lsra_new_stack(ls,dst->prev->prev->prev,b_index,iindex);
2044 lsra_new_stack(ls,dst->prev->prev,b_index,iindex);
2045 lsra_new_stack(ls,dst->prev,b_index,iindex);
2046 lsra_new_stack(ls,dst,b_index,iindex);
2049 /* pop 2 push 2 swap */
2052 lsra_from_stack(ls, src,b_index,iindex); /* from for to, or it will not work! inc usage_count! */
2053 lsra_from_stack(ls, src->prev,b_index,iindex); /*from for to, or it will not work! inc usage_count! */
2054 /* dst->varnum = src->varnum; */
2055 /* dst->varkind = src->varkind; */
2056 lsra_new_stack(ls,dst->prev,b_index,iindex);
2057 lsra_new_stack(ls,dst,b_index,iindex);
2106 lsra_from_stack(ls, src,b_index,iindex);
2107 lsra_from_stack(ls, src->prev,b_index,iindex);
2108 lsra_new_stack(ls,dst,b_index,iindex);
2113 case ICMD_IADDCONST:
2114 case ICMD_ISUBCONST:
2115 case ICMD_IMULCONST:
2118 case ICMD_IANDCONST:
2120 case ICMD_IXORCONST:
2121 case ICMD_ISHLCONST:
2122 case ICMD_ISHRCONST:
2123 case ICMD_IUSHRCONST:
2125 case ICMD_LADDCONST:
2126 case ICMD_LSUBCONST:
2127 case ICMD_LMULCONST:
2130 case ICMD_LANDCONST:
2132 case ICMD_LXORCONST:
2133 case ICMD_LSHLCONST:
2134 case ICMD_LSHRCONST:
2135 case ICMD_LUSHRCONST:
2137 case ICMD_IFEQ_ICONST:
2138 case ICMD_IFNE_ICONST:
2139 case ICMD_IFLT_ICONST:
2140 case ICMD_IFGE_ICONST:
2141 case ICMD_IFGT_ICONST:
2142 case ICMD_IFLE_ICONST:
2147 case ICMD_INT2SHORT:
2165 case ICMD_CHECKCAST:
2167 case ICMD_ARRAYLENGTH:
2168 case ICMD_INSTANCEOF:
2171 case ICMD_ANEWARRAY:
2174 lsra_from_stack(ls, src,b_index,iindex);
2175 lsra_new_stack(ls,dst,b_index,iindex);
2180 case ICMD_GETSTATIC:
2184 lsra_new_stack(ls,dst,b_index,iindex);
2187 /* pop many push any */
2188 case ICMD_INVOKEVIRTUAL:
2189 case ICMD_INVOKESPECIAL:
2190 case ICMD_INVOKESTATIC:
2191 case ICMD_INVOKEINTERFACE:
2195 lsra_from_stack(ls, src,b_index,iindex);
2198 if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID) {
2199 lsra_new_stack(ls,dst,b_index,iindex);
2205 lsra_from_stack(ls, src,b_index,iindex);
2208 lsra_from_stack(ls, src,b_index,iindex);
2211 lsra_from_stack(ls, src,b_index,iindex);
2212 src = src->prev; /* ??????????? */
2213 if (iptr->op1 != TYPE_VOID)
2214 lsra_new_stack(ls,dst,b_index,iindex);
2217 case ICMD_MULTIANEWARRAY:
2220 lsra_from_stack(ls, src,b_index,iindex);
2223 lsra_new_stack(ls,dst,b_index,iindex);
2227 printf("ICMD %d at %d\n", iptr->opc, (int)(iptr - m->instructions));
2228 panic("Missing ICMD code during register allocation");
2232 } /* while instructions */
2238 } /* while blocks */
2242 * These are local overrides for various environment variables in Emacs.
2243 * Please do not remove this and leave it at the end of the file, where
2244 * Emacs will automagically detect them.
2245 * ---------------------------------------------------------------------
2248 * indent-tabs-mode: t