CACAO
lifetimes.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/lifetimes.cpp - lifetime anaylsis
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 "mm/dumpmemory.hpp"
32 
33 #include "toolbox/bitvector.hpp"
34 #include "toolbox/worklist.hpp"
35 
36 #include "vm/exceptions.hpp"
37 #include "vm/descriptor.hpp"
38 #include "vm/resolve.hpp"
39 #include "vm/string.hpp"
40 
41 #include "vm/jit/builtin.hpp"
42 #include "vm/jit/jit.hpp"
48 
49 #ifdef LT_DEBUG_VERBOSE
50 #include "vm/options.hpp"
51 #endif
52 
53 #include <time.h>
54 #include <errno.h>
55 
56 /* function prototypes */
57 void _lt_scanlifetimes(jitdata *jd, graphdata *gd, basicblock *bptr, int);
58 void lt_usage(jitdata *, s4 , int , int , int );
59 
60 
61 void lt_lifeoutatblock(lsradata *ls, graphdata *gd, int *M, int b_index,
62  struct lifetime *lt, worklist *W);
63 void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index,
64  int iindex, struct lifetime *lt, bool life_in,
65  worklist *W);
66 #if 0
67 void lt_lifeinatstatement(lsradata *ls, graphdata *gd, int *M, int b_index,
68  int iindex, struct lifetime *lt);
69 void lt_lifeoutatstatement(lsradata *ls, graphdata *gd, int *M, int b_index,
70  int iindex, struct lifetime *lt);
71 #endif
72 #ifdef USAGE_COUNT
74 #endif
75 
76 void lt_set_use_site(struct lifetime *lt, struct site *use_site) {
77 }
78 
79 struct site *lt_get_first_use_site(struct lifetime *lt, lt_iterator *iter) {
80  return ((*iter) = lt->use);
81 }
82 
84  if ((*iter) == NULL)
85  return NULL;
86  else
87  return ((*iter) = (*iter)->next);
88 }
89 
90 struct site *lt_get_first_def_site(struct lifetime *lt, lt_iterator *iter) {
91  return ((*iter) = lt->def);
92 }
93 
95  struct lifetime * lt) {
96  struct site *def_site;
97  bool is_defined_at_s;
98 
99  def_site = lt->def;
100  is_defined_at_s = ((def_site->b_index == b_index)
101  && (def_site->iindex == iindex));
102  return is_defined_at_s;
103 }
104 
105 /****************************************************************************
106 Get Def & Use Sites
107 ****************************************************************************/
109  int i, l, p;
110  s4 t;
111  methodinfo *m;
112  lsradata *ls;
113  methoddesc *md;
114 
115  ls = jd->ls;
116  m = jd->m;
117  md = m->parseddesc;
118 
119  graph_DFS(ls, gd);
120 
121 #ifdef USAGE_COUNT
122  lt_get_nesting(ls, gd, dd);
123 #endif
124 
125 #if defined(LT_DEBUG_VERBOSE)
126  if (compileverbose) {
127  printf("Sorted: ");
128  for (i=0; i < ls->basicblockcount; i++) {
129  l = ls->sorted[i];
130  if (l != -1)
131  l = ls->basicblocks[l]->nr;
132  printf("%3i(%3i) ", ls->sorted[i], l);
133  }
134  printf("\n");
135  printf("Sorted_rev: ");
136  for (i=0; i < ls->basicblockcount; i++)
137  printf("%3i ", ls->sorted_rev[i]);
138  printf("\n");
139  }
140 #endif
141 
142  for(i = ls->basicblockcount - 1; i>= 0; i--)
143  if (ls->sorted[i] != -1)
144  _lt_scanlifetimes(jd, gd, ls->basicblocks[ls->sorted[i]],
145  ls->sorted[i]);
146 
147  /* Parameter initialisiation for locals [0 .. paramcount[ */
148  /* -> add local var write access at (bb=0,iindex=0) */
149 
150  for (p = 0, l = 0; p < md->paramcount; p++) {
151  t = md->paramtypes[p].type;
152  i = jd->local_map[l * 5 + t];
153  l++;
154  if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
155  l++;
156  if (i == jitdata::UNUSED)
157  continue;
158  i = ls->var_0[i];
159 /* _LT_ASSERT( i < jd->cd->maxlocals); */
160 /* printf("param %3i -> L %3i/%3i\n",p,i,t); */
161  _LT_ASSERT(t == VAR(i)->type);
162 
163  /* Param to Local init happens before normal Code */
164 
165 #ifdef LT_DEBUG_VERBOSE
166  if (compileverbose)
167  printf(" ok\n");
168 #endif
169  lt_usage(jd, i, 0, 0, LT_DEF);
170  } /* end for */
171 }
172 
173 
174 bool lt_is_simple_lt(struct lifetime *lt) {
175  lt_iterator i_def, i_use;
176  struct site *def, *use;
177  bool all_in_same_block;
178 
179 
180  def = lt_get_first_def_site(lt, &i_def);
181  use = lt_get_first_use_site(lt, &i_use);
182  all_in_same_block = true;
183  for (; (all_in_same_block && (use != NULL));
184  use = lt_get_next_site(&i_use)) {
185  all_in_same_block =
186  (use->iindex >= 0) && (use->b_index == def->b_index);
187  }
188  return all_in_same_block;
189 }
190 
191 void lt_is_live(lsradata *ls, struct lifetime *lt, int b_index, int iindex) {
192  int bb_sorted;
193 
194  bb_sorted = ls->sorted_rev[b_index];
195 
196  if ((lt->bb_last_use < bb_sorted) ||
197  ((lt->bb_last_use == bb_sorted) && (lt->i_last_use < iindex))) {
198  lt->bb_last_use = bb_sorted;
199  lt->i_last_use = iindex;
200  }
201  if ((lt->bb_first_def > bb_sorted) ||
202  ((lt->bb_first_def == bb_sorted) && (lt->i_first_def > iindex))) {
203  lt->bb_first_def = bb_sorted;
204  lt->i_first_def = iindex;
205  }
206 }
207 
208 void lt_set_simple_use(lsradata *ls, struct lifetime *lt) {
209  lt_iterator i_use;
210  struct site *use;
211 
212  /* SAVEDVAR is nowhere set!!!! */
213 
214  /* Def is first use */
215 /* lt->bb_first_def = ls->sorted_rev[lt->def->b_index]; */
216 /* lt->i_first_def = lt->def->iindex; */
217 
218  lt_is_live(ls, lt, lt->def->b_index, lt->def->iindex);
219 
220  /* get last use */
221  use = lt_get_first_use_site(lt, &i_use);
222 /* lt->bb_last_use = ls->sorted_rev[use->b_index]; */
223 /* lt->i_last_use = use->iindex; */
224  for (; (use != NULL); use = lt_get_next_site(&i_use))
225  lt_is_live(ls, lt, use->b_index, use->iindex);
226 /* if (use->iindex > lt->i_last_use) */
227 /* lt->i_last_use = use->iindex; */
228 }
229 
231  int *M; /* bit_vecor of visited blocks */
232  int *use; /* bit_vecor of blocks with use sites visited */
233  worklist *W; /* Worklist of Basic Blocks, where lt is life-out */
234 
235  struct site *use_site, *u_site;
236  lt_iterator iter, iter1;
237  graphiterator pred_iter;
238 
239  int lt_index, i, pred, iindex, iindex1, b_index;
240  struct lifetime *lt;
241  int *phi;
242 /* #define MEASURE_RT */
243 #ifdef MEASURE_RT
244  struct timespec time_start,time_end;
245 #endif
246 
247  lsradata *ls;
248  methodinfo *m;
249 
250  ls = jd->ls;
251  m = jd->m;
252 
253 
254 #ifdef MEASURE_RT
255  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,&(time_start)) != 0) {
256  fprintf(stderr,"could not get time: %s\n",strerror(errno));
257  abort();
258  }
259 #endif
260 
261  M = bv_new(ls->basicblockcount);
262  use = bv_new(ls->basicblockcount);
263  W = wl_new(ls->basicblockcount);
264 
265 #ifdef LT_DEBUG_VERBOSE
266  if (compileverbose)
267  printf("LT_ANALYSE: \n");
268 #endif
269  for(lt_index = 0; lt_index < ls->lifetimecount; lt_index++) {
270  lt = &(ls->lifetime[lt_index]);
271  if (lt->type == -1)
272  continue;
273 #ifdef LT_DEBUG_VERBOSE
274  if (compileverbose)
275  printf("LT: %3i:", lt_index);
276 #endif
277 
278  lt->savedvar = 0;
279 
280  _LT_ASSERT(lt->def != NULL);
281  _LT_ASSERT(lt->def->next == NULL); /* SSA! */
282 /* _LT_ASSERT(lt->use != NULL); */
283 
284  lt->bb_last_use = -1;
285  lt->bb_first_def = ls->basicblockcount;
286 
287  bv_reset(M, ls->basicblockcount);
288  bv_reset(use, ls->basicblockcount);
289  wl_reset(W, ls->basicblockcount);
290 
291  use_site = lt_get_first_use_site(lt, &iter);
292 
293  /* Make unused Vars life at their Def Site */
294 
295  if (use_site == NULL) {
296  lt_is_live(ls, lt, lt->def->b_index, lt->def->iindex);
297  if (lt->def->iindex < 0) {
298 
299  /* def only in phi function */
300 
301  lt_is_live(ls, lt, lt->def->b_index, 0);
302  }
303  }
304  for (;use_site != NULL; use_site = lt_get_next_site(&iter)) {
305  iindex = use_site->iindex;
306  if ((lt->def->b_index == use_site->b_index) &&
307  (iindex < 0) &&
308  (iindex <= lt->def->iindex)) {
309 
310 /* bv_set_bit(use, use_site->b_index); */
311  /* do normal analysis */
312  /* there is a use in a phi function before def site */
313 
314  }
315  else if (bv_get_bit(use, use_site->b_index)) {
316  continue;
317  }
318  else {
319  bv_set_bit(use, use_site->b_index);
320 
321  /* use sites of this basic block not visited till now */
322  /* get use site of this bb with highest iindex lower than */
323  /* def site */
324 
325  iindex1 = -1;
326  u_site = use_site;
327  for(iter1= iter; u_site != NULL;
328  u_site = lt_get_next_site(&iter1)) {
329  if ((u_site->b_index == use_site->b_index) &&
330  (lt->def->b_index == use_site->b_index) &&
331  (u_site->iindex >= 0) &&
332  (u_site->iindex < lt->def->iindex) &&
333  (u_site->iindex > iindex1)) {
334  iindex1 = u_site->iindex;
335  } else {
336  if ((u_site->b_index == use_site->b_index) &&
337  (u_site->iindex > iindex))
338  iindex = u_site->iindex;
339  }
340  }
341  if (iindex1 != -1)
342  iindex = iindex1;
343  }
344 
345 #ifdef LT_DEBUG_VERBOSE
346  if (compileverbose)
347  printf("(%3i,%3i)", use_site->b_index, iindex);
348 #endif
349 
350  if (iindex < 0) {
351 
352  /* use in phi function */
353  /* ls->phi[use_site->b_index][-use_site->iindex-1]*/
354 
355  lt_is_live(ls, lt, use_site->b_index, iindex);
356 
357  phi = ls->phi[use_site->b_index][-iindex-1];
358  _LT_ASSERT(phi != NULL);
359 
360  pred = graph_get_first_predecessor(gd, use_site->b_index,
361  &pred_iter);
362  for(i = 1; (pred != -1); i++,pred =
363  graph_get_next(&pred_iter))
364  if (lt->v_index == phi[i]) {
365 
366  /* Add "Life out Basic Blocks to Worklist */
367 
368  wl_add(W, pred);
369  }
370  }
371  else /* lt is live-in at this statement */
372  lt_lifeatstatement(ls, gd, use_site->b_index,
373  iindex, lt, true, W);
374  } /* for (;use_site != NULL; use_site = lt_get_next_site(&iter)) */
375 
376  /* process Worklist */
377 
378  while (!wl_is_empty(W)) {
379  b_index = wl_get(W);
380  lt_lifeoutatblock(ls, gd, M, b_index, lt, W);
381  }
382 
383 
384 #ifdef LT_DEBUG_VERBOSE
385  if (compileverbose)
386  printf("\n");
387 #endif
388 
389  } /* for(lt_index = 0; lt_index < ls->lifetimecount; lt_index++) */
390 
391 #ifdef MEASURE_RT
392  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,&(time_end)) != 0) {
393  fprintf(stderr,"could not get time: %s\n",strerror(errno));
394  abort();
395  }
396 
397  {
398  long diff;
399  time_t atime;
400 
401  diff = (time_end.tv_nsec - time_start.tv_nsec) / 1000;
402  atime = time_start.tv_sec;
403  while (atime < time_end.tv_sec) {
404  atime++;
405  diff += 1000000;
406  }
407  printf("%8li %s.%s.%s\n", diff,
408  UTF_TEXT(m->clazz->name),
409  UTF_TEXT(m->name),
410  UTF_TEXT(m->descriptor));
411  }
412 #endif
413 }
414 
415 /*******************************************************************************
416 lt_lifeatstatement
417 
418 
419 IN: lsradata *ls pointer to worklist created with wl_new
420  graphdata *gd
421  int b_index Basic block index of instruction
422  int iindex index of instruction in Basic Block
423  struct lifetime *lt Pointer to lifetime structure
424  bool life_in TRUE lifetime lt is life 'into' that instruction
425  FALSE lifetime lt is life 'out' of that instruction
426 
427 IN/OUT: worklist *W Worklist of Basic Blocks, where lt is life-out
428 *******************************************************************************/
429 void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index,
430  int iindex, struct lifetime *lt, bool life_in,
431  worklist *W) {
432 
433  int prev_iindex; /* Statement before iindex */
434  int pred;
435  graphiterator pred_iter;
436  instruction *iptr;
437 
438  while (true) {
439  if (!life_in) {
440 #ifdef LT_DEBUG_VERBOSE
441  if ((compileverbose) && (iindex >= 0))
442  printf("LO@ST: vi %3i bi %3i ii %3i\n",
443  lt->v_index, b_index, iindex);
444 #endif
445 
446  /* lt->v_index is life-out at statement at (b_index,iindex) */
447 
448  /* Once a interference graph is needed, add here an edge (v,w) */
449  /* to the ig, for each variable w defined at this instruction */
450  /* except v=lt->v_index */
451 
452  if (!lt_v_is_defined_at_s(ls, b_index, iindex, lt)) {
453 
454  /* v is life in at out of statement -> check if the SAVEDVAR */
455  /* flag is needed to be set */
456 
457  if ((iindex >= 0) && (b_index != 0)) {
458 
459  /* real ICMD, no phi-function, no param initialisation */
460 
461  _LT_ASSERT(ls->basicblocks[b_index]->iinstr != NULL);
462 
463  iptr = ls->basicblocks[b_index]->iinstr + iindex;
464  if (icmd_table[iptr->opc].flags & ICMDTABLE_CALLS)
465  lt->savedvar = SAVEDVAR;
466  }
467 
468  /* lt stays life-in at statement */
469 
470  life_in = true;
471  } else {
472 
473  /* print LO verbose message only for phi functions, which */
474  /* define this var */
475 
476 #ifdef LT_DEBUG_VERBOSE
477  if ((compileverbose) && (iindex < 0))
478  printf("LO@ST: vi %3i bi %3i ii %3i\n",
479  lt->v_index, b_index, iindex);
480  if ((compileverbose))
481  printf("--> definition\n");
482 #endif
483 
484  lt_is_live(ls, lt, b_index, iindex);
485 
486  /* Stop - lt is defined and not life before this instruction */
487 
488  break;
489  }
490  }
491 
492  if (life_in) {
493 
494  /* lt->v_index is live-in at statement (b_index,iindex) */
495 
496 #ifdef LT_DEBUG_VERBOSE
497  if ((compileverbose) && (iindex >= 0))
498  printf("LI@ST: vi %3i bi %3i ii %3i\n",
499  lt->v_index, b_index, iindex);
500 #endif
501 
502  lt_is_live(ls, lt, b_index, iindex);
503 
504 
505  if (iindex == -ls->ssavarcount-1) {
506 
507 #ifdef LT_DEBUG_VERBOSE
508  if ((compileverbose))
509  printf("LI@ST: vi %3i bi %3i ii %3i\n",
510  lt->v_index, b_index, iindex);
511 #endif
512  /* iindex is the first statement of b_index */
513  /* Statements -ls->ssavarcounts-1 .. -1 are possible phi functions*/
514  /* lt->v_index is live-in at b_index */
515 
516  pred = graph_get_first_predecessor(gd, b_index, &pred_iter);
517 
518  /* Add "Life out Basic Blocks to Worklist */
519 
520  for(; pred != -1; pred = graph_get_next(&pred_iter))
521  wl_add(W, pred);
522 
523  /* Stop here - beginning of Basic Block reached */
524 
525  break;
526  } else {
527 
528  prev_iindex = iindex - 1;
529  if (prev_iindex < 0)
530 
531  /* look through phi functions */
532 
533  for(; prev_iindex > -ls->ssavarcount-1; prev_iindex--)
534  if (ls->phi[b_index][-prev_iindex-1] != NULL)
535  break;
536 
537  /* lt is live out at instruction prev_iindex */
538 
539  iindex = prev_iindex;
540  life_in = false;
541  }
542  }
543  }
544 }
545 
546 
547 void lt_lifeoutatblock(lsradata *ls, graphdata *gd, int *M, int b_index,
548  struct lifetime *lt, worklist *W) {
549 
550 #if defined(LT_DEBUG_VERBOSE)
551  if (compileverbose) {
552  printf("V %3i LO at BB %3i\n",lt->v_index, b_index);
553  }
554 #endif
555 
556  /* lt->v_index is life out of Block b_index */
557  if (!bv_get_bit(M, b_index)) { /* BB b_index not visited till now */
558  bv_set_bit(M, b_index);
559 
560  /* lt->v_index is life out of last Statement of b_index */
561 
562  if (b_index != 0) {
563  int i;
564  i = ls->basicblocks[b_index]->icount - 1;
565  for (;((i>0) && ((ls->basicblocks[b_index]->iinstr+i)->opc == ICMD_NOP));
566  i--);
567  lt_lifeatstatement(ls, gd, b_index, i, lt, false, W);
568  }
569  else
570  lt_lifeatstatement(ls, gd, b_index, 0, lt, false, W);
571  }
572 }
573 
574 void lt_move_use_sites(struct lifetime *from, struct lifetime *to) {
575  struct site *s;
576 
577 #if 0
578  /* not anymore true for copy propagated lifetimes */
579  _LT_ASSERT(from->use != NULL);
580 #endif
581  if (from->use == NULL)
582  return;
583  for(s = from->use; s->next != NULL; s = s->next);
584 
585  s->next = to->use;
586  to->use = from->use;
587  from->use = NULL;
588 }
589 
590 void lt_add_use_site(struct lifetime *lt, int block, int iindex) {
591  struct site *n;
592 
593  n = DNEW(struct site);
594  n->b_index = block;
595  n->iindex = iindex;
596  n->next = lt->use;
597  lt->use = n;
598 
599  /* CFG is analysed from the end to the start -> so first found use site */
600  /* is the last use of the Local Var */
601 
602  if (lt->last_use == NULL)
603  lt->last_use = n;
604 }
605 
606 void lt_remove_use_site(struct lifetime *lt, int block, int iindex) {
607  struct site *n;
608 
609  /* check lt->use itself */
610 
611  if ((lt->use->b_index == block) && (lt->use->iindex == iindex)) {
612  /* found */
613  lt->use = lt->use->next;
614  } else {
615 
616  /* look through list */
617 
618  for (n = lt->use; (n->next != NULL) && ((n->next->b_index != block) ||
619  (n->next->iindex != iindex)); n = n->next);
620 
621  /* assert, that lt was found */
622 
623  _LT_ASSERT(n->next != NULL);
624  _LT_ASSERT(n->next->b_index == block);
625  _LT_ASSERT(n->next->iindex == iindex);
626 
627  n->next = n->next->next;
628  }
629 }
630 
631 void lt_add_def_site(struct lifetime *lt, int block, int iindex) {
632  struct site *n;
633 
634  /* SSA <-> only one definition per lifetime! */
635 
636  _LT_ASSERT(lt->def == NULL);
637  n = DNEW(struct site);
638  n->b_index = block;
639  n->iindex = iindex;
640  n->next = NULL;
641  lt->def = n;
642 }
643 
644 void lt_usage(jitdata *jd,s4 v_index, int block, int instr,
645  int store)
646 {
647  struct lifetime *n;
648  lsradata *ls;
649 
650  ls = jd->ls;
651 
652  n = ls->lifetime + v_index;
653 
654  if (n->type == -1) { /* new local lifetime */
655  _LT_ASSERT(0);
656  n->v_index=v_index;
657  n->type=VAR(v_index)->type;
658  /* TODO: check!!!! */
659  /* All var are SAVEDVARS or this gets reset afterwards???? */
660  n->savedvar = SAVEDVAR;
661  n->flags = 0;
662  n->usagecount = 0;
663 
664  n->bb_last_use = -1;
665  n->bb_first_def = -1;
666 
667  n->use = NULL;
668  n->def = NULL;
669  n->last_use = NULL;
670  }
671  _LT_ASSERT(VAR(v_index)->type == n->type);
672 
673  /* add access at (block, instr) to instruction list */
674  /* remember last USE, so only write, if USE Field is undefined (==-1) */
675  /* count store as use, too -> defined and not used vars would overwrite */
676  /* other vars */
677 
678  if (store == LT_USE) {
679 #ifdef USAGE_COUNT
680  n->usagecount += ls->nesting[block];
681 #endif
682  lt_add_use_site(n, block, instr);
683  }
684  if (store == LT_DEF) {
685  lt_add_def_site(n, block, instr);
686  }
687 }
688 
689 /***************************************************************************
690 use sites: dead code elemination, LifenessAnalysis
691 def sites: dead code elemination
692 ***************************************************************************/
694  int b_index)
695 {
696 /* methodinfo *lm; */
697  builtintable_entry *bte;
698  methoddesc *md;
699  int i, j, t, v;
700  int iindex/*, b_index*/;
701  instruction *iptr;
702  s4 *argp;
703 
704  lsradata *ls;
705 
706  ls = jd->ls;
707 
708 #ifdef LT_DEBUG_VERBOSE
709  if (compileverbose)
710  printf("_lt_scanlifetimes: BB %3i flags %3i\n", b_index, bptr->state);
711 #endif
712 
713  if (bptr->state >= basicblock::REACHED) {
714 
715 /* b_index = bptr->nr; */
716 
717  /* get instruction count for BB */
718 
719  iindex = bptr->icount - 1;
720 
721  /* regard not setup new BB with maybe just in and outstack */
722 
723  if (iindex < 0)
724  iindex = 0;
725 
726  /* Regard phi_functions (Definition of target, Use of source) */
727 
728  for(i = 0; i < ls->ssavarcount; i++) {
729  if (ls->phi[b_index][i] != NULL) {
730  /* Phi Function for var i at b_index exists */
731  v = ls->phi[b_index][i][0];
733  t = VAR(i)->type;
734 
735  /* Add definition of target add - phi index -1*/
736 #ifdef LT_DEBUG_VERBOSE
737  if (compileverbose)
738  printf("_lt_scanlifetimes: phi_def: v: %3i\n i: %3i\n",
739  v, -i-1);
740 #endif
741  lt_usage(jd, v, b_index, -i-1, LT_DEF);
742 
743  /* Add Use of sources */
744 
745  for (j = 1; j <= graph_get_num_predecessor(gd, b_index); j++) {
746  if (ls->phi[b_index][i][j] != ls->varcount_with_indices)
747  if (ls->phi[b_index][i][j] != jitdata::UNUSED)
748  lt_usage(jd, ls->phi[b_index][i][j], b_index,
749  -i-1, LT_USE);
750  }
751  }
752  }
753 
754  if (bptr->iinstr != NULL) {
755  /* set iptr to last instruction of BB */
756  iptr = bptr->iinstr + iindex;
757  } else
758  iindex = -1;
759 
760  for (;iindex >= 0; iindex--, iptr--) {
761  i = jitdata::UNUSED;
762  v = jitdata::UNUSED;
763 
764  if (icmd_table[iptr->opc].dataflow >= DF_DST_BASE)
765  v = iptr->dst.varindex;
766 
767  /* check for use (s1, s2, s3 or special (argp) ) */
768  /* and definitions (dst) */
769  switch(icmd_table[iptr->opc].dataflow) {
770  case DF_3_TO_0:
771  case DF_3_TO_1: /* icmd has s1, s2 and s3 */
772  lt_usage(jd, iptr->sx.s23.s3.varindex, b_index, iindex, LT_USE);
773 
774  /* now "fall through" for handling of s2 and s1 */
775 
776  case DF_2_TO_0:
777  case DF_2_TO_1: /* icmd has s1 and s2 */
778  lt_usage(jd, iptr->sx.s23.s2.varindex, b_index, iindex, LT_USE);
779 
780  /* now "fall through" for handling of s1 */
781 
782  case DF_1_TO_0:
783  case DF_1_TO_1:
784  case DF_MOVE:
785  case DF_COPY: /* icmd has s1 */
786  lt_usage(jd, iptr->s1.varindex, b_index, iindex, LT_USE);
787  break;
788 
789  case DF_INVOKE:
791  i = md->paramcount;
792  if (md->returntype.type == TYPE_VOID)
793  v = jitdata::UNUSED;
794  break;
795 
796  case DF_BUILTIN:
797  bte = iptr->sx.s23.s3.bte;
798  md = bte->md;
799  i = md->paramcount;
800  if (md->returntype.type == TYPE_VOID)
801  v = jitdata::UNUSED;
802  break;
803 
804  case DF_N_TO_1:
805  i = iptr->s1.argcount;
806  break;
807 
808  }
809 
810  if (i != jitdata::UNUSED) {
811  argp = iptr->sx.s23.s2.args;
812  while (--i >= 0) {
813  lt_usage(jd, *argp, b_index, iindex, LT_USE);
814  argp++;
815  }
816  }
817 
818  if (v != jitdata::UNUSED) {
819  lt_usage(jd, v, b_index, iindex, LT_DEF);
820  }
821  } /* for (;iindex >= 0; iindex--, iptr--) */
822  } /* if (bptr->state >= basicblock::REACHED) */
823 } /* scan_lifetimes */
824 
825 
826 #ifdef USAGE_COUNT
827 /*******************************************************************************
828 true, if i dominates j
829 *******************************************************************************/
830 bool dominates(dominatordata *dd, int i, int j) {
831  bool dominates = false;
832 
833  while(!dominates && (dd->idom[j] != -1)) {
834  dominates = (i == dd->idom[j]);
835  j = dd->idom[j];
836  }
837  return dominates;
838 }
839 
840 /*******************************************************************************
841 lt_get_nesting
842 
843 Look for loops in the CFG and set the nesting depth of all Basicblocks in
844 gd->nesting:
845 
846 The Loop Header BB h is an element of DF[n] for all Basicblocks n of this loop
847 So Look through all x element of DF[n] for a backedge n->x. If this
848 exists, increment nesting for all n with x in DF[n]
849 *******************************************************************************/
851  int i, j, lh;
852  bitvector loop_header;
853  worklist *loop, *loop1;
854 
855  int succ;
856  graphiterator iter;
857 
858  int num_loops;
859 
860  int *loop_parent;
861  int lh_p;
862 
863  /* init nesting to 1 and get loop_headers */
864  ls->nesting = DMNEW(long, ls->basicblockcount);
865  loop_header = bv_new(ls->basicblockcount);
866  loop = wl_new(ls->basicblockcount);
867  num_loops = 0;
868  for(i = 0; i < ls->basicblockcount; i++) {
869  ls->nesting[i] = 1;
870 
871  for(succ = graph_get_first_successor(gd, i, &iter); succ != -1;
872  succ = graph_get_next(&iter)) {
873  for (j = 0; j < dd->num_DF[i]; j++) {
874  if (succ == dd->DF[i][j]) {
875  /* There is an edge from i to DF[i][j] */
876 
877  /* look if DF[i][j] dominates i -> backedge */
878  if (dominates(dd, dd->DF[i][j], i)) {
879  /* this edge is a backedge */
880  /* -> DF[i][j] is a loop header */
881  _LT_CHECK_BOUNDS(dd->DF[i][j], 0, ls->basicblockcount);
882  if (!bv_get_bit(loop_header, dd->DF[i][j])) {
883  /* new loop_header found */
884  num_loops++;
885  bv_set_bit(loop_header, dd->DF[i][j]);
886  ls->nesting[dd->DF[i][j]] = 10;
887  }
888  wl_add(loop, dd->DF[i][j]);
889  }
890  }
891  }
892  }
893  }
894 
895  loop_parent = DMNEW(int , ls->basicblockcount);
896  loop1 = wl_new(ls->basicblockcount);
897 
898  /* look for direct parents of nested loopheaders */
899  /* (DF[loop_header[i]] has the element loop_header[j] with i != j */
900  /* TODO: BULLSHIT:unfortunately not such an easy condition ;( */
901  while(!wl_is_empty(loop)) {
902  lh = wl_get(loop);
903  wl_add(loop1, lh);
904 
905  loop_parent[lh] = -1;
906 
907  for (j = 0; j < dd->num_DF[lh]; j++) {
908  _LT_CHECK_BOUNDS(dd->DF[lh][j], 0, ls->basicblockcount);
909  if (lh != dd->DF[lh][j]) {
910  if (bv_get_bit(loop_header, dd->DF[lh][j])) {
911 #ifdef LT_DEBUG_VERBOSE
912  if (compileverbose)
913  if (loop_parent[lh] != -1)
914  printf("Warning: LoopHeader has more than one parent\n");
915 #endif
916 /* _LT_ASSERT( loop_parent[lh] == -1); */
917  loop_parent[lh] = dd->DF[lh][j];
918  }
919  }
920  }
921  }
922 
923  /* create nesting for loopheaders */
924  while(!wl_is_empty(loop1)) {
925  lh = wl_get(loop1);
926  for (lh_p = lh; lh_p != -1; lh_p = loop_parent[lh_p]) {
927  ls->nesting[lh] *= 10;
928  }
929  }
930 
931 
932  /* copy loopheader nesting to loop body */
933  for(i = 0; i < ls->basicblockcount; i++) {
934  if (!bv_get_bit(loop_header, i)) {
935  /* Do not touch the nesting of a loopheader itself */
936  for(j = 0; j < dd->num_DF[i]; j++) {
937  _LT_CHECK_BOUNDS(dd->DF[i][j], 0, ls->basicblockcount);
938  if (bv_get_bit(loop_header, dd->DF[i][j])) {
939  /* DF[i][j] is a loop header -> copy nesting for i */
940 #ifdef LT_DEBUG_VERBOSE
941  if (compileverbose)
942  if (ls->nesting[i] != 1)
943  printf("Warning: More than one loopheader for one BB\n");
944 /* _LT_ASSERT(ls->nesting[i] == 1); */
945 #endif
946  ls->nesting[i] = ls->nesting[dd->DF[i][j]];
947  }
948  }
949  }
950  }
951 
952 #ifdef LT_DEBUG_VERBOSE
953  if (compileverbose) {
954  printf("Num Loops: %3i\n",num_loops);
955  for(i = 0; i < ls->basicblockcount; i++)
956  printf("(BB%3i->N%3li) ",i, ls->nesting[i]);
957  printf("\n");
958  }
959 #endif
960 }
961 #endif
962 
963 
964 /*
965  * These are local overrides for various environment variables in Emacs.
966  * Please do not remove this and leave it at the end of the file, where
967  * Emacs will automagically detect them.
968  * ---------------------------------------------------------------------
969  * Local variables:
970  * mode: c++
971  * indent-tabs-mode: t
972  * c-basic-offset: 4
973  * tab-width: 4
974  * End:
975  * vim:noexpandtab:sw=4:ts=4:
976  */
int i_last_use
Definition: lsra.hpp:107
Utf8String name
Definition: method.hpp:71
struct site * lt_get_next_site(lt_iterator *iter)
Definition: lifetimes.cpp:83
int savedvar
Definition: lsra.hpp:101
int graph_get_next(graphiterator *i)
Definition: graph.cpp:104
int * bitvector
Definition: bitvector.hpp:34
#define DF_1_TO_0
Definition: icmd.hpp:335
int bb_last_use
Definition: lsra.hpp:105
Definition: lsra.hpp:67
Definition: jit.hpp:126
#define DF_2_TO_0
Definition: icmd.hpp:336
#define DF_1_TO_1
Definition: icmd.hpp:342
methoddesc * md
Definition: builtin.hpp:71
#define LT_DEF
Definition: lifetimes.hpp:53
int bb_first_def
Definition: lsra.hpp:106
argument_type from
void lt_usage(jitdata *, s4, int, int, int)
Definition: lifetimes.cpp:644
State state
Definition: jit.hpp:313
int basicblockcount
Definition: lsra.hpp:188
struct site * lt_get_first_use_site(struct lifetime *lt, lt_iterator *iter)
Definition: lifetimes.cpp:79
#define ICMDTABLE_CALLS
Definition: icmd.hpp:385
int varcount_with_indices
Definition: lsra.hpp:122
MachineLoop * loop
int32_t argcount
Definition: instruction.hpp:64
struct site * use
Definition: lsra.hpp:90
void lt_lifeness_analysis(jitdata *jd, graphdata *gd)
Definition: lifetimes.cpp:230
int v_index
Definition: lsra.hpp:97
void lt_remove_use_site(struct lifetime *lt, int block, int iindex)
Definition: lifetimes.cpp:606
int32_t varindex
Definition: instruction.hpp:63
void lt_is_live(lsradata *ls, struct lifetime *lt, int b_index, int iindex)
Definition: lifetimes.cpp:191
void _lt_scanlifetimes(jitdata *jd, graphdata *gd, basicblock *bptr, int)
Definition: lifetimes.cpp:693
struct site * def
Definition: lsra.hpp:89
int graph_get_first_predecessor(graphdata *gd, int b_index, graphiterator *i)
Definition: graph.cpp:99
struct lifetime * lifetime
Definition: lsra.hpp:168
#define DF_3_TO_0
Definition: icmd.hpp:337
bool bv_get_bit(bitvector bv, int bit)
Definition: bitvector.cpp:148
bool lt_v_is_defined_at_s(lsradata *ls, int b_index, int iindex, struct lifetime *lt)
Definition: lifetimes.cpp:94
int iindex
Definition: lsra.hpp:69
#define DF_3_TO_1
Definition: icmd.hpp:344
instruction * iinstr
Definition: jit.hpp:319
#define VAR(i)
Definition: jit.hpp:252
s4 icount
Definition: jit.hpp:318
void graph_DFS(lsradata *ls, graphdata *gd)
Definition: graph.cpp:416
#define DNEW(type)
Definition: dumpmemory.hpp:370
void wl_reset(worklist *w, int size)
Definition: worklist.cpp:135
struct site * lt_get_first_def_site(struct lifetime *lt, lt_iterator *iter)
Definition: lifetimes.cpp:90
typedesc paramtypes[1]
Definition: descriptor.hpp:167
void lt_set_use_site(struct lifetime *lt, struct site *use_site)
Definition: lifetimes.cpp:76
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
void lt_scanlifetimes(jitdata *jd, graphdata *gd, dominatordata *dd)
Definition: lifetimes.cpp:108
BeginInst *& block
Utf8String descriptor
Definition: method.hpp:72
#define DF_N_TO_1
Definition: icmd.hpp:345
long * nesting
Definition: lsra.hpp:163
#define abort
Definition: md-asm.hpp:112
dst_operand_t dst
void lt_add_def_site(struct lifetime *lt, int block, int iindex)
Definition: lifetimes.cpp:631
bool compileverbose
Definition: options.cpp:82
#define LT_USE
Definition: lifetimes.hpp:54
classinfo * clazz
Definition: method.hpp:80
int32_t dataflow
Definition: icmd.hpp:395
int * var_0
Definition: lsra.hpp:126
Utf8String name
Definition: class.hpp:91
#define DF_COPY
Definition: icmd.hpp:350
int ssavarcount
Definition: lsra.hpp:115
struct site * last_use
Definition: lsra.hpp:91
s4 * local_map
Definition: jit.hpp:153
int flags
Definition: lsra.hpp:102
struct site * next
Definition: lsra.hpp:70
MIIterator i
typedesc returntype
Definition: descriptor.hpp:166
bool wl_is_empty(worklist *w)
Definition: worklist.cpp:124
void bv_reset(bitvector bv, int size)
Definition: bitvector.cpp:204
basicblock ** basicblocks
Definition: lsra.hpp:189
int32_t s4
Definition: types.hpp:45
#define DF_MOVE
Definition: icmd.hpp:351
int * sorted
Definition: lsra.hpp:155
union instruction::@12 sx
int type
Definition: lsra.hpp:98
int32_t varindex
icmdtable_entry_t icmd_table[256]
Definition: icmd.cpp:60
#define INSTRUCTION_GET_METHODDESC(iptr, md)
long usagecount
Definition: lsra.hpp:99
int * sorted_rev
Definition: lsra.hpp:156
s1_operand_t s1
bool dominates(dominatordata *dd, int i, int j)
Definition: lifetimes.cpp:830
void lt_move_use_sites(struct lifetime *from, struct lifetime *to)
Definition: lifetimes.cpp:574
bool lt_is_simple_lt(struct lifetime *lt)
Definition: lifetimes.cpp:174
int b_index
Definition: lsra.hpp:68
void lt_lifeoutatblock(lsradata *ls, graphdata *gd, int *M, int b_index, struct lifetime *lt, worklist *W)
Definition: lifetimes.cpp:547
methoddesc * parseddesc
Definition: method.hpp:78
int graph_get_num_predecessor(graphdata *gd, int b_index)
Definition: graph.cpp:84
#define _LT_ASSERT(a)
Definition: lifetimes.hpp:45
Definition: builtin.hpp:60
methodinfo * m
Definition: jit.hpp:127
#define _LT_CHECK_BOUNDS(i, l, h)
Definition: lifetimes.hpp:44
worklist * wl_new(int size)
Definition: worklist.cpp:68
const Method & M
#define DF_INVOKE
Definition: icmd.hpp:347
s4 nr
Definition: jit.hpp:312
#define DMNEW(type, num)
Definition: dumpmemory.hpp:371
void wl_add(worklist *w, int element)
Definition: worklist.cpp:88
struct instruction::@12::@13 s23
int wl_get(worklist *w)
Definition: worklist.cpp:107
void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index, int iindex, struct lifetime *lt, bool life_in, worklist *W)
Definition: lifetimes.cpp:429
bitvector bv_new(int size)
Definition: bitvector.cpp:122
void bv_set_bit(bitvector bv, int bit)
Definition: bitvector.cpp:166
#define DF_BUILTIN
Definition: icmd.hpp:348
#define DF_DST_BASE
Definition: icmd.hpp:339
#define printf(...)
Definition: ssa2.cpp:40
#define DF_2_TO_1
Definition: icmd.hpp:343
void lt_add_use_site(struct lifetime *lt, int block, int iindex)
Definition: lifetimes.cpp:590
void lt_get_nesting(lsradata *ls, graphdata *gd, dominatordata *dd)
Definition: lifetimes.cpp:850
int *** phi
Definition: lsra.hpp:193
int32_t flags
Definition: icmd.hpp:397
int graph_get_first_successor(graphdata *gd, int b_index, graphiterator *i)
Definition: graph.cpp:94
int i_first_def
Definition: lsra.hpp:108
void lt_set_simple_use(lsradata *ls, struct lifetime *lt)
Definition: lifetimes.cpp:208