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 "vm/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 cfg_add_exceptional_edges(jd);
122 /*pythonpass_run(jd, "foo", "cfg_print");*/
123 /*dominator_tree_validate(jd, dd);*/
124 /*pythonpass_run(jd, "ssa2", "main");*/
125 /*pythonpass_run(jd, "alt_ssa", "main");*/
126 /*pythonpass_run(jd, "foo", "before");*/
128 /*if (getenv("XSSA")) {
129 dominator_tree_build(jd);
130 dominance_frontier_build(jd);
135 /*pythonpass_run(jd, "foo", "after");*/
142 /* Generate the Control Flow Graph */
143 /* Add one for a Basic Block 0 to be inserted, so lateron */
144 /* with SSA Parameter initialization is handled right */
146 gd = graph_init(jd->basicblockcount + 1);
147 graph_make_cfg(jd, gd);
149 dd = compute_Dominators(gd, ls->basicblockcount);
150 computeDF(gd, dd, ls->basicblockcount, 0);
152 ssa_place_phi_functions(jd, gd, dd);
153 ssa_rename(jd, gd, dd);
154 #ifdef SSA_DEBUG_VERBOSE
155 if (compileverbose) {
156 printf("Phi before Cleanup\n");
157 ssa_print_phi(ls, gd);
161 lt_scanlifetimes(jd, gd, dd);
162 #ifdef SSA_DEBUG_VERBOSE
163 if (compileverbose) {
168 dead_code_elimination(jd, gd);
169 #ifdef SSA_DEBUG_VERBOSE
170 if (compileverbose) {
171 printf("Phi after dead code elemination\n");
172 ssa_print_phi(ls, gd);
178 copy_propagation(jd, gd);
179 #ifdef SSA_DEBUG_VERBOSE
180 if (compileverbose) {
181 printf("Phi after copy propagation\n");
182 ssa_print_phi(ls, gd);
188 ssa_generate_phi_moves(jd, gd);
189 transform_BB(jd, gd);
191 lt_lifeness_analysis(jd, gd);
193 #ifdef SSA_DEBUG_CHECK
195 int i, j, pred, in_d, out_d;
196 graphiterator iter_pred;
203 for(i = 0; i < ls->basicblockcount; i++) {
204 if (ls->basicblocks[i]->indepth != 0) {
205 pred = graph_get_first_predecessor(gd, i, &iter_pred);
206 for (; (pred != -1); pred = graph_get_next(&iter_pred)) {
207 in_d = ls->basicblocks[i]->indepth - 1;
208 in = ls->basicblocks[i]->invars;
209 for (; in_d >= 0; in_d--) {
211 for (j = 0; (!phi_define) && (j<ls->ssavarcount); j++) {
212 if (ls->phi[i][j] != NULL)
213 if (ls->phi[i][j][0] == in[in_d])
217 /* in not defined in phi function -> check with */
218 /* outstack(s) of predecessor(s) */
219 out_d = ls->basicblocks[pred]->outdepth - 1;
220 out = ls->basicblocks[pred]->outvars;
221 _SSA_ASSERT(out_d >= in_d);
222 for(; out_d > in_d; out_d--);
223 if ((in[in_d] != out[out_d]) ||
224 (VAR(in[in_d])->flags != VAR(out[out_d])->flags)) {
225 printf("Method: %s %s\n",
226 m->clazz->name->text, m->name->text);
227 printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
229 printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
231 /* _SSA_ASSERT(0); */
242 #ifdef SSA_DEBUG_VERBOSE
244 ssa_print_trees(jd, gd, dd);
249 /* ssa_init *******************************************************************
251 Initialise data structures for ssa
253 IOVARS of same stackdepth and same type are coalesced:
254 interface_map[ 5 * stackdepth + type ] = new_varindex with
255 0 <= new_varindex < ls->ssavarcount
257 TODO: check if coalescing of IOVARS of same stackdepth and type only of adjacent
258 basic blocks could decrease the number of phi functions and so improve ssa
259 analysis performance!
261 All LOCALVARS and IOVARS get a new unique varindex:
262 ls->new_varindex[0..jd->varcount[ = new_varindex with
263 0 <= new_varindex < ls->ssavarcount
265 The jd->varcount bits long bitvectors ls->var_def[0..jd->basicblockindex+1[
266 are set to the definitions of LOCALVARS and IOVARS. (So the only the first
267 ls->ssavarcount bits of each of these vectors contain valid data, but
268 ls->ssavarcount is computed at the same time as the definitons are stored.)
270 The basic block number used as index for the bitvector array ls->var_def is
271 already shifted by one to make space for the new basic block 0 for parameter
274 ******************************************************************************/
276 void ssa_init(jitdata *jd) {
279 int i, l, b_index, len;
282 s4 *interface_map; /* holds an new unique index for every used */
283 /* basic block inoutvar described by a dupel */
284 /*(depth,type). Used to coalesce the inoutvars*/
287 builtintable_entry *bte;
294 #if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
295 # if defined(SSA_DEBUG_VERBOSE)
296 if (compileverbose) {
297 printf("%s %s ",m->clazz->name->text, m->name->text);
298 if (code_is_leafmethod(jd->code))
299 printf("**Leafmethod**");
303 if (strcmp(m->clazz->name->text,"spec/benchmarks/_213_javac/Parser")==0)
304 if (strcmp(m->name->text,"parseTerm")==0)
305 # if defined(SSA_DEBUG_VERBOSE)
307 printf("12-------------------12\n");
309 { int dummy=1; dummy++; }
313 #ifdef SSA_DEBUG_VERBOSE
315 printf("ssa_init: basicblockcount %3i localcount %3i\n",
316 jd->basicblockcount, jd->localcount);
319 /* As first step all definitions of local variables and in/out vars are */
320 /* gathered. in/outvars are coalesced for same type and depth */
321 /* "normal" tempvars (just living within one basicblock are) ignored */
323 ls->num_defs = DMNEW(int, jd->varcount);
324 ls->new_varindex = DMNEW(int , jd->varcount);
326 for(p = 0; p < jd->varcount; p++) {
328 ls->new_varindex[p] = UNUSED;
331 /* init Var Definition bitvectors */
333 ls->var_def = DMNEW(int *, jd->basicblockcount + 1);
334 for(i = 0; i < jd->basicblockcount + 1; i++) {
335 ls->var_def[i] = bv_new(jd->varcount);
340 /* Add parameters first in right order, so the new local indices */
341 /* 0..p will correspond to "their" parameters */
342 /* They get defined at the artificial Block 0, the real method bbs will */
343 /* be ed to start at block 1 */
345 /* don't look at already eliminated (not used) parameters (locals) */
347 for (p = 0, l = 0; p < md->paramcount; p++) {
348 t = md->paramtypes[p].type;
349 i = jd->local_map[l * 5 + t];
351 if (IS_2_WORD_TYPE(t)) /* increment local counter a second time */
352 l++; /* for 2 word types */
355 ssa_set_local_def(ls, -1, i);
358 _SSA_ASSERT(ls->ssavarcount < jd->varcount);
360 /* coalesce bb in/out vars */
362 interface_map = DMNEW(s4, jd->stackcount * 5);
363 for(i = 0; i < jd->stackcount * 5; i++)
364 interface_map[i] = UNUSED;
366 bptr = jd->basicblocks;
368 for(; bptr != NULL; bptr = bptr->next) {
369 #ifdef SSA_DEBUG_VERBOSE
371 printf("ssa_init: BB %3i flags %3x\n",bptr->nr, bptr->flags);
373 if (bptr->flags >= BBREACHED) {
375 /* 'valid' Basic Block */
381 ssa_set_interface(jd, bptr, interface_map);
383 /* !!!!!!!!! not true for now !!!!!!!!! */
384 /* All baseline optimizations from stack.c are turned off for */
387 for (; len > 0; len--, iptr++) {
389 /* Look for definitions (iptr->dst). INVOKE and BUILTIN have */
390 /* an optional dst - so they to be checked first */
393 if (icmd_table[iptr->opc].dataflow == DF_INVOKE) {
394 INSTRUCTION_GET_METHODDESC(iptr,md);
395 if (md->returntype.type != TYPE_VOID)
396 v = iptr->dst.varindex;
398 else if (icmd_table[iptr->opc].dataflow == DF_BUILTIN) {
399 bte = iptr->sx.s23.s3.bte;
401 if (md->returntype.type != TYPE_VOID)
402 v = iptr->dst.varindex;
404 else if (icmd_table[iptr->opc].dataflow >= DF_DST_BASE) {
405 v = iptr->dst.varindex;
409 if (( v < jd->localcount) || ( VAR(v)->flags & INOUT )) {
411 /* !IS_TEMPVAR && !IS_PREALLOC == (IS_LOCALVAR || IS_INOUT) */
413 ssa_set_local_def(ls, b_index, v);
419 _SSA_ASSERT(ls->ssavarcount < jd->varcount);
421 #ifdef SSA_DEBUG_VERBOSE
422 if (compileverbose) {
423 printf("ssa_init: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
425 for(i = 0; i < jd->varcount; i++) {
426 if ((i < jd->localcount) || ( VAR(i)->flags & INOUT)) {
427 printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
428 ssa_show_variable(jd, i, VAR(i),0);
429 if (i < ls->ssavarcount) {
430 printf(" -> %3i", ls->new_varindex[i]);
439 /* ssa_set_def ****************************************************************
441 Helper for ssa_set_local_def and ssa_set_interface
443 The definition of a var is stored in the bitvector array ls->var_def.
445 The number of definitons of each var is counted, so the number of new vars with
448 ******************************************************************************/
450 void ssa_set_def(lsradata *ls, int b_index, int varindex) {
452 /* b_index + 1 to leave space for the param init block 0 */
454 bv_set_bit(ls->var_def[b_index + 1], varindex);
456 /* count number of defs for every var since SSA */
457 /* will create a new var for every definition */
459 ls->num_defs[varindex]++;
462 /* ssa_set_local_def **********************************************************
466 Assigns a new unique index for the local var varindex (if not already done so)
467 and then calls ssa_set_def to remember the definition in the bitvector array
470 ******************************************************************************/
472 void ssa_set_local_def(lsradata *ls, int b_index, int varindex) {
474 if (ls->new_varindex[varindex] == UNUSED) {
475 ls->new_varindex[varindex] = ls->ssavarcount++;
478 ssa_set_def(ls, b_index, ls->new_varindex[varindex]);
481 /* ssa_set_local_def **********************************************************
483 Helper for ssa_set_interface
485 IN: ls pointer to lsradata structure
486 iovar varindex of INOUTVAR to process
487 map_index stackdepth * 5 + type, used for coalescing IOVARS.
490 interface_map used for coalescing IOVARS. interface_map[map_index] ==
491 UNUSED, if this map_index (==stackdepth,type tupel) did not
492 occur till now. Then interface_map[map_index] will be set
493 to a new unique index.
494 ls->new_varindex will be set to this new unique index to map the old
495 varindizes to the new ones.
497 Assigns a new unique index for the local var varindex (if not already done so)
498 and then calls ssa_set_def to remember the definition in the bitvector array
501 ******************************************************************************/
503 void ssa_set_iovar(lsradata *ls, s4 iovar, int map_index, s4 *interface_map) {
504 if (interface_map[map_index] == UNUSED)
505 interface_map[map_index] = ls->ssavarcount++;
507 ls->new_varindex[iovar] = interface_map[map_index];
511 /* ssa_set_interface ***********************************************************
515 IN: ls pointer to lsradata structure
516 *bptr pointer to the basic block to be processed
519 interface_map used for coalescing IOVARS. interface_map[map_index] ==
520 UNUSED, if this map_index (==stackdepth,type tupel) did not
521 occur till now. Then interface_map[map_index] will be set
522 to a new unique index. (see ssa_set_iovar)
524 Searches the basic block given by *bptr for IN and OUTVARS and coalesces them
525 for each unique stackdepth,type dupel. For each OUTVAR with a different or no
526 INVAR at the same stackdepth the definition of this OUTVAR in this basic block
527 is remembered in ls->var_def. (see ssa_set_def)
529 ******************************************************************************/
531 void ssa_set_interface(jitdata *jd, basicblock *bptr, s4 *interface_map) {
534 int o_map_index, i_map_index;
541 in_d = bptr->indepth - 1;
542 out_d = bptr->outdepth - 1;
544 /* ignore top Stackelement of instack in case of EXH or SBR blocks */
545 /* These are no Interface stackslots! */
546 if ((bptr->type == BBTYPE_EXH) ||
547 (bptr->type == BBTYPE_SBR)) {
551 /* invars with no corresponding outvars are not defined here */
552 /* just set up the interface_map */
554 for(;(in_d > out_d); in_d--) {
555 i_map_index = in_d * 5 + VAR(in[in_d])->type;
556 ssa_set_iovar(ls, in[in_d], i_map_index, interface_map);
559 while((out_d >= 0)) {
560 /* set up interface_map */
562 o_map_index = out_d * 5 + VAR(out[out_d])->type;
564 i_map_index = in_d * 5 + VAR(in[in_d])->type;
565 ssa_set_iovar(ls, in[in_d], i_map_index, interface_map);
567 ssa_set_iovar(ls, out[out_d], o_map_index, interface_map);
578 #ifdef SSA_DEBUG_VERBOSE
579 void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd) {
585 printf("ssa_printtrees: maxlocals %3i", jd->localcount);
587 printf("Dominator Tree: \n");
588 for(i = 0; i < ls->basicblockcount; i++) {
590 for(j = 0; j < ls->basicblockcount; j++) {
591 if (dd->idom[j] == i) {
598 printf("Dominator Forest:\n");
599 for(i = 0; i < ls->basicblockcount; i++) {
601 for(j = 0; j < dd->num_DF[i]; j++) {
602 printf(" %3i", dd->DF[i][j]);
607 if (ls->ssavarcount > 0) {
608 printf("Use Sites\n");
609 for(i = 0; i < ls->ssavarcount; i++) {
610 printf("use_sites[%3i]=%p:",i,(void *)ls->use_sites[i]);
611 for(j = 0; j < ls->basicblockcount; j++) {
612 if ((j % 5) == 0) printf(" ");
613 if (bv_get_bit(ls->use_sites[i], j))
622 printf("var Definitions:\n");
623 for(i = 0; i < jd->basicblockcount; i++) {
624 printf("var_def[%3i]=%p:",i,(void *)ls->var_def[i]);
625 for(j = 0; j < ls->ssavarcount; j++) {
626 if ((j % 5) == 0) printf(" ");
627 if (bv_get_bit(ls->var_def[i], j))
633 for(j=0; j < ((((ls->ssavarcount * 5+7)/8) + sizeof(int) - 1)/sizeof(int));
635 printf("%8x",ls->var_def[i][j]);
642 /****************************************************************************
644 ****************************************************************************/
647 /****************************************************************************
648 Dead Code Elimination
649 ****************************************************************************/
650 void dead_code_elimination(jitdata *jd, graphdata *gd) {
655 struct lifetime *lt, *s_lt;
657 bool remove_statement;
661 #ifdef SSA_DEBUG_VERBOSE
668 W = wl_new(ls->lifetimecount);
669 if (ls->lifetimecount > 0) {
671 /* put all lifetimes into Worklist W */
673 for(a = 0; a < ls->lifetimecount; a++) {
674 if (ls->lifetime[a].type != UNUSED) {
680 /* Remove unused lifetimes */
682 while(!wl_is_empty(W)) {
684 /* take a var out of Worklist */
688 lt = &(ls->lifetime[a]);
689 if ((lt->def == NULL) || (lt->type == UNUSED))
691 /* lifetime was already removed -> no defs anymore */
695 /* Remove lifetimes, which are only used in the phi function which */
698 remove_statement = (lt->use != NULL) && (lt->use->iindex < 0);
699 for(use = lt->use; (remove_statement && (use != NULL));
702 remove_statement = remove_statement &&
703 (use->b_index == lt->def->b_index) &&
704 (use->iindex == lt->def->iindex);
707 if (remove_statement) {
708 #ifdef SSA_DEBUG_CHECK
710 /* def == use can only happen in phi functions */
712 if (remove_statement)
713 _SSA_ASSERT(lt->use->iindex < 0);
716 /* give it free for removal */
721 if (lt->use == NULL) {
723 /* Look at statement of definition of a and remove it, */
724 /* if the Statement has no sideeffects other than the assignemnt */
727 if (lt->def->iindex < 0 ) {
730 /* delete use of sources , delete phi functions */
732 _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] !=
735 for (i = 1;i <= graph_get_num_predecessor(gd, lt->def->b_index);
738 ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
739 if ((source != ls->varcount_with_indices) &&
740 (source != lt->v_index) &&
741 (source != UNUSED)) {
743 /* phi Argument was not already removed (already in
744 because of "selfdefinition") */
746 s_lt = &(ls->lifetime[source]);
750 lt_remove_use_site(s_lt,lt->def->b_index,
753 /* put it on the Worklist */
759 /* now delete phi function itself */
760 #ifdef SSA_DEBUG_VERBOSE
761 if (compileverbose) {
762 printf("dce: BB%3i phi for var %3i=%3i removed \n",
763 lt->def->b_index, -lt->def->iindex - 1,
768 ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
772 /* "normal" Use by ICMD */
774 remove_statement = false;
775 if (lt->def->b_index != 0) {
777 /* do not look at artificial block 0 (parameter init) */
779 iptr = ls->basicblocks[lt->def->b_index]->iinstr +
782 if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {
784 /* if ICMD could throw an exception do not remove it! */
786 remove_statement = false;
787 #ifdef SSA_DEBUG_VERBOSE
788 if (compileverbose) {
789 printf("dce: PEI: BB%3i II%3i %s not removed \n",
790 lt->def->b_index, lt->def->iindex,
791 bytecode[iptr->opc].mnemonic);
797 remove_statement = true;
799 switch (icmd_table[iptr->opc].dataflow) {
801 case DF_3_TO_1: /* icmd has s1, s2 and s3 */
802 a = iptr->sx.s23.s3.varindex;
803 s_lt = ls->lifetime + a;
804 lt_remove_use_site(s_lt, lt->def->b_index,
808 /* "fall through" for handling of s2 and s1 */
811 case DF_2_TO_1: /* icmd has s1 and s2 */
812 a = iptr->sx.s23.s2.varindex;
813 s_lt = ls->lifetime + a;
814 lt_remove_use_site(s_lt, lt->def->b_index,
818 /* "fall through" for handling of s1 */
820 /* DF_{IINC,STORE,LOAD} are DF_{1_TO_1,MOVE,COPY} */
826 a = iptr->s1.varindex;
827 s_lt = ls->lifetime + a;
828 lt_remove_use_site(s_lt, lt->def->b_index,
832 #ifdef SSA_DEBUG_VERBOSE
833 if (compileverbose) {
834 printf("dce: BB%3i II%3i %s removed \n",
835 lt->def->b_index, lt->def->iindex,
836 bytecode[iptr->opc].mnemonic);
841 if (remove_statement) {
843 /* remove statement */
845 #ifdef SSA_DEBUG_VERBOSE
847 printf("dce: %s %s:at BB %3i II %3i NOP-<%s\n",
848 m->clazz->name->text, m->name->text,
849 lt->def->b_index, lt->def->iindex,
850 icmd_table[iptr->opc].name);
852 iptr->opc = ICMD_NOP;
854 } /* (lt->def->b_index != 0) */
855 } /* if (lt->def->iindex < 0 ) else */
857 /* remove definition of a */
859 #ifdef SSA_DEBUG_VERBOSE
861 printf("dce: var %3i removed\n", lt->v_index);
863 VAR(lt->v_index)->type = UNUSED;
867 } /* if (lt->use == NULL) */
868 } /* while(!wl_is_empty(W)) */
869 } /* dead_code_elimination */
871 /****************************************************************************
872 Simple Constant Propagation
873 ****************************************************************************/
875 void simple_constant_propagation() {
878 /****************************************************************************
880 *******************************************************************************/
881 void copy_propagation(jitdata *jd, graphdata *gd) {
888 struct lifetime *lt, *s_lt;
894 W = wl_new(ls->lifetimecount);
895 if (ls->lifetimecount > 0) {
896 /* put all lifetimes on Worklist */
897 for(a = 0; a < ls->lifetimecount; a++) {
898 if (ls->lifetime[a].type != UNUSED) {
904 while(!wl_is_empty(W)) {
905 /* take a var out of Worklist */
908 lt = ls->lifetime + a;
909 if (lt->type == UNUSED)
911 _SSA_ASSERT(lt->def != NULL);
913 _SSA_ASSERT(lt->use != NULL);
915 if (lt->def->iindex < 0 ) {
918 /* look, if phi function degenerated to a x = phi(y) */
919 /* and if so, substitute y for every use of x */
921 _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] != NULL);
923 only_source = ls->varcount_with_indices;
924 for (i = 1; i <= graph_get_num_predecessor(gd, lt->def->b_index);
926 source = ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
927 if ((source != ls->varcount_with_indices) &&
928 (source != UNUSED)) {
929 if (only_source == ls->varcount_with_indices) {
931 /* first valid source argument of phi function */
933 only_source = source;
936 /* second valid source argument of phi function */
939 only_source = ls->varcount_with_indices;
945 if (only_source != ls->varcount_with_indices) {
947 #ifdef SSA_DEBUG_VERBOSE
950 "-- copy propagation phi-func: BB %3i II %3i: %3i -> %3i\n",
951 lt->def->b_index, lt->def->iindex,
952 only_source, lt->v_index);
954 s_lt = ls->lifetime + only_source;
956 /* replace all use sites of lt with the var_index only_source */
958 ssa_replace_use_sites( jd, gd, lt, only_source, W);
960 /* delete def of lt */
962 ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
964 /* remove this deleted use site of s_lt */
966 lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
970 /* move use sites from lt to s_lt */
972 lt_move_use_sites(lt, s_lt);
977 VAR(lt->v_index)->type = UNUSED;
979 /* add s_lt again to Worklist W */
981 wl_add(W, s_lt->v_index);
982 #ifdef SSA_DEBUG_VERBOSE
986 } /* if (only_source != ls->varcount_with_indices) */
988 else { /* if (lt->def->iindex < 0 ) */
990 /* def in argument passing - no propagation possible */
991 /* (there is no ICMD for this... */
993 if (lt->def->b_index == 0)
996 /* def in "normal" ICMD */
998 iptr = ls->basicblocks[lt->def->b_index]->iinstr +
1013 #ifdef SSA_DEBUG_VERBOSE
1016 "-- copy propagation %3i %s: BB %3i II %3i: %3i -> %3i\n",
1017 iptr->opc, bytecode[iptr->opc].mnemonic,
1018 lt->def->b_index, lt->def->iindex,
1019 iptr->s1.varindex, iptr->dst.varindex);
1021 s_lt = ls->lifetime + iptr->s1.varindex;
1023 _SSA_ASSERT( lt->v_index == iptr->dst.varindex);
1025 /* replace all use sites of lt with the var_index */
1026 /* iptr->s1.varindex (==lt->v_index) */
1028 ssa_replace_use_sites(jd, gd, lt, iptr->s1.varindex, W);
1030 _SSA_ASSERT(lt->def->next == NULL);
1031 _SSA_ASSERT(s_lt->def != NULL);
1032 _SSA_ASSERT(s_lt->def->next == NULL);
1034 /* this ICMD is not a PEI -> so no danger in deleting it! */
1035 /* delete def of lt (ICMD_NOP) */
1037 /* lt->def->iindex > 0 -> ICMD */
1039 iptr->opc = ICMD_NOP;
1041 /* remove this deleted use site of s_lt */
1043 lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
1045 /* invalidate def site of lt */
1049 /* move use sites from lt to s_lt */
1051 lt_move_use_sites(lt, s_lt);
1056 VAR(lt->v_index)->type = UNUSED;
1058 /* add s_lt again to Worklist W */
1059 wl_add(W, s_lt->v_index);
1060 #ifdef SSA_DEBUG_VERBOSE
1062 _ssa_print_lt(s_lt);
1066 } /* if (lt->def->iindex < 0 ) */
1067 } /* while(!wl_is_empty(W)) */
1070 void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
1071 int new_v_index, worklist *W) {
1078 builtintable_entry *bte;
1082 md = jd->m->parseddesc;
1085 for(s = lt->use; s != NULL; s = s->next) {
1086 if (s->iindex < 0) {
1088 /* Use in phi function */
1090 for (i = 1;i <= graph_get_num_predecessor(gd, s->b_index); i++) {
1091 source = ls->phi[s->b_index][-s->iindex-1][i];
1092 if (source == lt->v_index) {
1094 /* check if this use in this phi function is a */
1095 /* "selfdefinition" (x = phi(...,x,...)) */
1096 /* if so replace the use with -1 (x=phi(...,-1,...)*/
1098 if (new_v_index == ls->phi[s->b_index][-s->iindex-1][0]) {
1099 #ifdef SSA_DEBUG_VERBOSE
1103 "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
1104 s->b_index, s->iindex, -1, source);
1107 ls->phi[s->b_index][-s->iindex-1][i] = -1;
1109 /* remove this use site of use site */
1110 lt_remove_use_site(lt, s->b_index, s->iindex);
1113 #ifdef SSA_DEBUG_VERBOSE
1117 "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
1118 s->b_index, s->iindex, new_v_index, source);
1121 ls->phi[s->b_index][-s->iindex-1][i] = new_v_index;
1127 /* Add var, which is defined by this phi function to */
1130 source = ls->phi[s->b_index][-s->iindex-1][0];
1134 else { /* use in ICMD */
1136 iptr = ls->basicblocks[s->b_index]->iinstr +
1139 /* check for use (s1, s2, s3 or special (argp) ) */
1142 switch (icmd_table[iptr->opc].dataflow) {
1144 case DF_3_TO_1: /* icmd has s1, s2 and s3 */
1145 if (iptr->sx.s23.s3.varindex == lt->v_index) {
1146 #ifdef SSA_DEBUG_VERBOSE
1149 printf("copy propagation loc3: BB %3i I %3i: %3i -> \
1150 %3i\n", s->b_index, s->iindex,
1151 new_v_index, iptr->sx.s23.s3.varindex);
1154 iptr->sx.s23.s3.varindex = new_v_index;
1157 /* now "fall through" for handling of s2 and s1 */
1160 case DF_2_TO_1: /* icmd has s1 and s2 */
1161 if (iptr->sx.s23.s2.varindex == lt->v_index) {
1162 #ifdef SSA_DEBUG_VERBOSE
1165 printf("copy propagation loc2: BB %3i I %3i: %3i -> \
1166 %3i\n", s->b_index, s->iindex,
1167 new_v_index, iptr->sx.s23.s2.varindex);
1170 iptr->sx.s23.s2.varindex = new_v_index;
1173 /* now "fall through" for handling of s1 */
1179 if (iptr->s1.varindex == lt->v_index) {
1180 #ifdef SSA_DEBUG_VERBOSE
1184 "copy propagation loc1: BB %3i I %3i: %3i -> %3i\n",
1185 s->b_index, s->iindex, new_v_index,
1189 iptr->s1.varindex = new_v_index;
1194 /* ? really look at md->paramcount or iptr->s1.argcount */
1195 /* has to be taken, so that pass-through stackslots get */
1199 INSTRUCTION_GET_METHODDESC(iptr,md);
1203 bte = iptr->sx.s23.s3.bte;
1208 i = iptr->s1.argcount;
1212 argp = iptr->sx.s23.s2.args;
1214 if (*argp == lt->v_index) {
1215 #ifdef SSA_DEBUG_VERBOSE
1219 "copy propagation locN: BB %3i I %3i: %3i -> %3i\n"
1220 , s->b_index, s->iindex, new_v_index, *argp);
1223 *argp = new_v_index;
1230 } /* if (s->iindex < 0) */
1231 } /* for(s = lt->use; s != NULL; s = s->next) */
1234 #ifdef SSA_DEBUG_VERBOSE
1235 void ssa_print_lt(lsradata *ls) {
1237 struct lifetime *lt;
1239 printf("SSA LT Def/Use\n");
1240 for(i = 0; i < ls->lifetimecount; i++) {
1241 lt = ls->lifetime + i;
1246 void _ssa_print_lt(struct lifetime *lt) {
1249 if (lt->type != UNUSED) {
1250 printf("VI %3i Type %3i Def: ",lt->v_index, lt->type);
1251 if (lt->def != NULL)
1252 printf("%3i,%3i Use: ",lt->def->b_index, lt->def->iindex);
1254 printf("%3i,%3i Use: ",0,0);
1255 for(use = lt->use; use != NULL; use = use->next)
1256 printf("%3i,%3i ",use->b_index, use->iindex);
1261 void ssa_show_variable(jitdata *jd, int index, varinfo *v, int stage)
1267 case TYPE_INT: type = 'i'; break;
1268 case TYPE_LNG: type = 'l'; break;
1269 case TYPE_FLT: type = 'f'; break;
1270 case TYPE_DBL: type = 'd'; break;
1271 case TYPE_ADR: type = 'a'; break;
1272 case TYPE_RET: type = 'r'; break;
1273 default: type = '?';
1276 if (index < jd->localcount) {
1278 if (v->flags & (PREALLOC | INOUT))
1279 printf("<INVALID FLAGS!>");
1282 if (v->flags & PREALLOC) {
1284 if (v->flags & INOUT)
1285 printf("<INVALID FLAGS!>");
1287 else if (v->flags & INOUT)
1293 printf("%c%c%3d", kind, type, index);
1295 if (v->flags & SAVEDVAR)
1303 /****************************************************************************
1305 ****************************************************************************/
1308 * These are local overrides for various environment variables in Emacs.
1309 * Please do not remove this and leave it at the end of the file, where
1310 * Emacs will automagically detect them.
1311 * ---------------------------------------------------------------------
1314 * indent-tabs-mode: t