CACAO
ssa.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/ssa.cpp - static single-assignment form
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/descriptor.hpp"
37 
38 #include "vm/jit/cfg.hpp"
39 #include "vm/jit/builtin.hpp"
40 
41 #include "vm/jit/code.hpp"
42 #include "vm/jit/jit.hpp" /* icmd_table */
43 
44 #include "vm/jit/ir/bytecode.hpp"
45 
50 
54 
55 #if defined(SSA_DEBUG_VERBOSE)
56 #include "vm/options.hpp" /* compileverbose */
57 #endif
58 
59 /* function prototypes */
60 void ssa_set_local_def(lsradata *, int , int);
62 
64 void copy_propagation(jitdata *jd, graphdata *gd);
66  int , worklist *);
67 
68 void ssa_set_def(lsradata *, int , int );
69 void ssa_set_local_def(lsradata *, int , int );
70 void ssa_set_iovar(lsradata *, s4 , int , s4 *);
72 
73 #ifdef SSA_DEBUG_VERBOSE
75 void ssa_print_lt(lsradata *ls);
76 void _ssa_print_lt(struct lifetime *lt);
77 #endif
78 
79 /* ssa ************************************************************************
80 
81 SSA main procedure:
82 
83 SSA Algorithms are based on "modern compiler implementation in C" from andrew
84 w. appel, edition 2004
85 
86 Corrections:
87 page 441 Algorithm 19.6. Inserting phi-functions:
88 
89 ...
90  for each Y in DF[n]
91 - if Y not element of A phi [n]
92 + if a not element of A phi [n]
93  insert the statment a <- ...
94 ...
95 ...
96 - A phi [n] <- A phi [n] join {Y}
97 + A phi [n] <- A phi [n] join {a}
98 - if Y not element of A orig [n]
99 + if a not element of A orig [Y]
100  W <- W join {Y}
101 
102 ******************************************************************************/
103 void xssa(jitdata *jd);
104 void yssa(jitdata *jd);
105 void ssa(jitdata *jd) {
106  struct dominatordata *dd;
107  lsradata *ls;
108  graphdata *gd;
109 
110 #if defined(ENABLE_LOOPS)
111  /* Loop optimization "destroys" the basicblock array */
112  /* TODO: work with the basicblock list */
113  if (opt_loops) {
114  log_text("lsra not possible with loop optimization\n");
115  exit(1);
116  }
117 #endif
118 
119  cfg_add_root(jd);
121  /*pythonpass_run(jd, "foo", "cfg_print");*/
122  /*dominator_tree_validate(jd, dd);*/
123  /*pythonpass_run(jd, "ssa2", "main");*/
124  /*pythonpass_run(jd, "alt_ssa", "main");*/
125  /*pythonpass_run(jd, "foo", "before");*/
126 
127  /*if (getenv("XSSA")) {
128  dominator_tree_build(jd);
129  dominance_frontier_build(jd);
130  xssa(jd);
131  } else */{
132  yssa(jd);
133  }
134  /*pythonpass_run(jd, "foo", "after");*/
135  cfg_remove_root(jd);
136  return;
137 
138  ls = jd->ls;
139 
140  ssa_init(jd);
141  /* Generate the Control Flow Graph */
142  /* Add one for a Basic Block 0 to be inserted, so lateron */
143  /* with SSA Parameter initialization is handled right */
144 
145  gd = graph_init(jd->basicblockcount + 1);
146  graph_make_cfg(jd, gd);
147 
148  dd = compute_Dominators(gd, ls->basicblockcount);
149  computeDF(gd, dd, ls->basicblockcount, 0);
150 
151  ssa_place_phi_functions(jd, gd, dd);
152  ssa_rename(jd, gd, dd);
153 #ifdef SSA_DEBUG_VERBOSE
154  if (compileverbose) {
155  printf("Phi before Cleanup\n");
156  ssa_print_phi(ls, gd);
157  ssa_print_lt(ls);
158  }
159 #endif
160  lt_scanlifetimes(jd, gd, dd);
161 #ifdef SSA_DEBUG_VERBOSE
162  if (compileverbose) {
163  ssa_print_lt(ls);
164  }
165 #endif
166  if (opt_ssa_dce) {
167  dead_code_elimination(jd, gd);
168 #ifdef SSA_DEBUG_VERBOSE
169  if (compileverbose) {
170  printf("Phi after dead code elemination\n");
171  ssa_print_phi(ls, gd);
172  ssa_print_lt(ls);
173  }
174 #endif
175  }
176  if (opt_ssa_cp) {
177  copy_propagation(jd, gd);
178 #ifdef SSA_DEBUG_VERBOSE
179  if (compileverbose) {
180  printf("Phi after copy propagation\n");
181  ssa_print_phi(ls, gd);
182  ssa_print_lt(ls);
183  }
184 #endif
185  }
186 
187  ssa_generate_phi_moves(jd, gd);
188  transform_BB(jd, gd);
189 
190  lt_lifeness_analysis(jd, gd);
191 
192 #ifdef SSA_DEBUG_CHECK
193  {
194  int i, j, pred, in_d, out_d;
195  graphiterator iter_pred;
196  s4 *in, *out;
197  bool phi_define;
198  methodinfo *m;
199 
200  m = jd->m;
201 
202  for(i = 0; i < ls->basicblockcount; i++) {
203  if (ls->basicblocks[i]->indepth != 0) {
204  pred = graph_get_first_predecessor(gd, i, &iter_pred);
205  for (; (pred != -1); pred = graph_get_next(&iter_pred)) {
206  in_d = ls->basicblocks[i]->indepth - 1;
207  in = ls->basicblocks[i]->invars;
208  for (; in_d >= 0; in_d--) {
209  phi_define = false;
210  for (j = 0; (!phi_define) && (j<ls->ssavarcount); j++) {
211  if (ls->phi[i][j] != NULL)
212  if (ls->phi[i][j][0] == in[in_d])
213  phi_define = true;
214  }
215  if (!phi_define) {
216  /* in not defined in phi function -> check with */
217  /* outstack(s) of predecessor(s) */
218  out_d = ls->basicblocks[pred]->outdepth - 1;
219  out = ls->basicblocks[pred]->outvars;
220  _SSA_ASSERT(out_d >= in_d);
221  for(; out_d > in_d; out_d--);
222  if ((in[in_d] != out[out_d]) ||
223  (VAR(in[in_d])->flags != VAR(out[out_d])->flags)) {
224  printf("Method: %s %s\n",
225  m->clazz->name.begin(), m->name.begin());
226  printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
227  if (compileverbose)
228  printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
229 /* else */
230 /* _SSA_ASSERT(0); */
231  }
232  }
233  }
234  }
235  }
236  }
237  }
238 
239 #endif
240 
241 #ifdef SSA_DEBUG_VERBOSE
242  if (compileverbose)
243  ssa_print_trees(jd, gd, dd);
244 #endif
245 
246 }
247 
248 /* ssa_init *******************************************************************
249 
250 Initialise data structures for ssa
251 
252 IOVARS of same stackdepth and same type are coalesced:
253 interface_map[ 5 * stackdepth + type ] = new_varindex with
254 0 <= new_varindex < ls->ssavarcount
255 
256 TODO: check if coalescing of IOVARS of same stackdepth and type only of adjacent
257 basic blocks could decrease the number of phi functions and so improve ssa
258 analysis performance!
259 
260 All LOCALVARS and IOVARS get a new unique varindex:
261 ls->new_varindex[0..jd->varcount[ = new_varindex with
262 0 <= new_varindex < ls->ssavarcount
263 
264 The jd->varcount bits long bitvectors ls->var_def[0..jd->basicblockindex+1[
265  are set to the definitions of LOCALVARS and IOVARS. (So the only the first
266 ls->ssavarcount bits of each of these vectors contain valid data, but
267 ls->ssavarcount is computed at the same time as the definitons are stored.)
268 
269 The basic block number used as index for the bitvector array ls->var_def is
270 already shifted by one to make space for the new basic block 0 for parameter
271 initialization.
272 
273 ******************************************************************************/
274 
275 void ssa_init(jitdata *jd) {
276  int p, t, v;
277  methoddesc *md;
278  int i, l, b_index, len;
279  instruction *iptr;
280  basicblock *bptr;
281  s4 *interface_map; /* holds an new unique index for every used */
282  /* basic block inoutvar described by a dupel */
283  /*(depth,type). Used to coalesce the inoutvars*/
284  methodinfo *m;
285  lsradata *ls;
286  builtintable_entry *bte;
287 
288  ls = jd->ls;
289  m = jd->m;
290  md = m->parseddesc;
291 
292 
293 #if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
294 # if defined(SSA_DEBUG_VERBOSE)
295  if (compileverbose) {
296  printf("%s %s ", m->clazz->name.begin(), m->name.begin());
297  if (code_is_leafmethod(jd->code))
298  printf("**Leafmethod**");
299  printf("\n");
300  }
301 # endif
302  if (strcmp(m->clazz->name.begin(), "spec/benchmarks/_213_javac/Parser")==0)
303  if (strcmp(m->name.begin(),"parseTerm")==0)
304 # if defined(SSA_DEBUG_VERBOSE)
305  if (compileverbose)
306  printf("12-------------------12\n");
307 # else
308  { int dummy=1; dummy++; }
309 # endif
310 #endif
311 
312 #ifdef SSA_DEBUG_VERBOSE
313  if (compileverbose)
314  printf("ssa_init: basicblockcount %3i localcount %3i\n",
315  jd->basicblockcount, jd->localcount);
316 #endif
317 
318  /* As first step all definitions of local variables and in/out vars are */
319  /* gathered. in/outvars are coalesced for same type and depth */
320  /* "normal" tempvars (just living within one basicblock are) ignored */
321 
322  ls->num_defs = DMNEW(int, jd->varcount);
323  ls->new_varindex = DMNEW(int , jd->varcount);
324 
325  for(p = 0; p < jd->varcount; p++) {
326  ls->num_defs[p] = 0;
327  ls->new_varindex[p] = jitdata::UNUSED;
328  }
329 
330  /* init Var Definition bitvectors */
331 
332  ls->var_def = DMNEW(int *, jd->basicblockcount + 1);
333  for(i = 0; i < jd->basicblockcount + 1; i++) {
334  ls->var_def[i] = bv_new(jd->varcount);
335  }
336 
337  ls->ssavarcount = 0;
338 
339  /* Add parameters first in right order, so the new local indices */
340  /* 0..p will correspond to "their" parameters */
341  /* They get defined at the artificial Block 0, the real method bbs will */
342  /* be ed to start at block 1 */
343 
344  /* don't look at already eliminated (not used) parameters (locals) */
345 
346  for (p = 0, l = 0; p < md->paramcount; p++) {
347  t = md->paramtypes[p].type;
348  i = jd->local_map[l * 5 + t];
349  l++;
350  if (IS_2_WORD_TYPE(t)) /* increment local counter a second time */
351  l++; /* for 2 word types */
352  if (i == jitdata::UNUSED)
353  continue;
354  ssa_set_local_def(ls, -1, i);
355  }
356 
357  _SSA_ASSERT(ls->ssavarcount < jd->varcount);
358 
359  /* coalesce bb in/out vars */
360 
361  interface_map = DMNEW(s4, jd->stackcount * 5);
362  for(i = 0; i < jd->stackcount * 5; i++)
363  interface_map[i] = jitdata::UNUSED;
364 
365  bptr = jd->basicblocks;
366 
367  for(; bptr != NULL; bptr = bptr->next) {
368 #ifdef SSA_DEBUG_VERBOSE
369  if (compileverbose)
370  printf("ssa_init: BB %3i state %3x\n",bptr->nr, bptr->state);
371 #endif
372  if (bptr->state >= basicblock::REACHED) {
373 
374  /* 'valid' Basic Block */
375 
376  b_index = bptr->nr;
377 
378  len = bptr->icount;
379  iptr = bptr->iinstr;
380  ssa_set_interface(jd, bptr, interface_map);
381 
382  /* !!!!!!!!! not true for now !!!!!!!!! */
383  /* All baseline optimizations from stack.c are turned off for */
384  /* SSA! */
385 
386  for (; len > 0; len--, iptr++) {
387 
388  /* Look for definitions (iptr->dst). INVOKE and BUILTIN have */
389  /* an optional dst - so they to be checked first */
390 
391  v = jitdata::UNUSED;
392  if (icmd_table[iptr->opc].dataflow == DF_INVOKE) {
394  if (md->returntype.type != TYPE_VOID)
395  v = iptr->dst.varindex;
396  }
397  else if (icmd_table[iptr->opc].dataflow == DF_BUILTIN) {
398  bte = iptr->sx.s23.s3.bte;
399  md = bte->md;
400  if (md->returntype.type != TYPE_VOID)
401  v = iptr->dst.varindex;
402  }
403  else if (icmd_table[iptr->opc].dataflow >= DF_DST_BASE) {
404  v = iptr->dst.varindex;
405  }
406 
407  if (v != jitdata::UNUSED) {
408  if (( v < jd->localcount) || ( VAR(v)->flags & INOUT )) {
409 
410  /* !IS_TEMPVAR && !IS_PREALLOC == (IS_LOCALVAR || IS_INOUT) */
411 
412  ssa_set_local_def(ls, b_index, v);
413  }
414  }
415  }
416  }
417  }
418  _SSA_ASSERT(ls->ssavarcount < jd->varcount);
419 
420 #ifdef SSA_DEBUG_VERBOSE
421  if (compileverbose) {
422  printf("ssa_init: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
423  ls->ssavarcount);
424  for(i = 0; i < jd->varcount; i++) {
425  if ((i < jd->localcount) || ( VAR(i)->flags & INOUT)) {
426  printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
427  ssa_show_variable(jd, i, VAR(i),0);
428  if (i < ls->ssavarcount) {
429  printf(" -> %3i", ls->new_varindex[i]);
430  }
431  printf("\n");
432  }
433  }
434  }
435 #endif
436 }
437 
438 /* ssa_set_def ****************************************************************
439 
440 Helper for ssa_set_local_def and ssa_set_interface
441 
442 The definition of a var is stored in the bitvector array ls->var_def.
443 
444 The number of definitons of each var is counted, so the number of new vars with
445 SSA is known.
446 
447 ******************************************************************************/
448 
449 void ssa_set_def(lsradata *ls, int b_index, int varindex) {
450 
451  /* b_index + 1 to leave space for the param init block 0 */
452 
453  bv_set_bit(ls->var_def[b_index + 1], varindex);
454 
455  /* count number of defs for every var since SSA */
456  /* will create a new var for every definition */
457 
458  ls->num_defs[varindex]++;
459 }
460 
461 /* ssa_set_local_def **********************************************************
462 
463 Helper for ssa_init
464 
465 Assigns a new unique index for the local var varindex (if not already done so)
466 and then calls ssa_set_def to remember the definition in the bitvector array
467 ls->var_def
468 
469 ******************************************************************************/
470 
471 void ssa_set_local_def(lsradata *ls, int b_index, int varindex) {
472 
473  if (ls->new_varindex[varindex] == jitdata::UNUSED) {
474  ls->new_varindex[varindex] = ls->ssavarcount++;
475  }
476 
477  ssa_set_def(ls, b_index, ls->new_varindex[varindex]);
478 }
479 
480 /* ssa_set_local_def **********************************************************
481 
482 Helper for ssa_set_interface
483 
484 IN: ls pointer to lsradata structure
485  iovar varindex of INOUTVAR to process
486  map_index stackdepth * 5 + type, used for coalescing IOVARS.
487 
488 IN/OUT
489  interface_map used for coalescing IOVARS. interface_map[map_index] ==
490  UNUSED, if this map_index (==stackdepth,type tupel) did not
491  occur till now. Then interface_map[map_index] will be set
492  to a new unique index.
493  ls->new_varindex will be set to this new unique index to map the old
494  varindizes to the new ones.
495 
496 Assigns a new unique index for the local var varindex (if not already done so)
497 and then calls ssa_set_def to remember the definition in the bitvector array
498 ls->var_def
499 
500 ******************************************************************************/
501 
502 void ssa_set_iovar(lsradata *ls, s4 iovar, int map_index, s4 *interface_map) {
503  if (interface_map[map_index] == jitdata::UNUSED)
504  interface_map[map_index] = ls->ssavarcount++;
505 
506  ls->new_varindex[iovar] = interface_map[map_index];
507 }
508 
509 
510 /* ssa_set_interface ***********************************************************
511 
512 Helper for ssa_init
513 
514 IN: ls pointer to lsradata structure
515  *bptr pointer to the basic block to be processed
516 
517 IN/OUT
518  interface_map used for coalescing IOVARS. interface_map[map_index] ==
519  UNUSED, if this map_index (==stackdepth,type tupel) did not
520  occur till now. Then interface_map[map_index] will be set
521  to a new unique index. (see ssa_set_iovar)
522 
523 Searches the basic block given by *bptr for IN and OUTVARS and coalesces them
524 for each unique stackdepth,type dupel. For each OUTVAR with a different or no
525 INVAR at the same stackdepth the definition of this OUTVAR in this basic block
526 is remembered in ls->var_def. (see ssa_set_def)
527 
528 ******************************************************************************/
529 
530 void ssa_set_interface(jitdata *jd, basicblock *bptr, s4 *interface_map) {
531  s4 *out, *in;
532  int in_d, out_d;
533  int o_map_index, i_map_index;
534  lsradata *ls;
535 
536  ls = jd->ls;
537 
538  out = bptr->outvars;
539  in = bptr->invars;
540  in_d = bptr->indepth - 1;
541  out_d = bptr->outdepth - 1;
542 
543  /* ignore top Stackelement of instack in case of EXH or SBR blocks */
544  /* These are no Interface stackslots! */
545  if ((bptr->type == basicblock::TYPE_EXH) ||
546  (bptr->type == basicblock::TYPE_SBR)) {
547  in_d--;
548  }
549 
550  /* invars with no corresponding outvars are not defined here */
551  /* just set up the interface_map */
552 
553  for(;(in_d > out_d); in_d--) {
554  i_map_index = in_d * 5 + VAR(in[in_d])->type;
555  ssa_set_iovar(ls, in[in_d], i_map_index, interface_map);
556  }
557 
558  while((out_d >= 0)) {
559  /* set up interface_map */
560 
561  o_map_index = out_d * 5 + VAR(out[out_d])->type;
562  if (in_d >= 0) {
563  i_map_index = in_d * 5 + VAR(in[in_d])->type;
564  ssa_set_iovar(ls, in[in_d], i_map_index, interface_map);
565  }
566  ssa_set_iovar(ls, out[out_d], o_map_index, interface_map);
567  if (in_d == out_d) {
568  out_d--;
569  in_d--;
570  }
571  else {
572  out_d--;
573  }
574  }
575 }
576 
577 #ifdef SSA_DEBUG_VERBOSE
579  int i,j;
580  lsradata *ls;
581 
582  ls = jd->ls;
583 
584  printf("ssa_printtrees: maxlocals %3i", jd->localcount);
585 
586  printf("Dominator Tree: \n");
587  for(i = 0; i < ls->basicblockcount; i++) {
588  printf("%3i:",i);
589  for(j = 0; j < ls->basicblockcount; j++) {
590  if (dd->idom[j] == i) {
591  printf(" %3i", j);
592  }
593  }
594  printf("\n");
595  }
596 
597  printf("Dominator Forest:\n");
598  for(i = 0; i < ls->basicblockcount; i++) {
599  printf("%3i:",i);
600  for(j = 0; j < dd->num_DF[i]; j++) {
601  printf(" %3i", dd->DF[i][j]);
602  }
603  printf("\n");
604  }
605 #if 0
606  if (ls->ssavarcount > 0) {
607  printf("Use Sites\n");
608  for(i = 0; i < ls->ssavarcount; i++) {
609  printf("use_sites[%3i]=%p:",i,(void *)ls->use_sites[i]);
610  for(j = 0; j < ls->basicblockcount; j++) {
611  if ((j % 5) == 0) printf(" ");
612  if (bv_get_bit(ls->use_sites[i], j))
613  printf("1");
614  else
615  printf("0");
616  }
617  printf("\n");
618  }
619  }
620 #endif
621  printf("var Definitions:\n");
622  for(i = 0; i < jd->basicblockcount; i++) {
623  printf("var_def[%3i]=%p:",i,(void *)ls->var_def[i]);
624  for(j = 0; j < ls->ssavarcount; j++) {
625  if ((j % 5) == 0) printf(" ");
626  if (bv_get_bit(ls->var_def[i], j))
627  printf("1");
628  else
629  printf("0");
630  }
631  printf(" (");
632  for(j=0; j < ((((ls->ssavarcount * 5+7)/8) + sizeof(int) - 1)/sizeof(int));
633  j++)
634  printf("%8x",ls->var_def[i][j]);
635  printf(")\n");
636  }
637 }
638 #endif
639 
640 
641 /****************************************************************************
642 Optimizations
643 ****************************************************************************/
644 
645 
646 /****************************************************************************
647 Dead Code Elimination
648 ****************************************************************************/
650  int a, i, source;
651  worklist *W;
652 
653  instruction *iptr;
654  struct lifetime *lt, *s_lt;
655 
656  bool remove_statement;
657  struct site *use;
658 
659  lsradata *ls;
660 #ifdef SSA_DEBUG_VERBOSE
661  methodinfo *m;
662 
663  m = jd->m;
664 #endif
665  ls = jd->ls;
666 
667  W = wl_new(ls->lifetimecount);
668  if (ls->lifetimecount > 0) {
669 
670  /* put all lifetimes into Worklist W */
671 
672  for(a = 0; a < ls->lifetimecount; a++) {
673  if (ls->lifetime[a].type != jitdata::UNUSED) {
674  wl_add(W, a);
675  }
676  }
677  }
678 
679  /* Remove unused lifetimes */
680 
681  while(!wl_is_empty(W)) {
682 
683  /* take a var out of Worklist */
684 
685  a = wl_get(W);
686 
687  lt = &(ls->lifetime[a]);
688  if ((lt->def == NULL) || (lt->type == jitdata::UNUSED))
689 
690  /* lifetime was already removed -> no defs anymore */
691 
692  continue;
693 
694  /* Remove lifetimes, which are only used in the phi function which */
695  /* defines them! */
696 
697  remove_statement = (lt->use != NULL) && (lt->use->iindex < 0);
698  for(use = lt->use; (remove_statement && (use != NULL));
699  use = use->next)
700  {
701  remove_statement = remove_statement &&
702  (use->b_index == lt->def->b_index) &&
703  (use->iindex == lt->def->iindex);
704  }
705 
706  if (remove_statement) {
707 #ifdef SSA_DEBUG_CHECK
708 
709  /* def == use can only happen in phi functions */
710 
711  if (remove_statement)
712  _SSA_ASSERT(lt->use->iindex < 0);
713 #endif
714 
715  /* give it free for removal */
716 
717  lt->use = NULL;
718  }
719 
720  if (lt->use == NULL) {
721 
722  /* Look at statement of definition of a and remove it, */
723  /* if the Statement has no sideeffects other than the assignemnt */
724  /* of a */
725 
726  if (lt->def->iindex < 0 ) {
727 
728  /* phi function */
729  /* delete use of sources , delete phi functions */
730 
731  _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] !=
732  NULL);
733 
734  for (i = 1;i <= graph_get_num_predecessor(gd, lt->def->b_index);
735  i++) {
736  source =
737  ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
738  if ((source != ls->varcount_with_indices) &&
739  (source != lt->v_index) &&
740  (source != jitdata::UNUSED)) {
741 
742  /* phi Argument was not already removed (already in
743  because of "selfdefinition") */
744 
745  s_lt = &(ls->lifetime[source]);
746 
747  /* remove it */
748 
749  lt_remove_use_site(s_lt,lt->def->b_index,
750  lt->def->iindex);
751 
752  /* put it on the Worklist */
753 
754  wl_add(W, source);
755  }
756  }
757 
758  /* now delete phi function itself */
759 #ifdef SSA_DEBUG_VERBOSE
760  if (compileverbose) {
761  printf("dce: BB%3i phi for var %3i=%3i removed \n",
762  lt->def->b_index, -lt->def->iindex - 1,
763  lt->v_index);
764  }
765 #endif
766 
767  ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
768  }
769  else {
770 
771  /* "normal" Use by ICMD */
772 
773  remove_statement = false;
774  if (lt->def->b_index != 0) {
775 
776  /* do not look at artificial block 0 (parameter init) */
777 
778  iptr = ls->basicblocks[lt->def->b_index]->iinstr +
779  lt->def->iindex;
780 
781  if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {
782 
783  /* if ICMD could throw an exception do not remove it! */
784 
785  remove_statement = false;
786 #ifdef SSA_DEBUG_VERBOSE
787  if (compileverbose) {
788  printf("dce: PEI: BB%3i II%3i %s not removed \n",
789  lt->def->b_index, lt->def->iindex,
790  bytecode[iptr->opc].mnemonic);
791  }
792 #endif
793 
794  }
795  else {
796  remove_statement = true;
797 
798  switch (icmd_table[iptr->opc].dataflow) {
799  case DF_3_TO_0:
800  case DF_3_TO_1: /* icmd has s1, s2 and s3 */
801  a = iptr->sx.s23.s3.varindex;
802  s_lt = ls->lifetime + a;
803  lt_remove_use_site(s_lt, lt->def->b_index,
804  lt->def->iindex);
805  wl_add(W, a);
806 
807  /* "fall through" for handling of s2 and s1 */
808 
809  case DF_2_TO_0:
810  case DF_2_TO_1: /* icmd has s1 and s2 */
811  a = iptr->sx.s23.s2.varindex;
812  s_lt = ls->lifetime + a;
813  lt_remove_use_site(s_lt, lt->def->b_index,
814  lt->def->iindex);
815  wl_add(W, a);
816 
817  /* "fall through" for handling of s1 */
818 
819  /* DF_{IINC,STORE,LOAD} are DF_{1_TO_1,MOVE,COPY} */
820 
821  case DF_1_TO_0:
822  case DF_1_TO_1:
823  case DF_MOVE:
824  case DF_COPY:
825  a = iptr->s1.varindex;
826  s_lt = ls->lifetime + a;
827  lt_remove_use_site(s_lt, lt->def->b_index,
828  lt->def->iindex);
829  wl_add(W, a);
830  }
831 #ifdef SSA_DEBUG_VERBOSE
832  if (compileverbose) {
833  printf("dce: BB%3i II%3i %s removed \n",
834  lt->def->b_index, lt->def->iindex,
835  bytecode[iptr->opc].mnemonic);
836  }
837 #endif
838  }
839 
840  if (remove_statement) {
841 
842  /* remove statement */
843 
844 #ifdef SSA_DEBUG_VERBOSE
845  if (compileverbose)
846  printf("dce: %s %s:at BB %3i II %3i NOP-<%s\n",
847  m->clazz->name.begin(), m->name.begin(),
848  lt->def->b_index, lt->def->iindex,
849  icmd_table[iptr->opc].name);
850 #endif
851  iptr->opc = ICMD_NOP;
852  }
853  } /* (lt->def->b_index != 0) */
854  } /* if (lt->def->iindex < 0 ) else */
855 
856  /* remove definition of a */
857 
858 #ifdef SSA_DEBUG_VERBOSE
859  if (compileverbose)
860  printf("dce: var %3i removed\n", lt->v_index);
861 #endif
862  VAR(lt->v_index)->type = (Type) jitdata::UNUSED;
863  lt->type = (Type) jitdata::UNUSED;
864  lt->def = NULL;
865 /* jd->var */
866  } /* if (lt->use == NULL) */
867  } /* while(!wl_is_empty(W)) */
868 } /* dead_code_elimination */
869 
870 /****************************************************************************
871 Simple Constant Propagation
872 ****************************************************************************/
873 
875 }
876 
877 /****************************************************************************
878 Optimization
879 *******************************************************************************/
881  int a, i, source;
882  int only_source;
883 
884  worklist *W;
885 
886  instruction *iptr;
887  struct lifetime *lt, *s_lt;
888 
889  lsradata *ls;
890 
891  ls = jd->ls;
892 
893  W = wl_new(ls->lifetimecount);
894  if (ls->lifetimecount > 0) {
895  /* put all lifetimes on Worklist */
896  for(a = 0; a < ls->lifetimecount; a++) {
897  if (ls->lifetime[a].type != jitdata::UNUSED) {
898  wl_add(W, a);
899  }
900  }
901  }
902 
903  while(!wl_is_empty(W)) {
904  /* take a var out of Worklist */
905  a = wl_get(W);
906 
907  lt = ls->lifetime + a;
908  if (lt->type == jitdata::UNUSED)
909  continue;
910  _SSA_ASSERT(lt->def != NULL);
911 #if 0
912  _SSA_ASSERT(lt->use != NULL);
913 #endif
914  if (lt->def->iindex < 0 ) {
915 
916  /* phi function */
917  /* look, if phi function degenerated to a x = phi(y) */
918  /* and if so, substitute y for every use of x */
919 
920  _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] != NULL);
921 
922  only_source = ls->varcount_with_indices;
923  for (i = 1; i <= graph_get_num_predecessor(gd, lt->def->b_index);
924  i++) {
925  source = ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
926  if ((source != ls->varcount_with_indices) &&
927  (source != jitdata::UNUSED)) {
928  if (only_source == ls->varcount_with_indices) {
929 
930  /* first valid source argument of phi function */
931 
932  only_source = source;
933  } else {
934 
935  /* second valid source argument of phi function */
936  /* exit for loop */
937 
938  only_source = ls->varcount_with_indices;
939  break;
940  }
941  }
942  }
943 
944  if (only_source != ls->varcount_with_indices) {
945 
946 #ifdef SSA_DEBUG_VERBOSE
947  if (compileverbose)
948  printf(
949  "-- copy propagation phi-func: BB %3i II %3i: %3i -> %3i\n",
950  lt->def->b_index, lt->def->iindex,
951  only_source, lt->v_index);
952 #endif
953  s_lt = ls->lifetime + only_source;
954 
955  /* replace all use sites of lt with the var_index only_source */
956 
957  ssa_replace_use_sites( jd, gd, lt, only_source, W);
958 
959  /* delete def of lt */
960 
961  ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
962 
963  /* remove this deleted use site of s_lt */
964 
965  lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
966 
967  lt->def = NULL;
968 
969  /* move use sites from lt to s_lt */
970 
971  lt_move_use_sites(lt, s_lt);
972 
973  /* invalidate lt */
974 
975  lt->type = (Type) jitdata::UNUSED;
976  VAR(lt->v_index)->type = (Type) jitdata::UNUSED;
977 
978  /* add s_lt again to Worklist W */
979 
980  wl_add(W, s_lt->v_index);
981 #ifdef SSA_DEBUG_VERBOSE
982  if (compileverbose)
983  _ssa_print_lt(s_lt);
984 #endif
985  } /* if (only_source != ls->varcount_with_indices) */
986  }
987  else { /* if (lt->def->iindex < 0 ) */
988 
989  /* def in argument passing - no propagation possible */
990  /* (there is no ICMD for this... */
991 
992  if (lt->def->b_index == 0)
993  continue;
994 
995  /* def in "normal" ICMD */
996 
997  iptr = ls->basicblocks[lt->def->b_index]->iinstr +
998  lt->def->iindex;
999 
1000  switch(iptr->opc) {
1001  case ICMD_ISTORE:
1002  case ICMD_LSTORE:
1003  case ICMD_FSTORE:
1004  case ICMD_DSTORE:
1005  case ICMD_ASTORE:
1006  case ICMD_ILOAD:
1007  case ICMD_LLOAD:
1008  case ICMD_FLOAD:
1009  case ICMD_DLOAD:
1010  case ICMD_ALOAD:
1011  case ICMD_MOVE:
1012 #ifdef SSA_DEBUG_VERBOSE
1013  if (compileverbose)
1014  printf(
1015  "-- copy propagation %3i %s: BB %3i II %3i: %3i -> %3i\n",
1016  iptr->opc, bytecode[iptr->opc].mnemonic,
1017  lt->def->b_index, lt->def->iindex,
1018  iptr->s1.varindex, iptr->dst.varindex);
1019 #endif
1020  s_lt = ls->lifetime + iptr->s1.varindex;
1021 
1022  _SSA_ASSERT( lt->v_index == iptr->dst.varindex);
1023 
1024  /* replace all use sites of lt with the var_index */
1025  /* iptr->s1.varindex (==lt->v_index) */
1026 
1027  ssa_replace_use_sites(jd, gd, lt, iptr->s1.varindex, W);
1028 
1029  _SSA_ASSERT(lt->def->next == NULL);
1030  _SSA_ASSERT(s_lt->def != NULL);
1031  _SSA_ASSERT(s_lt->def->next == NULL);
1032 
1033  /* this ICMD is not a PEI -> so no danger in deleting it! */
1034  /* delete def of lt (ICMD_NOP) */
1035 
1036  /* lt->def->iindex > 0 -> ICMD */
1037 
1038  iptr->opc = ICMD_NOP;
1039 
1040  /* remove this deleted use site of s_lt */
1041 
1042  lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
1043 
1044  /* invalidate def site of lt */
1045 
1046  lt->def = NULL;
1047 
1048  /* move use sites from lt to s_lt */
1049 
1050  lt_move_use_sites(lt, s_lt);
1051 
1052  /* invalidate lt */
1053 
1054  lt->type = (Type) jitdata::UNUSED;
1055  VAR(lt->v_index)->type = (Type) jitdata::UNUSED;
1056 
1057  /* add s_lt again to Worklist W */
1058  wl_add(W, s_lt->v_index);
1059 #ifdef SSA_DEBUG_VERBOSE
1060  if (compileverbose)
1061  _ssa_print_lt(s_lt);
1062 #endif
1063  break;
1064  default:
1065  break;
1066  }
1067  } /* if (lt->def->iindex < 0 ) */
1068  } /* while(!wl_is_empty(W)) */
1069 }
1070 
1072  int new_v_index, worklist *W) {
1073  struct site *s;
1074  int i, source;
1075  instruction *iptr;
1076  s4 *argp;
1077 
1078  methoddesc *md;
1079  builtintable_entry *bte;
1080  lsradata *ls;
1081 
1082  ls = jd->ls;
1083  md = jd->m->parseddesc;
1084 
1085 
1086  for(s = lt->use; s != NULL; s = s->next) {
1087  if (s->iindex < 0) {
1088 
1089  /* Use in phi function */
1090 
1091  for (i = 1;i <= graph_get_num_predecessor(gd, s->b_index); i++) {
1092  source = ls->phi[s->b_index][-s->iindex-1][i];
1093  if (source == lt->v_index) {
1094 
1095  /* check if this use in this phi function is a */
1096  /* "selfdefinition" (x = phi(...,x,...)) */
1097  /* if so replace the use with -1 (x=phi(...,-1,...)*/
1098 
1099  if (new_v_index == ls->phi[s->b_index][-s->iindex-1][0]) {
1100 #ifdef SSA_DEBUG_VERBOSE
1101  if (W != NULL) {
1102  if (compileverbose)
1103  printf(
1104  "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
1105  s->b_index, s->iindex, -1, source);
1106  }
1107 #endif
1108  ls->phi[s->b_index][-s->iindex-1][i] = -1;
1109 
1110  /* remove this use site of use site */
1111  lt_remove_use_site(lt, s->b_index, s->iindex);
1112  }
1113  else {
1114 #ifdef SSA_DEBUG_VERBOSE
1115  if (W != NULL) {
1116  if (compileverbose)
1117  printf(
1118  "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
1119  s->b_index, s->iindex, new_v_index, source);
1120  }
1121 #endif
1122  ls->phi[s->b_index][-s->iindex-1][i] = new_v_index;
1123  }
1124  }
1125  }
1126  if (W != NULL) {
1127 
1128  /* Add var, which is defined by this phi function to */
1129  /* the worklist */
1130 
1131  source = ls->phi[s->b_index][-s->iindex-1][0];
1132  wl_add(W, source);
1133  }
1134  }
1135  else { /* use in ICMD */
1136 
1137  iptr = ls->basicblocks[s->b_index]->iinstr +
1138  s->iindex;
1139 
1140  /* check for use (s1, s2, s3 or special (argp) ) */
1141 
1142  i = jitdata::UNUSED;
1143  switch (icmd_table[iptr->opc].dataflow) {
1144  case DF_3_TO_0:
1145  case DF_3_TO_1: /* icmd has s1, s2 and s3 */
1146  if (iptr->sx.s23.s3.varindex == lt->v_index) {
1147 #ifdef SSA_DEBUG_VERBOSE
1148  if (W != NULL) {
1149  if (compileverbose)
1150  printf("copy propagation loc3: BB %3i I %3i: %3i -> \
1151  %3i\n", s->b_index, s->iindex,
1152  new_v_index, iptr->sx.s23.s3.varindex);
1153  }
1154 #endif
1155  iptr->sx.s23.s3.varindex = new_v_index;
1156  }
1157 
1158  /* now "fall through" for handling of s2 and s1 */
1159 
1160  case DF_2_TO_0:
1161  case DF_2_TO_1: /* icmd has s1 and s2 */
1162  if (iptr->sx.s23.s2.varindex == lt->v_index) {
1163 #ifdef SSA_DEBUG_VERBOSE
1164  if (W != NULL) {
1165  if (compileverbose)
1166  printf("copy propagation loc2: BB %3i I %3i: %3i -> \
1167  %3i\n", s->b_index, s->iindex,
1168  new_v_index, iptr->sx.s23.s2.varindex);
1169  }
1170 #endif
1171  iptr->sx.s23.s2.varindex = new_v_index;
1172  }
1173 
1174  /* now "fall through" for handling of s1 */
1175 
1176  case DF_1_TO_0:
1177  case DF_1_TO_1:
1178  case DF_MOVE:
1179  case DF_COPY:
1180  if (iptr->s1.varindex == lt->v_index) {
1181 #ifdef SSA_DEBUG_VERBOSE
1182  if (W != NULL) {
1183  if (compileverbose)
1184  printf(
1185  "copy propagation loc1: BB %3i I %3i: %3i -> %3i\n",
1186  s->b_index, s->iindex, new_v_index,
1187  iptr->s1.varindex);
1188  }
1189 #endif
1190  iptr->s1.varindex = new_v_index;
1191  }
1192  break;
1193 
1194  /* TODO: */
1195  /* ? really look at md->paramcount or iptr->s1.argcount */
1196  /* has to be taken, so that pass-through stackslots get */
1197  /* renamed, too? */
1198 
1199  case DF_INVOKE:
1200  INSTRUCTION_GET_METHODDESC(iptr,md);
1201  i = md->paramcount;
1202  break;
1203  case DF_BUILTIN:
1204  bte = iptr->sx.s23.s3.bte;
1205  md = bte->md;
1206  i = md->paramcount;
1207  break;
1208  case DF_N_TO_1:
1209  i = iptr->s1.argcount;
1210  break;
1211  }
1212  if (i != jitdata::UNUSED) {
1213  argp = iptr->sx.s23.s2.args;
1214  while (--i >= 0) {
1215  if (*argp == lt->v_index) {
1216 #ifdef SSA_DEBUG_VERBOSE
1217  if (W != NULL) {
1218  if (compileverbose)
1219  printf(
1220  "copy propagation locN: BB %3i I %3i: %3i -> %3i\n"
1221  , s->b_index, s->iindex, new_v_index, *argp);
1222  }
1223 #endif
1224  *argp = new_v_index;
1225 
1226  }
1227  argp++;
1228  }
1229  }
1230 
1231  } /* if (s->iindex < 0) */
1232  } /* for(s = lt->use; s != NULL; s = s->next) */
1233 }
1234 
1235 #ifdef SSA_DEBUG_VERBOSE
1237  int i;
1238  struct lifetime *lt;
1239 
1240  printf("SSA LT Def/Use\n");
1241  for(i = 0; i < ls->lifetimecount; i++) {
1242  lt = ls->lifetime + i;
1243  _ssa_print_lt(lt);
1244  }
1245 }
1246 
1247 void _ssa_print_lt(struct lifetime *lt) {
1248  struct site *use;
1249 
1250  if (lt->type != jitdata::UNUSED) {
1251  printf("VI %3i Type %3i Def: ",lt->v_index, lt->type);
1252  if (lt->def != NULL)
1253  printf("%3i,%3i Use: ",lt->def->b_index, lt->def->iindex);
1254  else
1255  printf("%3i,%3i Use: ",0,0);
1256  for(use = lt->use; use != NULL; use = use->next)
1257  printf("%3i,%3i ",use->b_index, use->iindex);
1258  printf("\n");
1259  }
1260 }
1261 
1262 void ssa_show_variable(jitdata *jd, int index, varinfo *v, int stage)
1263 {
1264  char type;
1265  char kind;
1266 
1267  switch (v->type) {
1268  case TYPE_INT: type = 'i'; break;
1269  case TYPE_LNG: type = 'l'; break;
1270  case TYPE_FLT: type = 'f'; break;
1271  case TYPE_DBL: type = 'd'; break;
1272  case TYPE_ADR: type = 'a'; break;
1273  case TYPE_RET: type = 'r'; break;
1274  default: type = '?';
1275  }
1276 
1277  if (index < jd->localcount) {
1278  kind = 'L';
1279  if (v->flags & (PREALLOC | INOUT))
1280  printf("<INVALID FLAGS!>");
1281  }
1282  else {
1283  if (v->flags & PREALLOC) {
1284  kind = 'A';
1285  if (v->flags & INOUT)
1286  printf("<INVALID FLAGS!>");
1287  }
1288  else if (v->flags & INOUT)
1289  kind = 'I';
1290  else
1291  kind = 'T';
1292  }
1293 
1294  printf("%c%c%3d", kind, type, index);
1295 
1296  if (v->flags & SAVEDVAR)
1297  putchar('!');
1298 
1299  putchar(' ');
1300  fflush(stdout);
1301 }
1302 #endif
1303 
1304 /****************************************************************************
1305 Optimization
1306 ****************************************************************************/
1307 
1308 /*
1309  * These are local overrides for various environment variables in Emacs.
1310  * Please do not remove this and leave it at the end of the file, where
1311  * Emacs will automagically detect them.
1312  * ---------------------------------------------------------------------
1313  * Local variables:
1314  * mode: c++
1315  * indent-tabs-mode: t
1316  * c-basic-offset: 4
1317  * tab-width: 4
1318  * End:
1319  * vim:noexpandtab:sw=4:ts=4:
1320  */
Utf8String name
Definition: method.hpp:71
int graph_get_next(graphiterator *i)
Definition: graph.cpp:104
std::size_t index
void ssa_set_iovar(lsradata *, s4, int, s4 *)
Definition: ssa.cpp:502
#define DF_1_TO_0
Definition: icmd.hpp:335
basicblock * basicblocks
Definition: jit.hpp:141
Definition: lsra.hpp:67
Definition: jit.hpp:126
#define DF_2_TO_0
Definition: icmd.hpp:336
Definition: stack.hpp:46
void cfg_add_root(jitdata *jd)
Definition: cfg.cpp:468
#define DF_1_TO_1
Definition: icmd.hpp:342
methoddesc * md
Definition: builtin.hpp:71
#define _SSA_ASSERT(a)
Definition: ssa.hpp:44
s4 localcount
Definition: jit.hpp:152
int lifetimecount
Definition: lsra.hpp:169
bitvector * use_sites
Definition: lsra.hpp:156
State state
Definition: jit.hpp:313
bitvector * var_def
Definition: lsra.hpp:154
s4 * invars
Definition: jit.hpp:323
int basicblockcount
Definition: lsra.hpp:188
basicblock * next
Definition: jit.hpp:337
codeinfo * code
Definition: jit.hpp:128
int varcount_with_indices
Definition: lsra.hpp:122
s4 outdepth
Definition: jit.hpp:326
int32_t argcount
Definition: instruction.hpp:64
void computeDF(graphdata *gd, dominatordata *dd, int basicblockcount, int n)
Definition: dominators.cpp:153
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 ssa_set_interface(jitdata *, basicblock *, s4 *)
Definition: ssa.cpp:530
const char * name
Definition: icmd.hpp:393
void ssa_print_phi(lsradata *, graphdata *)
Definition: ssa_phi.cpp:279
void ssa_show_variable(jitdata *jd, int index, varinfo *v, int stage)
Definition: ssa.cpp:1262
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
Type type
Definition: reg.hpp:44
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
Definition: reg.hpp:43
s4 icount
Definition: jit.hpp:318
void cfg_remove_root(jitdata *jd)
Definition: cfg.cpp:500
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd)
Definition: ssa.cpp:578
s4 varcount
Definition: jit.hpp:151
typedesc paramtypes[1]
Definition: descriptor.hpp:167
void _ssa_print_lt(struct lifetime *lt)
Definition: ssa.cpp:1247
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
const char * mnemonic
Definition: bytecode.hpp:39
void lt_scanlifetimes(jitdata *jd, graphdata *gd, dominatordata *dd)
Definition: lifetimes.cpp:108
void ssa_replace_use_sites(jitdata *, graphdata *, struct lifetime *, int, worklist *)
Definition: ssa.cpp:1071
static void ssa_rename(ssa_info *ssa)
Definition: ssa2.cpp:412
#define DF_N_TO_1
Definition: icmd.hpp:345
int * new_varindex
Definition: lsra.hpp:123
#define ICMDTABLE_PEI
Definition: icmd.hpp:384
dst_operand_t dst
bool compileverbose
Definition: options.cpp:82
void simple_constant_propagation()
Definition: ssa.cpp:874
classinfo * clazz
Definition: method.hpp:80
int32_t dataflow
Definition: icmd.hpp:395
Utf8String name
Definition: class.hpp:91
void ssa_init(jitdata *jd)
Definition: ssa.cpp:275
#define DF_COPY
Definition: icmd.hpp:350
int ssavarcount
Definition: lsra.hpp:115
Type
Types used internally by JITTED code.
Definition: global.hpp:117
s4 indepth
Definition: jit.hpp:325
void transform_BB(jitdata *jd, graphdata *gd)
Definition: graph.cpp:658
s4 * local_map
Definition: jit.hpp:153
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
basicblock ** basicblocks
Definition: lsra.hpp:189
int32_t s4
Definition: types.hpp:45
void graph_make_cfg(jitdata *jd, graphdata *gd)
Definition: graph.cpp:206
#define DF_MOVE
Definition: icmd.hpp:351
s4 * outvars
Definition: jit.hpp:324
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)
void yssa(jitdata *jd)
Definition: ssa3.cpp:2374
s1_operand_t s1
void lt_move_use_sites(struct lifetime *from, struct lifetime *to)
Definition: lifetimes.cpp:574
int b_index
Definition: lsra.hpp:68
void cfg_add_exceptional_edges(jitdata *jd)
byte_iterator begin() const
Definition: utf8.hpp:106
methoddesc * parseddesc
Definition: method.hpp:78
int graph_get_num_predecessor(graphdata *gd, int b_index)
Definition: graph.cpp:84
Definition: builtin.hpp:60
methodinfo * m
Definition: jit.hpp:127
void ssa_set_def(lsradata *, int, int)
Definition: ssa.cpp:449
worklist * wl_new(int size)
Definition: worklist.cpp:68
s4 flags
Definition: reg.hpp:45
void ssa_set_local_def(lsradata *, int, int)
Definition: ssa.cpp:471
void ssa_generate_phi_moves(jitdata *jd, graphdata *gd)
Definition: ssa_phi.cpp:203
#define DF_INVOKE
Definition: icmd.hpp:347
void dead_code_elimination(jitdata *jd, graphdata *gd)
Definition: ssa.cpp:649
s4 nr
Definition: jit.hpp:312
s4 basicblockcount
Definition: jit.hpp:144
dominatordata * compute_Dominators(graphdata *gd, int basicblockcount)
Definition: dominators.cpp:71
#define DMNEW(type, num)
Definition: dumpmemory.hpp:371
void wl_add(worklist *w, int element)
Definition: worklist.cpp:88
void copy_propagation(jitdata *jd, graphdata *gd)
Definition: ssa.cpp:880
OStream & out()
Definition: OStream.cpp:39
struct instruction::@12::@13 s23
void ssa(jitdata *jd)
Definition: ssa.cpp:105
int * num_defs
Definition: lsra.hpp:165
int wl_get(worklist *w)
Definition: worklist.cpp:107
bitvector bv_new(int size)
Definition: bitvector.cpp:122
void bv_set_bit(bitvector bv, int bit)
Definition: bitvector.cpp:166
bytecode_t bytecode[256]
Definition: bytecode.cpp:33
s4 stackcount
Definition: jit.hpp:145
#define DF_BUILTIN
Definition: icmd.hpp:348
#define log_text(s)
Definition: logging.hpp:170
Type type
Definition: jit.hpp:315
#define DF_DST_BASE
Definition: icmd.hpp:339
#define printf(...)
Definition: ssa2.cpp:40
#define DF_2_TO_1
Definition: icmd.hpp:343
graphdata * graph_init(int basicblockcount)
Definition: graph.cpp:60
void ssa_print_lt(lsradata *ls)
Definition: ssa.cpp:1236
void xssa(jitdata *jd)
Definition: ssa2.cpp:627
int *** phi
Definition: lsra.hpp:193
int32_t flags
Definition: icmd.hpp:397
static void ssa_place_phi_functions(ssa_info *ssa)
Definition: ssa2.cpp:96