70c445f404e07d43971d770bd2698b07e73fbb68
[cacao.git] / src / vm / jit / allocator / lsra.c
1 /* src/vm/jit/allocator/lsra.inc - linear scan register allocator
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Ullrich
28
29    Changes: Christian Thalinger
30             Edwin Steiner
31
32    $Id: lsra.c 4710 2006-03-30 10:23:11Z twisti $
33
34 */
35
36
37 #include "config.h"
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <assert.h>
42
43 #include "arch.h"
44 #include "md-abi.h"
45
46 #include "vm/types.h"
47
48 #include "mm/memory.h"
49 #include "toolbox/logging.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/resolve.h"
53 #include "vm/options.h"
54 #include "vm/statistics.h"
55 #include "vm/stringlocal.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/reg.h"
58 #include "vm/jit/allocator/lsra.h"
59
60
61 /* function prototypes */
62 bool lsra_test(methodinfo *, codegendata *);
63 void lsra_init(methodinfo *, codegendata *, lsradata *);
64 void lsra_setup(methodinfo *, codegendata *, registerdata *, lsradata *);
65 void lsra_main(methodinfo *, lsradata *, registerdata *, codegendata *);
66 void lsra_clean_Graph( methodinfo *, codegendata *, lsradata *);
67
68 #ifdef LSRA_DEBUG 
69 void lsra_dump_stack(stackptr );
70 #endif
71 #ifdef LSRA_PRINTLIFETIMES
72 void print_lifetimes(registerdata *, lsradata *, int *, int);
73 #endif
74 #ifdef LSRA_TESTLT
75 void test_lifetimes( methodinfo *, lsradata *, registerdata *);
76 #endif
77
78 void lsra_reg_setup(methodinfo *m ,registerdata *,struct lsra_register *,struct lsra_register * );
79
80
81 void lsra_scan_registers_canditates(methodinfo *,  lsradata *, int);
82
83 void lsra_join_lifetimes( methodinfo *, lsradata *, int);
84 void lsra_calc_lifetime_length(methodinfo *, lsradata *, codegendata *);
85
86 void _lsra_new_stack( lsradata *, stackptr , int , int, int);
87 void _lsra_from_stack(lsradata *, stackptr , int , int, int);
88 void lsra_add_ss(struct lifetime *, stackptr );
89 void lsra_usage_local(lsradata *, s4 , int , int , int , int );
90
91 void _lsra_main( methodinfo *, lsradata *, int *, int, struct lsra_register *, int *);
92 void lsra_expire_old_intervalls(methodinfo *, lsradata *, struct lifetime *, struct lsra_register *);
93 void spill_at_intervall(methodinfo *, lsradata *, struct lifetime *);
94 void lsra_add_active(struct lifetime *, struct lifetime **, int *);
95 void _lsra_expire_old_intervalls(methodinfo *, struct lifetime *, struct lsra_register *, struct lifetime **, int *);
96 void _spill_at_intervall(struct lifetime *, struct lifetime **, int *);
97
98 void lsra_alloc(methodinfo *, registerdata *, struct lsradata *, int *, int, int *);
99 int lsra_getmem(struct lifetime *, struct freemem *, int *);
100 struct freemem *lsra_getnewmem(int *);
101 void lsra_align_stackslots(struct lsradata *, stackptr, stackptr);
102 void lsra_setflags(int *, int);
103
104
105 bool lsra(jitdata *jd)
106 {
107         methodinfo   *m;
108         codegendata  *cd;
109         registerdata *rd;
110         lsradata *ls;
111 #if defined(ENABLE_STATISTICS)
112         int locals_start;
113         int i,j;
114 #endif  
115 #if defined(LSRA_DEBUG) || defined(LSRA_LEAF)
116         char name[1256], name1[1256];
117 #endif
118
119 #if defined(LSRA_DEBUG)
120         int b_index;
121         stackptr in,out;
122         int      ind, outd;
123
124         b_index = 0;
125         while (b_index < m->basicblockcount ) {
126
127                 if (m->basicblocks[b_index].flags >= BBREACHED) {
128
129                         in=m->basicblocks[b_index].instack;
130                         ind=m->basicblocks[b_index].indepth;
131                         for (;ind != 0;in=in->prev, ind--) {
132                                                         /* ARGVAR or LOCALVAR in instack is ok*/
133                                 if (in->varkind == ARGVAR) printf("ARGVAR in instack: \n");
134                                 if (in->varkind == LOCALVAR) printf("LOCALVAR in instack\n");
135                         }
136                         out=m->basicblocks[b_index].outstack;
137                         outd=m->basicblocks[b_index].outdepth;
138                         for (;outd != 0;out=out->prev, outd--) {
139                                 if (out->varkind == ARGVAR)
140                                         { log_text("ARGVAR in outstack\n"); assert(0); }
141                                 if (out->varkind == LOCALVAR)
142                                         { log_text("LOCALVAR in outstack\n"); assert(0); }
143                         }
144                 }
145                         b_index++;
146         }
147 #endif
148
149 #if defined(LSRA_DEBUG) || defined(LSRA_LEAF)
150         printf("Max Lifetimes %i \n", m->maxlifetimes);
151         utf_sprint(name, m->class->name);
152         utf_sprint(name1, m->name);
153         strcat(name, ".");
154         strcat(name, name1);
155         utf_sprint(name1, m->descriptor);
156         strcat(name, name1);
157
158 #ifndef LSRA_LEAF
159         printf("/******************************************************/\n");
160 #endif
161 #ifdef LSRA_LEAF
162         if (m->isleafmethod)
163 #endif
164 /*              printf("LSRA Start for %s opt_from: %i opt_to: %i\n", name, opt_from, opt_to);  */
165 #ifndef LSRA_LEAF
166         if (strcmp(name,"java/util/Vector.<init>(II)V")==0) {
167                 printf("-------------------\n");
168         }
169         if (m->isleafmethod)
170                 printf("**Leafmethod**\n");
171 #endif
172 #endif
173
174         /* get required compiler data */
175
176         m  = jd->m;
177         cd = jd->cd;
178         rd = jd->rd;
179
180         ls=DNEW(lsradata);
181         lsra_init(m, cd, ls);
182
183 #if 0
184 #if defined(LSRA_USES_REG_RES)
185         for (i=opt_from; i<=opt_to; i++) {
186                 icmd_uses_reg_res[i][0]=S|D|YES;
187                 icmd_uses_reg_res[i][1]=S|D|YES;
188                 icmd_uses_reg_res[i][2]=S|D|YES;
189                 icmd_uses_reg_res[i][3]=REG_NULL;
190         }
191 #endif
192 #endif
193         
194         lsra_setup(m, cd, rd, ls);
195
196 #if defined(ENABLE_STATISTICS)
197         /* find conflicts between locals for statistics */
198         if (opt_stat) {
199                 /* local Variable Lifetimes are at the end of the lifetime array and  */
200                 /* have v_index >= 0 */
201                 for (locals_start = ls->lifetimecount-1; (locals_start >=0) && 
202                         (ls->lifetime[ls->lt_used[locals_start]].v_index >= 0);
203                          locals_start--);
204                 for (i=locals_start + 1; i < ls->lifetimecount; i++)
205                         for (j=i+1; j < ls->lifetimecount; j++)
206                                 if ( !((ls->lifetime[ls->lt_used[i]].i_end 
207                                            < ls->lifetime[ls->lt_used[j]].i_start) 
208                                         || (ls->lifetime[ls->lt_used[j]].i_end < 
209                                            ls->lifetime[ls->lt_used[i]].i_start)) )
210                                         count_locals_conflicts += 2;
211          }
212 #endif
213         /* Run LSRA */
214         lsra_main(m, ls, rd, cd);
215
216         /* everything's ok */
217
218         return true;
219 }
220
221 /* sort Basic Blocks using Depth First Search in reverse post order in */
222 /* ls->sorted.  */
223 void lsra_DFS(methodinfo *m, lsradata *ls) {
224         int *stack;
225         int *visited;
226         int stack_top;
227         bool not_finished;
228         int i,p;
229     struct _list *succ;
230
231         stack = DMNEW( int, m->basicblockcount + 1);
232         visited = DMNEW( bool, m->basicblockcount + 1);
233         for (i = 0; i <= m->basicblockcount; i++) {
234                 visited[i] = 0;
235                 ls->sorted[i]=-1;
236                 ls->sorted_rev[i]=-1;
237         }
238
239     stack[0] = 0; /* start with Block 0 */
240         stack_top = 1;
241         visited[0] = ls->num_pred[0]; /* Start Block is handled right and can be */
242                                       /* put in sorted */
243         p = 0; 
244         not_finished = true;
245         while (not_finished) {
246                 while (stack_top != 0) {
247                         stack_top--;
248                         i = stack[stack_top];
249                         ls->sorted[p]=i;
250                         p++; /*--;*/
251                         for (succ = ls->succ[i]; succ != NULL; succ = succ->next) {
252                                 visited[succ->value]++;
253                                 if (visited[succ->value] == ls->num_pred[succ->value]) {
254                                         /* push the node on the stack, only if all ancestors have */
255                                         /* been visited */
256                                         stack[stack_top] = succ->value;
257                                         stack_top++;
258                                 }
259                         }
260                 }
261                 not_finished = false;
262                 for (i=1; i <= m->basicblockcount; i++) {
263                         /* search for visited blocks, which have not reached the num_pred */
264                         /* and put them on the stack -> happens with backedges */
265                         if ((visited[i] != 0) && (visited[i] < ls->num_pred[i])) {
266                                 stack[stack_top] = i;
267                                 stack_top++;
268                                 visited[i] = ls->num_pred[i];
269                                 not_finished=true;
270                                 break;
271                         }
272                 }
273         }
274 }
275
276 void lsra_get_backedges_(lsradata *ls, int basicblockcount) {
277         struct _list *s;
278         struct _backedge *n;
279         struct _backedge *_backedges;
280         int    i;
281
282
283         _backedges = NULL;
284
285         /* now look for backedges */
286         ls->backedge_count = 0;
287         for(i=0; i < basicblockcount; i++) {
288                 if (ls->sorted[i] != -1)
289                         for(s=ls->succ[ls->sorted[i]]; s != NULL; s=s->next) {
290                                 if (i >= ls->sorted_rev[s->value]) {
291                                         n=DNEW(struct _backedge);
292                                         n->start = max(i, ls->sorted_rev[s->value]);
293                                         n->end = min(i, ls->sorted_rev[s->value]);
294                                         n->next = _backedges;
295                                         _backedges = n;
296                                         ls->backedge_count++;
297                                 }
298                         }
299         }
300         /* put _backedges in ls->backedge array */
301         ls->backedge = DMNEW(struct _backedge *, ls->backedge_count);
302         for (n=_backedges, i=0; n != NULL; n=n->next, i++) {
303                 ls->backedge[i] = n;
304                 ls->backedge[i]->nesting = 1;
305         }
306 }
307
308 void lsra_get_nesting(methodinfo *m, lsradata *ls) {
309         int    i,j, end;
310         struct _backedge *n;
311
312         for (i=0; i <= m->basicblockcount; i++)
313                 if (ls->sorted[i] != -1) 
314                         ls->sorted_rev[ls->sorted[i]]=i;
315
316         lsra_get_backedges_(ls, m->basicblockcount + 1);
317         /* - sort backedge by increasing end: */
318         for (i=0; i < ls->backedge_count; i++)
319                 for (j=i+1; j < ls->backedge_count; j++) 
320                         if ((ls->backedge[i]->end > ls->backedge[j]->end) ||     /* -> swap */
321                                   ((ls->backedge[i]->end == ls->backedge[j]->end) &&
322                                    (ls->backedge[i]->start > ls->backedge[j]->start) )) {
323                                 n=ls->backedge[i];
324                                 ls->backedge[i]=ls->backedge[j];
325                                 ls->backedge[j]=n;
326                         }
327
328         /* create ls->nesting */
329         /* look for nesting depth (overlapping backedges*/
330         for (i=0; i < ls->backedge_count - 1; i++) {
331                 for (j = i + 1; (j < ls->backedge_count) &&
332                                  (ls->backedge[i]->start >= ls->backedge[j]->end); j++)
333                         ls->backedge[j]->nesting += ls->backedge[i]->nesting;
334         }
335
336     i = 0;
337     j = 0;
338         while ( (i < m->basicblockcount + 1)  ) {
339                 if (j < ls->backedge_count) {
340                         while ( i < ls->backedge[j]->end ) {
341                                 ls->nesting[i] = 0;
342                                 i++;
343                         }
344                         if ( (j+1) < ls->backedge_count)
345                                 end = min(ls->backedge[j]->start, ls->backedge[j+1]->end - 1);
346                         else
347                                 end = ls->backedge[j]->start;
348                         while (i <= end) {
349                                 ls->nesting[i] = ls->backedge[j]->nesting;
350                                 i++;
351                         }
352                         j++;
353                 } else {
354                         ls->nesting[i] = 0;
355                         i++;
356                 }
357         }
358
359 #ifdef LSRA_DEBUG
360         printf("sorted: \n");
361         for (i=0; i < ls->backedge_count; i++)
362                 printf("Backedge: %i - %i, %i - %i\n", ls->sorted[ls->backedge[i]->start], ls->sorted[ls->backedge[i]->end], ls->backedge[i]->start, ls->backedge[i]->end);
363         printf("Nesting Level \n");
364         for (i=0; i<m->basicblockcount; i++) printf(" %3li", ls->nesting[i]);
365         printf("\n");
366 #endif
367         for (i=0; i <= m->basicblockcount; i++) {
368                 ls->sorted_rev[i] = -1;
369                 ls->nesting[i] = 1+ls->nesting[i]*ls->nesting[i];
370         }
371 }
372
373 void lsra_get_backedges( methodinfo *m, lsradata *ls) {
374         struct _list **next;
375         struct _backedge *n;
376         int    i,j;
377         bool   merged;
378
379         /* first remove artificial end basicblock from ls->sorted, succ and pred */
380     j=-1;
381         for (i=0; i < m->basicblockcount; i++) {
382                 for (next=&(ls->succ[i]); *next != NULL; next=&((*next)->next)) {
383                         if ( (*next)->value == m->basicblockcount ) {
384                                 /* artificial end bb found */
385                                 *next = (*next)->next;
386                                 if (*next == NULL) break;
387                         }
388                 }
389                 for (next=&(ls->pred[i]); *next != NULL; next=&((*next)->next)) {
390                         if ( (*next)->value == m->basicblockcount ) {
391                                 /* artificial end bb found */
392                                 *next = (*next)->next;
393                                 if (*next == NULL) break;
394                         }
395                 }
396                 if (j==-1)
397                         if (ls->sorted[i] == m->basicblockcount) j=i;
398         }
399
400         /* if an artificial end block was removed -> change ls->sorted accordingly*/
401         if (j!=-1)
402                 for (i=j+1; i <= m->basicblockcount; i++) {
403                         ls->sorted[i-1] = ls->sorted[i];
404                         ls->nesting[i-1] = ls->nesting[i];
405                 }
406
407         for (i=0; i < m->basicblockcount; i++)
408                 if (ls->sorted[i] != -1) 
409                         ls->sorted_rev[ls->sorted[i]]=i;
410
411         lsra_get_backedges_(ls, m->basicblockcount);
412
413         /* - sort backedge by increasing start */
414         for (i=0; i < ls->backedge_count; i++)
415                 for (j=i+1; j < ls->backedge_count; j++) 
416                         if (ls->backedge[i]->start > ls->backedge[j]->start) {     /* -> swap */
417                                 n=ls->backedge[i];
418                                 ls->backedge[i]=ls->backedge[j];
419                                 ls->backedge[j]=n;
420                         }
421
422 #ifdef LSRA_DEBUG
423         printf("sorted: \n");
424         for (i=0; i < ls->backedge_count; i++)
425                 printf("Backedge: %i - %i, %i - %i\n", ls->sorted[ls->backedge[i]->start], ls->sorted[ls->backedge[i]->end], ls->backedge[i]->start, ls->backedge[i]->end);
426         printf("Nesting Level \n");
427         for (i=0; i<m->basicblockcount; i++) printf(" %3li", ls->nesting[i]);
428         printf("\n");
429 #endif
430
431         merged = true;
432         /* - merge overlapping backedges */
433         while (merged) {
434                 merged = false;
435                 for (i=0; i < ls->backedge_count-1; i++) {
436                         if (ls->backedge[i] != NULL) {
437                                 for (j = i + 1; (j < ls->backedge_count) && (ls->backedge[j] == NULL); j++ );
438                                 if (j != ls->backedge_count) {
439                                         if (ls->backedge[i]->start >= ls->backedge[j]->end) {
440                                                 merged = true;
441                                                 /* overlapping -> merge */
442                                                 ls->backedge[j]->end = min (ls->backedge[j]->end, 
443                                                                                                     ls->backedge[i]->end);
444                                                 ls->backedge[i] = NULL;
445                                         }
446                                 }
447                         }
448                 }
449         }
450 #ifdef LSRA_DEBUG
451         printf("merged: \n");
452         for (i = 0; i < ls->backedge_count; i++)
453                 if (ls->backedge[i] != NULL)
454                         printf("Backedge: %i - %i, %i - %i\n",ls->sorted[ls->backedge[i]->start],ls->sorted[ls->backedge[i]->end],ls->backedge[i]->start, ls->backedge[i]->end);
455 #endif
456         /* - remove backedge[] == NULL from array */
457
458         for (j = ls->backedge_count - 1; ((j>=0) && (ls->backedge[j] == NULL));
459                  j--);
460         i=j;
461         while (i >= 0) {
462                 if (ls->backedge[i] == NULL) { /* swap backedge[i] and backedge[j]*/
463                         n=ls->backedge[j];
464                         ls->backedge[j] = ls->backedge[i];
465                         ls->backedge[i] = n;
466                         i--;
467                         j--;
468                         ls->backedge_count--;
469                 } else i--;
470         }
471 #ifdef LSRA_DEBUG
472         printf("ready: \n");
473         for (i=0; i < ls->backedge_count; i++)
474                 printf("Backedge: %i - %i, %i - %i\n",ls->sorted[ls->backedge[i]->start],ls->sorted[ls->backedge[i]->end],ls->backedge[i]->start, ls->backedge[i]->end);
475 #endif
476 }
477
478 void lsra_add_cfg( methodinfo *m, lsradata *ls, int from, int to) {
479         struct _list *n;
480
481         /* ignore Empty, Deleted,... Basic Blocks as target */
482         /* TODO: Setup BasicBlock array before to avoid this */
483         /*       best together with using the basicblock list, so lsra works */
484         /*       with opt_loops, too */
485         for (;(to < m->basicblockcount) && (m->basicblocks[to].flags < BBREACHED); to++);
486
487         for (n=ls->succ[from]; (n!= NULL) && (n->value != to); n=n->next);
488         if (n != NULL) return; /* edge from->to already existing */
489
490         n=DNEW(struct _list);
491                         
492         n->value=to;
493         n->next=ls->succ[from];
494         ls->succ[from]=n;
495
496         n=DNEW(struct _list);
497         n->value=from;
498         n->next=ls->pred[to];
499         ls->pred[to]=n;
500         ls->num_pred[to]++;
501 }
502
503 /* add Edges from guarded Areas to Exception handlers in the CFG */     
504 void lsra_add_exceptions(methodinfo *m, codegendata *cd, lsradata *ls) { 
505         int i;
506
507         /* add cfg edges from all bb of a try block to the start of the according */
508         /* exception handler to ensure the right order after depthfirst search    */
509         exceptiontable *ex;
510         ex=cd->exceptiontable;
511 #ifdef LSRA_DEBUG
512         printf("ExTable(%i): ", cd->exceptiontablelength);
513 #endif
514
515         for (; ex != NULL; ex = ex->down) {
516
517 #ifdef LSRA_DEBUG
518                 printf("[%i-%i]->%i ",ex->start->debug_nr, ex->end->debug_nr,
519                            ex->handler->debug_nr);
520                 if (ex->handler->debug_nr >= m->basicblockcount)
521                         { log_text("Exceptionhandler Basicblocknummer invalid\n");
522                                 assert(0); }
523                 if (m->basicblocks[ex->handler->debug_nr].flags < BBREACHED)
524                         { log_text("Exceptionhandler Basicblocknummer not reachable\n");
525                                 assert(0); }
526                 if (ex->start->debug_nr > ex->end->debug_nr)
527                         { log_text("Guarded Area starts after its end\n"); assert(0); }
528 #endif
529                 /* loop all valid Basic Blocks of the guarded area and add CFG edges  */
530                 /* to the appropriate handler */
531                 for (i=ex->start->debug_nr; (i <= ex->end->debug_nr) &&
532                                  (i < m->basicblockcount); i++)
533                         if (m->basicblocks[i].flags >= BBREACHED)
534                                 lsra_add_cfg(m, ls, i, ex->handler->debug_nr);
535         }
536 #ifdef LSRA_DEBUG
537         printf("\n");
538 #endif
539 }
540
541 void lsra_add_jsr( methodinfo *m, lsradata *ls, int from, int to) {
542         struct _sbr *sbr, *n;
543         struct _list *ret;
544
545         /* ignore Empty, Deleted,... Basic Blocks as target */
546         /* TODO: Setup BasicBlock array before to avoid this */
547         /*       best together with using the basicblock list, so lsra works */
548         /*       with opt_loops, too */
549         for (; (to < m->basicblockcount) && (m->basicblocks[to].flags < BBREACHED);
550                  to++);
551 #ifdef LSRA_DEBUG
552         if (to == m->basicblockcount)
553                 { log_text("Invalid subroutine start index\n"); assert(0); }
554 #endif
555
556         lsra_add_cfg(m, ls, from, to);
557
558         /* from + 1 ist the return Basic Block Index */
559         for (from++; (from < m->basicblockcount) &&
560                          (m->basicblocks[from].flags < BBREACHED); from++);
561 #ifdef LSRA_DEBUG
562         if (from == m->basicblockcount)
563                 { log_text("Invalid return basic block index for jsr\n"); assert(0); }
564 #endif
565
566         /* add subroutine info in ls->sbr.next */
567
568         /* search for right place to insert */
569         for (sbr = &(ls->sbr); (sbr->next != NULL) && (sbr->next->header < to); sbr=sbr->next);
570         
571         if ((sbr->next!= NULL) && (sbr->next->header == to)) {
572                 /* Entry for this sub already exist */
573                 sbr = sbr->next;
574         } else {
575                 /* make new Entry and insert it in ls->sbr.next */
576                 n = DNEW( struct _sbr );
577                 n->header = to;
578                 n->ret = NULL;
579
580                 n->next = sbr->next;
581                 sbr->next = n;
582
583                 sbr = n;
584         }
585
586         /* now insert return adress in sbr->ret */
587         ret = DNEW( struct _list);
588         ret->value = from;
589         ret->next = sbr->ret;
590         sbr->ret = ret;
591 }
592
593 void lsra_add_sub( methodinfo *m, lsradata *ls, int b_index, struct _list *ret, bool *visited )
594 {
595         struct _list *l;
596         instruction *ip;
597         bool next_block;
598
599         /* break at virtual End Block */
600         if (b_index != m->basicblockcount) {
601                 visited[b_index] = true;
602                 next_block = false;
603
604                 if (m->basicblocks[b_index].flags < BBREACHED)
605                         next_block = true;
606                 if (!next_block && !(m->basicblocks[b_index].icount))
607                         next_block = true;
608
609                 if (!next_block) {
610                         ip = m->basicblocks[b_index].iinstr + m->basicblocks[b_index].icount -1;
611                 
612                         if (ip->opc == ICMD_JSR) /* nested Subroutines */
613                                 next_block = true;
614                 }
615
616                 if (!next_block) {
617                         if (ip->opc == ICMD_RET) { /* subroutine return found -> add return adresses to CFG */
618                                 for (l = ret; l != NULL; l = l->next)
619                                         lsra_add_cfg( m, ls, b_index, l->value);
620                         } else { /* follow CFG */
621                                 for ( l = ls->succ[b_index]; l != NULL; l = l->next)
622                                         if (!visited[l->value])
623                                                 lsra_add_sub( m, ls, l->value, ret, visited);
624                         }
625                 } else { /* fall through to next block */
626                                 if (!visited[b_index + 1])
627                                         lsra_add_sub(m, ls, b_index + 1, ret, visited);
628                 }
629         }
630 }
631
632 /* Add subroutines from ls->sbr list to CFG */
633 void lsra_add_subs(methodinfo *m, lsradata *ls) {
634         struct _sbr *sbr;
635         bool *visited;
636         int i;
637 #ifdef LSRA_DEBUG
638         struct _list *ret;
639 #endif
640
641         visited = DMNEW(int, m->basicblockcount + 1);
642         for (i=0; i <= m->basicblockcount; i++); visited[i] = false;
643         for (sbr = ls->sbr.next; sbr != NULL; sbr=sbr->next) {
644 #ifdef LSRA_DEBUG
645                 printf("Subroutine Header: %3i Return Adresses:",sbr->header);
646                 for (ret = sbr->ret; ret != NULL; ret = ret->next)
647                         printf(" %3i", ret->value);
648                 printf("\n");
649 #endif
650                 lsra_add_sub( m, ls, sbr->header, sbr->ret, visited );
651
652         }
653 }
654
655
656
657 /* Generate the Control Flow Graph             */
658 /* ( pred,succ,num_pred of lsradata structure) */
659
660 void lsra_make_cfg(methodinfo *m, lsradata *ls)
661 {
662         instruction *ip;
663         s4 *s4ptr;
664         int high, low, count;
665         int b_index;
666
667         b_index=0;
668         while (b_index < m->basicblockcount ) {
669                 if (m->basicblocks[b_index].flags >= BBREACHED) {
670                         ip = m->basicblocks[b_index].iinstr +
671                                 m->basicblocks[b_index].icount -1;
672                         /* set ip to last instruction                   */
673                                                                         
674                         if (m->basicblocks[b_index].icount) {
675                                 /* block contains instructions  */
676                                 switch (ip->opc) {                      /* check type of last instruction */
677                                 case ICMD_RETURN:
678                                 case ICMD_IRETURN:
679                                 case ICMD_LRETURN:
680                                 case ICMD_FRETURN:
681                                 case ICMD_DRETURN:
682                                 case ICMD_ARETURN:
683                                 case ICMD_ATHROW:
684                                         lsra_add_cfg(m, ls, b_index, m->basicblockcount);
685                                         break;                            /* function returns -> end of graph */
686
687                                 case ICMD_IFNULL:
688                                 case ICMD_IFNONNULL:
689                                 case ICMD_IFEQ:
690                                 case ICMD_IFNE:
691                                 case ICMD_IFLT:
692                                 case ICMD_IFGE:
693                                 case ICMD_IFGT:
694                                 case ICMD_IFLE:
695                                 case ICMD_IF_LEQ:
696                                 case ICMD_IF_LNE:
697                                 case ICMD_IF_LLT:
698                                 case ICMD_IF_LGE:
699                                 case ICMD_IF_LGT:
700                                 case ICMD_IF_LLE:
701                                 case ICMD_IF_ICMPEQ:
702                                 case ICMD_IF_ICMPNE:
703                                 case ICMD_IF_ICMPLT:
704                                 case ICMD_IF_ICMPGE:
705                                 case ICMD_IF_ICMPGT:
706                                 case ICMD_IF_ICMPLE:
707                                 case ICMD_IF_LCMPEQ:
708                                 case ICMD_IF_LCMPNE:
709                                 case ICMD_IF_LCMPLT:
710                                 case ICMD_IF_LCMPGE:
711                                 case ICMD_IF_LCMPGT:
712                                 case ICMD_IF_LCMPLE:
713                                 case ICMD_IF_ACMPEQ:
714                                 case ICMD_IF_ACMPNE:                /* branch -> add next block */
715                                         lsra_add_cfg(m, ls, b_index, b_index+1);
716                                         /* fall throu -> add branch target */
717                            
718                                 case ICMD_GOTO:
719                                         lsra_add_cfg(m, ls, b_index,  m->basicblockindex[ip->op1]);
720                                         break;                                  /* visit branch (goto) target   */
721                                 
722                                 case ICMD_TABLESWITCH:          /* switch statement                             */
723                                         s4ptr = ip->val.a;
724                                 
725                                         lsra_add_cfg(m, ls, b_index,  m->basicblockindex[*s4ptr]);
726                                 
727                                         s4ptr++;
728                                         low = *s4ptr;
729                                         s4ptr++;
730                                         high = *s4ptr;
731                                 
732                                         count = (high-low+1);
733                                 
734                                         while (--count >= 0) {
735                                                 s4ptr++;
736                                                 lsra_add_cfg(m, ls, b_index, 
737                                                                          m->basicblockindex[*s4ptr]);
738                                     }
739                                         break;
740                                 
741                                 case ICMD_LOOKUPSWITCH:         /* switch statement                             */
742                                         s4ptr = ip->val.a;
743                            
744                                         lsra_add_cfg(m, ls, b_index,  m->basicblockindex[*s4ptr]);
745                                 
746                                         ++s4ptr;
747                                         count = *s4ptr++;
748                                 
749                                         while (--count >= 0) {
750                                                 lsra_add_cfg(m, ls, b_index, 
751                                                                          m->basicblockindex[s4ptr[1]]);
752                                                 s4ptr += 2;
753                                     }
754                                         break;
755
756                                 case ICMD_JSR:
757                                         lsra_add_jsr(m, ls, b_index, m->basicblockindex[ip->op1]);
758                                         break;
759                                 
760                                 case ICMD_RET:
761                                         break;
762                                 
763                                 default:
764                                         lsra_add_cfg(m, ls, b_index, b_index + 1 );
765                                         break;  
766                             } /* switch (ip->opc)*/                        
767                     }     /* if (m->basicblocks[blockIndex].icount) */
768             }         /* if (m->basicblocks[b_index].flags >= BBREACHED) */
769                 b_index++;
770         }             /* while (b_index < m->basicblockcount ) */
771 }
772
773
774
775
776 void lsra_init(methodinfo *m, codegendata *cd, lsradata *ls) 
777 {
778         int i;
779
780         /* Init LSRA Data Structures */
781         /* allocate lifetimes for all Basicblocks */
782         /* + 1 for an artificial exit node */
783         /* which is needed as "start" point for the reverse postorder sorting */
784         ls->pred = DMNEW(struct _list *, m->basicblockcount+1);
785         ls->succ = DMNEW(struct _list *, m->basicblockcount+1);
786         ls->sorted = DMNEW(int , m->basicblockcount+1);
787         ls->sorted_rev = DMNEW(int , m->basicblockcount+1); 
788         ls->num_pred = DMNEW(int , m->basicblockcount+1);
789         ls->nesting = DMNEW(long , m->basicblockcount); 
790         for (i=0; i<m->basicblockcount; i++) {
791                 ls->pred[i]=NULL;
792                 ls->succ[i]=NULL;
793                 ls->sorted[i]=-1;
794                 ls->sorted_rev[i]=-1;
795                 ls->num_pred[i]=0;
796                 ls->nesting[i] = 1;
797         }
798         ls->pred[m->basicblockcount]=NULL;
799         ls->succ[m->basicblockcount]=NULL;
800         ls->sorted[m->basicblockcount]=-1;
801         ls->sorted_rev[m->basicblockcount]=-1;
802         ls->num_pred[m->basicblockcount]=0;     
803
804 #ifdef LSRA_DEBUG
805         if (cd->maxlocals != id->cumlocals) 
806                 { log_text("lsra: Welche locals nehmen?\n"); assert(0); }
807 #endif
808
809         ls->maxlifetimes = m->maxlifetimes;
810         ls->lifetimecount = ls->maxlifetimes + cd->maxlocals * (TYPE_ADR+1);
811         ls->lifetime = DMNEW(struct lifetime, ls->lifetimecount);
812         ls->lt_used = DMNEW(int, ls->lifetimecount);
813         ls->lt_int = DMNEW(int, ls->lifetimecount);
814         ls->lt_int_count = 0;
815         ls->lt_flt = DMNEW(int, ls->lifetimecount);
816         ls->lt_flt_count = 0;
817         ls->lt_mem = DMNEW(int, ls->lifetimecount);
818         ls->lt_mem_count = 0;
819         for (i=0; i < ls->lifetimecount; i++) ls->lifetime[i].type = -1;
820
821         ls->sbr.next = NULL;
822
823         ls->v_index = -1;
824 }
825
826 void lsra_setup(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls)
827 {
828 #ifdef LSRA_DEBUG
829         basicblock  *bptr;
830         struct _list *nl;
831 #endif
832         int i,p;
833         s4  t;
834         methoddesc *md = m->parseddesc;
835
836         /* Loop optimization "destroys" the basicblock array */
837         /* TODO: work with the basicblock list               */
838         if (opt_loops) {
839                 log_text("lsra not possible with loop optimization\n");
840                 assert(0);
841         }
842
843         /* Setup LSRA Data structures */
844
845         /* Generate the Control Flow Graph */
846         lsra_make_cfg(m, ls);
847         /* gather nesting before adding of Exceptions and Subroutines!!! */
848 #ifdef USAGE_COUNT
849         lsra_DFS(m, ls);  
850         lsra_get_nesting( m, ls);
851 #endif
852 #ifdef LSRA_DEBUG       
853         printf("Successors:\n");
854         for (i=0; i < m->basicblockcount; i++) {
855                 printf("%3i->: ",i);
856                 for (nl=ls->succ[i]; nl!= NULL; nl=nl->next)
857                         printf("%3i ",nl->value);
858                 printf("\n");
859         }
860         printf("Predecessors:\n");
861         for (i=0; i < m->basicblockcount; i++) {
862                 printf("%3i->: ",i);
863                 for (nl=ls->pred[i]; nl!= NULL; nl=nl->next)
864                         printf("%3i ",nl->value);
865                 printf("\n");
866         }
867         printf("Sorted: ");
868         for (i=0; i < m->basicblockcount; i++) printf("%3i ", ls->sorted[i]);
869         printf("\n");
870         printf("Sorted_rev: ");
871         for (i=0; i < m->basicblockcount; i++) printf("%3i ", ls->sorted_rev[i]);
872         printf("\n");
873 #endif
874         /* add subroutines before exceptions! They "destroy" the CFG */
875         lsra_add_subs(m, ls); 
876         lsra_add_exceptions(m, cd, ls);
877
878         /* generate reverse post order sort */
879         lsra_DFS(m, ls);  
880
881         /* setup backedge and nested data structures*/
882         lsra_get_backedges( m, ls);
883 #ifdef LSRA_DEBUG       
884         printf("Successors:\n");
885         for (i=0; i < m->basicblockcount; i++) {
886                 printf("%3i->: ",i);
887                 for (nl=ls->succ[i]; nl!= NULL; nl=nl->next)
888                         printf("%3i ",nl->value);
889                 printf("\n");
890         }
891         printf("Predecessors:\n");
892         for (i=0; i < m->basicblockcount; i++) {
893                 printf("%3i->: ",i);
894                 for (nl=ls->pred[i]; nl!= NULL; nl=nl->next)
895                         printf("%3i ",nl->value);
896                 printf("\n");
897         }
898         printf("Sorted: ");
899         for (i=0; i < m->basicblockcount; i++) printf("%3i ", ls->sorted[i]);
900         printf("\n");
901         printf("Sorted_rev: ");
902         for (i=0; i < m->basicblockcount; i++) printf("%3i ", ls->sorted_rev[i]);
903         printf("\n");
904 #endif
905
906
907 #ifdef LSRA_DEBUG
908         /* compare m->basicblocks[] with the list basicblocks->next */
909         printf("LSRA BB check\n");
910         i=0;
911         bptr = m->basicblocks;
912         while (bptr != NULL) {
913                 if (i > m->basicblockcount){
914                         { log_text("linked bb list does not correspond with bb array(1)\n");
915                                 assert(0); }
916                 }
917                 if (bptr != &(m->basicblocks[i])){
918                         { log_text("linked bb list does not correspond with bb array(2)\n");
919                                 assert(0); }
920                 }
921
922                 i++;
923                 bptr=bptr->next;
924         }
925         if (i<m->basicblockcount){
926                 { log_text("linked bb list does not correspond with bb array(3)\n");
927                         assert(0); }
928         }
929
930 #endif
931
932         /* Create Stack Slot lifetimes over all basic blocks */
933         for (i=m->basicblockcount-1; i >= 0; i--) {
934                 if (ls->sorted[i] != -1) {
935                         lsra_scan_registers_canditates(m, ls, ls->sorted[i]);
936                         lsra_join_lifetimes(m, ls, ls->sorted[i]);
937                 }
938         }
939
940         /* Parameter initialisiation for locals [0 .. paramcount[            */
941         /* -> add local var write access at (bb=0,iindex=-1)                 */
942         /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   */
943         /* this needs a special treatment, wenn lifetimes get extended       */
944         /* over backedges, since this parameter initialisation happens       */
945         /* outside of Basic Block 0 !!!!                                     */
946         /* this could have been avoided by marking the read access with -1,0 */
947
948         for (p = 0, i = 0; p < md->paramcount; p++) {
949                 t = md->paramtypes[p].type;
950
951                 if (rd->locals[i][t].type >= 0) 
952                         /* Param to Local init happens before normal Code */
953                         lsra_usage_local(ls, i, t, 0, -1, LSRA_STORE); 
954                 i++;
955                 if (IS_2_WORD_TYPE(t))    /* increment local counter a second time  */
956                         i++;                  /* for 2 word types */
957         }  /* end for */
958
959         lsra_calc_lifetime_length(m, ls, cd);
960
961 #ifdef LSRA_PRINTLIFETIMES
962         printf("Basicblockcount: %4i\n",m->basicblockcount);
963 /*      print_lifetimes(rd, ls, ls->lt_used, ls->lifetimecount); */
964 #endif
965 }
966
967 bool lsra_join_ss( struct lsradata *ls, struct stackelement *in,
968                                    struct stackelement *out, int join_flag) {
969         struct lifetime *lt, *lto;
970         struct stackslot *ss, *ss_last;
971
972
973         if (in->varnum != out->varnum) {
974                 lt = &(ls->lifetime[-in->varnum - 1]);
975 #if 0
976                 printf("Lifetime1 %3i:",-in->varnum-1);
977                 for (ss=lt->local_ss; ss!=NULL; ss=ss->next)
978                         printf(" %p",ss);
979                 printf("\n");
980 #endif
981         
982 #ifdef LSRA_DEBUG
983                 if (join_flag == JOIN_BB)
984                         if (lt->type == -1) { 
985                                 log_text("lsra_join_ss: lifetime for instack not found\n");
986                                 assert(0);
987                         }
988 #endif
989
990                 if (out->varnum >= 0) { /* no lifetime for this slot till now */
991                         lsra_add_ss(lt, out);
992                 } else {
993                         lto = &(ls->lifetime[-out->varnum - 1]);
994                         if ((join_flag == JOIN_DUP) || (join_flag == JOIN_OP))
995                                 if ( (lt->flags & JOIN_BB) || (lto->flags & JOIN_BB)) {
996 #ifdef LSRA_DEBUG
997                                         printf("DUP or OP join rejected for JOIN_BB Lifetime: v_index1 %3i v_index2 %3i\n",in->varnum, out->varnum);
998 #endif
999                                         return false;
1000                                 }
1001                         if (join_flag == JOIN_DUP)
1002                                 if ( (lt->flags & JOIN_OP) || (lto->flags & JOIN_OP)) {
1003 #ifdef LSRA_DEBUG
1004                                         printf("DUP join rejected for JOIN_OP Lifetime: v_index1 %3i v_index2 %3i\n",in->varnum, out->varnum);
1005 #endif
1006                                         return false;
1007                                 }
1008 #ifdef LSRA_DEBUG
1009                         if (lto->type == -1) {
1010                                 log_text("lsra_join_ss: lifetime for outstack not found\n");
1011                                 assert(0);
1012                         }
1013 #endif
1014 #ifdef LSRA_DEBUG
1015                         if (lto->type != lt->type) {
1016                                 log_text("lsra_join_ss: in/out stack type mismatch\n");
1017                                 assert(0);
1018                         }
1019 #endif
1020 #if 0
1021                 printf("Lifetime2 %3i:",-out->varnum-1);
1022                 for (ss=lto->local_ss; ss!=NULL; ss=ss->next)
1023                         printf(" %p",ss);
1024                 printf("\n");
1025 #endif
1026
1027         
1028                         lt->flags |= JOINING;
1029
1030                         /* take Lifetime lto out of ls->lifetimes */
1031                         lto->type = -1;
1032
1033                         /* merge lto into lt of in */
1034
1035                         ss_last = ss = lto->local_ss;
1036                         while (ss != NULL) {
1037                                 ss_last = ss;
1038                                 ss->s->varnum = lt->v_index;
1039                                 ss = ss->next;
1040                         }
1041                         if (ss_last != NULL) {
1042                                 ss_last->next = lt->local_ss;
1043                                 lt->local_ss = lto->local_ss;
1044                         }
1045 #if 0
1046                 printf("Lifetime1+2 %3i:",-in->varnum-1);
1047                 for (ss=lt->local_ss; ss!=NULL; ss=ss->next)
1048                         printf(" %p",ss);
1049                 printf("\n");
1050 #endif
1051                         lt->savedvar |= lto->savedvar;
1052                         lt->flags |= lto->flags | join_flag;
1053                         lt->usagecount += lto->usagecount;
1054
1055                         /*join of bb_first_def, i_first_def und *_last_use */
1056                         if (lto->bb_first_def < lt->bb_first_def) {
1057                                 lt->bb_first_def = lto->bb_first_def;
1058                                 lt->i_first_def = lto->i_first_def;
1059                         } else if ((lto->bb_first_def == lt->bb_first_def) &&
1060                                            ( lto->i_first_def < lt->i_first_def)) {
1061                                 lt->i_first_def = lto->i_first_def;
1062                         }       
1063                         if (lto->bb_last_use > lt->bb_last_use) {
1064                                 lt->bb_last_use = lto->bb_last_use;
1065                                 lt->i_last_use = lto->i_last_use;
1066                         } else if ((lto->bb_last_use == lt->bb_last_use) &&
1067                                            ( lto->i_last_use > lt->i_last_use)) {
1068                                 lt->i_last_use = lto->i_last_use;
1069                         }       
1070                 }
1071         }
1072         return true;
1073 }
1074
1075 /* join instack of Basic Block b_index with outstack of predecessors */
1076 void lsra_join_lifetimes(methodinfo *m, lsradata *ls, int b_index) {
1077         struct stackelement *in, *i, *out;
1078     struct _list *pred;
1079
1080         /* do not join instack of Exception Handler */ 
1081         if (m->basicblocks[b_index].type == BBTYPE_EXH)
1082                 return;
1083         in=m->basicblocks[b_index].instack;
1084         /* do not join first instack element of a subroutine header */
1085         if (m->basicblocks[b_index].type == BBTYPE_SBR)
1086                 in=in->prev; 
1087         
1088         if (in != NULL) {
1089                 for (pred = ls->pred[b_index]; pred != NULL; pred = pred->next) {
1090                         out = m->basicblocks[pred->value].outstack;
1091                         for (i=in; (i != NULL); i = i->prev, out=out->prev) {
1092                                 lsra_join_ss(ls, i, out, JOIN_BB);
1093                         }
1094                 }
1095         }
1096 }
1097
1098 void lsra_reg_setup(methodinfo *m , registerdata *rd,
1099                                         struct lsra_register *int_reg,
1100                                         struct lsra_register *flt_reg ) {
1101         int i, j, iarg, farg;
1102         int int_sav_top;
1103         int flt_sav_top;
1104         bool *fltarg_used, *intarg_used;
1105
1106         int_reg->nregdesc = nregdescint;
1107         flt_reg->nregdesc = nregdescfloat;
1108         if (m->isleafmethod) { 
1109                 /* Temp and Argumentregister can be used as saved registers */
1110                 methoddesc *md = m->parseddesc;
1111
1112                 int_reg->sav_top = INT_ARG_CNT + INT_TMP_CNT + INT_SAV_CNT;
1113                 int_reg->sav_reg = DMNEW(int, int_reg->sav_top);
1114                 int_reg->tmp_reg = NULL;
1115                 int_reg->tmp_top = -1;
1116                 flt_reg->sav_top = FLT_ARG_CNT + FLT_TMP_CNT + FLT_SAV_CNT;
1117                 flt_reg->sav_reg = DMNEW(int, flt_reg->sav_top);
1118                 flt_reg->tmp_reg = NULL;
1119                 flt_reg->tmp_top = -1;
1120
1121
1122                 /* additionaly precolour registers for Local Variables acting as */
1123                 /* Parameters */
1124
1125                 farg = FLT_ARG_CNT;
1126                 iarg = INT_ARG_CNT;
1127
1128                 intarg_used = DMNEW(bool, INT_ARG_CNT);
1129                 for (i=0; i < INT_ARG_CNT; i++)
1130                         intarg_used[i]=false;
1131
1132                 fltarg_used = DMNEW(bool, FLT_ARG_CNT);
1133                 for (i=0; i < FLT_ARG_CNT; i++)
1134                         fltarg_used[i]=false;
1135
1136                 int_sav_top=int_reg->sav_top;
1137                 flt_sav_top=flt_reg->sav_top;
1138
1139                 for (i=0; (i < md->paramcount); i++) {
1140                         if (!md->params[i].inmemory) {
1141                                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
1142 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1143                                         if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
1144                                                 int_reg->sav_reg[--int_sav_top] = 
1145                                                         rd->argintregs[GET_HIGH_REG(md->params[i].regoff)];
1146                                                 intarg_used[GET_HIGH_REG(md->params[i].regoff)]=true;
1147                                                 /*used -> don't copy later on */
1148                                                 int_reg->sav_reg[--int_sav_top] = 
1149                                                         rd->argintregs[GET_LOW_REG(md->params[i].regoff)];
1150                                                 intarg_used[GET_LOW_REG(md->params[i].regoff)]=true;
1151                                                 /*used -> don't copy later on */
1152                                         } else
1153 #endif
1154                                         { /* !IS_2_WORD_TYPE(md->paramtypes[i].type */
1155                                                 int_reg->sav_reg[--int_sav_top] = 
1156                                                         rd->argintregs[md->params[i].regoff];
1157                                                 intarg_used[md->params[i].regoff]=true;
1158                                                 /*used -> don't copy later on */
1159                                         }
1160                                 }
1161 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
1162                                 /* do not precolour float arguments if they are passed in     */
1163                                 /* integer registers. But these integer argument registers    */
1164                                 /* still be used in the method! */
1165                                 else { /* IS_FLT_DBL_TYPE(md->paramtypes[i].type */
1166                                                 flt_reg->sav_reg[--flt_sav_top] = 
1167                                                         rd->argfltregs[md->params[i].regoff];
1168                                                 fltarg_used[md->params[i].regoff]=true;
1169                                 }
1170 #endif
1171                                         
1172                         }
1173                 }
1174
1175                 /* copy rest of argument registers to flt_reg->sav_reg and */
1176                 /* int_reg->sav_reg; */
1177                 for (i=0; i < INT_ARG_CNT; i++)
1178                         if (!intarg_used[i])
1179                                 int_reg->sav_reg[--int_sav_top]=rd->argintregs[i];
1180                 for (i=0; i < FLT_ARG_CNT; i++)
1181                         if (!fltarg_used[i])
1182                                 flt_reg->sav_reg[--flt_sav_top]=rd->argfltregs[i];
1183
1184                 /* copy temp registers to flt_reg->sav_reg and int_reg->sav_reg */
1185                 for (i=0; i < INT_TMP_CNT; i++)
1186                         int_reg->sav_reg[--int_sav_top]=rd->tmpintregs[i];
1187                 for (i=0; i < FLT_TMP_CNT; i++)
1188                         flt_reg->sav_reg[--flt_sav_top]=rd->tmpfltregs[i];
1189
1190         } else {
1191                 /* non leaf method -> use Argument Registers [arg[int|flt]reguse */
1192                 /* ... [INT|FLT]_ARG_CNT[ as temp reg */
1193                 /* divide temp and saved registers */
1194                 int_sav_top = int_reg->sav_top = INT_SAV_CNT;
1195                 int_reg->sav_reg = DMNEW(int, int_reg->sav_top);
1196                 int_reg->tmp_top = INT_TMP_CNT +
1197                         max(0, (INT_ARG_CNT - rd->argintreguse));
1198                 int_reg->tmp_reg = DMNEW(int, int_reg->tmp_top);
1199
1200                 flt_sav_top =flt_reg->sav_top = FLT_SAV_CNT;
1201                 flt_reg->sav_reg = DMNEW(int, flt_reg->sav_top);
1202                 flt_reg->tmp_top = FLT_TMP_CNT +
1203                         max(0 , (FLT_ARG_CNT - rd->argfltreguse));
1204                 flt_reg->tmp_reg = DMNEW(int, flt_reg->tmp_top);
1205
1206                 /* copy temp and unused argument registers to flt_reg->tmp_reg and */
1207                 /* int_reg->tmp_reg */
1208                 for (i=0; i < INT_TMP_CNT; i++)
1209                         int_reg->tmp_reg[i]=rd->tmpintregs[i];
1210                 for (j=rd->argintreguse; j < INT_ARG_CNT; j++, i++)
1211                         int_reg->tmp_reg[i]=rd->argintregs[j];
1212                 for (i=0; i < FLT_TMP_CNT; i++)
1213                         flt_reg->tmp_reg[i]=rd->tmpfltregs[i];
1214                 for (j=rd->argfltreguse; j < FLT_ARG_CNT; j++, i++)
1215                         flt_reg->tmp_reg[i]=rd->argfltregs[j];
1216         }
1217
1218         /* now copy saved registers to flt_reg->sav_reg and int_reg->sav_reg */
1219         for (i = INT_SAV_CNT-1; i >= 0; i--)
1220                 int_reg->sav_reg[--int_sav_top]=rd->savintregs[i];
1221         for (i = FLT_SAV_CNT-1; i >= 0; i--)
1222                 flt_reg->sav_reg[--flt_sav_top]=rd->savfltregs[i];
1223         /* done */
1224 }
1225
1226 void lsra_insertion( struct lsradata *ls, int *a, int lo, int hi) {
1227         int i,j,t,tmp;
1228
1229         for (i=lo+1; i<=hi; i++) {
1230                 j=i;
1231                 t=ls->lifetime[a[j]].i_start;
1232                 tmp = a[j];
1233                 while ((j>lo) && (ls->lifetime[a[j-1]].i_start > t)) {
1234                         a[j]=a[j-1];
1235                         j--;
1236                 }
1237                 a[j]=tmp;
1238         }
1239 }
1240
1241 void lsra_qsort( struct lsradata *ls, int *a, int lo, int hi) {
1242         int i,j,x,tmp;
1243         if (lo < hi) {
1244                 if ( (lo+5)<hi) {
1245                         i = lo;
1246                         j = hi;
1247                         x = ls->lifetime[a[(lo+hi)/2]].i_start;
1248
1249                         while (i <= j) {
1250                                 while (ls->lifetime[a[i]].i_start < x) i++;
1251                                 while (ls->lifetime[a[j]].i_start > x) j--;
1252                                 if (i <= j) {
1253                                         /* exchange a[i], a[j] */
1254                                         tmp = a[i];
1255                                         a[i] = a[j];
1256                                         a[j] = tmp;
1257                         
1258                                         i++;
1259                                         j--;
1260                                 }
1261                         }
1262
1263                         if (lo < j) lsra_qsort( ls, a, lo, j);
1264                         if (i < hi) lsra_qsort( ls, a, i, hi);
1265                 } else
1266                         lsra_insertion(ls, a, lo, hi);
1267         }
1268 }
1269
1270 void lsra_param_sort(struct lsradata *ls, int *lifetime, int lifetime_count) {
1271
1272         int param_count;
1273         int i,j,tmp;
1274
1275         /* count number of parameters ( .i_start == -1) */
1276         for (param_count=0; (param_count < lifetime_count) &&
1277                  (ls->lifetime[lifetime[param_count]].i_start == -1); param_count++);
1278
1279         if (param_count > 0) {
1280                 /* now sort the parameters by v_index */
1281                 for (i=0; i < param_count -1; i++)
1282                         for (j=i+1; j < param_count; j++)
1283                                 if ( ls->lifetime[lifetime[i]].v_index >
1284                                          ls->lifetime[lifetime[j]].v_index) {
1285                                         /* swap */
1286                                         tmp = lifetime[i];
1287                                         lifetime[i]=lifetime[j];
1288                                         lifetime[j]=tmp;
1289                                 }
1290         }                       
1291 }
1292
1293 void lsra_main(methodinfo *m, lsradata *ls, registerdata *rd, codegendata *cd)
1294 {
1295 #ifdef LSRA_DEBUG
1296         int i;
1297 #endif
1298         int lsra_mem_use;
1299         int lsra_reg_use;
1300         struct lsra_register flt_reg, int_reg;
1301
1302 /* sort lifetimes by increasing start */
1303         lsra_qsort( ls, ls->lt_mem, 0, ls->lt_mem_count - 1);
1304         lsra_qsort( ls, ls->lt_int, 0, ls->lt_int_count - 1);
1305         lsra_qsort( ls, ls->lt_flt, 0, ls->lt_flt_count - 1);
1306 /* sort local vars used as parameter */
1307         lsra_param_sort( ls, ls->lt_int, ls->lt_int_count);
1308         lsra_param_sort( ls, ls->lt_flt, ls->lt_flt_count);
1309         lsra_reg_setup(m, rd, &int_reg, &flt_reg);
1310
1311 #ifdef LSRA_DEBUG
1312         printf("INTSAV REG: ");
1313         for (i=0; i<int_reg.sav_top; i++)
1314                 printf("%2i ",int_reg.sav_reg[i]);
1315         printf("\nINTTMP REG: ");
1316         for (i=0; i<int_reg.tmp_top; i++)
1317                 printf("%2i ",int_reg.tmp_reg[i]);
1318         printf("\nFLTSAV REG: ");
1319         for (i=0; i<flt_reg.sav_top; i++)
1320                 printf("%2i ",flt_reg.sav_reg[i]);
1321         printf("\nFLTTMP REG: ");
1322         for (i=0; i<flt_reg.tmp_top; i++)
1323                 printf("%2i ",flt_reg.tmp_reg[i]);
1324         printf("\n");
1325 #endif
1326         ls->active_tmp = DMNEW( struct lifetime *, max(INT_REG_CNT, FLT_REG_CNT));
1327         ls->active_sav = DMNEW( struct lifetime *, max(INT_REG_CNT, FLT_REG_CNT));
1328
1329         lsra_reg_use=INT_SAV_CNT; /* init to no saved reg used... */
1330         _lsra_main(m, ls, ls->lt_int, ls->lt_int_count, &int_reg,
1331                                    &lsra_reg_use);
1332         if (lsra_reg_use > INT_SAV_CNT) lsra_reg_use=INT_SAV_CNT;
1333         rd->savintreguse = lsra_reg_use;
1334
1335         lsra_reg_use = FLT_SAV_CNT; /* no saved reg used... */
1336
1337         _lsra_main(m,ls, ls->lt_flt, ls->lt_flt_count, &flt_reg, &lsra_reg_use);
1338         if (lsra_reg_use > FLT_SAV_CNT) lsra_reg_use=FLT_SAV_CNT;
1339
1340         rd->savfltreguse=lsra_reg_use;
1341
1342         /* rd->memuse was already set in stack.c to allocate stack space for */
1343         /* passing arguments to called methods */
1344 #if defined(__I386__)
1345         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1346                 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
1347                 if (rd->memuse < 1)
1348                         rd->memuse = 1;
1349         }
1350 #endif
1351
1352         lsra_mem_use = rd->memuse; /* Init with memuse from stack.c */
1353
1354         lsra_alloc(m, rd, ls, ls->lt_mem, ls->lt_mem_count, &lsra_mem_use);
1355         lsra_alloc(m, rd, ls, ls->lt_int, ls->lt_int_count, &lsra_mem_use);
1356         lsra_alloc(m, rd, ls, ls->lt_flt, ls->lt_flt_count, &lsra_mem_use);
1357
1358 #ifdef LSRA_PRINTLIFETIMES
1359         printf("Int RA complete \n");
1360         printf("Lifetimes after splitting int: \n");
1361         print_lifetimes(rd, ls, ls->lt_int, ls->lt_int_count);
1362
1363         printf("Flt RA complete \n");
1364         printf("Lifetimes after splitting flt:\n");
1365         print_lifetimes(rd, ls, ls->lt_flt, ls->lt_flt_count);
1366
1367         printf("Rest RA complete \n");
1368         printf("Lifetimes after leftt:\n");
1369         print_lifetimes(rd, ls, ls->lt_mem, ls->lt_mem_count);
1370 #endif
1371         rd->memuse=lsra_mem_use;
1372 #ifdef LSRA_TESTLT
1373         test_lifetimes(m, ls, rd );
1374 #endif
1375
1376 }
1377
1378 void lsra_alloc(methodinfo *m, registerdata *rd, struct lsradata *ls, int *lifet, int lifetimecount, int *mem_use)
1379 {
1380         int flags,regoff;
1381         struct lifetime *lt;
1382         struct freemem *fmem;
1383         struct stackslot *n;
1384         int lt_index;
1385 #ifdef HAS_4BYTE_STACKSLOT
1386         struct freemem *fmem_2;
1387 #endif
1388
1389         fmem=DNEW(struct freemem);
1390         fmem->off=-1;
1391         fmem->next=NULL;
1392 #ifdef HAS_4BYTE_STACKSLOT
1393         fmem_2=DNEW(struct freemem);
1394         fmem_2->off=-1;
1395         fmem_2->next=NULL;
1396 #endif
1397
1398         for (lt_index = 0; lt_index < lifetimecount; lt_index ++) {
1399                 lt = &(ls->lifetime[lifet[lt_index]]);
1400 #ifdef LSRA_MEMORY
1401                 lt->reg=-1;
1402 #endif
1403                 if (lt->reg==-1) {
1404                         flags=INMEMORY;
1405 #ifdef HAS_4BYTE_STACKSLOT
1406                         if (IS_2_WORD_TYPE(lt->type))
1407                                 regoff=lsra_getmem(lt, fmem_2, mem_use);
1408                         else
1409 #endif
1410                         regoff=lsra_getmem(lt, fmem, mem_use);
1411                 } else {
1412                         flags=lt->savedvar;
1413                         regoff=lt->reg;
1414                 }
1415
1416                 if (lt->v_index < 0) {
1417                         for (n=lt->local_ss; n!=NULL; n=n->next) {
1418                                 lsra_setflags( &(n->s->flags), flags);
1419                                 n->s->regoff=regoff;
1420                         }
1421                 } else { /* local var */
1422                         if (rd->locals[lt->v_index][lt->type].type>=0) {
1423                                 rd->locals[lt->v_index][lt->type].flags= flags;
1424                                 rd->locals[lt->v_index][lt->type].regoff=regoff;
1425                         } else { log_text("Type Data mismatch 1\n"); assert(0); }
1426                 }               
1427                 lt->reg = regoff;
1428         }
1429 }
1430
1431 void lsra_setflags(int *flags, int newflags)
1432 {
1433         if ( newflags & INMEMORY)
1434                 *flags |= INMEMORY;
1435         else
1436                 *flags &= ~INMEMORY;
1437         
1438         if (newflags & SAVEDVAR)
1439                 *flags |= SAVEDVAR;
1440 }
1441
1442 int lsra_getmem(struct lifetime *lt, struct freemem *fmem, int *mem_use)
1443 {
1444         struct freemem *fm, *p;
1445
1446         /* noch kein Speicher vergeben, oder alle Enden später */
1447         if ((fmem->next == NULL) || (fmem->next->end > lt->i_start)) {
1448 #ifdef HAS_4BYTE_STACKSLOT
1449                 if (IS_2_WORD_TYPE(lt->type))
1450                         if ( (*mem_use)&1 ) /* align memory location for 2 Word Types */
1451                                 (*mem_use)++;
1452                 fm=lsra_getnewmem(mem_use);
1453                 if (IS_2_WORD_TYPE(lt->type))
1454                         /* allocate a second following Slot for 2 Word Types */
1455                         (*mem_use)++;
1456 #else
1457                 fm=lsra_getnewmem(mem_use);
1458 #endif
1459         } else {
1460                 /* Speicherstelle frei */
1461                 fm=fmem->next;
1462                 fmem->next=fm->next;
1463                 fm->next=NULL;
1464         }
1465         fm->end=lt->i_end;
1466         for (p=fmem; (p->next!=NULL) && (p->next->end < fm->end); p=p->next);
1467         fm->next=p->next;
1468         p->next=fm;
1469         return fm->off;
1470 }
1471
1472 struct freemem *lsra_getnewmem(int *mem_use)
1473 {
1474         struct freemem *fm;
1475
1476         fm=DNEW(struct freemem);
1477         fm->next=NULL;
1478         fm->off=*mem_use;
1479         (*mem_use)++;
1480         return fm;
1481 }
1482
1483 void _lsra_main( methodinfo *m, lsradata *ls, int *lifet, int lifetimecount,
1484                                  struct lsra_register *reg, int *reg_use)
1485 {
1486         struct lifetime *lt;
1487         int lt_index;
1488         int reg_index;
1489         int regsneeded;
1490         bool temp; /* reg from temp registers (true) or saved registers (false) */
1491         
1492 #if !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1493         regsneeded = 0;
1494 #endif
1495         if ((reg->tmp_top+reg->sav_top) == 0) {
1496
1497                 /* no registers available */
1498                 for (lt_index = 0; lt_index < lifetimecount; lt_index++)
1499                         ls->lifetime[lifet[lt_index]].reg = -1;
1500                 return;
1501         }
1502
1503         ls->active_tmp_top = 0;
1504         ls->active_sav_top = 0;
1505
1506         for (lt_index = 0; lt_index < lifetimecount; lt_index++) {
1507                 lt = &(ls->lifetime[lifet[lt_index]]);
1508
1509 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1510         regsneeded = (lt->type == TYPE_LNG)?1:0;
1511 #endif
1512
1513                 lsra_expire_old_intervalls(m, ls, lt, reg);
1514                 reg_index = -1;
1515                 temp = false;
1516                 if (lt->savedvar || m->isleafmethod) {
1517                         /* use Saved Reg (in case of leafmethod all regs are saved regs) */
1518                         if (reg->sav_top > regsneeded) {
1519 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1520                                 if (regsneeded)
1521                                         reg_index = PACK_REGS(reg->sav_reg[--reg->sav_top],
1522                                                                                   reg->sav_reg[--reg->sav_top]);
1523                                 else
1524 #endif
1525
1526                                         reg_index = reg->sav_reg[--reg->sav_top];
1527                         }
1528                 } else { /* use Temp Reg or if none is free a Saved Reg */
1529                         if (reg->tmp_top > regsneeded) {
1530                                 temp = true;
1531 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1532                         if (regsneeded)
1533                                 reg_index = PACK_REGS(reg->tmp_reg[--reg->tmp_top],
1534                                                                           reg->tmp_reg[--reg->tmp_top]);
1535                         else
1536 #endif
1537                                 reg_index = reg->tmp_reg[--reg->tmp_top];
1538                         }
1539                         else
1540                                 if (reg->sav_top > regsneeded) {
1541
1542 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1543                                 if (regsneeded)
1544                                         reg_index = PACK_REGS(reg->sav_reg[--reg->sav_top],
1545                                                                                   reg->sav_reg[--reg->sav_top]);
1546                                 else
1547 #endif
1548                                         reg_index = reg->sav_reg[--reg->sav_top];
1549                                 }
1550                 }
1551                 if (reg_index == -1) /* no reg is available anymore... -> spill */
1552                         spill_at_intervall(m, ls, lt);
1553                 else {
1554                         lt->reg = reg_index;
1555                         if (temp)
1556                                 lsra_add_active(lt, ls->active_tmp, &(ls->active_tmp_top));
1557                         else {
1558                                 if (reg->sav_top<*reg_use) *reg_use=reg->sav_top;
1559                                 lsra_add_active(lt, ls->active_sav, &(ls->active_sav_top));
1560                         }
1561                 }
1562         }
1563 }
1564
1565 void lsra_add_active(struct lifetime *lt, struct lifetime **active, int *active_top)
1566 {
1567         int i, j;
1568
1569         for(i = 0; (i < *active_top) && (active[i]->i_end < lt->i_end); i++);
1570
1571         for(j = *active_top; j > i; j--) active[j] = active[j-1];
1572
1573         (*active_top)++;
1574
1575         active[i] = lt;
1576
1577 }
1578
1579 void lsra_expire_old_intervalls(methodinfo *m, lsradata *ls,
1580                                                                 struct lifetime *lt, struct lsra_register *reg)
1581 {
1582         _lsra_expire_old_intervalls(m, lt, reg, ls->active_tmp, &(ls->active_tmp_top));
1583         _lsra_expire_old_intervalls(m, lt, reg, ls->active_sav, &(ls->active_sav_top));
1584 }
1585
1586 void _lsra_expire_old_intervalls(methodinfo *m, struct lifetime *lt,
1587                                                                  struct lsra_register *reg,
1588                                                                  struct lifetime **active, int *active_top)
1589 {
1590         int i, j, k;
1591
1592         for(i = 0; i < *active_top; i++) {
1593                 if (active[i]->i_end > lt->i_start) break;
1594
1595                 /* make active[i]->reg available again */
1596                 if (m->isleafmethod) { 
1597                         /* leafmethod -> don't care about type -> put all again into */
1598                         /* reg->sav_reg */
1599 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1600                         if (active[i]->type == TYPE_LNG) {
1601                                 reg->sav_reg[reg->sav_top++] = GET_LOW_REG(active[i]->reg);
1602                                 reg->sav_reg[reg->sav_top++] = GET_HIGH_REG(active[i]->reg);
1603                         } else
1604 #endif
1605                                 reg->sav_reg[reg->sav_top++] = active[i]->reg;
1606                 } else { 
1607                         /* no leafmethod -> distinguish between temp and saved register */
1608 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1609                         if (active[i]->type == TYPE_LNG) {
1610                                 /* no temp and saved regs are packed together, so looking at */
1611                                 /* LOW_REG is sufficient */
1612                                 if ( reg->nregdesc[ GET_LOW_REG(active[i]->reg)] == REG_SAV) {
1613                                         reg->sav_reg[reg->sav_top++] = GET_LOW_REG(active[i]->reg);
1614                                         reg->sav_reg[reg->sav_top++] = GET_HIGH_REG(active[i]->reg);
1615                                 } else {
1616                                         reg->tmp_reg[reg->tmp_top++] = GET_LOW_REG(active[i]->reg);
1617                                         reg->tmp_reg[reg->tmp_top++] = GET_HIGH_REG(active[i]->reg);
1618                                 }
1619                         } else
1620 #endif
1621                         if ( reg->nregdesc[active[i]->reg] == REG_SAV) {
1622                                         reg->sav_reg[reg->sav_top++] = active[i]->reg;
1623                         } else {
1624                                         reg->tmp_reg[reg->tmp_top++] = active[i]->reg;
1625                         }
1626                 }
1627         }
1628         
1629         /* active[0..i[ is to be removed */
1630         /* -> move [i..*active_top[ to [0..*active_top-i[ */
1631         for(k = 0, j = i; (j < *active_top); k++,j++)
1632                 active[k] = active[j];
1633
1634         (*active_top) -= i;
1635
1636 }
1637
1638 void spill_at_intervall(methodinfo *m, lsradata *ls, struct lifetime *lt )
1639 {
1640         if (lt->savedvar || m->isleafmethod) {
1641                 _spill_at_intervall(lt, ls->active_sav, &(ls->active_sav_top));
1642         } else {
1643                 _spill_at_intervall(lt, ls->active_tmp, &(ls->active_tmp_top));
1644                 if (lt->reg == -1) { /* kein tmp mehr frei gewesen */
1645                         _spill_at_intervall(lt, ls->active_sav, &(ls->active_sav_top));
1646                 }
1647         }
1648 }
1649
1650 void _spill_at_intervall(struct lifetime *lt, struct lifetime **active, int *active_top)
1651 {
1652         int i, j;
1653 #if 0
1654 #ifdef USAGE_COUNT
1655         int u_min, i_min;
1656 #endif
1657 #endif
1658
1659         if (*active_top == 0) {
1660                 lt->reg=-1;
1661                 return;
1662         }
1663         
1664         i = *active_top - 1;
1665 #ifdef USAGE_COUNT
1666 #if 0
1667         /* find intervall which ends later or equal than than lt and has the lowest usagecount lower than lt*/
1668         i_min = -1;
1669         u_min = lt->usagecount;
1670         for (; (i >= 0) && (active[i]->i_end >= lt->i_end); i--) {
1671                 if (active[i]->usagecount < u_min) {
1672                         u_min = active[i]->usagecount;
1673                         i_min = i;
1674                 }
1675         }
1676
1677         if (i_min != -1) {
1678                 i = i_min;
1679 #endif
1680         if ((active[i]->i_end >= lt->i_end) && (active[i]->usagecount < lt->usagecount)) {
1681 #else
1682         /* get last intervall from active */
1683         if (active[i]->i_end > lt->i_end) {
1684 #endif
1685 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1686                 /* Don't spill between one and two word int types */
1687                 if ((active[i]->type == TYPE_LNG) != (lt->type == TYPE_LNG))
1688                         return;
1689 #endif
1690
1691                 lt->reg=active[i]->reg;
1692                 active[i]->reg=-1;
1693
1694                 (*active_top)--;
1695                 for (j = i; j < *active_top; j++)
1696                         active[j] = active[j + 1];
1697
1698                 lsra_add_active(lt, active, active_top);
1699         } else {
1700                 lt->reg=-1;
1701         }
1702 }
1703
1704 void lsra_calc_lifetime_length(methodinfo *m, lsradata *ls, codegendata *cd)
1705 {
1706         struct lifetime *lt;
1707         int i, lt_index;
1708         int lifetimecount;
1709 #if 0
1710         struct stackslot *ss;
1711 #endif
1712         int *icount_block, icount;
1713         int flags; /* 0 INMEMORY -> ls->lt_mem */
1714                    /* 1 INTREG   -> ls->lt_int  */
1715                    /* 2 FLTREG   -> ls->lt_flt  */
1716
1717 #if 0
1718         int max_local_ss;
1719         int cum_local_ss,local_ss_count;
1720         int i_count;
1721 #endif
1722
1723         icount_block = DMNEW(int, m->basicblockcount);
1724         icount_block[0] = icount = 0;
1725         for (i=1; i < m->basicblockcount; i++) {
1726                 if (ls->sorted[i-1] != -1)
1727                         icount += m->basicblocks[ ls->sorted[i-1] ].icount;
1728                 if (ls->sorted[i] != -1)
1729                         icount_block[i] = icount;
1730         }
1731
1732 #ifdef LSRA_DEBUG
1733         printf("icount_block: ");
1734         for (i=0; i < m->basicblockcount; i++)
1735             printf("(%3i-%3i) ",i, icount_block[i]);
1736         printf("\n");
1737 #endif
1738
1739         /* extend lifetime over backedges */
1740         /* now iterate through lifetimes and expand them */
1741         
1742 #if 0
1743         max_local_ss = cum_local_ss = 0;
1744 #endif
1745         lifetimecount = 0;
1746         for(lt_index = 0 ;lt_index < ls->lifetimecount; lt_index++) {
1747                 if ( ls->lifetime[lt_index].type != -1) { /* used lifetime */
1748                         /* remember lt_index in lt_sorted */
1749                         ls->lt_used[lifetimecount ++] = lt_index; 
1750                         lt = &(ls->lifetime[lt_index]);
1751 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1752                         /* prevent conflicts between lifetimes of type long by increasing */
1753                         /* the lifetime by one instruction */
1754                         /* i.e.(ri/rj)  ...       */
1755                         /*     (rk/rl)  ICMD_LNEG */
1756                         /* with i==l and/or j==k  */
1757                         /* to resolve this during codegeneration a temporary register     */
1758                         /* would be needed */
1759                         if (lt->type == TYPE_LNG) 
1760                                 lt->i_last_use++;
1761 #endif
1762
1763 /* distribute lifetimes to lt_int, lt_flt and lt_mem */
1764
1765                         lt->reg = -1;
1766
1767                         switch (lt->type) {
1768                         case TYPE_LNG:
1769 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1770                                 flags = 0;
1771 #else
1772                                 flags = 1;
1773 #endif
1774                                 break;
1775
1776                         case TYPE_INT:
1777                         case TYPE_ADR:
1778                                 flags=1;
1779                                 break;
1780                         case TYPE_DBL:
1781                         case TYPE_FLT:
1782 #if defined(__I386__)
1783                                 /*
1784                                  * for i386 put all floats in memory
1785                                  */
1786                                 flags=0;
1787                                 break;
1788 #endif
1789                                 flags=2;
1790                                 break;
1791                         default:
1792                                 { log_text("Unknown Type\n"); assert(0); }
1793                         }
1794
1795                         switch (flags) {
1796                         case 0: /* lt_used[lt_used_index] -> lt_rest */
1797                                 ls->lt_mem[ ls->lt_mem_count++ ] = lt_index;
1798                                 break;
1799                         case 1: /* l->lifetimes -> lt_int */
1800                                 ls->lt_int[ ls->lt_int_count++ ] = lt_index;
1801                                 break;
1802                         case 2: /* l->lifetimes -> lt_flt */
1803                                 ls->lt_flt[ ls->lt_flt_count++ ] = lt_index;
1804                                 break;
1805                         }
1806
1807
1808 #if 0
1809                         local_ss_count = 0;
1810                         for (ss=lt->local_ss; ss != 0; ss = ss->next, local_ss_count++);
1811                         if (local_ss_count > max_local_ss) max_local_ss = local_ss_count;
1812                         cum_local_ss+=local_ss_count;
1813 #endif
1814
1815                         if (lt->bb_first_def == -1) {
1816 /*                              printf("--------- Warning: variable not defined!------------------vi: %i start: %i end: %i\n", lt->v_index, lt->i_start, lt->i_end); */
1817                                 lt->bb_first_def = 0;
1818                                 lt->i_first_def = 0;
1819                         }
1820
1821                         lt->i_start = icount_block[lt->bb_first_def] + lt->i_first_def;
1822
1823                         if (lt->bb_last_use == -1) {
1824 /*                              printf("--------- Warning: variable not used! --------------------vi: %i start: %i end: %i\n", lt->v_index, lt->i_start, lt->i_end); */
1825                                 lt->bb_last_use = lt->bb_first_def;
1826                                 lt->i_last_use = lt->i_first_def;
1827                         }
1828
1829                         lt->i_end = icount_block[lt->bb_last_use] + lt->i_last_use;
1830
1831                         if (lt->i_start > lt->i_end) 
1832                                 printf("Warning: last use before first def! vi: %i start: %i end: %i\n", lt->v_index, lt->i_start, lt->i_end);
1833
1834                         if ((lt->bb_first_def != lt->bb_last_use) ||
1835                                 (lt->i_first_def == -1)) {
1836                                 /* Lifetime goes over more than one Basic Block ->  */
1837                                 /* check for necessary extension over backedges     */
1838                                 /* see lsra_get_backedges                           */
1839                                 /* Arguments are set "before" Block 0, so they have */
1840                                 /* a lifespan of more then one block, too           */
1841
1842                                 for (i=0; i < ls->backedge_count; i++) {
1843                                         if (!( (lt->bb_first_def > ls->backedge[i]->start) ||
1844                                                    (lt->bb_last_use < ls->backedge[i]->end) )) {
1845                                                 /* Live intervall intersects with a backedge */
1846                                                 /*      if (lt->bb_first_def <= ls->backedge[i]->start) */
1847                                                 if (lt->bb_last_use <= ls->backedge[i]->start)
1848                                                         lt->i_end = icount_block[ls->backedge[i]->start] +
1849                                           m->basicblocks[ls->sorted[ls->backedge[i]->start]].icount;
1850                                 }
1851                                 }
1852                         }
1853 #ifdef USAGE_PER_INSTR
1854                         lt->usagecount = lt->usagecount / ( lt->i_end - lt->i_start + 1);
1855 #endif
1856                 }
1857         }
1858         ls->lifetimecount = lifetimecount;
1859 #if 0
1860         i_count=0;
1861         for (i=0; i<m->basicblockcount; i++)
1862                 if (m->basicblocks[i].flags >= BBREACHED)
1863                         i_count+=m->basicblocks[i].icount;
1864         printf("Instr: %5i Lifetimes: %5i Local SS Max: %4i Cum: %4i m->maxlifetimes %4i\n",i_count, lifetimecount, max_local_ss, cum_local_ss, m->maxlifetimes);
1865 #endif
1866 }
1867
1868 #ifdef LSRA_PRINTLIFETIMES
1869 void print_lifetimes(registerdata *rd, lsradata *ls, int *lt, int lifetimecount)
1870 {
1871         struct lifetime *n;
1872         int lt_index;
1873         int type,flags,regoff,varkind;
1874
1875         for (lt_index = 0; lt_index < lifetimecount; lt_index++) {
1876                 n = &(ls->lifetime[lt[lt_index]]);
1877                 if (n->v_index < 0) { /* stackslot */
1878                         type = n->local_ss->s->type;
1879                         flags=n->local_ss->s->flags;
1880                         regoff=n->local_ss->s->regoff;
1881                         varkind=n->local_ss->s->varkind;
1882                 } else { /* local var */
1883                         if (rd->locals[n->v_index][n->type].type>=0) {
1884                                 type = rd->locals[n->v_index][n->type].type;
1885                                 flags=rd->locals[n->v_index][n->type].flags;
1886                                 regoff=rd->locals[n->v_index][n->type].regoff;
1887                                 varkind=-1;
1888                         } else 
1889                                 { log_text("Type Data mismatch 3\n"); assert(0); }
1890                 }
1891                 printf("i_Start: %3i(%3i,%3i) i_stop: %3i(%3i,%3i) reg: %3i VI: %3i type: %3i flags: %3i varkind: %3i usage: %3li ltflags: %xi \n",n->i_start, ls->sorted[n->bb_first_def], n->i_first_def,n->i_end, ls->sorted[n->bb_last_use], n->i_last_use,regoff,n->v_index,type,flags, varkind, n->usagecount, n->flags);
1892         }
1893         printf( "%3i Lifetimes printed \n",lt_index);
1894 }
1895 #endif
1896
1897 struct stackslot *lsra_make_ss(stackptr s, int bb_index)
1898 {
1899         struct stackslot *ss;
1900
1901         ss=DNEW(struct stackslot);
1902         ss->bb=bb_index;
1903         ss->s=s;
1904         return ss;
1905 }
1906
1907 void lsra_add_ss(struct lifetime *lt, stackptr s) {
1908         struct stackslot *ss;
1909         /* Stackslot noch nicht eingetragen? */
1910
1911         if (s->varnum != lt->v_index) {
1912                 ss = DNEW(struct stackslot);
1913                 ss->s = s;
1914                 ss->s->varnum = lt->v_index;
1915                 ss->next = lt->local_ss;
1916                 lt->local_ss = ss;
1917                 if (s != NULL) lt->savedvar |= s->flags & SAVEDVAR;
1918                 if (s != NULL) lt->type = s->type;
1919 #if 0
1920                 printf("New ss vn %i s %p ss %p\n",ss->s->varnum, ss->s, ss);
1921 #endif
1922         }
1923 }
1924
1925 struct lifetime *get_ss_lifetime(lsradata *ls, stackptr s) {
1926         struct lifetime *n;
1927         
1928         if (s->varnum >= 0) { /* new stackslot lifetime */
1929                 if (-ls->v_index - 1 >= ls->maxlifetimes) {
1930                         printf("%i %i\n", -ls->v_index - 1, ls->maxlifetimes);
1931                 }
1932                 assert(-ls->v_index - 1 < ls->maxlifetimes);
1933
1934                 n = &(ls->lifetime[-ls->v_index - 1]);
1935                 n->type = s->type;
1936                 n->v_index = ls->v_index--;
1937                 n->usagecount = 0;
1938                 
1939                 n->bb_last_use = -1;
1940                 n->bb_first_def = -1;
1941                 n->local_ss = NULL;
1942                 n->savedvar = 0;
1943                 n->flags = 0;
1944         } else
1945                 n = &(ls->lifetime[-s->varnum - 1]);
1946
1947         lsra_add_ss( n, s);
1948         return n;
1949 }
1950
1951 #define IS_TEMP_VAR(s) (((s)->varkind != ARGVAR) && ((s)->varkind != LOCALVAR))
1952
1953 #define lsra_join_3_stack(ls, dst, src1, src2, join_type) \
1954         if ( IS_TEMP_VAR(dst) ) { \
1955                 join_ret = false; \
1956                 if ( IS_TEMP_VAR(src1) && ((src1)->type == (dst)->type)) { \
1957                         join_ret = lsra_join_ss(ls, dst, src1, join_type);                                                              \
1958                 } \
1959                 if ((!join_ret) && IS_TEMP_VAR(src2) && ((src2)->type == (dst)->type)) { \
1960                         lsra_join_ss(ls, dst, src2, join_type); \
1961                 } \
1962         }
1963
1964 #define lsra_join_2_stack(ls, dst, src, join_type) \
1965         if ( IS_TEMP_VAR(dst) ) { \
1966                 if ( (IS_TEMP_VAR(src)) && ((src)->type == (dst)->type)) {      \
1967                         lsra_join_ss(ls, dst, src, join_type); \
1968                 } \
1969         }
1970
1971 #define lsra_join_dup(ls, s1, s2, s3) {                            \
1972                 if (IS_TEMP_VAR(s1)) {                                             \
1973                         join_ret = false;                                                  \
1974                         if (IS_TEMP_VAR(s2))                                   \
1975                                 join_ret = lsra_join_ss(ls, s1, s2, JOIN);/* undangerous join!*/        \
1976                         if (IS_TEMP_VAR(s3)) {                                 \
1977                                 if (join_ret)   /* first join succesfull -> second of type */ \
1978                                                     /* JOIN_DUP */                      \
1979                     lsra_join_ss(ls, s1, s3, JOIN_DUP); \
1980                                 else                                                                    \
1981                         lsra_join_ss(ls, s1, s3, JOIN); /* first join did not */ \
1982                                                           /* happen -> second undangerous */ \
1983                     }                                                                           \
1984                 }                                                                                       \
1985         if (IS_TEMP_VAR(s2) && IS_TEMP_VAR(s3))         \
1986                 lsra_join_ss(ls, s2, s3, JOIN_DUP);                 \
1987         }
1988
1989 #define lsra_new_stack(ls, s, block, instr) if ((s)->varkind != ARGVAR) _lsra_new_stack(ls, s, block, instr, LSRA_STORE)
1990 void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store)
1991 {
1992         struct lifetime *n;
1993
1994         if (s->varkind == LOCALVAR) {
1995                 lsra_usage_local(ls, s->varnum, s->type, block, instr, LSRA_STORE);
1996         } else /* if (s->varkind != ARGVAR) */ {
1997                 
1998                 n=get_ss_lifetime( ls, s );
1999
2000                 if (store == LSRA_BB_IN)
2001                         n->flags |= JOIN_BB;
2002                 /* remember first def -> overwrite everytime */
2003                 n->bb_first_def = ls->sorted_rev[block];
2004                 n->i_first_def = instr;
2005
2006                 n->usagecount+=ls->nesting[ls->sorted_rev[block]];
2007         }
2008 }
2009
2010 #define lsra_from_stack(ls, s, block, instr) if ((s)->varkind != ARGVAR) _lsra_from_stack(ls, s, block, instr, LSRA_LOAD)
2011 #define lsra_pop_from_stack(ls, s, block, instr) if ((s)->varkind != ARGVAR) _lsra_from_stack(ls, s, block, instr, LSRA_POP)
2012 void _lsra_from_stack(lsradata *ls, stackptr s, int block, int instr, int store)
2013 {
2014         struct lifetime *n;
2015
2016         if (s->varkind == LOCALVAR) {
2017                 lsra_usage_local(ls, s->varnum, s->type, block, instr, LSRA_LOAD);
2018         } else /* if (s->varkind != ARGVAR) */ {
2019                 if (s->varkind == STACKVAR )
2020                         /* No STACKVARS possible with lsra! */
2021                         s->varkind = TEMPVAR;
2022
2023                 n=get_ss_lifetime( ls, s );
2024
2025                 if (store == LSRA_BB_OUT)
2026                         n->flags |= JOIN_BB;
2027                 if (n->flags & JOINING)
2028                         n->flags &= ~JOINING;
2029                 n->usagecount+=ls->nesting[ls->sorted_rev[block]];
2030
2031                 /* remember last USE, so only write, if USE Field is undefined (==-1) */
2032                 if (n->bb_last_use == -1) {
2033                         n->bb_last_use = ls->sorted_rev[block];
2034                         n->i_last_use = instr;
2035                 }
2036         }
2037 }
2038
2039 void lsra_usage_local(lsradata *ls, s4 v_index, int type, int block, int instr, int store)
2040 {
2041         struct lifetime *n;
2042
2043         n = &(ls->lifetime[ ls->maxlifetimes + v_index * (TYPE_ADR+1) + type]);
2044
2045         if (n->type == -1) { /* new local lifetime */
2046 #ifdef LSRA_DEBUG
2047 /*              if (store != LSRA_STORE) printf("lsra_local_store: Read before write Local var: %i paramcount: ?\n", v_index); */
2048 #endif
2049                 n->local_ss=NULL;
2050                 n->v_index=v_index;
2051                 n->type=type;
2052                 n->savedvar = SAVEDVAR;
2053                 n->flags = 0;
2054                 n->usagecount = 0;
2055
2056                 n->bb_last_use = -1;
2057                 n->bb_first_def = -1;
2058         }
2059         n->usagecount+=ls->nesting[ls->sorted_rev[block]];
2060         /* add access at (block, instr) to instruction list */
2061         /* remember last USE, so only write, if USE Field is undefined (==-1)   */
2062         /* count store as use, too -> defined and not used vars would overwrite */
2063         /* other vars */
2064         if (n->bb_last_use == -1) {
2065                 n->bb_last_use = ls->sorted_rev[block];
2066                 n->i_last_use = instr;
2067         }
2068         if (store == LSRA_STORE) {
2069                 /* store == LSRA_STORE, remember first def -> overwrite everytime */
2070                 n->bb_first_def = ls->sorted_rev[block];
2071                 n->i_first_def = instr;
2072         }
2073 }       
2074
2075 #ifdef LSRA_DEBUG
2076 void lsra_dump_stack(stackptr s)
2077 {
2078         while (s!=NULL) {
2079                 printf("%p(R%3i N%3i K%3i T%3i F%3i) ",(void *)s,s->regoff, s->varnum, s->varkind, s->type, s->flags);
2080                 s=s->prev;
2081         }
2082         printf("\n");
2083 }
2084 #endif
2085
2086
2087 void lsra_scan_registers_canditates(methodinfo *m, lsradata *ls, int b_index)
2088 {
2089         methodinfo         *lm;
2090         builtintable_entry *bte;
2091         methoddesc         *md;
2092         int i;
2093         int opcode;
2094         int iindex;
2095         stackptr    src;
2096         stackptr    dst;
2097         instruction *iptr;
2098         bool join_ret; /* for lsra_join* Macros */
2099 #if defined(LSRA_USES_REG_RES)
2100         int  v_index_min_before_instruction;
2101         int v_index_min[REG_RES_CNT];
2102
2103         for (i=0; i < REG_RES_CNT; i++) {
2104                 ls->reg_res_free[i] = -1;
2105                 v_index_min[i] = ls->v_index;
2106         }
2107 #endif
2108
2109     /* get instruction count for BB and remember the max instruction count */
2110         /* of all BBs */
2111         iindex = m->basicblocks[b_index].icount - 1;
2112
2113         src = m->basicblocks[b_index].instack;
2114         if (m->basicblocks[b_index].type != BBTYPE_STD) {
2115 #ifdef LSRA_DEBUG
2116                 if (src == NULL) {
2117                         log_text("No Incoming Stackslot for Exception/Subroutine BB\n");
2118                         assert(0);
2119                 }
2120 #endif
2121                 lsra_new_stack(ls, src, b_index, 0);
2122                 if (src->varkind == STACKVAR)
2123                         src->varkind = TEMPVAR;
2124                 src = src->prev;
2125         }
2126         for (;src != NULL; src=src->prev) {
2127                 /* no ARGVAR possible at BB Boundaries with LSRA! */
2128                 /* -> change to TEMPVAR                           */
2129                 if (src->varkind == ARGVAR ) {
2130                         src->varkind = TEMPVAR;
2131            /* On Architectures with own return registers a return stackslot is */
2132            /* marked as varkind=ARGVAR with varnum=-1                          */
2133            /* but for lsra a varkind==TEMPVAR, varnum=-1 would mean, that already */
2134            /* a lifetime was allocated! */
2135                         if (src->varnum < 0) src->varnum = 0;
2136                 }
2137                 else if (src->varkind == LOCALVAR )
2138                         /* only allowed for top most ss at sbr or exh entries! */
2139                         { log_text("LOCALVAR at basicblock instack\n"); assert(0); } 
2140                 else {
2141                         if (src->varkind == STACKVAR )
2142                                 /* no Interfaces at BB Boundaries with LSRA! */
2143                                 /* -> change to TEMPVAR                      */
2144                                 src->varkind = TEMPVAR;
2145 /*******************************************************************************
2146 Check this - ? For every incoming Stack Slot a lifetime has to be created ?
2147 *******************************************************************************/
2148                         _lsra_new_stack(ls, src, b_index, 0, LSRA_BB_IN);
2149                 }
2150         }
2151         src = m->basicblocks[b_index].outstack;
2152         for (;src != NULL; src=src->prev) {
2153                 if (src->varkind == ARGVAR )  
2154                         { log_text("ARGVAR at basicblock outstack\n"); assert(0); }
2155                 else if (src->varkind == LOCALVAR )
2156                         { log_text("LOCALVAR at basicblock outstack\n"); assert(0); }
2157                 else {
2158                         /* no Interfaces at BB Boundaries with LSRA! */
2159                         /* -> change to TEMPVAR                      */
2160                         if (src->varkind == STACKVAR )
2161                                 src->varkind = TEMPVAR;
2162                         _lsra_from_stack(ls, src, b_index, iindex, LSRA_BB_OUT);
2163                 }
2164         }
2165                         
2166         /* set iptr to last instruction of BB */
2167         iptr = m->basicblocks[b_index].iinstr + iindex;
2168
2169         for (;iindex >= 0; iindex--, iptr--)  {
2170                 /* get source and destination Stack for the current instruction     */
2171                 /* destination stack is available as iptr->dst                      */
2172                 dst = iptr->dst;
2173                 /* source stack is either the destination stack of the previos      */
2174                 /* instruction, or the basicblock instack for the first instruction */
2175                 if (iindex) /* != 0 is > 0 here, since iindex ist always >= 0 */
2176                         src=(iptr-1)->dst;
2177                 else
2178                         src=m->basicblocks[b_index].instack;
2179
2180 #if defined(LSRA_USES_REG_RES)
2181                 /* remember last Stack Slot v_index, so not all lifetimes have to */
2182                 /* be checked for reserved register allocation                    */
2183                 v_index_min_before_instruction = ls->v_index;
2184 #endif
2185
2186 #ifdef LSRA_DEBUG
2187                 /*                              printf("bb: %3i bcount: %3i iindex: %3i ilen: %3i opcode: %3i %s\n",b_index,m->basicblockcount,iindex,len,opcode,icmd_names[opcode]); */
2188                 /*                              lsra_dump_stack(src); */
2189                 /*                              lsra_dump_stack(dst); */
2190 #endif
2191                 opcode = iptr->opc;
2192                 switch (opcode) {
2193
2194                         /* pop 0 push 0 */
2195                 case ICMD_RET:
2196                         /* local read (return adress) */
2197                         lsra_usage_local(ls, iptr->op1, TYPE_ADR, b_index, iindex,
2198                                                          LSRA_LOAD);
2199                         break;
2200                 case ICMD_NOP:
2201                 case ICMD_ELSE_ICONST:
2202                 case ICMD_CHECKNULL:
2203                 case ICMD_JSR:
2204                 case ICMD_RETURN:
2205                 case ICMD_GOTO:
2206                 case ICMD_PUTSTATICCONST:
2207                 case ICMD_INLINE_START:
2208                 case ICMD_INLINE_END:
2209                         break;
2210                              
2211                 case ICMD_IINC:
2212                         /* local = local+<const> */
2213                         lsra_usage_local(ls, iptr->op1, TYPE_INT, b_index, iindex, 
2214                                                          LSRA_LOAD);
2215                         lsra_usage_local(ls, iptr->op1, TYPE_INT, b_index, iindex, 
2216                                                          LSRA_STORE);
2217                         break;
2218
2219                         /* pop 0 push 1 const: const->stack */
2220                 case ICMD_ICONST:
2221                 case ICMD_LCONST:
2222                 case ICMD_FCONST:
2223                 case ICMD_DCONST:
2224                 case ICMD_ACONST:
2225                         /* new stack slot */
2226                         lsra_new_stack(ls, dst, b_index, iindex);
2227                         break;
2228
2229                         /* pop 0 push 1 load: local->stack */
2230                 case ICMD_ILOAD:
2231                 case ICMD_LLOAD:
2232                 case ICMD_FLOAD:
2233                 case ICMD_DLOAD:
2234                 case ICMD_ALOAD:
2235                         if (dst->varkind != LOCALVAR) {
2236                                 /* local->value on stack */
2237                                 lsra_usage_local(ls, iptr->op1, opcode - ICMD_ILOAD, b_index, 
2238                                                                  iindex, LSRA_LOAD);
2239                                 lsra_new_stack(ls, dst, b_index, iindex); /* value->stack */
2240                         } else /* if (dst->varnum != iptr->op1) */ {
2241                                 /* local -> local */
2242                                 lsra_usage_local(ls, iptr->op1, opcode - ICMD_ILOAD, b_index, 
2243                                                                  iindex,LSRA_LOAD); /* local->value */
2244                                 lsra_usage_local(ls, dst->varnum, opcode - ICMD_ILOAD, b_index,
2245                                                                  iindex, LSRA_STORE); /* local->value */
2246                         }
2247
2248                         break;
2249
2250                         /* pop 2 push 1 */
2251                         /* Stack(arrayref,index)->stack */
2252                 case ICMD_IALOAD:
2253                 case ICMD_LALOAD:
2254                 case ICMD_FALOAD:
2255                 case ICMD_DALOAD:
2256                 case ICMD_AALOAD:
2257
2258                 case ICMD_BALOAD:
2259                 case ICMD_CALOAD:
2260                 case ICMD_SALOAD:
2261                         /* stack->index */
2262                         lsra_from_stack(ls, src, b_index, iindex); 
2263                         /* stack->arrayref */
2264                         lsra_from_stack(ls, src->prev, b_index, iindex); 
2265                         /* arrayref[index]->stack */
2266                         lsra_new_stack(ls, dst, b_index, iindex); 
2267                         break;
2268
2269                         /* pop 3 push 0 */
2270                         /* stack(arrayref,index,value)->arrayref[index]=value */
2271                 case ICMD_IASTORE:
2272                 case ICMD_LASTORE:
2273                 case ICMD_FASTORE:
2274                 case ICMD_DASTORE:
2275                 case ICMD_AASTORE:
2276
2277                 case ICMD_BASTORE:
2278                 case ICMD_CASTORE:
2279                 case ICMD_SASTORE:
2280
2281                         lsra_from_stack(ls, src,b_index, iindex); /* stack -> value */
2282                         lsra_from_stack(ls, src->prev, b_index, iindex); /* stack -> index*/
2283                         /* stack -> arrayref */
2284                         lsra_from_stack(ls, src->prev->prev, b_index, iindex); 
2285                         break;
2286
2287                         /* pop 1 push 0 store: stack -> local */
2288                 case ICMD_ISTORE:
2289                 case ICMD_LSTORE:
2290                 case ICMD_FSTORE:
2291                 case ICMD_DSTORE:
2292                 case ICMD_ASTORE:
2293                         if (src->varkind != LOCALVAR) {
2294                                 lsra_from_stack(ls, src, b_index, iindex); /* stack -> value */
2295                                 lsra_usage_local(ls, iptr->op1, opcode-ICMD_ISTORE, b_index,
2296                                                                  iindex, LSRA_STORE); /* local->value */
2297                         } else /* if (src->varnum != iptr->op1) */ {
2298                                 lsra_usage_local(ls, iptr->op1, opcode-ICMD_ISTORE, b_index, 
2299                                                                  iindex, LSRA_STORE); /* local->value */
2300                                 lsra_usage_local(ls, src->varnum, opcode-ICMD_ISTORE, b_index, 
2301                                                                  iindex, LSRA_LOAD); /* local->value */
2302                         }
2303                         break;
2304
2305                         /* pop 1 push 0 */
2306                 case ICMD_POP: /* throw away a stackslot */
2307                         /* TODO: check if used anyway (DUP...) and change codegen to */
2308                         /*       ignore this stackslot */
2309                         lsra_pop_from_stack(ls, src, b_index, iindex);
2310                         break;
2311
2312                         /* pop 1 push 0 */
2313                 case ICMD_IRETURN:
2314                 case ICMD_LRETURN:
2315                 case ICMD_FRETURN:
2316                 case ICMD_DRETURN:
2317                 case ICMD_ARETURN: /* stack(value) -> [empty]    */
2318
2319                 case ICMD_ATHROW:  /* stack(objref) -> undefined */
2320
2321                 case ICMD_PUTSTATIC: /* stack(value) -> static_field */
2322                 case ICMD_PUTFIELDCONST:
2323
2324                         /* pop 1 push 0 branch */
2325                 case ICMD_IFNULL: /* stack(value) -> branch? */
2326                 case ICMD_IFNONNULL:
2327
2328                 case ICMD_IFEQ:
2329                 case ICMD_IFNE:
2330                 case ICMD_IFLT:
2331                 case ICMD_IFGE:
2332                 case ICMD_IFGT:
2333                 case ICMD_IFLE:
2334
2335                 case ICMD_IF_LEQ:
2336                 case ICMD_IF_LNE:
2337                 case ICMD_IF_LLT:
2338                 case ICMD_IF_LGE:
2339                 case ICMD_IF_LGT:
2340                 case ICMD_IF_LLE:
2341
2342                         /* pop 1 push 0 table branch */
2343                 case ICMD_TABLESWITCH:
2344                 case ICMD_LOOKUPSWITCH:
2345
2346                 case ICMD_MONITORENTER:
2347                 case ICMD_MONITOREXIT:
2348                         lsra_from_stack(ls, src, b_index, iindex); /* stack -> value */
2349                         break;
2350
2351                         /* pop 2 push 0 */
2352                 case ICMD_POP2: /* throw away 2 stackslots */
2353                         /* TODO: check if used anyway (DUP...) and change codegen to */
2354                         /*       ignore this stackslot */
2355                         lsra_pop_from_stack(ls, src, b_index, iindex);
2356                         lsra_pop_from_stack(ls, src->prev, b_index, iindex);
2357                         break;
2358
2359                         /* pop 2 push 0 branch */
2360
2361                 case ICMD_IF_ICMPEQ: /* stack (v1,v2) -> branch(v1,v2) */
2362                 case ICMD_IF_ICMPNE:
2363                 case ICMD_IF_ICMPLT:
2364                 case ICMD_IF_ICMPGE:
2365                 case ICMD_IF_ICMPGT:
2366                 case ICMD_IF_ICMPLE:
2367
2368                 case ICMD_IF_LCMPEQ:
2369                 case ICMD_IF_LCMPNE:
2370                 case ICMD_IF_LCMPLT:
2371                 case ICMD_IF_LCMPGE:
2372                 case ICMD_IF_LCMPGT:
2373                 case ICMD_IF_LCMPLE:
2374
2375                 case ICMD_IF_ACMPEQ:
2376                 case ICMD_IF_ACMPNE:
2377
2378                         /* pop 2 push 0 */
2379                 case ICMD_PUTFIELD: /* stack(objref,value) -> objref = value */
2380
2381                 case ICMD_IASTORECONST:
2382                 case ICMD_LASTORECONST:
2383                 case ICMD_AASTORECONST:
2384                 case ICMD_BASTORECONST:
2385                 case ICMD_CASTORECONST:
2386                 case ICMD_SASTORECONST:
2387                         lsra_from_stack(ls, src, b_index, iindex);         /* stack -> value*/
2388                         lsra_from_stack(ls, src->prev, b_index, iindex); 
2389                         break;
2390
2391                         /* pop 0 push 1 dup */
2392                 case ICMD_DUP: /* src == dst->prev, src -> dst */
2393                         /* lsra_from_stack(ls, src,b_index,iindex);*/ 
2394                         lsra_new_stack(ls, dst, b_index, iindex);
2395
2396 #ifdef JOIN_DUP_STACK
2397                         /* src is identical to dst->prev */
2398                         lsra_join_2_stack(ls, src, dst, JOIN_DUP);
2399 #endif
2400                         break;
2401
2402                         /* pop 0 push 2 dup */
2403                 case ICMD_DUP2: 
2404                         /* lsra_from_stack(ls, src,b_index, iindex); */ 
2405                         /* lsra_from_stack(ls, src->prev, b_index, iindex); */
2406                         lsra_new_stack(ls, dst->prev, b_index, iindex);
2407                         lsra_new_stack(ls, dst, b_index, iindex); 
2408
2409 #ifdef JOIN_DUP_STACK
2410                         lsra_join_2_stack(ls, src, dst, JOIN_DUP);
2411                         lsra_join_2_stack(ls, src->prev, dst->prev, JOIN_DUP);
2412                         /* src is identical to dst->prev->prev */
2413                         /* src->prev is identical to dst->prev->prev->prev */
2414 #endif
2415                         break;
2416
2417                         /* pop 2 push 3 dup */
2418                 case ICMD_DUP_X1:
2419                         lsra_from_stack(ls, src, b_index, iindex); 
2420                         lsra_from_stack(ls, src->prev, b_index, iindex);
2421                         lsra_new_stack(ls, dst->prev->prev, b_index, iindex);
2422                         lsra_new_stack(ls, dst->prev, b_index, iindex);
2423                         lsra_new_stack(ls, dst, b_index, iindex); 
2424 #ifdef JOIN_DUP_STACK
2425                         lsra_join_dup(ls, src, dst, dst->prev->prev);
2426                         lsra_join_2_stack(ls, src->prev, dst->prev, JOIN);
2427 #endif
2428                         break;
2429
2430                         /* pop 3 push 4 dup */
2431                 case ICMD_DUP_X2:
2432                         lsra_from_stack(ls, src,b_index, iindex); 
2433                         lsra_from_stack(ls, src->prev, b_index, iindex); 
2434                         lsra_from_stack(ls, src->prev->prev, b_index, iindex); 
2435                         lsra_new_stack(ls, dst->prev->prev->prev, b_index, iindex);
2436                         lsra_new_stack(ls, dst->prev->prev, b_index, iindex);
2437                         lsra_new_stack(ls, dst->prev, b_index, iindex);
2438                         lsra_new_stack(ls, dst, b_index, iindex); 
2439
2440 #ifdef JOIN_DUP_STACK
2441                         lsra_join_dup(ls, src, dst, dst->prev->prev->prev);
2442                         lsra_join_2_stack(ls, src->prev, dst->prev, JOIN);
2443                         lsra_join_2_stack(ls, src->prev->prev, dst->prev->prev, JOIN);
2444 #endif
2445                         break;
2446
2447                         /* pop 3 push 5 dup */
2448                 case ICMD_DUP2_X1:
2449                         lsra_from_stack(ls, src, b_index, iindex); 
2450                         lsra_from_stack(ls, src->prev, b_index, iindex); 
2451                         lsra_from_stack(ls, src->prev->prev, b_index, iindex); 
2452                         lsra_new_stack(ls, dst->prev->prev->prev->prev, b_index, iindex);
2453                         lsra_new_stack(ls, dst->prev->prev->prev, b_index, iindex);
2454                         lsra_new_stack(ls, dst->prev->prev, b_index, iindex);
2455                         lsra_new_stack(ls, dst->prev, b_index, iindex);
2456                         lsra_new_stack(ls, dst, b_index, iindex); 
2457
2458 #ifdef JOIN_DUP_STACK
2459                         lsra_join_dup(ls, src, dst, dst->prev->prev->prev);
2460                         lsra_join_dup(ls, src->prev, dst->prev, 
2461                                                   dst->prev->prev->prev->prev);
2462                         lsra_join_2_stack(ls, src->prev->prev, dst->prev->prev, JOIN);
2463 #endif
2464                         break;
2465
2466                         /* pop 4 push 6 dup */
2467                 case ICMD_DUP2_X2:
2468                         lsra_from_stack(ls, src, b_index, iindex); 
2469                         lsra_from_stack(ls, src->prev, b_index, iindex); 
2470                         lsra_from_stack(ls, src->prev->prev, b_index, iindex); 
2471                         lsra_from_stack(ls, src->prev->prev->prev, b_index, iindex); 
2472                         lsra_new_stack(ls, dst->prev->prev->prev->prev->prev, b_index, 
2473                                                    iindex);
2474                         lsra_new_stack(ls, dst->prev->prev->prev->prev, b_index, iindex);
2475                         lsra_new_stack(ls, dst->prev->prev->prev, b_index, iindex);
2476                         lsra_new_stack(ls, dst->prev->prev, b_index, iindex);
2477                         lsra_new_stack(ls, dst->prev, b_index, iindex);
2478                         lsra_new_stack(ls, dst, b_index, iindex); 
2479
2480 #ifdef JOIN_DUP_STACK
2481                         lsra_join_dup(ls, src, dst, dst->prev->prev->prev->prev);
2482                         lsra_join_dup(ls, src->prev, dst->prev,
2483                                                   dst->prev->prev->prev->prev->prev);
2484                         lsra_join_2_stack(ls, src->prev->prev, dst->prev->prev, JOIN);
2485                         lsra_join_2_stack(ls, src->prev->prev->prev, dst->prev->prev->prev, 
2486                                                           JOIN);
2487 #endif
2488                         break;
2489
2490                         /* pop 2 push 2 swap */
2491                 case ICMD_SWAP:
2492                         lsra_from_stack(ls, src, b_index, iindex); 
2493                         lsra_from_stack(ls, src->prev, b_index, iindex);
2494                         lsra_new_stack(ls, dst->prev, b_index, iindex);
2495                         lsra_new_stack(ls, dst, b_index, iindex);
2496
2497                         lsra_join_2_stack(ls, src->prev, dst, JOIN);
2498                         lsra_join_2_stack(ls, src, dst->prev, JOIN);
2499
2500                         break;
2501
2502                         /* pop 2 push 1 */
2503                                         
2504                 case ICMD_LADD:
2505                 case ICMD_LSUB:
2506                 case ICMD_LMUL:
2507
2508                 case ICMD_LOR:
2509                 case ICMD_LAND:
2510                 case ICMD_LXOR:
2511
2512                 case ICMD_LSHL:
2513                 case ICMD_LSHR:
2514                 case ICMD_LUSHR:
2515
2516                 case ICMD_IADD:
2517                 case ICMD_IMUL:
2518
2519                 case ICMD_ISHL:
2520                 case ICMD_ISHR:
2521                 case ICMD_IUSHR:
2522                 case ICMD_IAND:
2523                 case ICMD_IOR:
2524                 case ICMD_IXOR:
2525
2526
2527                 case ICMD_FADD:
2528                 case ICMD_FSUB:
2529                 case ICMD_FMUL:
2530
2531                 case ICMD_DADD:
2532                 case ICMD_DSUB:
2533                 case ICMD_DMUL:
2534                 case ICMD_DDIV:
2535                 case ICMD_DREM:
2536                         lsra_from_stack(ls, src, b_index, iindex);
2537                         lsra_from_stack(ls, src->prev, b_index, iindex);
2538                         lsra_new_stack(ls, dst, b_index, iindex);
2539 #ifdef JOIN_DEST_STACK
2540                         lsra_join_3_stack(ls, dst, src->prev, src, JOIN_OP);
2541 #endif
2542                         break;
2543
2544                 case ICMD_ISUB:
2545                         lsra_from_stack(ls, src, b_index, iindex);
2546                         lsra_from_stack(ls, src->prev,b_index,iindex);
2547                         lsra_new_stack(ls, dst, b_index, iindex);
2548 #ifdef JOIN_DEST_STACK
2549                         lsra_join_2_stack(ls, src, dst, JOIN_OP);
2550 #endif
2551                         break;
2552
2553                 case ICMD_LDIV:
2554                 case ICMD_LREM:
2555
2556                 case ICMD_IDIV:
2557                 case ICMD_IREM:
2558
2559                 case ICMD_FDIV:
2560                 case ICMD_FREM:
2561
2562                 case ICMD_LCMP:
2563                 case ICMD_FCMPL:
2564                 case ICMD_FCMPG:
2565                 case ICMD_DCMPL:
2566                 case ICMD_DCMPG:
2567                         lsra_from_stack(ls, src, b_index, iindex);
2568                         lsra_from_stack(ls, src->prev, b_index, iindex);
2569                         lsra_new_stack(ls, dst, b_index, iindex);
2570                         break;
2571
2572                         /* pop 1 push 1 */
2573                 case ICMD_LADDCONST:
2574                 case ICMD_LSUBCONST:
2575                 case ICMD_LMULCONST:
2576                 case ICMD_LMULPOW2:
2577                 case ICMD_LDIVPOW2:
2578                 case ICMD_LREMPOW2:
2579                 case ICMD_LANDCONST:
2580                 case ICMD_LORCONST:
2581                 case ICMD_LXORCONST:
2582                 case ICMD_LSHLCONST:
2583                 case ICMD_LSHRCONST:
2584                 case ICMD_LUSHRCONST:
2585
2586                 case ICMD_IADDCONST:
2587                 case ICMD_ISUBCONST:
2588                 case ICMD_IMULCONST:
2589                 case ICMD_IMULPOW2:
2590                 case ICMD_IDIVPOW2:
2591                 case ICMD_IREMPOW2:
2592                 case ICMD_IANDCONST:
2593                 case ICMD_IORCONST:
2594                 case ICMD_IXORCONST:
2595                 case ICMD_ISHLCONST:
2596                 case ICMD_ISHRCONST:
2597                 case ICMD_IUSHRCONST:
2598
2599                 case ICMD_IFEQ_ICONST:
2600                 case ICMD_IFNE_ICONST:
2601                 case ICMD_IFLT_ICONST:
2602                 case ICMD_IFGE_ICONST:
2603                 case ICMD_IFGT_ICONST:
2604                 case ICMD_IFLE_ICONST:
2605
2606                 case ICMD_INEG:
2607                 case ICMD_INT2BYTE:
2608                 case ICMD_INT2CHAR:
2609                 case ICMD_INT2SHORT:
2610                 case ICMD_LNEG:
2611                 case ICMD_FNEG:
2612                 case ICMD_DNEG:
2613
2614                 case ICMD_I2L:
2615                 case ICMD_I2F:
2616                 case ICMD_I2D:
2617                 case ICMD_L2I:
2618                 case ICMD_L2F:
2619                 case ICMD_L2D:
2620                 case ICMD_F2I:
2621                 case ICMD_F2L:
2622                 case ICMD_F2D:
2623                 case ICMD_D2I:
2624                 case ICMD_D2L:
2625                 case ICMD_D2F:
2626
2627                 case ICMD_CHECKCAST:
2628                         lsra_from_stack(ls, src, b_index, iindex);
2629                         lsra_new_stack(ls, dst, b_index, iindex);
2630 #ifdef JOIN_DEST_STACK
2631                         lsra_join_2_stack(ls, src, dst, JOIN_OP);
2632 #endif
2633                         break;
2634
2635                         /* TODO: check if for these ICMDs JOIN_DEST_STACK works, too! */
2636                 case ICMD_ARRAYLENGTH:
2637                 case ICMD_INSTANCEOF:
2638
2639                 case ICMD_NEWARRAY:
2640                 case ICMD_ANEWARRAY:
2641
2642                 case ICMD_GETFIELD:
2643                         lsra_from_stack(ls, src, b_index, iindex);
2644                         lsra_new_stack(ls, dst, b_index, iindex);
2645                         break;
2646
2647                         /* pop 0 push 1 */
2648                 case ICMD_GETSTATIC:
2649
2650                 case ICMD_NEW:
2651                         lsra_new_stack(ls, dst, b_index, iindex);
2652                         break;
2653
2654                         /* pop many push any */
2655
2656                 case ICMD_INVOKESTATIC:
2657                 case ICMD_INVOKESPECIAL:
2658                 case ICMD_INVOKEVIRTUAL:
2659                 case ICMD_INVOKEINTERFACE:
2660                         lm = iptr->val.a;
2661
2662                         if (lm)
2663                                 md = lm->parseddesc;
2664                         else {
2665                                 unresolved_method *um = iptr->target;
2666                                 md = um->methodref->parseddesc.md;
2667                         }
2668                         i = md->paramcount;
2669                         while (--i >= 0) {
2670                                 lsra_from_stack(ls, src, b_index, iindex);
2671                                 src = src->prev;
2672                         }
2673                         if (md->returntype.type != TYPE_VOID)
2674                                 lsra_new_stack(ls, dst, b_index, iindex);
2675                         break;
2676
2677
2678                 case ICMD_BUILTIN:
2679                         bte = iptr->val.a;
2680                         md = bte->md;
2681                         i = md->paramcount;
2682                         while (--i >= 0) {
2683                                 lsra_from_stack(ls, src, b_index, iindex);
2684                                 src = src->prev;
2685                         }
2686                         if (md->returntype.type != TYPE_VOID)
2687                                 lsra_new_stack(ls, dst, b_index, iindex);
2688                         break;
2689
2690                 case ICMD_MULTIANEWARRAY:
2691                         i = iptr->op1;
2692                         while (--i >= 0) {
2693                                 lsra_from_stack(ls, src, b_index, iindex);
2694                                 src = src->prev;
2695                         }
2696                         lsra_new_stack(ls, dst, b_index, iindex);
2697                         break;
2698
2699                 default:
2700                         *exceptionptr =
2701                                 new_internalerror("Unknown ICMD %d during register allocation",
2702                                                                   iptr->opc);
2703                         return;
2704                 } /* switch */
2705
2706 #if defined(LSRA_USES_REG_RES)
2707                 {
2708                         int /* length, */ maxlength, j;
2709                         int index, reg_res,start_iindex, end_iindex;
2710                         struct stackslot * ss;
2711                         struct lifetime *n;
2712
2713                         end_iindex = -1;
2714 /*                      length = 0; */
2715
2716                         if ((reg_res = icmd_uses_reg_res[opcode][REG_RES_CNT])==REG_NULL)
2717                                 /* no preferred "output" register for this ICMD -> start with */
2718                                 /* EAX */
2719                                 reg_res = EAX;
2720                         for (j=0; j < REG_RES_CNT; j++, reg_res=(reg_res+1)%REG_RES_CNT) {
2721                                 maxlength = -1;
2722                                 index = -1;
2723                                 if ((iindex == 0) || (icmd_uses_reg_res[opcode][reg_res])) {
2724                                         /* least iindex looked at, or reg_res does not */
2725                                         /* "fully" survivy this ICMD */
2726                                         if (ls->reg_res_free[reg_res] != -1) {
2727                                                 /* reg_res is free from ls->reg_res_free[] til here   */
2728                                                 /* (iindex). Now search for the longest lifetime,     */
2729                                                 /* which fits in this intervall and if found assign   */
2730                                                 /* reg_res to it */
2731                                                 if (icmd_uses_reg_res[opcode][reg_res] & D)
2732                                                         /* ICMD destroys REG_RES as destination operand */
2733                                                         start_iindex = iindex +1;
2734                                                 else
2735                                                         start_iindex = iindex;
2736                                                 for (i = (-v_index_min[reg_res] - 1); 
2737                                                          i < (-ls->v_index -1); i++) {
2738                                                         n = &(ls->lifetime[i]);
2739                                                         if (!(n->flags & (JOINING || JOIN_BB))) {
2740                                                                 /* do not assign reserved Regs to lifetimes   */
2741                                                                 /* not completely seen till now */
2742                                                                 if ((n->type == TYPE_INT) 
2743                                                                         || (n->type == TYPE_ADR)) {
2744                                                                         if (n->savedvar == 0) {
2745                                                                                 if ((n->bb_last_use == n->bb_first_def)
2746                                                                                         && (n->bb_last_use 
2747                                                                                                 == ls->sorted_rev[b_index])) {
2748                                                                                         if ((n->i_last_use 
2749                                                                                                  <= ls->reg_res_free[reg_res]) 
2750                                                                                                 && (n->i_first_def >= 
2751                                                                                                         start_iindex)) {
2752
2753 /*                                                                                              length = n->i_last_use -  */
2754 /*                                                                                                      n->i_first_def; */
2755 /*                                                                                              if (length > maxlength) { */
2756 /*                                                                                                      maxlength = length; */
2757 /*                                                                                                      index = i; */
2758 /*                                                                                              } */
2759 /*                                                                                              length++; */
2760                                                                                                 /* there is a lifetime, which a reserved register can */
2761                                                                                                 /* be assigned to */
2762
2763                                                                                                 ls->lifetime[i].reg = lsra_reg_res[reg_res];
2764                                                                                                 for (ss = ls->lifetime[i].local_ss; ss != NULL; 
2765                                                                                                          ss=ss->next) {
2766                                                                                                         ss->s->regoff = lsra_reg_res[reg_res];
2767                                                                                                 }
2768                                                                                                 /* drop lifetime, no further processing required */
2769                                                                                                 ls->lifetime[i].type = -1; 
2770                                                                                                 
2771                                                                                                 ls->reg_res_free[reg_res] = n->i_first_def;
2772                                                                                         }
2773                                                                                 }
2774                                                                         }
2775                                                                 }
2776                                                         }
2777                                                 }
2778 /*                                              if (length > 1) */
2779 /*                                                      printf("%i reg res Lifetimes assigned for this intervall \n",length); */
2780                                         }
2781                                         if (icmd_uses_reg_res[opcode][reg_res] & S)
2782                                                 /* ICMD destroys REG_RES as source operand */
2783                                                 ls->reg_res_free[reg_res] = -1;
2784                                         else
2785                                                 ls->reg_res_free[reg_res] = iindex;
2786
2787                                         v_index_min[reg_res] = v_index_min_before_instruction;
2788                                 } else
2789                                         if (ls->reg_res_free[reg_res] == -1)
2790                                                 ls->reg_res_free[reg_res] = iindex;
2791                         }
2792                 }
2793 #endif /* defined(LSRA_USES_REG_RES) */
2794 #if 0
2795                 {
2796                         int i, j;
2797                         stackptr t;
2798
2799                         i = 14; /* maxstack */
2800                         t = dst;
2801         
2802                         while (t) {
2803                                 i--;
2804                                 t = t->prev;
2805                         }
2806                         j = 14 - i;
2807                         while (--i >= 0)                        
2808                                 printf("    ");
2809                         t = dst;
2810                         while (t) {
2811                                 printf(" %3i (%p)", t->varnum);
2812                                 t=t->prev;
2813                         }
2814                         printf(" %3i %s\n", iindex, icmd_names[opcode]);
2815                         fflush(stdout);
2816                 }
2817 #endif
2818
2819         }
2820 }
2821
2822 #ifdef LSRA_TESTLT
2823
2824 int lsra_test_lt(registerdata *rd, struct lifetime *n, int store, int *values, bool inmemory) {
2825         int value_index;
2826
2827         if (inmemory) {
2828                 value_index = n->reg;
2829         } else {
2830                 if (IS_FLT_DBL_TYPE(n->type)) {
2831                         value_index = rd->memuse + INT_REG_CNT + n->reg;
2832                 } else {
2833                         value_index = rd->memuse + n->reg;
2834                 }
2835         }
2836
2837         if ((store == LSRA_LOAD) || (store == LSRA_POP)) {
2838                 if (values[value_index] == VS) {
2839 #if 0
2840                         /* this happens through not really returning right from subroutines while the test */
2841                         /* so this (in this case) useless warning is inhibited till this case is handled   */
2842                         /* right */
2843                         if (n->i_start != -1) { /* not a parameter */
2844                                 printf("lsra_test: Warning: v_index %3i type %3i reg %3i", n->v_index, n->type, n->reg);
2845                                 if (inmemory)
2846                                         printf (" MEM");
2847                                 printf(" not initialized\n");
2848                         }
2849 #endif
2850                 } else if (values[value_index] != n->v_index) {
2851                         printf("lsra_test: Error: v_index %3i  type %3i reg %3i", n->v_index, n->type, n->reg);
2852                         if (inmemory)
2853                                 printf (" MEM  ");
2854                         printf("Conflict: %3i \n", values[value_index]);
2855                         return (n->reg);                        
2856                 }
2857
2858         } else { /* LSRA_STORE */
2859                 values[value_index] = n->v_index;
2860         }
2861         return -1;
2862 }
2863
2864 int lsra_test_local( lsradata *ls, registerdata *rd, int v_index, int type, int store, int *values) {
2865         struct lifetime *n;
2866
2867         n = &(ls->lifetime[ ls->maxlifetimes + v_index * (TYPE_ADR+1) + type]);
2868         if (n->type == -1)
2869                 { log_text("lsra_test: Local Var Lifetime not initialized!\n"); assert(0); }
2870
2871         return lsra_test_lt(rd, n, store, values, rd->locals[v_index][type].flags & INMEMORY);
2872 }
2873
2874 #define lsra_test_new_stack( ls, rd, s, values) lsra_test_stack(ls, rd, s, values, LSRA_STORE)
2875 #define lsra_test_from_stack( ls, rd, s, values) lsra_test_stack(ls, rd, s, values,LSRA_LOAD)
2876 #define lsra_test_pop_from_stack( ls, rd, s, values) lsra_test_stack(ls, rd, s, values,  LSRA_LOAD)
2877 int lsra_test_stack( lsradata *ls, registerdata *rd, stackptr s, int *values, int store)
2878 {
2879         struct lifetime *n;
2880         int value_index;
2881
2882         if (s->varkind == LOCALVAR) {
2883                 return lsra_test_local(ls, rd, s->varnum, s->type, store, values);
2884         }
2885         if (s->varkind != ARGVAR) {
2886                 if (s->varnum >=0)
2887                         { log_text("lsra_test: Stackslot not initialized!\n"); assert(0); }
2888                 n = &(ls->lifetime[-s->varnum - 1]);
2889                 if (n->type == -1)
2890                         { log_text("lsra_test: Stackslot Lifetime not initialized!\n"); assert(0); }
2891
2892                 return lsra_test_lt(rd, n, store, values, s->flags & INMEMORY);
2893         }
2894         return -1;
2895 }
2896
2897 int _test_lifetimes(methodinfo *m, lsradata *ls, registerdata *rd, int b_index, int *values, int rec_depth)
2898 {
2899         struct stackslot *ss;
2900         int *v, i, j;
2901
2902
2903         int opcode;
2904         int iindex;
2905         stackptr    src;
2906         stackptr    dst;
2907         instruction *iptr;
2908
2909         struct _list *succ;
2910
2911         bool       end_of_method;
2912
2913         int ret;
2914
2915         if (rec_depth > 1000) {
2916                 printf("%s.%s rec_depth > 1000\n", m->class->name->text, m->name->text);
2917                 return -1;
2918         }
2919
2920         ret = -1;
2921         end_of_method = false;
2922         iptr = m->basicblocks[b_index].iinstr;
2923                         
2924         dst = m->basicblocks[b_index].instack;
2925
2926         if (m->basicblocks[b_index].type != BBTYPE_STD) {
2927                 /* init incoming stackslot (exception or return address) */
2928                         ret = lsra_test_new_stack(ls, rd , dst , values);
2929
2930         }
2931                         
2932         for (iindex =0 ;(iindex < m->basicblocks[b_index].icount) && (ret == -1) ; iindex++, iptr++)  {
2933                 src = dst;
2934                 dst = iptr->dst;
2935                 opcode = iptr->opc;
2936
2937                 switch (opcode) {
2938
2939                         /* pop 0 push 0 */
2940                 case ICMD_RET:
2941                         ret = lsra_test_local(ls, rd, iptr->op1, TYPE_ADR, LSRA_LOAD, values); /* local read (return adress) */
2942                         break;
2943                 case ICMD_NOP:
2944                 case ICMD_ELSE_ICONST:
2945                 case ICMD_CHECKNULL:
2946                 case ICMD_CHECKASIZE:
2947                 case ICMD_CHECKEXCEPTION:
2948                 case ICMD_JSR:
2949                 case ICMD_GOTO:
2950                 case ICMD_PUTSTATICCONST:
2951                 case ICMD_INLINE_START:
2952                 case ICMD_INLINE_END:
2953                         break;
2954
2955                 case ICMD_RETURN:
2956                         end_of_method = true;
2957                         break;
2958                            
2959                 case ICMD_IINC:
2960                         ret = lsra_test_local(ls, rd,iptr->op1,TYPE_INT, LSRA_LOAD, values); /* local */
2961                         ret = lsra_test_local(ls, rd,iptr->op1,TYPE_INT, LSRA_STORE, values); /* local = local+<const> */
2962                         break;
2963
2964                         /* pop 0 push 1 const */
2965                         /* const->stack */
2966                                         
2967                 case ICMD_ICONST:
2968                 case ICMD_LCONST:
2969                 case ICMD_FCONST:
2970                 case ICMD_DCONST:
2971                 case ICMD_ACONST:
2972                         /* new stack slot */
2973                         ret = lsra_test_new_stack(ls, rd,dst, values); /* const->stack */
2974                         break;
2975
2976                         /* pop 0 push 1 load */
2977                         /* local->stack */
2978                                         
2979                 case ICMD_ILOAD:
2980                 case ICMD_LLOAD:
2981                 case ICMD_FLOAD:
2982                 case ICMD_DLOAD:
2983                 case ICMD_ALOAD:
2984                         if (dst->varkind != LOCALVAR) {
2985                                 ret = lsra_test_local(ls, rd,iptr->op1,opcode-ICMD_ILOAD, LSRA_LOAD, values); /* local->value */
2986                                 ret = lsra_test_new_stack(ls, rd,dst, values); /* value->stack */
2987                         } else if (dst->varnum != iptr->op1) {
2988                                 ret = lsra_test_local(ls, rd,iptr->op1,opcode-ICMD_ILOAD, LSRA_LOAD, values); /* local->value */
2989                                 ret = lsra_test_local(ls, rd,dst->varnum,opcode-ICMD_ILOAD, LSRA_STORE, values); /* local->value */
2990                         }
2991
2992                         break;
2993
2994                         /* pop 2 push 1 */
2995                         /* Stack(arrayref,index)->stack */
2996
2997                 case ICMD_IALOAD:
2998                 case ICMD_LALOAD:
2999                 case ICMD_FALOAD:
3000                 case ICMD_DALOAD:
3001                 case ICMD_AALOAD:
3002
3003                 case ICMD_BALOAD:
3004                 case ICMD_CALOAD:
3005                 case ICMD_SALOAD:
3006                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack->index */
3007                         ret = lsra_test_from_stack(ls, rd, src->prev, values); /* stack->arrayref */
3008                         ret = lsra_test_new_stack(ls, rd, dst, values); /* arrayref[index]->stack */
3009                         break;
3010
3011                         /* pop 3 push 0 */
3012                         /* stack(arrayref,index,value)->arrayref[index]=value */
3013
3014                 case ICMD_IASTORE:
3015                 case ICMD_LASTORE:
3016                 case ICMD_FASTORE:
3017                 case ICMD_DASTORE:
3018                 case ICMD_AASTORE:
3019
3020                 case ICMD_BASTORE:
3021                 case ICMD_CASTORE:
3022                 case ICMD_SASTORE:
3023
3024                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3025                         ret = lsra_test_from_stack(ls, rd, src->prev, values); /* stack -> index */
3026                         ret = lsra_test_from_stack(ls, rd, src->prev->prev, values); /* stack -> arrayref */
3027                         break;
3028
3029                 case ICMD_POP: /* throw away a stackslot -> check if used anyway! */
3030                         ret = lsra_test_pop_from_stack(ls, rd,src, values);
3031                         break;
3032
3033                         /* pop 1 push 0 store */
3034                         /* stack -> local */
3035
3036                 case ICMD_ISTORE:
3037                 case ICMD_LSTORE:
3038                 case ICMD_FSTORE:
3039                 case ICMD_DSTORE:
3040                 case ICMD_ASTORE:
3041                         if (src->varkind != LOCALVAR) {
3042                                 ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3043                                 ret = lsra_test_local(ls, rd,iptr->op1,opcode-ICMD_ISTORE, LSRA_STORE, values); /* local->value */
3044                         } else if (src->varnum != iptr->op1) {
3045                                 ret = lsra_test_local(ls, rd,iptr->op1,opcode-ICMD_ISTORE, LSRA_STORE, values); /* local->value */
3046                                 ret = lsra_test_local(ls, rd,src->varnum,opcode-ICMD_ISTORE, LSRA_LOAD, values); /* local->value */
3047                         }
3048                         break;
3049
3050                         /* pop 1 push 0 */
3051
3052                 case ICMD_IRETURN:
3053                 case ICMD_LRETURN:
3054                 case ICMD_FRETURN:
3055                 case ICMD_DRETURN:
3056                 case ICMD_ARETURN: /* stack(value) -> [empty] */
3057                 case ICMD_ATHROW: /* stack(objref) -> undefined */
3058                         end_of_method = true;
3059                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3060                         break;
3061                 case ICMD_PUTSTATIC: /* stack(value) -> static_field */
3062                 case ICMD_PUTFIELDCONST:
3063                         /* pop 1 push 0 branch */
3064                 case ICMD_MONITORENTER:
3065                 case ICMD_MONITOREXIT:
3066                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3067                         break;
3068
3069                 case ICMD_IFNULL: /* stack(value) -> branch? */
3070                 case ICMD_IFNONNULL:
3071                 case ICMD_IFEQ:
3072                 case ICMD_IFNE:
3073                 case ICMD_IFLT:
3074                 case ICMD_IFGE:
3075                 case ICMD_IFGT:
3076                 case ICMD_IFLE:
3077                 case ICMD_IF_LEQ:
3078                 case ICMD_IF_LNE:
3079                 case ICMD_IF_LLT:
3080                 case ICMD_IF_LGE:
3081                 case ICMD_IF_LGT:
3082                 case ICMD_IF_LLE:
3083                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3084                         break;
3085
3086                         /* pop 1 push 0 table branch */
3087
3088                 case ICMD_TABLESWITCH:
3089                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3090                         break;
3091                 case ICMD_LOOKUPSWITCH:
3092                         ret = lsra_test_from_stack(ls, rd, src, values); /* stack -> value */
3093                         break;
3094
3095                         /* pop 2 push 0 */
3096
3097                 case ICMD_POP2: /* throw away 2 stackslots -> check if used anyway! */
3098                         ret = lsra_test_pop_from_stack(ls, rd,src, values);
3099                         ret = lsra_test_pop_from_stack(ls, rd,src->prev, values);
3100                         break;
3101
3102                         /* pop 2 push 0 branch */
3103
3104                 case ICMD_IF_ICMPEQ: /* stack (v1,v2) -> branch(v1,v2) */
3105                 case ICMD_IF_ICMPNE:
3106                 case ICMD_IF_ICMPLT:
3107                 case ICMD_IF_ICMPGE:
3108                 case ICMD_IF_ICMPGT:
3109                 case ICMD_IF_ICMPLE:
3110
3111                 case ICMD_IF_LCMPEQ:
3112                 case ICMD_IF_LCMPNE:
3113                 case ICMD_IF_LCMPLT:
3114                 case ICMD_IF_LCMPGE:
3115                 case ICMD_IF_LCMPGT:
3116                 case ICMD_IF_LCMPLE:
3117
3118                 case ICMD_IF_ACMPEQ:
3119                 case ICMD_IF_ACMPNE:
3120                         ret = lsra_test_from_stack(ls, rd, src, values);           /* stack -> value*/
3121                         ret = lsra_test_from_stack(ls, rd, src->prev, values); /* stack -> objref*/
3122                         break;
3123
3124                         /* pop 2 push 0 */
3125
3126                 case ICMD_PUTFIELD: /* stack(objref,value) -> objref->method=value */
3127
3128                 case ICMD_IASTORECONST:
3129                 case ICMD_LASTORECONST:
3130                 case ICMD_AASTORECONST:
3131                 case ICMD_BASTORECONST:
3132                 case ICMD_CASTORECONST:
3133                 case ICMD_SASTORECONST:
3134                         ret = lsra_test_from_stack(ls, rd, src, values);           /* stack -> value*/
3135                         ret = lsra_test_from_stack(ls, rd, src->prev, values); /* stack -> objref*/
3136                         break;
3137
3138                         /* pop 0 push 1 dup */
3139                         /* merge dupped vars??? */
3140                 case ICMD_DUP: /* src == dst->prev, src -> dst */
3141                         /* ret = lsra_test_from_stack(ls, rd, src,b_index,iindex);*/ /* just inc usage count? */
3142                         ret = lsra_test_new_stack(ls, rd,dst, values);
3143                         break;
3144
3145                         /* pop 0 push 2 dup */
3146                                         
3147                 case ICMD_DUP2: 
3148                         /* ret = lsra_test_from_stack(ls, rd, src,b_index,iindex); */ /* just inc usage count? */
3149                         /* ret = lsra_test_from_stack(ls, rd, src->prev,b_index,iindex); */ /* just inc usage count? */
3150                         ret = lsra_test_new_stack(ls, rd,dst->prev, values);
3151                         ret = lsra_test_new_stack(ls, rd,dst, values); 
3152                         break;
3153
3154                         /* pop 2 push 3 dup */
3155                                         
3156                 case ICMD_DUP_X1:
3157                         ret = lsra_test_from_stack(ls, rd, src, values); 
3158                         ret = lsra_test_from_stack(ls, rd, src->prev, values);
3159                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev, values);
3160                         ret = lsra_test_new_stack(ls, rd,dst->prev, values);
3161                         ret = lsra_test_new_stack(ls, rd,dst, values); 
3162                         break;
3163
3164                         /* pop 3 push 4 dup */
3165                                         
3166                 case ICMD_DUP_X2:
3167                         ret = lsra_test_from_stack(ls, rd, src, values); 
3168                         ret = lsra_test_from_stack(ls, rd, src->prev, values); 
3169                         ret = lsra_test_from_stack(ls, rd, src->prev->prev, values); 
3170                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev->prev, values);
3171                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev, values);
3172                         ret = lsra_test_new_stack(ls, rd,dst->prev, values);
3173                         ret = lsra_test_new_stack(ls, rd,dst, values); 
3174                         break;
3175
3176                         /* pop 3 push 5 dup */
3177                                         
3178                 case ICMD_DUP2_X1:
3179                         ret = lsra_test_from_stack(ls, rd, src, values); 
3180                         ret = lsra_test_from_stack(ls, rd, src->prev, values); 
3181                         ret = lsra_test_from_stack(ls, rd, src->prev->prev, values); 
3182                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev->prev->prev, values);
3183                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev->prev, values);
3184                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev, values);
3185                         ret = lsra_test_new_stack(ls, rd,dst->prev, values);
3186                         ret = lsra_test_new_stack(ls, rd,dst, values); 
3187                         break;
3188
3189                         /* pop 4 push 6 dup */
3190                                         
3191                 case ICMD_DUP2_X2:
3192                         ret = lsra_test_from_stack(ls, rd, src, values); 
3193                         ret = lsra_test_from_stack(ls, rd, src->prev, values); 
3194                         ret = lsra_test_from_stack(ls, rd, src->prev->prev, values); 
3195                         ret = lsra_test_from_stack(ls, rd, src->prev->prev->prev, values); 
3196                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev->prev->prev->prev, values);
3197                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev->prev->prev, values);
3198                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev->prev, values);
3199                         ret = lsra_test_new_stack(ls, rd,dst->prev->prev, values);
3200                         ret = lsra_test_new_stack(ls, rd,dst->prev, values);
3201                         ret = lsra_test_new_stack(ls, rd,dst, values); 
3202
3203                         break;
3204
3205                         /* pop 2 push 2 swap */
3206                                         
3207                 case ICMD_SWAP:
3208                         ret = lsra_test_from_stack(ls, rd, src, values); 
3209                         ret = lsra_test_from_stack(ls, rd, src->prev, values);
3210                         ret = lsra_test_new_stack(ls, rd,dst->prev, values);
3211                         ret = lsra_test_new_stack(ls, rd,dst, values);
3212
3213                         break;
3214
3215                         /* pop 2 push 1 */
3216                                         
3217                 case ICMD_IADD:
3218                 case ICMD_ISUB:
3219                 case ICMD_IMUL:
3220                 case ICMD_IDIV:
3221                 case ICMD_IREM:
3222
3223                 case ICMD_ISHL:
3224                 case ICMD_ISHR:
3225                 case ICMD_IUSHR:
3226                 case ICMD_IAND:
3227                 case ICMD_IOR:
3228                 case ICMD_IXOR:
3229
3230                 case ICMD_LADD:
3231                 case ICMD_LSUB:
3232                 case ICMD_LMUL:
3233                 case ICMD_LDIV:
3234                 case ICMD_LREM:
3235
3236                 case ICMD_LOR:
3237                 case ICMD_LAND:
3238                 case ICMD_LXOR:
3239
3240                 case ICMD_LSHL:
3241                 case ICMD_LSHR:
3242                 case ICMD_LUSHR:
3243
3244                 case ICMD_FADD:
3245                 case ICMD_FSUB:
3246                 case ICMD_FMUL:
3247                 case ICMD_FDIV:
3248                 case ICMD_FREM:
3249
3250                 case ICMD_DADD:
3251                 case ICMD_DSUB:
3252                 case ICMD_DMUL:
3253                 case ICMD_DDIV:
3254                 case ICMD_DREM:
3255
3256                 case ICMD_LCMP:
3257                 case ICMD_FCMPL:
3258                 case ICMD_FCMPG:
3259                 case ICMD_DCMPL:
3260                 case ICMD_DCMPG:
3261                         ret = lsra_test_from_stack(ls, rd, src, values);
3262                         ret = lsra_test_from_stack(ls, rd, src->prev, values);
3263                         ret = lsra_test_new_stack(ls, rd,dst, values);
3264                         break;
3265
3266                         /* pop 1 push 1 */
3267                 case ICMD_IADDCONST:
3268                 case ICMD_ISUBCONST:
3269                 case ICMD_IMULCONST:
3270                 case ICMD_IMULPOW2:
3271                 case ICMD_IDIVPOW2:
3272                 case ICMD_IREMPOW2:
3273                 case ICMD_IANDCONST:
3274                 case ICMD_IORCONST:
3275                 case ICMD_IXORCONST:
3276                 case ICMD_ISHLCONST:
3277                 case ICMD_ISHRCONST:
3278                 case ICMD_IUSHRCONST:
3279
3280                 case ICMD_LADDCONST:
3281                 case ICMD_LSUBCONST:
3282                 case ICMD_LMULCONST:
3283                 case ICMD_LMULPOW2:
3284                 case ICMD_LDIVPOW2:
3285                 case ICMD_LREMPOW2:
3286                 case ICMD_LANDCONST:
3287                 case ICMD_LORCONST:
3288                 case ICMD_LXORCONST:
3289                 case ICMD_LSHLCONST:
3290                 case ICMD_LSHRCONST:
3291                 case ICMD_LUSHRCONST:
3292
3293                 case ICMD_IFEQ_ICONST:
3294                 case ICMD_IFNE_ICONST:
3295                 case ICMD_IFLT_ICONST:
3296                 case ICMD_IFGE_ICONST:
3297                 case ICMD_IFGT_ICONST:
3298                 case ICMD_IFLE_ICONST:
3299
3300                 case ICMD_INEG:
3301                 case ICMD_INT2BYTE:
3302                 case ICMD_INT2CHAR:
3303                 case ICMD_INT2SHORT:
3304                 case ICMD_LNEG:
3305                 case ICMD_FNEG:
3306                 case ICMD_DNEG:
3307
3308                 case ICMD_I2L:
3309                 case ICMD_I2F:
3310                 case ICMD_I2D:
3311                 case ICMD_L2I:
3312                 case ICMD_L2F:
3313                 case ICMD_L2D:
3314                 case ICMD_F2I:
3315                 case ICMD_F2L:
3316                 case ICMD_F2D:
3317                 case ICMD_D2I:
3318                 case ICMD_D2L:
3319                 case ICMD_D2F:
3320
3321                 case ICMD_CHECKCAST:
3322                 case ICMD_ARRAYCHECKCAST:
3323
3324                 case ICMD_ARRAYLENGTH:
3325                 case ICMD_INSTANCEOF:
3326
3327                 case ICMD_NEWARRAY:
3328                 case ICMD_ANEWARRAY:
3329
3330                 case ICMD_GETFIELD:
3331                         ret = lsra_test_from_stack(ls, rd, src, values);
3332                         ret = lsra_test_new_stack(ls, rd,dst, values);
3333                         break;
3334
3335                         /* pop 0 push 1 */
3336                                         
3337                 case ICMD_GETSTATIC:
3338                 case ICMD_NEW:
3339                         ret = lsra_test_new_stack(ls, rd,dst, values);
3340                         break;
3341
3342                         /* pop many push any */
3343                 case ICMD_INVOKEVIRTUAL:
3344                 case ICMD_INVOKESPECIAL:
3345                 case ICMD_INVOKESTATIC:
3346                 case ICMD_INVOKEINTERFACE:
3347 #error XXX FIXME TWISTI: use md->paramcount (2005/10/4)
3348                         i = iptr->op1;
3349                         while (--i >= 0) {
3350                                 ret = lsra_test_from_stack(ls, rd, src, values);
3351                                 src = src->prev;
3352                         }
3353                         if (((unresolved_method *) iptr->target)->methodref->parseddesc.md->returntype.type != TYPE_VOID)        
3354                                 ret = lsra_test_new_stack(ls, rd,dst, values);
3355                         break;
3356
3357                 case ICMD_BUILTIN:
3358                         i = iptr->op1;
3359                         while (--i >= 0) {
3360                                 ret = lsra_test_from_stack(ls, rd, src, values);
3361                                 src = src->prev;
3362                         }
3363                         if (((builtintable_entry *) iptr->val.a)->md->returntype.type != TYPE_VOID)
3364                                 ret = lsra_test_new_stack(ls, rd,dst, values);
3365                         break;
3366
3367                 case ICMD_MULTIANEWARRAY:
3368                         i = iptr->op1;
3369                         while (--i >= 0) {
3370                                 ret = lsra_test_from_stack(ls, rd, src, values);
3371                                 src = src->prev;
3372                         }
3373                         ret = lsra_test_new_stack(ls, rd, dst, values);
3374                         break;
3375
3376                 default:
3377                         printf("ICMD %d at %d\n", iptr->opc, (int)(iptr - m->instructions));
3378                         { log_text("Missing ICMD code during register allocation"); assert(0); }
3379                 } /* switch */
3380         }
3381
3382         if (ret != -1) {
3383                 printf("BB: %i IIndex %i \n", b_index, iindex);
3384         } else {
3385
3386                 i=0;
3387
3388                 for (succ = ls->succ[b_index]; succ != NULL; succ = succ->next)
3389                         i++;
3390
3391                 if (end_of_method) {
3392                         /* XRETURN or ATHROW encountered */
3393                         /* take a 50% chance to end testing */
3394                         /* otherwise follow successor (possible exception handler) */
3395                         if (rand() % 2) i = 0;
3396                 }
3397
3398                 if (i != 0) {
3399                         j = rand() % i;
3400
3401                         for (i=0, succ = ls->succ[b_index]; i!=j; i++, succ=succ->next);
3402
3403                         if ( (ret=_test_lifetimes(m, ls, rd, succ->value, values, rec_depth + 1)) != -1) {
3404                                 printf("[BB %3i IIndex %3i]",b_index, iindex);
3405                         }
3406                 }
3407         }
3408         return ret;
3409 }
3410
3411 void test_lifetimes( methodinfo *m, lsradata *ls, registerdata *rd)
3412 {
3413         int *values, i, j, p, t;
3414         int v_max,ret;
3415         methoddesc *md = m->parseddesc;
3416
3417         v_max = rd->memuse + INT_REG_CNT + FLT_REG_CNT;
3418
3419         if ( (values = MNEW(int, v_max)) == NULL )
3420                  { log_text("test_lifetimes: out of memory\n"); assert(0); }
3421
3422         ret = -1;
3423         for (j=0; (j < 100) && (ret == -1); j++ ) {
3424                 for (i=0; i < v_max; i++) values[i]=VS;
3425
3426                 for (p = 0, i = 0; p < md->paramcount; p++) {
3427                         t = md->paramtypes[p].type;
3428
3429                         if (rd->locals[i][t].type >= 0)
3430                                 lsra_test_local( ls, rd, i, t, LSRA_STORE, values);
3431                 
3432                         i++;
3433                         if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
3434                                 i++;
3435                 }  /* end for */
3436
3437                 if ((ret=_test_lifetimes(m, ls, rd, 0, values, 0)) != -1) {
3438                         printf("\n");
3439                 }
3440         }
3441
3442
3443         MFREE(values, int, v_max);
3444 }
3445 #endif
3446
3447 /*
3448  * These are local overrides for various environment variables in Emacs.
3449  * Please do not remove this and leave it at the end of the file, where
3450  * Emacs will automagically detect them.
3451  * ---------------------------------------------------------------------
3452  * Local variables:
3453  * mode: c
3454  * indent-tabs-mode: t
3455  * c-basic-offset: 4
3456  * tab-width: 4
3457  * End:
3458  * vim:noexpandtab:sw=4:ts=4:
3459  */