CACAO
lsra.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/lsra.inc - linear scan register allocator
2 
3  Copyright (C) 2005-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 
31 #include "arch.hpp"
32 #include "md-abi.hpp"
33 
34 #include "mm/dumpmemory.hpp"
35 
36 #include "toolbox/bitvector.hpp"
37 
38 #include "vm/statistics.hpp"
39 #include "vm/options.hpp"
40 #include "vm/method.hpp"
41 #include "vm/descriptor.hpp"
42 
43 #include "vm/jit/abi.hpp"
44 #include "vm/jit/code.hpp"
45 #include "vm/jit/reg.hpp"
46 #include "vm/jit/jit.hpp"
47 
51 
53 
54 #include "toolbox/logging.hpp"
55 
56 STAT_DECLARE_VAR(int,count_locals_conflicts,0)
57 
58 extern const char *string_java_lang_InternalError;
59 /* function prototypes */
60 void lsra_setup(jitdata *);
61 void lsra_main(jitdata *);
62 #ifdef LSRA_DEBUG_VERBOSE
64 void print_lifetimes(jitdata *, int *, int);
65 void print_all_lifetimes(jitdata *);
66 #endif
67 void lsra_reg_setup(jitdata *,struct lsra_register *,
68  struct lsra_register *);
69 
70 void lsra_calc_lifetime_length(jitdata *);
71 
72 void _lsra_main( jitdata *, int *, int, struct lsra_register *,
73  int *);
74 void lsra_expire_old_intervalls(jitdata *, struct lifetime *,
75  struct lsra_register *);
76 void spill_at_intervall(jitdata *, struct lifetime *);
77 void lsra_add_active(struct lifetime *, struct lifetime **, int *);
78 void _lsra_expire_old_intervalls(jitdata *, struct lifetime *,
79  struct lsra_register *,
80  struct lifetime **, int *);
81 void _spill_at_intervall(struct lifetime *, struct lifetime **, int *);
82 void lsra_alloc(jitdata *, int *, int,
83  int *);
84 int lsra_getmem(struct lifetime *, struct freemem *, int *);
85 struct freemem *lsra_getnewmem(int *);
86 
87 void lsra(jitdata *jd) {
88  methodinfo *m;
89  codegendata *cd;
90  registerdata *rd;
91  lsradata *ls;
92 #if defined(ENABLE_STATISTICS)
93  int locals_start;
94  int i,j;
95 #endif
96 #if defined(LSRA_DEBUG_CHECK)
97 #if 0
98  int b_index;
99  stackelement_t* in,out;
100  int ind, outd;
101 #endif
102 #endif
103 
104  m = jd->m;
105  cd = jd->cd;
106  rd = jd->rd;
107  ls = jd->ls;
108 
109 #if defined(LSRA_DEBUG_CHECK)
110 #if 0
111  b_index = 0;
112  while (b_index < jd->basicblockcount ) {
113 
114  if (jd->basicblocks[b_index].flags >= basicblock::REACHED) {
115 
116  in=m->basicblocks[b_index].instack;
117  ind=m->basicblocks[b_index].indepth;
118  for (;ind != 0;in=in->prev, ind--) {
119  /* ARGVAR or LOCALVAR in instack is ok*/
120 #if defined(LSRA_DEBUG_VERBOSE)
121  if (compileverbose) {
122  if (in->varkind == ARGVAR) printf("ARGVAR in instack: \n");
123  if (in->varkind == LOCALVAR)
124  printf("LOCALVAR in instack\n");
125  }
126 #endif
127  }
128  out=m->basicblocks[b_index].outstack;
129  outd=m->basicblocks[b_index].outdepth;
130  for (;outd != 0;out=out->prev, outd--) {
131  if (out->varkind == ARGVAR)
132  { log_text("ARGVAR in outstack\n"); assert(0); }
133  if (out->varkind == LOCALVAR)
134  { log_text("LOCALVAR in outstack\n"); assert(0); }
135  }
136  }
137  b_index++;
138  }
139 #endif
140 #endif
141 
142 #if defined(LSRA_DEBUG_CHECK) || defined(LSRA_DEBUG_VERBOSE)
143 #if defined(LSRA_DEBUG_VERBOSE)
144  if (compileverbose) {
145  printf("%s %s ", m->clazz->name.begin(), m->name.begin());
146  if (code_is_leafmethod(jd->code))
147  printf("**Leafmethod**");
148  printf("\n");
149  }
150 #endif
151  if (strcmp(m->clazz->name.begin(),"java/lang/String")==0)
152  if (strcmp(m->name.begin(),"toLowerCase")==0)
153 #if defined(LSRA_DEBUG_VERBOSE)
154  if (compileverbose)
155  printf("12-------------------12\n");
156 #else
157  { int dummy=1; dummy++; }
158 #endif
159 #endif
160 
161  lsra_setup(jd);
162 
163 #if defined(ENABLE_STATISTICS)
164  /* find conflicts between locals for statistics */
165  if (opt_stat) {
166  /* local Variable Lifetimes are at the end of the lifetime array and */
167  /* have v_index >= 0 */
168  for (locals_start = ls->lifetimecount-1; (locals_start >=0) &&
169  (ls->lifetime[ls->lt_used[locals_start]].v_index >= 0);
170  locals_start--);
171  for (i=locals_start + 1; i < ls->lifetimecount; i++)
172  for (j=i+1; j < ls->lifetimecount; j++)
173  if ( !((ls->lifetime[ls->lt_used[i]].i_end
174  < ls->lifetime[ls->lt_used[j]].i_start)
175  || (ls->lifetime[ls->lt_used[j]].i_end <
176  ls->lifetime[ls->lt_used[i]].i_start)) )
177  count_locals_conflicts += 2;
178  }
179 #endif
180  /* Run LSRA */
181  lsra_main(jd);
182 
183  fflush(stdout);
184 }
185 
186 
187 void lsra_setup(jitdata *jd)
188 {
189  methodinfo *m;
190  codegendata *cd;
191  registerdata *rd;
192  lsradata *ls;
193 
194 #if defined(ENABLE_LOOPS)
195  /* Loop optimization "destroys" the basicblock array */
196  /* TODO: work with the basicblock list */
197  if (opt_loops) {
198  log_text("lsra not possible with loop optimization\n");
199  exit(1);
200  }
201 #endif
202 
203  m = jd->m;
204  cd = jd->cd;
205  rd = jd->rd;
206  ls = jd->ls;
207 
208 #ifdef LSRA_DEBUG_VERBOSE
209  if (compileverbose) {
210  printf("Lifetimes after LifenessAnalyse: \n");
212  }
213 #endif
214 
216 
217 #ifdef LSRA_DEBUG_VERBOSE
218  if (compileverbose) {
219  printf("Basicblockcount: %4i\n",ls->basicblockcount);
220  }
221 #endif
222 }
223 
224 void lsra_reg_setup(jitdata *jd,
225  struct lsra_register *int_reg,
226  struct lsra_register *flt_reg ) {
227  int i, j, iarg, farg;
228  int int_sav_top;
229  int flt_sav_top;
230  bool *fltarg_used, *intarg_used;
231  methoddesc *md;
232  methodinfo *m;
233  registerdata *rd;
234 
235  m = jd->m;
236  rd = jd->rd;
237  md = m->parseddesc;
238 
239  int_reg->nregdesc = nregdescint;
240  flt_reg->nregdesc = nregdescfloat;
241  if (code_is_leafmethod(jd->code)) {
242  /* Temp and Argumentregister can be used as saved registers */
243 
245  int_reg->sav_reg = DMNEW(int, int_reg->sav_top);
246  int_reg->tmp_reg = NULL;
247  int_reg->tmp_top = -1;
249  flt_reg->sav_reg = DMNEW(int, flt_reg->sav_top);
250  flt_reg->tmp_reg = NULL;
251  flt_reg->tmp_top = -1;
252 
253  /* additionaly precolour registers for Local Variables acting as */
254  /* Parameters */
255 
256  farg = FLT_ARG_CNT;
257  iarg = INT_ARG_CNT;
258 
259  intarg_used = DMNEW(bool, INT_ARG_CNT);
260  for (i=0; i < INT_ARG_CNT; i++)
261  intarg_used[i]=false;
262 
263  fltarg_used = DMNEW(bool, FLT_ARG_CNT);
264  for (i=0; i < FLT_ARG_CNT; i++)
265  fltarg_used[i]=false;
266 
267  int_sav_top=int_reg->sav_top;
268  flt_sav_top=flt_reg->sav_top;
269 
270  for (i=0; (i < md->paramcount); i++) {
271  if (!md->params[i].inmemory) {
272  if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
273 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
274  if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
275  int_reg->sav_reg[--int_sav_top] =
276  GET_HIGH_REG(md->params[i].regoff);
277  intarg_used[GET_HIGH_REG(md->params[i].regoff)]=true;
278  /*used -> don't copy later on */
279  int_reg->sav_reg[--int_sav_top] =
280  GET_LOW_REG(md->params[i].regoff);
281  intarg_used[GET_LOW_REG(md->params[i].regoff)]=true;
282  /*used -> don't copy later on */
283  } else
284 #endif
285  { /* !IS_2_WORD_TYPE(md->paramtypes[i].type */
286  int_reg->sav_reg[--int_sav_top] =
287  md->params[i].regoff;
288  intarg_used[md->params[i].regoff]=true;
289  /*used -> don't copy later on */
290  }
291  }
292 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
293  /* do not precolour float arguments if they are passed in */
294  /* integer registers. But these integer argument registers */
295  /* still be used in the method! */
296  else { /* IS_FLT_DBL_TYPE(md->paramtypes[i].type */
297  flt_reg->sav_reg[--flt_sav_top] =
298  md->params[i].regoff;
299  fltarg_used[md->params[i].regoff]=true;
300  }
301 #endif
302 
303  }
304  }
305 
306  /* copy rest of argument registers to flt_reg->sav_reg and */
307  /* int_reg->sav_reg; */
308  for (i=0; i < INT_ARG_CNT; i++)
309  if (!intarg_used[i])
310  int_reg->sav_reg[--int_sav_top]=i;
311  for (i=0; i < FLT_ARG_CNT; i++)
312  if (!fltarg_used[i])
313  flt_reg->sav_reg[--flt_sav_top]=i;
314 
315  /* copy temp registers to flt_reg->sav_reg and int_reg->sav_reg */
316  for (i=0; i < INT_TMP_CNT; i++)
317  int_reg->sav_reg[--int_sav_top]=rd->tmpintregs[i];
318  for (i=0; i < FLT_TMP_CNT; i++)
319  flt_reg->sav_reg[--flt_sav_top]=rd->tmpfltregs[i];
320 
321  } else {
322  /* non leaf method -> use Argument Registers [arg[int|flt]reguse */
323  /* ... [INT|FLT]_ARG_CNT[ as temp reg */
324  /* divide temp and saved registers */
325 
326  int argintreguse, argfltreguse;
327 
328  /* with Locals as non SAVEDVAR, the used arg[int|flt] as in params */
329  /* of the method itself have to be regarded, or mismatch before */
330  /* block 0 with parameter copy could happen! */
331 
332  argintreguse = MAX(rd->argintreguse, md->argintreguse);
333  argfltreguse = MAX(rd->argfltreguse, md->argfltreguse);
334 
335  int_sav_top = int_reg->sav_top = INT_SAV_CNT;
336  int_reg->sav_reg = DMNEW(int, int_reg->sav_top);
337  int_reg->tmp_top = INT_TMP_CNT +
338  MAX(0, (INT_ARG_CNT - argintreguse));
339  int_reg->tmp_reg = DMNEW(int, int_reg->tmp_top);
340 
341  flt_sav_top =flt_reg->sav_top = FLT_SAV_CNT;
342  flt_reg->sav_reg = DMNEW(int, flt_reg->sav_top);
343  flt_reg->tmp_top = FLT_TMP_CNT +
344  MAX(0 , (FLT_ARG_CNT - argfltreguse));
345  flt_reg->tmp_reg = DMNEW(int, flt_reg->tmp_top);
346 
347  /* copy temp and unused argument registers to flt_reg->tmp_reg and */
348  /* int_reg->tmp_reg */
349 
350  for (i=0; i < INT_TMP_CNT; i++)
351  int_reg->tmp_reg[i]=rd->tmpintregs[i];
352 
353  /* quick and dirty patch for the drop of rd->argxxxreg[] - but will */
354  /* work anyhow on i386, !! has to be made "real" for other archs */
355 
356  for (j = argintreguse; j < INT_ARG_CNT; j++, i++)
357  int_reg->tmp_reg[i]=j;
358  for (i=0; i < FLT_TMP_CNT; i++)
359  flt_reg->tmp_reg[i]=rd->tmpfltregs[i];
360 
361  /* quick and dirty patch for the drop of rd->argxxxreg[] - but will */
362  /* work anyhow on i386, !! has to be made "real" for other archs */
363 
364  for (j = argfltreguse; j < FLT_ARG_CNT; j++, i++)
365  flt_reg->tmp_reg[i]=j;
366  }
367 
368  /* now copy saved registers to flt_reg->sav_reg and int_reg->sav_reg */
369  for (i = INT_SAV_CNT-1; i >= 0; i--)
370  int_reg->sav_reg[--int_sav_top]=rd->savintregs[i];
371  for (i = FLT_SAV_CNT-1; i >= 0; i--)
372  flt_reg->sav_reg[--flt_sav_top]=rd->savfltregs[i];
373  /* done */
374 }
375 
376 void lsra_insertion( struct lsradata *ls, int *a, int lo, int hi) {
377  int i,j,t,tmp;
378 
379  for (i=lo+1; i<=hi; i++) {
380  j=i;
381  t=ls->lifetime[a[j]].i_start;
382  tmp = a[j];
383  while ((j>lo) && (ls->lifetime[a[j-1]].i_start > t)) {
384  a[j]=a[j-1];
385  j--;
386  }
387  a[j]=tmp;
388  }
389 }
390 
391 void lsra_qsort( struct lsradata *ls, int *a, int lo, int hi) {
392  int i,j,x,tmp;
393  if (lo < hi) {
394  if ( (lo+5)<hi) {
395  i = lo;
396  j = hi;
397  x = ls->lifetime[a[(lo+hi)/2]].i_start;
398 
399  while (i <= j) {
400  while (ls->lifetime[a[i]].i_start < x) i++;
401  while (ls->lifetime[a[j]].i_start > x) j--;
402  if (i <= j) {
403  /* exchange a[i], a[j] */
404  tmp = a[i];
405  a[i] = a[j];
406  a[j] = tmp;
407 
408  i++;
409  j--;
410  }
411  }
412 
413  if (lo < j) lsra_qsort( ls, a, lo, j);
414  if (i < hi) lsra_qsort( ls, a, i, hi);
415  } else
416  lsra_insertion(ls, a, lo, hi);
417  }
418 }
419 
420 void lsra_param_sort(struct lsradata *ls, int *lifetime, int lifetime_count) {
421 
422  int param_count;
423  int i,j,tmp;
424 
425  /* count number of parameters ( .i_start == 0) */
426  for (param_count=0; (param_count < lifetime_count) &&
427  (ls->lifetime[lifetime[param_count]].i_start == 0); param_count++);
428 
429  if (param_count > 0) {
430  /* now sort the parameters by v_index */
431  for (i=0; i < param_count -1; i++)
432  for (j=i+1; j < param_count; j++)
433  if ( ls->lifetime[lifetime[i]].v_index >
434  ls->lifetime[lifetime[j]].v_index) {
435  /* swap */
436  tmp = lifetime[i];
437  lifetime[i]=lifetime[j];
438  lifetime[j]=tmp;
439  }
440  }
441 }
442 
443 void lsra_main(jitdata *jd)
444 {
445 #ifdef LSRA_DEBUG_VERBOSE
446  int i;
447 #endif
448  int lsra_mem_use;
449  int lsra_reg_use;
450  struct lsra_register flt_reg, int_reg;
451  methodinfo *m;
452  registerdata *rd;
453  lsradata *ls;
454 
455  ls = jd->ls;
456  m = jd->m;
457  rd = jd->rd;
458 
459 /* sort lifetimes by increasing start */
460  lsra_qsort( ls, ls->lt_mem, 0, ls->lt_mem_count - 1);
461  lsra_qsort( ls, ls->lt_int, 0, ls->lt_int_count - 1);
462  lsra_qsort( ls, ls->lt_flt, 0, ls->lt_flt_count - 1);
463 /* sort local vars used as parameter */
464  lsra_param_sort( ls, ls->lt_int, ls->lt_int_count);
465  lsra_param_sort( ls, ls->lt_flt, ls->lt_flt_count);
466  lsra_reg_setup(jd, &int_reg, &flt_reg);
467 
468 #ifdef LSRA_DEBUG_VERBOSE
469  if (compileverbose) {
470  printf("INTSAV REG: ");
471  for (i=0; i<int_reg.sav_top; i++)
472  printf("%2i ",int_reg.sav_reg[i]);
473  printf("\nINTTMP REG: ");
474  for (i=0; i<int_reg.tmp_top; i++)
475  printf("%2i ",int_reg.tmp_reg[i]);
476  printf("\nFLTSAV REG: ");
477  for (i=0; i<flt_reg.sav_top; i++)
478  printf("%2i ",flt_reg.sav_reg[i]);
479  printf("\nFLTTMP REG: ");
480  for (i=0; i<flt_reg.tmp_top; i++)
481  printf("%2i ",flt_reg.tmp_reg[i]);
482  printf("\n");
483  }
484 #endif
485 
486  ls->active_tmp = DMNEW( struct lifetime *, MAX(INT_REG_CNT, FLT_REG_CNT));
487  ls->active_sav = DMNEW( struct lifetime *, MAX(INT_REG_CNT, FLT_REG_CNT));
488 
489  lsra_reg_use=INT_SAV_CNT; /* init to no saved reg used... */
490  _lsra_main(jd, ls->lt_int, ls->lt_int_count, &int_reg,
491  &lsra_reg_use);
492  if (lsra_reg_use > INT_SAV_CNT) lsra_reg_use=INT_SAV_CNT;
493  rd->savintreguse = lsra_reg_use;
494 
495  lsra_reg_use = FLT_SAV_CNT; /* no saved reg used... */
496 
497  _lsra_main(jd, ls->lt_flt, ls->lt_flt_count, &flt_reg, &lsra_reg_use);
498  if (lsra_reg_use > FLT_SAV_CNT) lsra_reg_use=FLT_SAV_CNT;
499 
500  rd->savfltreguse=lsra_reg_use;
501 
502  /* rd->memuse was already set in stack.c to allocate stack space for */
503  /* passing arguments to called methods */
504 #if defined(__I386__)
505  if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
506  /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
507  if (rd->memuse < 1)
508  rd->memuse = 1;
509  }
510 #endif
511 
512  lsra_mem_use = rd->memuse; /* Init with memuse from stack.c */
513 
514  lsra_alloc(jd, ls->lt_mem, ls->lt_mem_count, &lsra_mem_use);
515  lsra_alloc(jd, ls->lt_int, ls->lt_int_count, &lsra_mem_use);
516  lsra_alloc(jd, ls->lt_flt, ls->lt_flt_count, &lsra_mem_use);
517 
518  rd->memuse=lsra_mem_use;
519 
520 #ifdef LSRA_DEBUG_VERBOSE
521  if (compileverbose) {
522  printf("Int RA complete \n");
523  printf("Lifetimes after splitting int: \n");
524  print_lifetimes(jd, ls->lt_int, ls->lt_int_count);
525 
526  printf("Flt RA complete \n");
527  printf("Lifetimes after splitting flt:\n");
528  print_lifetimes(jd, ls->lt_flt, ls->lt_flt_count);
529 
530  printf("Rest RA complete \n");
531  printf("Lifetimes after leftt:\n");
532  print_lifetimes(jd, ls->lt_mem, ls->lt_mem_count);
533 
534  printf("jd->varcount: %i jd->vartop %i\n", jd->varcount, jd->vartop);
535  }
536 #endif
537 }
538 
539 void lsra_alloc(jitdata *jd, int *lifet, int lifetimecount, int *mem_use)
540 {
541  int flags,regoff;
542  struct lifetime *lt;
543  struct freemem *fmem;
544  int lt_index;
545  methodinfo *m;
546  registerdata *rd;
547  lsradata *ls;
548 
549  m = jd->m;
550  rd = jd->rd;
551  ls = jd->ls;
552 
553  fmem=DNEW(struct freemem);
554  fmem->off=-1;
555  fmem->next=NULL;
556 
557  for (lt_index = 0; lt_index < lifetimecount; lt_index ++) {
558  lt = ls->lifetime + lifet[lt_index];
559 #ifdef LSRA_MEMORY
560  lt->reg=-1;
561 #endif
562  if (lt->regoff == -1) {
563  flags = INMEMORY;
564  regoff = lsra_getmem(lt, fmem, mem_use);
565  } else {
566  flags = lt->savedvar;
567  regoff = lt->regoff;
568  }
569 
570  lt->regoff = regoff;
571  VAR(lt->v_index)->vv.regoff = regoff;
572  VAR(lt->v_index)->flags = flags;
573  }
574 }
575 
576 int lsra_getmem(struct lifetime *lt, struct freemem *fmem, int *mem_use)
577 {
578  struct freemem *fm, *p;
579 
580  /* no memmory allocated till now, or all other are still live */
581  if ((fmem->next == NULL) || (fmem->next->end > lt->i_start)) {
582 /* if (1) { */
583  fm=lsra_getnewmem(mem_use);
584  } else {
585  /* Speicherstelle frei */
586  fm=fmem->next;
587  fmem->next=fm->next;
588  fm->next=NULL;
589  }
590  fm->end=lt->i_end;
591  for (p=fmem; (p->next!=NULL) && (p->next->end < fm->end); p=p->next);
592  fm->next=p->next;
593  p->next=fm;
594  /* HACK: stackslots are 8 bytes on all architectures for now, I hope.
595  * -- pm
596  */
597  return fm->off * 8;
598 }
599 
600 struct freemem *lsra_getnewmem(int *mem_use)
601 {
602  struct freemem *fm;
603 
604  fm=DNEW(struct freemem);
605  fm->next=NULL;
606  fm->off=*mem_use;
607  (*mem_use)++;
608  return fm;
609 }
610 
611 void _lsra_main( jitdata *jd, int *lifet, int lifetimecount,
612  struct lsra_register *reg, int *reg_use)
613 {
614  struct lifetime *lt;
615  int lt_index;
616  int reg_index;
617  int regsneeded;
618  bool temp; /* reg from temp registers (true) or saved registers (false) */
619  methodinfo *m;
620  lsradata *ls;
621 
622  m = jd->m;
623  ls = jd->ls;
624 
625 #if !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
626  regsneeded = 0;
627 #endif
628  if ((reg->tmp_top+reg->sav_top) == 0) {
629 
630  /* no registers available */
631  for (lt_index = 0; lt_index < lifetimecount; lt_index++)
632  ls->lifetime[lifet[lt_index]].regoff = -1;
633  return;
634  }
635 
636  ls->active_tmp_top = 0;
637  ls->active_sav_top = 0;
638 
639  for (lt_index = 0; lt_index < lifetimecount; lt_index++) {
640  lt = &(ls->lifetime[lifet[lt_index]]);
641 
642 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
643  regsneeded = (lt->type == TYPE_LNG)?1:0;
644 #endif
645 
646  lsra_expire_old_intervalls(jd, lt, reg);
647  reg_index = -1;
648  temp = false;
649 #ifdef LSRA_SAVEDVAR
650  lt->savedvar = SAVEDVAR;
651 #endif
652  if (lt->savedvar || code_is_leafmethod(jd->code)) {
653  /* use Saved Reg (in case of leafmethod all regs are saved regs) */
654  if (reg->sav_top > regsneeded) {
655 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
656  if (regsneeded)
657  reg_index = PACK_REGS(reg->sav_reg[--reg->sav_top],
658  reg->sav_reg[--reg->sav_top]);
659  else
660 #endif
661 
662  reg_index = reg->sav_reg[--reg->sav_top];
663  }
664  } else { /* use Temp Reg or if none is free a Saved Reg */
665  if (reg->tmp_top > regsneeded) {
666  temp = true;
667 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
668  if (regsneeded)
669  reg_index = PACK_REGS(reg->tmp_reg[--reg->tmp_top],
670  reg->tmp_reg[--reg->tmp_top]);
671  else
672 #endif
673  reg_index = reg->tmp_reg[--reg->tmp_top];
674  }
675  else
676  if (reg->sav_top > regsneeded) {
677 
678 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
679  if (regsneeded)
680  reg_index = PACK_REGS(reg->sav_reg[--reg->sav_top],
681  reg->sav_reg[--reg->sav_top]);
682  else
683 #endif
684  reg_index = reg->sav_reg[--reg->sav_top];
685  }
686  }
687  if (reg_index == -1) /* no reg is available anymore... -> spill */
688  spill_at_intervall(jd, lt);
689  else {
690  lt->regoff = reg_index;
691  if (temp)
692  lsra_add_active(lt, ls->active_tmp, &(ls->active_tmp_top));
693  else {
694  if (reg->sav_top<*reg_use) *reg_use=reg->sav_top;
695  lsra_add_active(lt, ls->active_sav, &(ls->active_sav_top));
696  }
697  }
698  }
699 }
700 
701 void lsra_add_active(struct lifetime *lt, struct lifetime **active,
702  int *active_top)
703 {
704  int i, j;
705 
706  for(i = 0; (i < *active_top) && (active[i]->i_end < lt->i_end); i++);
707 
708  for(j = *active_top; j > i; j--) active[j] = active[j-1];
709 
710  (*active_top)++;
711 
712  active[i] = lt;
713 
714 }
715 
716 void lsra_expire_old_intervalls(jitdata *jd,
717  struct lifetime *lt, struct lsra_register *reg)
718 {
719  _lsra_expire_old_intervalls(jd, lt, reg, jd->ls->active_tmp,
720  &(jd->ls->active_tmp_top));
721  _lsra_expire_old_intervalls(jd, lt, reg, jd->ls->active_sav,
722  &(jd->ls->active_sav_top));
723 }
724 
725 void _lsra_expire_old_intervalls(jitdata *jd, struct lifetime *lt,
726  struct lsra_register *reg,
727  struct lifetime **active, int *active_top)
728 {
729  int i, j, k;
730 
731  for(i = 0; i < *active_top; i++) {
732  if (active[i]->i_end > lt->i_start) break;
733 
734  /* make active[i]->reg available again */
735  if (code_is_leafmethod(jd->code)) {
736  /* leafmethod -> don't care about type -> put all again into */
737  /* reg->sav_reg */
738 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
739  if (active[i]->type == TYPE_LNG) {
740  reg->sav_reg[reg->sav_top++] = GET_LOW_REG(active[i]->reg);
741  reg->sav_reg[reg->sav_top++] = GET_HIGH_REG(active[i]->reg);
742  } else
743 #endif
744  reg->sav_reg[reg->sav_top++] = active[i]->regoff;
745  } else {
746  /* no leafmethod -> distinguish between temp and saved register */
747 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
748  if (active[i]->type == TYPE_LNG) {
749  /* no temp and saved regs are packed together, so looking at */
750  /* LOW_REG is sufficient */
751  if ( reg->nregdesc[ GET_LOW_REG(active[i]->reg)] == REG_SAV) {
752  reg->sav_reg[reg->sav_top++] = GET_LOW_REG(active[i]->reg);
753  reg->sav_reg[reg->sav_top++] = GET_HIGH_REG(active[i]->reg);
754  } else {
755  reg->tmp_reg[reg->tmp_top++] = GET_LOW_REG(active[i]->reg);
756  reg->tmp_reg[reg->tmp_top++] = GET_HIGH_REG(active[i]->reg);
757  }
758  } else
759 #endif
760  if ( reg->nregdesc[active[i]->regoff] == REG_SAV) {
761  reg->sav_reg[reg->sav_top++] = active[i]->regoff;
762  } else {
763  reg->tmp_reg[reg->tmp_top++] = active[i]->regoff;
764  }
765  }
766  }
767 
768  /* active[0..i[ is to be removed */
769  /* -> move [i..*active_top[ to [0..*active_top-i[ */
770  for(k = 0, j = i; (j < *active_top); k++,j++)
771  active[k] = active[j];
772 
773  (*active_top) -= i;
774 
775 }
776 
777 void spill_at_intervall(jitdata *jd, struct lifetime *lt )
778 {
779  lsradata *ls;
780 
781  ls = jd->ls;
782 
783  if (lt->savedvar || code_is_leafmethod(jd->code)) {
785  } else {
787  if (lt->regoff == -1) { /* kein tmp mehr frei gewesen */
789  }
790  }
791 }
792 
793 void _spill_at_intervall(struct lifetime *lt, struct lifetime **active,
794  int *active_top)
795 {
796  int i, j;
797 #if 0
798 #ifdef USAGE_COUNT
799  int u_min, i_min;
800 #endif /* USAGE_COUNT */
801 #endif /* 0 */
802 
803  if (*active_top == 0) {
804  lt->regoff = -1;
805  return;
806  }
807 
808  i = *active_top - 1;
809 #ifdef USAGE_COUNT
810 #if 0
811  /* find intervall which ends later or equal than than lt and has the */
812  /* lowest usagecount lower than lt */
813  i_min = -1;
814  u_min = lt->usagecount;
815  for (; (i >= 0) && (active[i]->i_end >= lt->i_end); i--) {
816  if (active[i]->usagecount < u_min) {
817  u_min = active[i]->usagecount;
818  i_min = i;
819  }
820  }
821 
822  if (i_min != -1) {
823  i = i_min;
824 #endif /* 0 */
825  if ((active[i]->i_end >= lt->i_end) &&
826  (active[i]->usagecount < lt->usagecount)) {
827 #else /* USAGE_COUNT */
828  /* get last intervall from active */
829  if (active[i]->i_end > lt->i_end) {
830 #endif /* USAGE_COUNT */
831 
832 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
833  /* Don't spill between one and two word int types */
834  if ((active[i]->type == TYPE_LNG) != (lt->type == TYPE_LNG))
835  return;
836 #endif
837 
838  lt->regoff = active[i]->regoff;
839  active[i]->regoff = -1;
840 
841  (*active_top)--;
842  for (j = i; j < *active_top; j++)
843  active[j] = active[j + 1];
844 
845  lsra_add_active(lt, active, active_top);
846  } else {
847  lt->regoff = -1;
848  }
849 }
850 
851 void lsra_calc_lifetime_length(jitdata *jd)
852 {
853  struct lifetime *lt;
854  int i, lt_index;
855  int lifetimecount;
856 
857  int *icount_block, icount;
858  int flags; /* 0 INMEMORY -> ls->lt_mem */
859  /* 1 INTREG -> ls->lt_int */
860  /* 2 FLTREG -> ls->lt_flt */
861 
862  lsradata *ls;
863 
864  ls = jd->ls;
865 
866  icount_block = DMNEW(int, ls->basicblockcount);
867  icount_block[0] = icount = 0 /* + ls->MAX_vars_with_indices + 1 */;
868  for (i=1; i < ls->basicblockcount; i++) {
869  if (ls->sorted[i-1] != -1)
870  icount += ls->basicblocks[ls->sorted[i-1]]->icount + 1 +
872  if (ls->sorted[i] != -1)
873  icount_block[i] = icount;
874  }
875 
876 #ifdef LSRA_DEBUG_VERBOSE
877  if (compileverbose) {
878  printf("icount_block: ");
879  for (i=0; i < ls->basicblockcount; i++)
880  printf("(%3i-%3i) ",i, icount_block[i]);
881  printf("\n");
882  }
883 #endif
884 
885  lifetimecount = 0;
886  for(lt_index = 0 ;lt_index < ls->lifetimecount; lt_index++) {
887  if ( ls->lifetime[lt_index].type != -1) { /* used lifetime */
888  /* remember lt_index in lt_sorted */
889  ls->lt_used[lifetimecount ++] = lt_index;
890  lt = &(ls->lifetime[lt_index]);
891 
892  /* compute lt->bb_first_def, i_first_def, bb_last_use and */
893  /* i_last_use */
894 
895  _LSRA_ASSERT(lt->def != NULL);
896  /* _LSRA_ASSERT(lt->use != NULL);*/
897  if (lt->use == NULL)
898  lt->use = lt->def;
899 
900 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
901  /* prevent conflicts between lifetimes of type long by increasing */
902  /* the lifetime by one instruction */
903  /* i.e.(ri/rj) ... */
904  /* (rk/rl) ICMD_LNEG */
905  /* with i==l and/or j==k */
906  /* to resolve this during codegeneration a temporary register */
907  /* would be needed */
908  if (lt->type == TYPE_LNG)
909  lt->i_last_use++;
910 #endif
911 
912 /* distribute lifetimes to lt_int, lt_flt and lt_mem */
913 
914  lt->regoff = -1;
915 
916  switch (lt->type) {
917  case TYPE_LNG:
918 #if defined (__I386__)
919  flags = 0;
920 #else
921  flags = 1;
922 #endif
923  break;
924 
925  case TYPE_INT:
926  case TYPE_ADR:
927  flags=1;
928  break;
929  case TYPE_DBL:
930  case TYPE_FLT:
931 #if defined(__I386__)
932  /*
933  * for i386 put all floats in memory
934  */
935  flags=0;
936  break;
937 #endif
938  flags=2;
939  break;
940  default:
941  { log_text("Unknown Type\n"); exit(1); }
942  }
943 
944  switch (flags) {
945  case 0: /* lt_used[lt_used_index] -> lt_rest */
946  ls->lt_mem[ ls->lt_mem_count++ ] = lt_index;
947  break;
948  case 1: /* l->lifetimes -> lt_int */
949  ls->lt_int[ ls->lt_int_count++ ] = lt_index;
950  break;
951  case 2: /* l->lifetimes -> lt_flt */
952  ls->lt_flt[ ls->lt_flt_count++ ] = lt_index;
953  break;
954  }
955 
956 
957  if (lt->bb_first_def < -1) {
958  printf("--------- Warning: variable not defined!------------------vi: %i start: %i end: %i\n", lt->v_index, lt->i_start, lt->i_end);
959  lt->bb_first_def = 0;
960  lt->i_first_def = 0;
961  }
962 
963  lt->i_start = icount_block[lt->bb_first_def] + lt->i_first_def;
964 
965  if (lt->bb_last_use == -1) {
966  /* unused Vars are not regarded by lifeness_analysis! */
967  _LSRA_ASSERT(lt->def != NULL)
968  _LSRA_ASSERT(lt->def->next == NULL)
969 
970  if (compileverbose) {
971  printf("--------- Warning: variable not used! ---------");
972  printf("vi: %i start: %i end: %i\n", lt->v_index,
973  lt->i_start, lt->i_end);
974  }
975  lt->bb_last_use = lt->bb_first_def;
976  lt->i_last_use = lt->i_first_def;
977  }
978 
979  lt->i_end = icount_block[lt->bb_last_use] + lt->i_last_use;
980 
981  if (lt->i_start < 0)
982  printf("------- Error: Lt %3i Vi %4i invalid!\n",lt_index, lt->v_index);
983 
984  if (lt->i_start > lt->i_end)
985  printf("--------- Warning: last use before first def! vi: %i start: %i end: %i\n", lt->v_index, lt->i_start, lt->i_end);
986 
987 #ifdef USAGE_PER_INSTR
988  lt->usagecount = lt->usagecount / ( lt->i_end - lt->i_start + 1);
989 #endif
990  }
991  }
992  ls->lifetimecount = lifetimecount;
993 }
994 
995 #ifdef LSRA_DEBUG_VERBOSE
996 void print_lifetimes(jitdata *jd, int *lt, int lifetimecount)
997 {
998  struct lifetime *n;
999  int lt_index;
1000  lsradata *ls;
1001  registerdata *rd;
1002 
1003  rd = jd->rd;
1004  ls = jd->ls;
1005 
1006  for (lt_index = 0; lt_index < lifetimecount; lt_index++) {
1007  n = ls->lifetime + lt[lt_index];
1008  printf("i_Start: %3i(%3i,%3i) i_stop: %3i(%3i,%3i) reg: %3i VI: %3i type: %3i flags: %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,n->regoff,n->v_index,n->type,n->flags, n->usagecount, n->flags);
1009  }
1010  printf( "%3i Lifetimes printed \n",lt_index);
1011 }
1012 
1013 void print_all_lifetimes(jitdata *jd)
1014 {
1015  struct lifetime *n;
1016  int lt_index;
1017  lsradata *ls;
1018  registerdata *rd;
1019 
1020  rd = jd->rd;
1021  ls = jd->ls;
1022 
1023  for (lt_index = 0; lt_index < ls->lifetimecount; lt_index++) {
1024  n = &(ls->lifetime[lt_index]);
1025  if (n->type != -1) {
1026  printf("i_Start: %3i(%3i,%3i) i_stop: %3i(%3i,%3i) VI: %3i type: %3i flags: %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,n->v_index,n->type,n->flags, n->usagecount, n->flags);
1027  }
1028  }
1029  printf( "%3i Lifetimes printed \n",lt_index);
1030 }
1031 #endif
1032 
1033 /*
1034  * These are local overrides for various environment variables in Emacs.
1035  * Please do not remove this and leave it at the end of the file, where
1036  * Emacs will automagically detect them.
1037  * ---------------------------------------------------------------------
1038  * Local variables:
1039  * mode: c++
1040  * indent-tabs-mode: t
1041  * c-basic-offset: 4
1042  * tab-width: 4
1043  * End:
1044  */
int i_last_use
Definition: lsra.hpp:107
Utf8String name
Definition: method.hpp:71
#define GET_HIGH_REG(a)
int end
Definition: lsra.hpp:190
struct freemem * next
Definition: lsra.hpp:191
int savedvar
Definition: lsra.hpp:101
int argintreguse
Definition: reg.hpp:86
int * lt_int
Definition: lsra.hpp:171
int bb_last_use
Definition: lsra.hpp:105
basicblock * basicblocks
Definition: jit.hpp:141
Definition: jit.hpp:126
paramdesc * params
Definition: descriptor.hpp:164
int bb_first_def
Definition: lsra.hpp:106
int lt_flt_count
Definition: lsra.hpp:174
int * savintregs
Definition: reg.hpp:71
int lifetimecount
Definition: lsra.hpp:169
#define REG_SAV
Definition: jit.hpp:442
#define IS_INT_LNG_TYPE(a)
Definition: global.hpp:130
void lsra_calc_lifetime_length(jitdata *)
Definition: lsra.cpp:1655
int basicblockcount
Definition: lsra.hpp:188
void lsra_setup(jitdata *)
Definition: lsra.cpp:845
int sav_top
Definition: lsra.hpp:133
codeinfo * code
Definition: jit.hpp:128
int varcount_with_indices
Definition: lsra.hpp:122
s4 nregdescint[]
Definition: md-abi.cpp:41
void lsra_alloc(jitdata *, int *, int, int *)
Definition: lsra.cpp:1338
struct site * use
Definition: lsra.hpp:90
void lsra_qsort(struct lsradata *ls, int *a, int lo, int hi)
Definition: lsra.cpp:1193
int v_index
Definition: lsra.hpp:97
codegendata * cd
Definition: jit.hpp:129
int * lt_flt
Definition: lsra.hpp:173
const char * string_java_lang_InternalError
void _spill_at_intervall(struct lifetime *, struct lifetime **, int *)
Definition: lsra.cpp:1600
s4 vartop
Definition: jit.hpp:149
Definition: stack.hpp:59
struct site * def
Definition: lsra.hpp:89
struct lifetime * lifetime
Definition: lsra.hpp:168
int * lt_mem
Definition: lsra.hpp:175
#define INT_REG_CNT
Definition: md-abi.hpp:72
int i_start
Definition: lsra.hpp:95
int * tmpfltregs
Definition: reg.hpp:72
int savintreguse
Definition: reg.hpp:88
stackelement_t * prev
Definition: stack.hpp:64
int * lt_used
Definition: lsra.hpp:170
void lsra_reg_setup(jitdata *, struct lsra_register *, struct lsra_register *)
Definition: lsra.cpp:1035
void lsra_main(jitdata *)
Definition: lsra.cpp:1245
int * nregdesc
Definition: lsra.hpp:132
#define VAR(i)
Definition: jit.hpp:252
s4 icount
Definition: jit.hpp:318
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define DNEW(type)
Definition: dumpmemory.hpp:370
struct freemem * lsra_getnewmem(int *)
Definition: lsra.cpp:1417
s4 varcount
Definition: jit.hpp:151
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define INT_SAV_CNT
Definition: md-abi.hpp:73
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
void spill_at_intervall(jitdata *, struct lifetime *)
Definition: lsra.cpp:1587
int reg
Definition: lsra.hpp:100
#define GET_LOW_REG(a)
void lsra_add_active(struct lifetime *, struct lifetime **, int *)
Definition: lsra.cpp:1515
struct lifetime ** active_sav
Definition: lsra.hpp:179
#define FLT_TMP_CNT
Definition: md-abi.hpp:82
int lt_int_count
Definition: lsra.hpp:172
Instruction::InstID tmp[]
Definition: Matcher.cpp:55
bool compileverbose
Definition: options.cpp:82
classinfo * clazz
Definition: method.hpp:80
This file contains the statistics framework.
Utf8String name
Definition: class.hpp:91
void lsra_param_sort(struct lsradata *ls, int *lifetime, int lifetime_count)
Definition: lsra.cpp:1222
int i_end
Definition: lsra.hpp:96
bool checksync
Definition: options.cpp:90
#define _LSRA_ASSERT(a)
Definition: lsra.hpp:42
#define INT_ARG_CNT
Definition: md-abi.hpp:74
bool lsra(jitdata *jd)
Definition: lsra.cpp:101
int lsra_getmem(struct lifetime *, struct freemem *, int *)
Definition: lsra.cpp:1397
int flags
Definition: lsra.hpp:102
int regoff
Definition: lsra.hpp:79
MIIterator i
basicblock ** basicblocks
Definition: lsra.hpp:189
int argfltreguse
Definition: reg.hpp:89
int * savfltregs
Definition: reg.hpp:73
VariableKind varkind
Definition: stack.hpp:68
registerdata * rd
Definition: jit.hpp:130
int * sorted
Definition: lsra.hpp:155
void lsra_dump_stack(stackelement_t *)
Definition: lsra.cpp:2144
void _lsra_main(jitdata *, int *, int, struct lsra_register *, int *)
Definition: lsra.cpp:1428
#define PACK_REGS(low, high)
int * sav_reg
Definition: lsra.hpp:130
int type
Definition: lsra.hpp:98
int savfltreguse
Definition: reg.hpp:91
bool inmemory
Definition: descriptor.hpp:151
void _lsra_expire_old_intervalls(jitdata *, struct lifetime *, struct lsra_register *, struct lifetime **, int *)
Definition: lsra.cpp:1535
long usagecount
Definition: lsra.hpp:99
#define INT_TMP_CNT
Definition: md-abi.hpp:75
#define FLT_SAV_CNT
Definition: md-abi.hpp:80
byte_iterator begin() const
Definition: utf8.hpp:106
methoddesc * parseddesc
Definition: method.hpp:78
int memuse
Definition: reg.hpp:84
int * tmpintregs
Definition: reg.hpp:70
methodinfo * m
Definition: jit.hpp:127
#define FLT_ARG_CNT
Definition: md-abi.hpp:81
int tmp_top
Definition: lsra.hpp:134
int lt_mem_count
Definition: lsra.hpp:177
#define DMNEW(type, num)
Definition: dumpmemory.hpp:371
int * tmp_reg
Definition: lsra.hpp:131
OStream & out()
Definition: OStream.cpp:39
int off
Definition: lsra.hpp:189
void print_lifetimes(jitdata *, int *, int)
Definition: lsra.cpp:1804
#define MAX(a, b)
Definition: global.hpp:99
void lsra_expire_old_intervalls(jitdata *, struct lifetime *, struct lsra_register *)
Definition: lsra.cpp:1526
static java_object_t * next
Definition: copy.c:43
struct lifetime ** active_tmp
Definition: lsra.hpp:179
int active_sav_top
Definition: lsra.hpp:180
s4 nregdescfloat[]
Definition: md-abi.cpp:98
#define log_text(s)
Definition: logging.hpp:170
#define STAT_DECLARE_VAR(type, var, init)
Declare an external statistics variable.
Definition: statistics.hpp:963
uint32_t regoff
Definition: descriptor.hpp:153
#define printf(...)
Definition: ssa2.cpp:40
#define FLT_REG_CNT
Definition: md-abi.hpp:79
int active_tmp_top
Definition: lsra.hpp:180
void print_all_lifetimes(jitdata *)
Definition: lsra.cpp:1013
void lsra_insertion(struct lsradata *ls, int *a, int lo, int hi)
Definition: lsra.cpp:376
int i_first_def
Definition: lsra.hpp:108