1 /* src/vm/jit/optimizing/ssa.c - static single-assignment form
3 Copyright (C) 2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
31 #include "mm/memory.h"
33 #include "toolbox/bitvector.h"
34 #include "toolbox/worklist.h"
36 #include "vm/builtin.h"
38 #include "vm/jit/jit.h" /* icmd_table */
40 #include "vm/jit/ir/bytecode.h"
42 #include "vm/jit/optimizing/dominators.h"
43 #include "vm/jit/optimizing/graph.h"
44 #include "vm/jit/optimizing/lifetimes.h"
45 #include "vm/jit/optimizing/lsra.h"
47 #include "vm/jit/optimizing/ssa.h"
48 #include "vm/jit/optimizing/ssa_rename.h"
49 #include "vm/jit/optimizing/ssa_phi.h"
51 #include "vm/jit/python.h"
53 #if defined(SSA_DEBUG_VERBOSE)
54 #include "vmcore/options.h" /* compileverbose */
57 /* function prototypes */
58 void ssa_set_local_def(lsradata *, int , int);
59 void ssa_set_interface(jitdata *, basicblock *, s4 *);
61 void dead_code_elimination(jitdata *jd, graphdata *gd);
62 void copy_propagation(jitdata *jd, graphdata *gd);
63 void ssa_replace_use_sites(jitdata *, graphdata *, struct lifetime *,
66 void ssa_set_def(lsradata *, int , int );
67 void ssa_set_local_def(lsradata *, int , int );
68 void ssa_set_iovar(lsradata *, s4 , int , s4 *);
69 void ssa_set_interface(jitdata *, basicblock *, s4 *);
72 #ifdef SSA_DEBUG_VERBOSE
73 void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd);
74 void ssa_print_lt(lsradata *ls);
75 void _ssa_print_lt(struct lifetime *lt);
76 void ssa_show_variable(jitdata *jd, int index, varinfo *v, int stage);
77 void ssa_print_phi(lsradata *, graphdata *);
80 /* ssa ************************************************************************
84 SSA Algorithms are based on "modern compiler implementation in C" from andrew
85 w. appel, edition 2004
88 page 441 Algorithm 19.6. Inserting phi-functions:
92 - if Y not element of A phi [n]
93 + if a not element of A phi [n]
94 insert the statment a <- ...
97 - A phi [n] <- A phi [n] join {Y}
98 + A phi [n] <- A phi [n] join {a}
99 - if Y not element of A orig [n]
100 + if a not element of A orig [Y]
103 ******************************************************************************/
104 void xssa(jitdata *jd);
105 void yssa(jitdata *jd);
106 void ssa(jitdata *jd) {
107 struct dominatordata *dd;
111 #if defined(ENABLE_LOOPS)
112 /* Loop optimization "destroys" the basicblock array */
113 /* TODO: work with the basicblock list */
115 log_text("lsra not possible with loop optimization\n");
121 dominator_tree_build(jd);
122 /*pythonpass_run(jd, "foo", "cfg_print");*/
123 dominance_frontier_build(jd);
124 /*dominator_tree_validate(jd, dd);*/
125 /*pythonpass_run(jd, "ssa2", "main");*/
126 /*pythonpass_run(jd, "alt_ssa", "main");*/
127 pythonpass_run(jd, "foo", "before");
128 if (getenv("XSSA")) {
133 pythonpass_run(jd, "foo", "after");
139 /* Generate the Control Flow Graph */
140 /* Add one for a Basic Block 0 to be inserted, so lateron */
141 /* with SSA Parameter initialization is handled right */
143 gd = graph_init(jd->basicblockcount + 1);
144 graph_make_cfg(jd, gd);
146 dd = compute_Dominators(gd, ls->basicblockcount);
147 computeDF(gd, dd, ls->basicblockcount, 0);
149 ssa_place_phi_functions(jd, gd, dd);
150 ssa_rename(jd, gd, dd);
151 #ifdef SSA_DEBUG_VERBOSE
152 if (compileverbose) {
153 printf("Phi before Cleanup\n");
154 ssa_print_phi(ls, gd);
158 lt_scanlifetimes(jd, gd, dd);
159 #ifdef SSA_DEBUG_VERBOSE
160 if (compileverbose) {
165 dead_code_elimination(jd, gd);
166 #ifdef SSA_DEBUG_VERBOSE
167 if (compileverbose) {
168 printf("Phi after dead code elemination\n");
169 ssa_print_phi(ls, gd);
175 copy_propagation(jd, gd);
176 #ifdef SSA_DEBUG_VERBOSE
177 if (compileverbose) {
178 printf("Phi after copy propagation\n");
179 ssa_print_phi(ls, gd);
185 ssa_generate_phi_moves(jd, gd);
186 transform_BB(jd, gd);
188 lt_lifeness_analysis(jd, gd);
190 #ifdef SSA_DEBUG_CHECK
192 int i, j, pred, in_d, out_d;
193 graphiterator iter_pred;
200 for(i = 0; i < ls->basicblockcount; i++) {
201 if (ls->basicblocks[i]->indepth != 0) {
202 pred = graph_get_first_predecessor(gd, i, &iter_pred);
203 for (; (pred != -1); pred = graph_get_next(&iter_pred)) {
204 in_d = ls->basicblocks[i]->indepth - 1;
205 in = ls->basicblocks[i]->invars;
206 for (; in_d >= 0; in_d--) {
208 for (j = 0; (!phi_define) && (j<ls->ssavarcount); j++) {
209 if (ls->phi[i][j] != NULL)
210 if (ls->phi[i][j][0] == in[in_d])
214 /* in not defined in phi function -> check with */
215 /* outstack(s) of predecessor(s) */
216 out_d = ls->basicblocks[pred]->outdepth - 1;
217 out = ls->basicblocks[pred]->outvars;
218 _SSA_ASSERT(out_d >= in_d);
219 for(; out_d > in_d; out_d--);
220 if ((in[in_d] != out[out_d]) ||
221 (VAR(in[in_d])->flags != VAR(out[out_d])->flags)) {
222 printf("Method: %s %s\n",
223 m->class->name->text, m->name->text);
224 printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
226 printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
228 /* _SSA_ASSERT(0); */
239 #ifdef SSA_DEBUG_VERBOSE
241 ssa_print_trees(jd, gd, dd);
246 /* ssa_init *******************************************************************
248 Initialise data structures for ssa
250 IOVARS of same stackdepth and same type are coalesced:
251 interface_map[ 5 * stackdepth + type ] = new_varindex with
252 0 <= new_varindex < ls->ssavarcount
254 TODO: check if coalescing of IOVARS of same stackdepth and type only of adjacent
255 basic blocks could decrease the number of phi functions and so improve ssa
256 analysis performance!
258 All LOCALVARS and IOVARS get a new unique varindex:
259 ls->new_varindex[0..jd->varcount[ = new_varindex with
260 0 <= new_varindex < ls->ssavarcount
262 The jd->varcount bits long bitvectors ls->var_def[0..jd->basicblockindex+1[
263 are set to the definitions of LOCALVARS and IOVARS. (So the only the first
264 ls->ssavarcount bits of each of these vectors contain valid data, but
265 ls->ssavarcount is computed at the same time as the definitons are stored.)
267 The basic block number used as index for the bitvector array ls->var_def is
268 already shifted by one to make space for the new basic block 0 for parameter
271 ******************************************************************************/
273 void ssa_init(jitdata *jd) {
276 int i, l, b_index, len;
279 s4 *interface_map; /* holds an new unique index for every used */
280 /* basic block inoutvar described by a dupel */
281 /*(depth,type). Used to coalesce the inoutvars*/
284 builtintable_entry *bte;
291 #if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
292 # if defined(SSA_DEBUG_VERBOSE)
293 if (compileverbose) {
294 printf("%s %s ",m->class->name->text, m->name->text);
295 if (code_is_leafmethod(jd->code))
296 printf("**Leafmethod**");
300 if (strcmp(m->class->name->text,"spec/benchmarks/_213_javac/Parser")==0)
301 if (strcmp(m->name->text,"parseTerm")==0)
302 # if defined(SSA_DEBUG_VERBOSE)
304 printf("12-------------------12\n");
306 { int dummy=1; dummy++; }
310 #ifdef SSA_DEBUG_VERBOSE
312 printf("ssa_init: basicblockcount %3i localcount %3i\n",
313 jd->basicblockcount, jd->localcount);
316 /* As first step all definitions of local variables and in/out vars are */
317 /* gathered. in/outvars are coalesced for same type and depth */
318 /* "normal" tempvars (just living within one basicblock are) ignored */
320 ls->num_defs = DMNEW(int, jd->varcount);
321 ls->new_varindex = DMNEW(int , jd->varcount);
323 for(p = 0; p < jd->varcount; p++) {
325 ls->new_varindex[p] = UNUSED;
328 /* init Var Definition bitvectors */
330 ls->var_def = DMNEW(int *, jd->basicblockcount + 1);
331 for(i = 0; i < jd->basicblockcount + 1; i++) {
332 ls->var_def[i] = bv_new(jd->varcount);
337 /* Add parameters first in right order, so the new local indices */
338 /* 0..p will correspond to "their" parameters */
339 /* They get defined at the artificial Block 0, the real method bbs will */
340 /* be ed to start at block 1 */
342 /* don't look at already eliminated (not used) parameters (locals) */
344 for (p = 0, l = 0; p < md->paramcount; p++) {
345 t = md->paramtypes[p].type;
346 i = jd->local_map[l * 5 + t];
348 if (IS_2_WORD_TYPE(t)) /* increment local counter a second time */
349 l++; /* for 2 word types */
352 ssa_set_local_def(ls, -1, i);
355 _SSA_ASSERT(ls->ssavarcount < jd->varcount);
357 /* coalesce bb in/out vars */
359 interface_map = DMNEW(s4, jd->stackcount * 5);
360 for(i = 0; i < jd->stackcount * 5; i++)
361 interface_map[i] = UNUSED;
363 bptr = jd->basicblocks;
365 for(; bptr != NULL; bptr = bptr->next) {
366 #ifdef SSA_DEBUG_VERBOSE
368 printf("ssa_init: BB %3i flags %3x\n",bptr->nr, bptr->flags);
370 if (bptr->flags >= BBREACHED) {
372 /* 'valid' Basic Block */
378 ssa_set_interface(jd, bptr, interface_map);
380 /* !!!!!!!!! not true for now !!!!!!!!! */
381 /* All baseline optimizations from stack.c are turned off for */
384 for (; len > 0; len--, iptr++) {
386 /* Look for definitions (iptr->dst). INVOKE and BUILTIN have */
387 /* an optional dst - so they to be checked first */
390 if (icmd_table[iptr->opc].dataflow == DF_INVOKE) {
391 INSTRUCTION_GET_METHODDESC(iptr,md);
392 if (md->returntype.type != TYPE_VOID)
393 v = iptr->dst.varindex;
395 else if (icmd_table[iptr->opc].dataflow == DF_BUILTIN) {
396 bte = iptr->sx.s23.s3.bte;
398 if (md->returntype.type != TYPE_VOID)
399 v = iptr->dst.varindex;
401 else if (icmd_table[iptr->opc].dataflow >= DF_DST_BASE) {
402 v = iptr->dst.varindex;
406 if (( v < jd->localcount) || ( VAR(v)->flags & INOUT )) {
408 /* !IS_TEMPVAR && !IS_PREALLOC == (IS_LOCALVAR || IS_INOUT) */
410 ssa_set_local_def(ls, b_index, v);
416 _SSA_ASSERT(ls->ssavarcount < jd->varcount);
418 #ifdef SSA_DEBUG_VERBOSE
419 if (compileverbose) {
420 printf("ssa_init: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
422 for(i = 0; i < jd->varcount; i++) {
423 if ((i < jd->localcount) || ( VAR(i)->flags & INOUT)) {
424 printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
425 ssa_show_variable(jd, i, VAR(i),0);
426 if (i < ls->ssavarcount) {
427 printf(" -> %3i", ls->new_varindex[i]);
436 /* ssa_set_def ****************************************************************
438 Helper for ssa_set_local_def and ssa_set_interface
440 The definition of a var is stored in the bitvector array ls->var_def.
442 The number of definitons of each var is counted, so the number of new vars with
445 ******************************************************************************/
447 void ssa_set_def(lsradata *ls, int b_index, int varindex) {
449 /* b_index + 1 to leave space for the param init block 0 */
451 bv_set_bit(ls->var_def[b_index + 1], varindex);
453 /* count number of defs for every var since SSA */
454 /* will create a new var for every definition */
456 ls->num_defs[varindex]++;
459 /* ssa_set_local_def **********************************************************
463 Assigns a new unique index for the local var varindex (if not already done so)
464 and then calls ssa_set_def to remember the definition in the bitvector array
467 ******************************************************************************/
469 void ssa_set_local_def(lsradata *ls, int b_index, int varindex) {
471 if (ls->new_varindex[varindex] == UNUSED) {
472 ls->new_varindex[varindex] = ls->ssavarcount++;
475 ssa_set_def(ls, b_index, ls->new_varindex[varindex]);
478 /* ssa_set_local_def **********************************************************
480 Helper for ssa_set_interface
482 IN: ls pointer to lsradata structure
483 iovar varindex of INOUTVAR to process
484 map_index stackdepth * 5 + type, used for coalescing IOVARS.
487 interface_map used for coalescing IOVARS. interface_map[map_index] ==
488 UNUSED, if this map_index (==stackdepth,type tupel) did not
489 occur till now. Then interface_map[map_index] will be set
490 to a new unique index.
491 ls->new_varindex will be set to this new unique index to map the old
492 varindizes to the new ones.
494 Assigns a new unique index for the local var varindex (if not already done so)
495 and then calls ssa_set_def to remember the definition in the bitvector array
498 ******************************************************************************/
500 void ssa_set_iovar(lsradata *ls, s4 iovar, int map_index, s4 *interface_map) {
501 if (interface_map[map_index] == UNUSED)
502 interface_map[map_index] = ls->ssavarcount++;
504 ls->new_varindex[iovar] = interface_map[map_index];
508 /* ssa_set_interface ***********************************************************
512 IN: ls pointer to lsradata structure
513 *bptr pointer to the basic block to be processed
516 interface_map used for coalescing IOVARS. interface_map[map_index] ==
517 UNUSED, if this map_index (==stackdepth,type tupel) did not
518 occur till now. Then interface_map[map_index] will be set
519 to a new unique index. (see ssa_set_iovar)
521 Searches the basic block given by *bptr for IN and OUTVARS and coalesces them
522 for each unique stackdepth,type dupel. For each OUTVAR with a different or no
523 INVAR at the same stackdepth the definition of this OUTVAR in this basic block
524 is remembered in ls->var_def. (see ssa_set_def)
526 ******************************************************************************/
528 void ssa_set_interface(jitdata *jd, basicblock *bptr, s4 *interface_map) {
531 int o_map_index, i_map_index;
538 in_d = bptr->indepth - 1;
539 out_d = bptr->outdepth - 1;
541 /* ignore top Stackelement of instack in case of EXH or SBR blocks */
542 /* These are no Interface stackslots! */
543 if ((bptr->type == BBTYPE_EXH) ||
544 (bptr->type == BBTYPE_SBR)) {
548 /* invars with no corresponding outvars are not defined here */
549 /* just set up the interface_map */
551 for(;(in_d > out_d); in_d--) {
552 i_map_index = in_d * 5 + VAR(in[in_d])->type;
553 ssa_set_iovar(ls, in[in_d], i_map_index, interface_map);
556 while((out_d >= 0)) {
557 /* set up interface_map */
559 o_map_index = out_d * 5 + VAR(out[out_d])->type;
561 i_map_index = in_d * 5 + VAR(in[in_d])->type;
562 ssa_set_iovar(ls, in[in_d], i_map_index, interface_map);
564 ssa_set_iovar(ls, out[out_d], o_map_index, interface_map);
575 #ifdef SSA_DEBUG_VERBOSE
576 void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd) {
582 printf("ssa_printtrees: maxlocals %3i", jd->localcount);
584 printf("Dominator Tree: \n");
585 for(i = 0; i < ls->basicblockcount; i++) {
587 for(j = 0; j < ls->basicblockcount; j++) {
588 if (dd->idom[j] == i) {
595 printf("Dominator Forest:\n");
596 for(i = 0; i < ls->basicblockcount; i++) {
598 for(j = 0; j < dd->num_DF[i]; j++) {
599 printf(" %3i", dd->DF[i][j]);
604 if (ls->ssavarcount > 0) {
605 printf("Use Sites\n");
606 for(i = 0; i < ls->ssavarcount; i++) {
607 printf("use_sites[%3i]=%p:",i,(void *)ls->use_sites[i]);
608 for(j = 0; j < ls->basicblockcount; j++) {
609 if ((j % 5) == 0) printf(" ");
610 if (bv_get_bit(ls->use_sites[i], j))
619 printf("var Definitions:\n");
620 for(i = 0; i < jd->basicblockcount; i++) {
621 printf("var_def[%3i]=%p:",i,(void *)ls->var_def[i]);
622 for(j = 0; j < ls->ssavarcount; j++) {
623 if ((j % 5) == 0) printf(" ");
624 if (bv_get_bit(ls->var_def[i], j))
630 for(j=0; j < ((((ls->ssavarcount * 5+7)/8) + sizeof(int) - 1)/sizeof(int));
632 printf("%8x",ls->var_def[i][j]);
639 /****************************************************************************
641 ****************************************************************************/
644 /****************************************************************************
645 Dead Code Elimination
646 ****************************************************************************/
647 void dead_code_elimination(jitdata *jd, graphdata *gd) {
652 struct lifetime *lt, *s_lt;
654 bool remove_statement;
658 #ifdef SSA_DEBUG_VERBOSE
665 W = wl_new(ls->lifetimecount);
666 if (ls->lifetimecount > 0) {
668 /* put all lifetimes into Worklist W */
670 for(a = 0; a < ls->lifetimecount; a++) {
671 if (ls->lifetime[a].type != UNUSED) {
677 /* Remove unused lifetimes */
679 while(!wl_is_empty(W)) {
681 /* take a var out of Worklist */
685 lt = &(ls->lifetime[a]);
686 if ((lt->def == NULL) || (lt->type == UNUSED))
688 /* lifetime was already removed -> no defs anymore */
692 /* Remove lifetimes, which are only used in the phi function which */
695 remove_statement = (lt->use != NULL) && (lt->use->iindex < 0);
696 for(use = lt->use; (remove_statement && (use != NULL));
699 remove_statement = remove_statement &&
700 (use->b_index == lt->def->b_index) &&
701 (use->iindex == lt->def->iindex);
704 if (remove_statement) {
705 #ifdef SSA_DEBUG_CHECK
707 /* def == use can only happen in phi functions */
709 if (remove_statement)
710 _SSA_ASSERT(lt->use->iindex < 0);
713 /* give it free for removal */
718 if (lt->use == NULL) {
720 /* Look at statement of definition of a and remove it, */
721 /* if the Statement has no sideeffects other than the assignemnt */
724 if (lt->def->iindex < 0 ) {
727 /* delete use of sources , delete phi functions */
729 _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] !=
732 for (i = 1;i <= graph_get_num_predecessor(gd, lt->def->b_index);
735 ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
736 if ((source != ls->varcount_with_indices) &&
737 (source != lt->v_index) &&
738 (source != UNUSED)) {
740 /* phi Argument was not already removed (already in
741 because of "selfdefinition") */
743 s_lt = &(ls->lifetime[source]);
747 lt_remove_use_site(s_lt,lt->def->b_index,
750 /* put it on the Worklist */
756 /* now delete phi function itself */
757 #ifdef SSA_DEBUG_VERBOSE
758 if (compileverbose) {
759 printf("dce: BB%3i phi for var %3i=%3i removed \n",
760 lt->def->b_index, -lt->def->iindex - 1,
765 ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
769 /* "normal" Use by ICMD */
771 remove_statement = false;
772 if (lt->def->b_index != 0) {
774 /* do not look at artificial block 0 (parameter init) */
776 iptr = ls->basicblocks[lt->def->b_index]->iinstr +
779 if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {
781 /* if ICMD could throw an exception do not remove it! */
783 remove_statement = false;
784 #ifdef SSA_DEBUG_VERBOSE
785 if (compileverbose) {
786 printf("dce: PEI: BB%3i II%3i %s not removed \n",
787 lt->def->b_index, lt->def->iindex,
788 bytecode[iptr->opc].mnemonic);
794 remove_statement = true;
796 switch (icmd_table[iptr->opc].dataflow) {
798 case DF_3_TO_1: /* icmd has s1, s2 and s3 */
799 a = iptr->sx.s23.s3.varindex;
800 s_lt = ls->lifetime + a;
801 lt_remove_use_site(s_lt, lt->def->b_index,
805 /* "fall through" for handling of s2 and s1 */
808 case DF_2_TO_1: /* icmd has s1 and s2 */
809 a = iptr->sx.s23.s2.varindex;
810 s_lt = ls->lifetime + a;
811 lt_remove_use_site(s_lt, lt->def->b_index,
815 /* "fall through" for handling of s1 */
817 /* DF_{IINC,STORE,LOAD} are DF_{1_TO_1,MOVE,COPY} */
823 a = iptr->s1.varindex;
824 s_lt = ls->lifetime + a;
825 lt_remove_use_site(s_lt, lt->def->b_index,
829 #ifdef SSA_DEBUG_VERBOSE
830 if (compileverbose) {
831 printf("dce: BB%3i II%3i %s removed \n",
832 lt->def->b_index, lt->def->iindex,
833 bytecode[iptr->opc].mnemonic);
838 if (remove_statement) {
840 /* remove statement */
842 #ifdef SSA_DEBUG_VERBOSE
844 printf("dce: %s %s:at BB %3i II %3i NOP-<%s\n",
845 m->class->name->text, m->name->text,
846 lt->def->b_index, lt->def->iindex,
847 icmd_table[iptr->opc].name);
849 iptr->opc = ICMD_NOP;
851 } /* (lt->def->b_index != 0) */
852 } /* if (lt->def->iindex < 0 ) else */
854 /* remove definition of a */
856 #ifdef SSA_DEBUG_VERBOSE
858 printf("dce: var %3i removed\n", lt->v_index);
860 VAR(lt->v_index)->type = UNUSED;
864 } /* if (lt->use == NULL) */
865 } /* while(!wl_is_empty(W)) */
866 } /* dead_code_elimination */
868 /****************************************************************************
869 Simple Constant Propagation
870 ****************************************************************************/
872 void simple_constant_propagation() {
875 /****************************************************************************
877 *******************************************************************************/
878 void copy_propagation(jitdata *jd, graphdata *gd) {
885 struct lifetime *lt, *s_lt;
891 W = wl_new(ls->lifetimecount);
892 if (ls->lifetimecount > 0) {
893 /* put all lifetimes on Worklist */
894 for(a = 0; a < ls->lifetimecount; a++) {
895 if (ls->lifetime[a].type != UNUSED) {
901 while(!wl_is_empty(W)) {
902 /* take a var out of Worklist */
905 lt = ls->lifetime + a;
906 if (lt->type == UNUSED)
908 _SSA_ASSERT(lt->def != NULL);
910 _SSA_ASSERT(lt->use != NULL);
912 if (lt->def->iindex < 0 ) {
915 /* look, if phi function degenerated to a x = phi(y) */
916 /* and if so, substitute y for every use of x */
918 _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] != NULL);
920 only_source = ls->varcount_with_indices;
921 for (i = 1; i <= graph_get_num_predecessor(gd, lt->def->b_index);
923 source = ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
924 if ((source != ls->varcount_with_indices) &&
925 (source != UNUSED)) {
926 if (only_source == ls->varcount_with_indices) {
928 /* first valid source argument of phi function */
930 only_source = source;
933 /* second valid source argument of phi function */
936 only_source = ls->varcount_with_indices;
942 if (only_source != ls->varcount_with_indices) {
944 #ifdef SSA_DEBUG_VERBOSE
947 "-- copy propagation phi-func: BB %3i II %3i: %3i -> %3i\n",
948 lt->def->b_index, lt->def->iindex,
949 only_source, lt->v_index);
951 s_lt = ls->lifetime + only_source;
953 /* replace all use sites of lt with the var_index only_source */
955 ssa_replace_use_sites( jd, gd, lt, only_source, W);
957 /* delete def of lt */
959 ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
961 /* remove this deleted use site of s_lt */
963 lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
967 /* move use sites from lt to s_lt */
969 lt_move_use_sites(lt, s_lt);
974 VAR(lt->v_index)->type = UNUSED;
976 /* add s_lt again to Worklist W */
978 wl_add(W, s_lt->v_index);
979 #ifdef SSA_DEBUG_VERBOSE
983 } /* if (only_source != ls->varcount_with_indices) */
985 else { /* if (lt->def->iindex < 0 ) */
987 /* def in argument passing - no propagation possible */
988 /* (there is no ICMD for this... */
990 if (lt->def->b_index == 0)
993 /* def in "normal" ICMD */
995 iptr = ls->basicblocks[lt->def->b_index]->iinstr +
1010 #ifdef SSA_DEBUG_VERBOSE
1013 "-- copy propagation %3i %s: BB %3i II %3i: %3i -> %3i\n",
1014 iptr->opc, bytecode[iptr->opc].mnemonic,
1015 lt->def->b_index, lt->def->iindex,
1016 iptr->s1.varindex, iptr->dst.varindex);
1018 s_lt = ls->lifetime + iptr->s1.varindex;
1020 _SSA_ASSERT( lt->v_index == iptr->dst.varindex);
1022 /* replace all use sites of lt with the var_index */
1023 /* iptr->s1.varindex (==lt->v_index) */
1025 ssa_replace_use_sites(jd, gd, lt, iptr->s1.varindex, W);
1027 _SSA_ASSERT(lt->def->next == NULL);
1028 _SSA_ASSERT(s_lt->def != NULL);
1029 _SSA_ASSERT(s_lt->def->next == NULL);
1031 /* this ICMD is not a PEI -> so no danger in deleting it! */
1032 /* delete def of lt (ICMD_NOP) */
1034 /* lt->def->iindex > 0 -> ICMD */
1036 iptr->opc = ICMD_NOP;
1038 /* remove this deleted use site of s_lt */
1040 lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
1042 /* invalidate def site of lt */
1046 /* move use sites from lt to s_lt */
1048 lt_move_use_sites(lt, s_lt);
1053 VAR(lt->v_index)->type = UNUSED;
1055 /* add s_lt again to Worklist W */
1056 wl_add(W, s_lt->v_index);
1057 #ifdef SSA_DEBUG_VERBOSE
1059 _ssa_print_lt(s_lt);
1063 } /* if (lt->def->iindex < 0 ) */
1064 } /* while(!wl_is_empty(W)) */
1067 void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
1068 int new_v_index, worklist *W) {
1075 builtintable_entry *bte;
1079 md = jd->m->parseddesc;
1082 for(s = lt->use; s != NULL; s = s->next) {
1083 if (s->iindex < 0) {
1085 /* Use in phi function */
1087 for (i = 1;i <= graph_get_num_predecessor(gd, s->b_index); i++) {
1088 source = ls->phi[s->b_index][-s->iindex-1][i];
1089 if (source == lt->v_index) {
1091 /* check if this use in this phi function is a */
1092 /* "selfdefinition" (x = phi(...,x,...)) */
1093 /* if so replace the use with -1 (x=phi(...,-1,...)*/
1095 if (new_v_index == ls->phi[s->b_index][-s->iindex-1][0]) {
1096 #ifdef SSA_DEBUG_VERBOSE
1100 "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
1101 s->b_index, s->iindex, -1, source);
1104 ls->phi[s->b_index][-s->iindex-1][i] = -1;
1106 /* remove this use site of use site */
1107 lt_remove_use_site(lt, s->b_index, s->iindex);
1110 #ifdef SSA_DEBUG_VERBOSE
1114 "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
1115 s->b_index, s->iindex, new_v_index, source);
1118 ls->phi[s->b_index][-s->iindex-1][i] = new_v_index;
1124 /* Add var, which is defined by this phi function to */
1127 source = ls->phi[s->b_index][-s->iindex-1][0];
1131 else { /* use in ICMD */
1133 iptr = ls->basicblocks[s->b_index]->iinstr +
1136 /* check for use (s1, s2, s3 or special (argp) ) */
1139 switch (icmd_table[iptr->opc].dataflow) {
1141 case DF_3_TO_1: /* icmd has s1, s2 and s3 */
1142 if (iptr->sx.s23.s3.varindex == lt->v_index) {
1143 #ifdef SSA_DEBUG_VERBOSE
1146 printf("copy propagation loc3: BB %3i I %3i: %3i -> \
1147 %3i\n", s->b_index, s->iindex,
1148 new_v_index, iptr->sx.s23.s3.varindex);
1151 iptr->sx.s23.s3.varindex = new_v_index;
1154 /* now "fall through" for handling of s2 and s1 */
1157 case DF_2_TO_1: /* icmd has s1 and s2 */
1158 if (iptr->sx.s23.s2.varindex == lt->v_index) {
1159 #ifdef SSA_DEBUG_VERBOSE
1162 printf("copy propagation loc2: BB %3i I %3i: %3i -> \
1163 %3i\n", s->b_index, s->iindex,
1164 new_v_index, iptr->sx.s23.s2.varindex);
1167 iptr->sx.s23.s2.varindex = new_v_index;
1170 /* now "fall through" for handling of s1 */
1176 if (iptr->s1.varindex == lt->v_index) {
1177 #ifdef SSA_DEBUG_VERBOSE
1181 "copy propagation loc1: BB %3i I %3i: %3i -> %3i\n",
1182 s->b_index, s->iindex, new_v_index,
1186 iptr->s1.varindex = new_v_index;
1191 /* ? really look at md->paramcount or iptr->s1.argcount */
1192 /* has to be taken, so that pass-through stackslots get */
1196 INSTRUCTION_GET_METHODDESC(iptr,md);
1200 bte = iptr->sx.s23.s3.bte;
1205 i = iptr->s1.argcount;
1209 argp = iptr->sx.s23.s2.args;
1211 if (*argp == lt->v_index) {
1212 #ifdef SSA_DEBUG_VERBOSE
1216 "copy propagation locN: BB %3i I %3i: %3i -> %3i\n"
1217 , s->b_index, s->iindex, new_v_index, *argp);
1220 *argp = new_v_index;
1227 } /* if (s->iindex < 0) */
1228 } /* for(s = lt->use; s != NULL; s = s->next) */
1231 #ifdef SSA_DEBUG_VERBOSE
1232 void ssa_print_lt(lsradata *ls) {
1234 struct lifetime *lt;
1236 printf("SSA LT Def/Use\n");
1237 for(i = 0; i < ls->lifetimecount; i++) {
1238 lt = ls->lifetime + i;
1243 void _ssa_print_lt(struct lifetime *lt) {
1246 if (lt->type != UNUSED) {
1247 printf("VI %3i Type %3i Def: ",lt->v_index, lt->type);
1248 if (lt->def != NULL)
1249 printf("%3i,%3i Use: ",lt->def->b_index, lt->def->iindex);
1251 printf("%3i,%3i Use: ",0,0);
1252 for(use = lt->use; use != NULL; use = use->next)
1253 printf("%3i,%3i ",use->b_index, use->iindex);
1258 void ssa_show_variable(jitdata *jd, int index, varinfo *v, int stage)
1264 case TYPE_INT: type = 'i'; break;
1265 case TYPE_LNG: type = 'l'; break;
1266 case TYPE_FLT: type = 'f'; break;
1267 case TYPE_DBL: type = 'd'; break;
1268 case TYPE_ADR: type = 'a'; break;
1269 case TYPE_RET: type = 'r'; break;
1270 default: type = '?';
1273 if (index < jd->localcount) {
1275 if (v->flags & (PREALLOC | INOUT))
1276 printf("<INVALID FLAGS!>");
1279 if (v->flags & PREALLOC) {
1281 if (v->flags & INOUT)
1282 printf("<INVALID FLAGS!>");
1284 else if (v->flags & INOUT)
1290 printf("%c%c%3d", kind, type, index);
1292 if (v->flags & SAVEDVAR)
1300 /****************************************************************************
1302 ****************************************************************************/
1305 * These are local overrides for various environment variables in Emacs.
1306 * Please do not remove this and leave it at the end of the file, where
1307 * Emacs will automagically detect them.
1308 * ---------------------------------------------------------------------
1311 * indent-tabs-mode: t