1 /* src/vm/jit/optimizing/ssa.c - static single-assignment form
3 Copyright (C) 2005, 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Ullrich
35 #include "mm/memory.h"
37 #include "toolbox/bitvector.h"
38 #include "toolbox/worklist.h"
40 #include "vm/jit/optimizing/dominators.h"
41 #include "vm/jit/optimizing/graph.h"
42 #include "vm/jit/optimizing/lifetimes.h"
43 #include "vm/jit/optimizing/lsra.h"
45 #include "vm/jit/optimizing/ssa.h"
47 #if defined(SSA_DEBUG_VERBOSE)
48 #include "vm/options.h" /* compileverbose */
49 #include "vm/jit/jit.h" /* icmd_table */
52 /* function prototypes */
53 void dead_code_elimination(methodinfo *m, registerdata *rd, lsradata *ls,
55 void copy_propagation(methodinfo *m,registerdata *rd, lsradata *ls,
57 void replace_use_sites( lsradata *ls, graphdata *gd, struct lifetime *lt,
58 int new_v_index, worklist *W);
59 void ssa_place_phi_functions(codegendata *cd, lsradata *ls, graphdata *gd,
61 void ssa_Rename_init(methodinfo *m, codegendata *cd, lsradata *ls,
63 void ssa_Rename(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls,
64 graphdata *gd, dominatordata *dd);
65 void ssa_Rename_(codegendata *cd, lsradata *ls, graphdata *gd,
66 dominatordata *dd, int n);
68 #ifdef SSA_DEBUG_VERBOSE
69 void ssa_print_trees(methodinfo *m, codegendata *cd, lsradata *ls,
70 graphdata *gd, dominatordata *dd);
71 void ssa_print_lt(lsradata *ls);
73 /*********************************************************
74 Data Collection (Use/Definition) while analyze_stack:
75 Basic Block indices of definition are needed for generation
82 These two functions use the internal Helpers:
85 *********************************************************/
86 void ssa_set_use(lsradata *ls, int b_index, int local_index, int type) {
87 /* just count uses to determine the needed max size for use def */
92 void ssa_set_def(lsradata *ls, int b_index, int var_index) {
94 /* b_index + 1 to leave space for the param init block 0 */
95 bv_set_bit(ls->var_def[b_index + 1], var_index);
96 /* count number of defs for every var since SSA */
97 /* will create a new var for every definition */
98 ls->num_defs[var_index]++;
101 void ssa_set_local_def(lsradata *ls, int b_index, int local_index, int type) {
103 if (ls->var[local_index][type] == -1) {
104 /* New Local Variable encountered -> create a new unique index */
105 ls->var[local_index][type] = ls->max_vars;
106 ls->var_to_index[ls->max_vars] = ls->max_locals++;
108 #ifdef SSA_DEBUG_VERBOSE
110 printf("Local %3i,%3i -> Var %3i\n",local_index,type,ls->max_vars-1);
114 ssa_set_def(ls, b_index, ls->var[local_index][type]);
117 void ssa_set_interface_(codegendata *cd, lsradata *ls, basicblock *bptr,
118 stackptr s, int depth) {
121 var_index = depth + jd->maxlocals;
122 if (ls->var[var_index][s->type] == -1) {
123 /* New Interface Stackslot encountered -> create a new unique index */
124 ls->var[var_index][s->type] = ls->max_vars;
125 ls->var_to_index[ls->max_vars] = ls->max_interfaces--;
127 #ifdef SSA_DEBUG_VERBOSE
129 printf("Interface SS %3i,%3i -> Var %3i\n",bptr->nr+1,depth,ls->max_vars-1);
132 ssa_set_def(ls, bptr->nr, ls->var[var_index][s->type]);
135 void ssa_set_interface(codegendata *cd, lsradata *ls, basicblock *bptr) {
139 out = bptr->outstack;
141 in_d = bptr->indepth;
142 out_d = bptr->outdepth;
144 /* ignore top Stackelement of instack in case of EXH or SBR blocks */
145 /* These are no Interface stackslots! */
146 if ((bptr->type == BBTYPE_EXH) ||
147 (bptr->type == BBTYPE_SBR)) {
152 for(;(in_d > out_d); in_d--, in = in->prev);
154 while((out != NULL)) {
157 /* out interface stackslot is defined in this basic block */
158 ssa_set_interface_(cd, ls, bptr, out, out_d - 1);
164 } else if (in_d < out_d ) {
165 /* out interface stackslot is defined in this basic block */
166 ssa_set_interface_(cd, ls, bptr, out, out_d - 1);
173 /*********************************************************************
174 Initialise needed Data structures
175 *********************************************************************/
177 void ssa_init(jitdata *jd) {
182 stackptr src, dst, tmp;
197 #if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
198 #if defined(SSA_DEBUG_VERBOSE)
199 if (compileverbose) {
200 printf("%s %s ",m->class->name->text, m->name->text);
201 if (jd->isleafmethod)
202 printf("**Leafmethod**");
206 if (strcmp(m->class->name->text,"java/util/Properties")==0)
207 if (strcmp(m->name->text,"load")==0)
208 #if defined(SSA_DEBUG_VERBOSE)
210 printf("12-------------------12\n");
212 { int dummy=1; dummy++; }
216 #ifdef SSA_DEBUG_VERBOSE
218 printf("ssa_init: basicblockcount %3i maxlocals %3i\n",
219 m->basicblockcount, jd->maxlocals);
221 ls->num_defs = DMNEW(int, jd->maxlocals * 5 + cd->maxstack * 5);
222 ls->var_to_index = DMNEW(int, jd->maxlocals * 5 + cd->maxstack * 5);
223 ls->var = DMNEW(int *, jd->maxlocals + cd->maxstack);
225 for(p = 0; p < jd->maxlocals + cd->maxstack; p++) {
226 ls->var[p] = DMNEW(int, 5);
227 for(i = 0; i < 5; i++) {
229 ls->num_defs[t++] = 0;
232 /* init Var Definition bitvectors */
233 ls->var_def = DMNEW(int *, m->basicblockcount + 1);
234 for(i = 0; i <= m->basicblockcount; i++) {
235 ls->var_def[i] = bv_new(jd->maxlocals * 5 + cd->maxstack * 5);
238 ls->max_vars = 0; /* no Vars seen till now */
239 /* A new Var Index will be created by SSA */
240 /* since locals[Index][Type] is a quite sparse array */
241 /* and locals will be renamed anyway by SSA */
242 ls->max_locals = 0; /* unique index for every local_var/type pair*/
243 ls->max_interfaces = -1; /* unique index for every interface/type pair*/
244 /* interfaces are < 0, locals > 0 */
245 /* Add parameters first in right order, so the new local indices */
246 /* 0..p will correspond to "their" parameters */
247 /* They get defined at the artificial Block 0, the real method bbs will be*/
248 /* moved to start at block 1 */
249 for (p = 0, i = 0; p < md->paramcount; p++) {
250 t = md->paramtypes[p].type;
252 ssa_set_local_def(ls, -1, i, t);
254 if (IS_2_WORD_TYPE(t)) /* increment local counter a second time */
255 i++; /* for 2 word types */
259 bptr = m->basicblocks;
261 for(; bptr != NULL; bptr = bptr->next) {
262 if (bptr->flags >= BBREACHED) {
263 /* 'valid' Basic Block */
266 /* Scan Number of Stack Lifetimes */
267 lifetimes += m->basicblocks[b_index].indepth;
269 dst = m->basicblocks[b_index].instack;
270 len = m->basicblocks[b_index].icount;
271 iptr = m->basicblocks[b_index].iinstr;
272 for (;len>0; len--, iptr++) {
276 /* Reset "leftover" LOCALVAR stackslots */
280 if (dst->varkind != ARGVAR)
281 dst->varkind = TEMPVAR;
285 for(i=0, tmp = dst; i < 2; i++, tmp = tmp->prev)
286 if (tmp->varkind != ARGVAR)
287 tmp->varkind = TEMPVAR;
291 for(i=0, tmp = dst; i < 3; i++, tmp = tmp->prev)
292 if (tmp->varkind != ARGVAR)
293 tmp->varkind = TEMPVAR;
297 for(i=0, tmp = dst; i < 5; i++, tmp = tmp->prev)
298 if (tmp->varkind != ARGVAR)
299 tmp->varkind = TEMPVAR;
303 for(i=0, tmp = dst; i < 4; i++, tmp = tmp->prev)
304 if (tmp->varkind != ARGVAR)
305 tmp->varkind = TEMPVAR;
309 for(i=0, tmp = dst; i < 6; i++, tmp = tmp->prev)
310 if (tmp->varkind != ARGVAR)
311 tmp->varkind = TEMPVAR;
319 if (( dst != NULL) && (src != dst))
321 dst->varkind = TEMPVAR;
324 ssa_set_use(ls, b_index, iptr->op1,
325 iptr->opc - ICMD_ILOAD);
329 if (( dst != NULL) && (src != dst))
331 /* For SSA IINC has to be handled as a seperate LOAD */
332 /* and STORE. The target local index is held in */
333 /* val._i.op1_t, The immediate val.i is held in */
338 iptr->val._i.op1_t = iptr->op1;
342 ssa_set_use(ls, b_index, iptr->op1,TYPE_INT);
343 ssa_set_local_def(ls, b_index,
344 iptr->val._i.op1_t, TYPE_INT);
352 src->varkind = TEMPVAR;
355 ssa_set_local_def(ls, b_index, iptr->op1,
356 iptr->opc - ICMD_ISTORE);
361 if (( dst != NULL) && (src != dst))
365 ssa_set_interface(cd, ls, &(m->basicblocks[b_index]));
368 ls->maxlifetimes = lifetimes;
369 ls->lifetimecount = lifetimes + jd->maxlocals * (TYPE_ADR+1);
374 void ssa_place_phi_functions(codegendata *cd, lsradata *ls, graphdata *gd,
378 bitvector *def_sites;
379 bitvector *A_phi; /* [0..ls->basicblockcount[ of ls->max_vars Bit */
385 W = wl_new(ls->basicblockcount);
387 def_sites = DMNEW(bitvector, ls->max_vars);
388 for(a = 0; a < ls->max_vars; a++)
389 def_sites[a] = bv_new(ls->basicblockcount);
391 ls->phi = DMNEW(int **, ls->basicblockcount);
392 A_phi = DMNEW(bitvector, ls->basicblockcount);
393 for(i = 0; i < ls->basicblockcount; i++) {
394 ls->phi[i] = DMNEW(int *, ls->max_vars);
395 for(j = 0; j < ls->max_vars; j++)
396 ls->phi[i][j] = NULL;
397 A_phi[i] = bv_new(ls->max_vars);
400 for(n = 0; n < ls->basicblockcount; n++)
401 for(a = 0; a < ls->max_vars; a++)
402 if (bv_get_bit(ls->var_def[n], a))
403 bv_set_bit(def_sites[a], n);
404 #ifdef SSA_DEBUG_VERBOSE
405 if (compileverbose) {
406 printf("var Definitions:\n");
407 for(i = 0; i < ls->max_vars; i++) {
408 printf("def_sites[%3i]=%p:",i,(void *)def_sites[i]);
409 for(j = 0; j < ls->basicblockcount; j++) {
410 if ((j % 5) == 0) printf(" ");
411 if (bv_get_bit(def_sites[i], j))
423 for(a = 0; a < ls->max_vars; a++) {
424 /* W<-def_sites(a) */
425 for(n = 0; n < ls->basicblockcount; n++)
426 if (bv_get_bit(def_sites[a],n)) {
430 while (!wl_is_empty(W)) { /* W not empty */
433 for(i = 0; i < dd->num_DF[n]; i++) {
435 /* Node Y is in Dominance Frontier of n -> */
436 /* insert phi function for a at top of Y*/
437 _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
438 if (bv_get_bit( A_phi[Y], a) == 0) {
439 /* a is not a Element of A_phi[Y] */
440 /* a <- phi(a,a...,a) to be inserted at top of Block Y */
441 /* phi has as many arguments, as Y has predecessors */
444 /* do not add a phi function for interface stackslots */
445 /* if a predecessor is not a def site of a <==> */
446 /* the block does not have the corresponding inslot*/
447 if ((ls->var_to_index[a] >= 0) ||
448 (bv_get_bit(def_sites[a],
449 graph_get_first_predecessor(gd, Y, &iter))))
451 /* for interface stackslots add a phi function only */
452 /* if the basicblock has the corresponding incoming */
453 /* stackslot -> it could be, that the stackslot is */
454 /* not live anymore at Y */
456 #ifdef SSA_DEBUG_VERBOSE
458 if (ls->var_to_index[a] < 0)
459 printf("SS CHeck BB %3i ID %3i V2I %3i A %3i ML %3i\n",Y,
460 ls->basicblocks[Y]->indepth,
461 ls->var_to_index[a], a, jd->maxlocals);
463 /* Add Locals in any case */
464 add_phi = (ls->var_to_index[a] >= 0);
467 s = ls->basicblocks[Y]->instack;
468 for(i = ls->basicblocks[Y]->indepth-1; i>=0; i--, s = s->prev) {
470 #ifdef SSA_DEBUG_VERBOSE
472 if (ls->var_to_index[a] < 0)
473 printf(" Depth %3i Var %3i\n",i,
474 ls->var[i + jd->maxlocals][s->type]);
476 if (ls->var[i + jd->maxlocals][s->type] == a) {
484 num_pred = graph_get_num_predecessor(gd, Y);
485 ls->phi[Y][a] = DMNEW(int, num_pred + 1);
486 for (j = 0; j < num_pred + 1; j++)
487 ls->phi[Y][a][j] = a;
488 /* increment the number of definitions of a by one */
489 /* for this phi function */
493 bv_set_bit(A_phi[Y], a);
494 if (bv_get_bit(ls->var_def[Y],a)==0) {
495 /* Iterated Dominance Frontier Criterion:*/
496 /* if Y had no definition for a insert it*/
497 /* into the Worklist, since now it */
498 /* defines a through the phi function */
507 void ssa_Rename_init(methodinfo *m, codegendata *cd, lsradata *ls, graphdata *gd)
513 /* set up new locals */
514 /* ls->var[index][type] holds the new unique index */
515 /* in the range of [0..ls-max_vars[ */
516 /* ls->num_defs[index] gives the number of indizes which will be created */
518 /* -> vars will be numbered in this sequence: L0(0)..L0(i) L1(0)..L1(j).*/
519 /* ls->var[index][type] will point to each LX(0) */
521 /* as first step cummulate the num_defs array */
523 /* last element is the maximum local count */
524 ls->local_0 = DMNEW(int, ls->max_locals + 1);
525 ls->interface_0 = DMNEW(int, -ls->max_interfaces);
527 ls->interface_0[0] = 0;
528 ls->max_vars_with_indices = 0;
529 for(i = 0, i_i = 1, i_l = 1; i < ls->max_vars; i++) {
530 ls->max_vars_with_indices += ls->num_defs[i];
531 if (ls->var_to_index[i] >= 0) {
533 ls->local_0[i_l] = ls->local_0[i_l-1] + ls->num_defs[i];
534 ls->var_to_index[i] = ls->local_0[i_l-1];
537 /* interface stackslot */
538 ls->interface_0[i_i] = ls->interface_0[i_i-1] + ls->num_defs[i];
539 ls->var_to_index[i] = -ls->interface_0[i_i-1] - 1;
544 /* Change the var indices in phi from La to La(0) */
545 for(i = 0; i < ls->basicblockcount; i++)
546 for (t = 0; t < ls->max_vars; t++)
547 if (ls->phi[i][t] != NULL)
548 for(p = 0; p < graph_get_num_predecessor(gd, i) + 1; p++)
549 ls->phi[i][t][p] = ls->var_to_index[t];
552 ls->count = DMNEW(int, ls->max_vars);
553 ls->stack = DMNEW(int *, ls->max_vars);
554 ls->stack_top = DMNEW(int, ls->max_vars);
555 for(a = 0; a < ls->max_vars; a++) {
557 ls->stack_top[a] = 0;
558 /* stack a has to hold number of defs of a Elements + 1 */
559 ls->stack[a] = DMNEW(int, ls->num_defs[a] + 1);
560 ls->stack[a][ls->stack_top[a]++] = 0;
562 if (ls->max_locals > 0) {
563 /* Create the num_var_use Array */
564 ls->num_var_use = DMNEW(int *, ls->basicblockcount);
565 for(i = 0; i < ls->basicblockcount; i++) {
566 ls->num_var_use[i] =DMNEW(int, max(1, ls->local_0[ls->max_locals]));
567 for(a = 0; a < ls->local_0[ls->max_locals]; a++)
568 ls->num_var_use[i][a] = 0;
570 /* Create the use_sites Array of Bitvectors*/
571 /* use max(1,..), to ensure that the array is created! */
572 ls->use_sites = DMNEW(bitvector, max(1, ls->local_0[ls->max_locals]));
573 for(a = 0; a < ls->local_0[ls->max_locals]; a++)
574 ls->use_sites[a] = bv_new(ls->basicblockcount);
578 ls->maxlifetimes = /*m*/ ls->maxlifetimes + ls->basicblockcount * m->maxstack;
579 ls->lifetimecount = ls->maxlifetimes + ls->local_0[ls->max_locals]
581 ls->lifetime = DMNEW(struct lifetime, ls->lifetimecount);
582 ls->lt_used = DMNEW(int, ls->lifetimecount);
583 ls->lt_int = DMNEW(int, ls->lifetimecount);
584 ls->lt_int_count = 0;
585 ls->lt_flt = DMNEW(int, ls->lifetimecount);
586 ls->lt_flt_count = 0;
587 ls->lt_mem = DMNEW(int, ls->lifetimecount);
588 ls->lt_mem_count = 0;
589 for (i=0; i < ls->lifetimecount; i++) ls->lifetime[i].type = -1;
593 int ssa_Rename_def(lsradata *ls, int n, int a) {
596 _SSA_CHECK_BOUNDS(a,0,ls->max_vars);
598 i = ls->count[a] - 1;
599 /* push i on stack[a] */
600 _SSA_CHECK_BOUNDS(ls->stack_top[a], 0, ls->num_defs[a] + 1);
601 ls->stack[a][ls->stack_top[a]++] = i;
605 void ssa_Rename_use(lsradata *ls, int n, int a) {
606 if (ls->max_locals > 0) {
607 bv_set_bit(ls->use_sites[a], n);
608 ls->num_var_use[n][a]++;
612 void ssa_Rename_(codegendata *cd, lsradata *ls, graphdata *gd,
613 dominatordata *dd, int n) {
614 int a, i, j, k, iindex, Y;
618 /* [0..ls->max_vars[ Number of Definitions of this var in this */
619 /* Basic Block. Used to remove the entries off the stack at the */
620 /* end of the function */
623 graphiterator iter_succ, iter_pred;
626 _SSA_CHECK_BOUNDS(n, 0, ls->basicblockcount);
628 def_count = DMNEW(int, ls->max_vars);
629 for(i = 0; i < ls->max_vars; i++)
632 /* change Store of possible phi functions from a0 to ai*/
633 for(a = 0; a < ls->max_vars; a++)
634 if (ls->phi[n][a] != NULL) {
636 /* do not mark this store as use - maybee this phi function */
637 /* can be removed for unused Vars*/
638 if (ls->var_to_index[a] >= 0)
640 ls->phi[n][a][0] += ssa_Rename_def(ls, n, a);
643 ls->phi[n][a][0] -= ssa_Rename_def(ls, n, a);
646 in = ls->basicblocks[n]->instack;
647 in_d = ls->basicblocks[n]->indepth;
648 /* change use of instack Interface stackslots except top SBR and EXH */
650 if ((ls->basicblocks[n]->type == BBTYPE_EXH) ||
651 (ls->basicblocks[n]->type == BBTYPE_SBR)) {
655 out = ls->basicblocks[n]->outstack;
656 out_d = ls->basicblocks[n]->outdepth;
658 for(;out_d > in_d; out = out->prev, out_d--);
660 for (;in != NULL; in = in->prev, in_d--) {
661 /* Possible Use of */
662 /* ls->var[in_d - 1 + jd->maxlocals][in->type] */
663 _SSA_CHECK_BOUNDS(in_d - 1 + jd->maxlocals, 0, jd->maxlocals + cd->maxstack);
664 a = ls->var[in_d - 1 + jd->maxlocals][in->type];
665 _SSA_CHECK_BOUNDS(a, 0, ls->max_vars);
666 /* i <- top(stack[a]) */
667 _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
668 i = ls->stack[a][ls->stack_top[a]-1];
669 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
670 /* Replace use of x with xi */
671 #ifdef SSA_DEBUG_VERBOSE
673 printf("Ren Use:BB %3i: stackslot: depth %3i old val: %3i Var,0: %3i varind: %3i\n", n, in_d, in->varnum, ls->var_to_index[a], ls->var_to_index[a]-i);
675 in->varnum = ls->var_to_index[a] - i;
676 lt = &(ls->lifetime[-in->varnum-1]);
677 lt->v_index = in->varnum;
678 lt->bb_last_use = -1;
680 in->varkind = TEMPVAR;
682 in = ls->basicblocks[n]->instack;
684 iptr = ls->basicblocks[n]->iinstr;
685 for(iindex = 0; iindex < ls->basicblocks[n]->icount; iindex++, iptr++) {
692 _SSA_CHECK_BOUNDS(iptr->op1, 0, jd->maxlocals);
693 a = ls->var[iptr->op1][iptr->opc - ICMD_ILOAD];
694 _SSA_CHECK_BOUNDS(a, 0, ls->max_vars);
695 /* i <- top(stack[a]) */
696 _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
697 i = ls->stack[a][ls->stack_top[a]-1];
698 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
699 /* Replace use of x with xi */
701 /* there are no LOCALVAR Stackslots with SSA */
702 if ((iptr->dst->varkind == LOCALVAR) &&
703 (iptr->dst->varnum == iptr->op1))
704 iptr->dst->varnum = ls->var_to_index[a] + i;
706 iptr->op1 = ls->var_to_index[a] + i;
708 ssa_Rename_use(ls, n, ls->var_to_index[a] + i);
716 /* replace definition of a with def of ai */
717 _SSA_CHECK_BOUNDS(iptr->op1, 0, jd->maxlocals);
718 a = ls->var[iptr->op1][iptr->opc - ICMD_ISTORE];
719 _SSA_CHECK_BOUNDS(a, 0, ls->max_vars);
722 i = ssa_Rename_def(ls, n, a);
723 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
725 iptr->op1 = ls->var_to_index[a] + i;
726 /* Mark Def as use, too. Since param initialisation is in var_def */
727 /* and this would not remove this locals, if not used elsewhere */
728 ssa_Rename_use(ls, n, ls->var_to_index[a] + i);
732 /* Load from iptr->op1 */
733 _SSA_CHECK_BOUNDS(iptr->op1, 0, jd->maxlocals);
734 a = ls->var[iptr->op1][TYPE_INT];
735 _SSA_CHECK_BOUNDS(a, 0, ls->max_vars);
736 /* i <- top(stack[a]) */
737 _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
738 i = ls->stack[a][ls->stack_top[a]-1];
739 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
740 /* Replace use of x with xi */
741 iptr->op1 = ls->var_to_index[a] + i;
743 ssa_Rename_use(ls, n, ls->var_to_index[a] + i);
744 /* Store new(iinced) value in iptr->val._i.opq_t */
746 /* replace definition of a with def of ai */
747 _SSA_CHECK_BOUNDS(iptr->val._i.op1_t, 0, jd->maxlocals);
748 a = ls->var[iptr->val._i.op1_t][TYPE_INT];
749 _SSA_CHECK_BOUNDS(a, 0, ls->max_vars);
752 i = ssa_Rename_def(ls, n, a);
753 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
755 iptr->val._i.op1_t = ls->var_to_index[a] + i;
756 /* Mark Def as use, too. Since param initialisation is in var_def */
757 /* and this would not remove this locals, if not used elsewhere */
758 ssa_Rename_use(ls, n, ls->var_to_index[a] + i);
764 /* change def of outstack Interface stackslots */
765 in = ls->basicblocks[n]->instack;
766 in_d = ls->basicblocks[n]->indepth;
767 out = ls->basicblocks[n]->outstack;
768 out_d = ls->basicblocks[n]->outdepth;
770 for(;in_d > out_d; in = in->prev, in_d--);
772 for (;out != NULL; out = out->prev, out_d--) {
773 if ((in_d < out_d) || (out != in)) {
774 /* Def of ls->var[out_d - 1 + jd->maxlocals][out->type] */
775 _SSA_CHECK_BOUNDS(out_d - 1 + jd->maxlocals, 0, jd->maxlocals + cd->maxstack);
776 a = ls->var[out_d - 1 + jd->maxlocals][out->type];
777 _SSA_CHECK_BOUNDS(a, 0, ls->max_vars);
779 i = ssa_Rename_def(ls, n, a);
780 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
781 /* Replace use of x with xi */
782 #ifdef SSA_DEBUG_VERBOSE
784 printf("Ren def:BB %3i: stackslot: depth %3i old val: %3i Var,0: %3i varind: %3i\n", n, in_d, out->varnum, ls->var_to_index[a], ls->var_to_index[a]-i);
786 out->varnum = ls->var_to_index[a] - i;
787 lt = &(ls->lifetime[-out->varnum-1]);
788 out->varkind = TEMPVAR;
789 lt->v_index = out->varnum;
790 lsra_add_ss(lt, out);
792 ls->lifetime[-out->varnum-1].bb_last_use = -1;
800 /* change phi Functions of Successors */
801 Y = graph_get_first_successor(gd, n, &iter_succ);
802 for(; Y != -1; Y = graph_get_next(&iter_succ)) {
803 _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
804 k = graph_get_first_predecessor(gd, Y, &iter_pred);
805 for (j = 0; (k != -1) && (k != n); j++, k = graph_get_next(&iter_pred));
807 /* n is jth Predecessor of Y */
808 for(a = 0; a < ls->max_vars; a++)
809 if (ls->phi[Y][a] != NULL) {
810 /* i <- top(stack[a]) */
811 _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
812 i = ls->stack[a][ls->stack_top[a]-1];
813 _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
814 /* change jth operand from a0 to ai */
815 if (ls->var_to_index[a] >= 0) {
817 ls->phi[Y][a][j+1] += i;
818 _SSA_CHECK_BOUNDS(ls->phi[Y][a][j+1], 0,
819 ls->local_0[ls->max_locals]);
820 /* use by phi function has to be remembered, too */
821 ssa_Rename_use(ls, n, ls->phi[Y][a][j+1]);
824 ls->phi[Y][a][j+1] -= i;
825 /* _SSA_CHECK_BOUNDS(ls->phi[Y][a][j+1], */
826 /* ls->interface_0[-ls->max_interfaces-1], 0); */
831 /* Call ssa_Rename_ for all Childs of n of the Dominator Tree */
832 for(i = 0; i < ls->basicblockcount; i++)
833 if (dd->idom[i] == n)
834 ssa_Rename_(cd, ls, gd, dd, i);
836 /* pop Stack[a] for each definition of a var a in the original S */
837 for(a = 0; a < ls->max_vars; a++) {
838 ls->stack_top[a] -= def_count[a];
839 _SSA_ASSERT(ls->stack_top[a] >= 0);
843 void ssa_Rename(methodinfo *m, codegendata *cd, registerdata *rd, lsradata *ls,
844 graphdata *gd, dominatordata *dd)
846 int i, p, t, type, flags;
847 methoddesc *md = m->parseddesc;
850 #ifdef SSA_DEBUG_VERBOSE
854 if (ls->max_vars == 0) {
855 /* no locals or interfaces to rename */
858 ls->maxlifetimes = /*m*/ ls->maxlifetimes + ls->basicblockcount * m->maxstack;
859 ls->lifetimecount = ls->maxlifetimes + ls->max_locals + cd->maxstack *5;
860 ls->lifetime = DMNEW(struct lifetime, ls->lifetimecount);
861 ls->lt_used = DMNEW(int, ls->lifetimecount);
862 ls->lt_int = DMNEW(int, ls->lifetimecount);
863 ls->lt_int_count = 0;
864 ls->lt_flt = DMNEW(int, ls->lifetimecount);
865 ls->lt_flt_count = 0;
866 ls->lt_mem = DMNEW(int, ls->lifetimecount);
867 ls->lt_mem_count = 0;
868 for (i=0; i < ls->lifetimecount; i++) ls->lifetime[i].type = -1;
872 ssa_Rename_init(m, cd, ls, gd);
874 /* Consider definition of Local Vars initialized with Arguments */
876 /* init is regarded as use too-> ssa_Rename_use ->bullshit!!*/
877 for (p = 0, i= 0; p < md->paramcount; p++) {
878 t = md->paramtypes[p].type;
880 /* !!!!! locals are now numbered as the parameters !!!! */
881 /* !!!!! no additional increment for 2 word types !!!!! */
882 /* this happens later on! here we still need the increment */
883 /* index of var can be in the range from 0 up to not including */
885 _SSA_CHECK_BOUNDS(i,0,jd->maxlocals);
886 _SSA_CHECK_BOUNDS(ls->var[i][t], 0, ls->local_0[ls->max_locals]);
887 ssa_Rename_def(ls, 0, ls->var[i][t]);
889 if (IS_2_WORD_TYPE(t))
892 ssa_Rename_(cd, ls, gd, dd, 0);
895 /* DO _NOT_ DO THIS! Look at java.util.stringtokenizer.counttokens! */
896 /* if there is no use of the defined Var itself by the phi function */
897 /* for an loop path, in which this var is not used, it will not be life */
898 /* in this path and overwritten! */
900 /* Invalidate all xij from phi(xi0)=xi1,xi2,xi3,..,xin with xij == xi0 */
901 /* this happens if the phi function is the first definition of x or in a */
902 /* path with a backedge xi has no definition */
903 /* a phi(xij) = ...,xij,... with the only use and definition of xij by */
904 /* this phi function would otherwise "deadlock" the dead code elemination */
905 /* invalidate means set it to ls->max_vars_with_indices */
906 /* a phi function phi(xi0)=xi1,xi2,...xin wiht xij == xi0 for all j in */
907 /* [1,n] can be removed */
909 for(i = 0; i < ls->max_vars; i++) {
910 for(t = 0; t < ls->basicblockcount; t++) {
911 if (ls->phi[t][i] != 0) {
913 for(p = 1; p <= graph_get_num_predecessor(gd, t); p++) {
914 if (ls->phi[t][i][0] == ls->phi[t][i][p])
915 ls->phi[t][i][p] = ls->max_vars_with_indices;
921 ls->phi[t][i] = NULL;
926 /* recreate rd->locals[][] */
927 /* now only one (local_index/type) pair exists anymore */
928 /* all var[t][i] with var_to_index[var[t][i]] >= 0 are locals */
929 /* max local index after SSA indexing is in ls->local_0[ls->max_locals] */
931 locals = DMNEW(varinfo5, ls->local_0[ls->max_locals]);
932 for(i = 0; i < ls->local_0[ls->max_locals] ; i++)
933 for(t = 0; t < 5; t++)
934 locals[i][t].type = -1;
935 for(t = 0; t < 5; t++) {
936 for(i = 0; i < jd->maxlocals; i++) {
939 _SSA_ASSERT(ls->var_to_index[p] >= 0);
940 /* It's a local variable */
941 p = ls->var_to_index[p];
942 locals[p][t].type = t;
943 locals[p][t].flags = rd->locals[i][t].flags;
944 #ifdef SSA_DEBUG_VERBOSE
946 printf("locals %3i %3i .type = %3i\n",p,t,t);
954 #ifdef SSA_DEBUG_VERBOSE
958 for(i = 0; i < ls->local_0[ls->max_locals]; i++) {
959 for(t = 0; (t < 5) && (locals[i][t].type == -1); t++);
961 _SSA_ASSERT(type != -1);
962 #ifdef SSA_DEBUG_VERBOSE
963 if (compileverbose) {
964 printf("L%3i=L%3i(%3i) type %3i\n",i,p,j,type);
968 locals[i][type].type = type;
969 locals[i][type].flags = flags;
971 type = locals[i][t].type;
972 flags = locals[i][t].flags;
973 #ifdef SSA_DEBUG_VERBOSE
974 if (compileverbose) {
977 printf("L%3i=L%3i(%3i) type %3i\n",i,p,j,type);
984 jd->maxlocals = ls->local_0[ls->max_locals];
987 #ifdef SSA_DEBUG_VERBOSE
988 void ssa_print_trees(methodinfo *m, codegendata *cd, lsradata *ls,
989 graphdata *gd, dominatordata *dd) {
991 printf("ssa_printtrees: maxlocals %3i", jd->maxlocals);
993 printf("Dominator Tree: \n");
994 for(i = 0; i < ls->basicblockcount; i++) {
996 for(j = 0; j < ls->basicblockcount; j++) {
997 if (dd->idom[j] == i) {
1004 printf("Dominator Forest:\n");
1005 for(i = 0; i < ls->basicblockcount; i++) {
1007 for(j = 0; j < dd->num_DF[i]; j++) {
1008 printf(" %3i", dd->DF[i][j]);
1013 if (ls->max_locals > 0) {
1014 printf("Use Sites\n");
1015 for(i = 0; i < ls->max_locals; i++) {
1016 printf("use_sites[%3i]=%p:",i,(void *)ls->use_sites[i]);
1017 for(j = 0; j < ls->basicblockcount; j++) {
1018 if ((j % 5) == 0) printf(" ");
1019 if (bv_get_bit(ls->use_sites[i], j))
1028 printf("var Definitions:\n");
1029 for(i = 0; i < ls->basicblockcount; i++) {
1030 printf("var_def[%3i]=%p:",i,(void *)ls->var_def[i]);
1031 for(j = 0; j < ls->max_vars; j++) {
1032 if ((j % 5) == 0) printf(" ");
1033 if (bv_get_bit(ls->var_def[i], j))
1039 for(j=0; j < ((((ls->max_vars * 5+7)/8) + sizeof(int) - 1)/sizeof(int));
1041 printf("%8x",ls->var_def[i][j]);
1046 void ssa_print_phi(lsradata *ls, graphdata *gd) {
1049 printf("phi Functions (max_vars_with_indices: %3i):\n",
1050 ls->max_vars_with_indices);
1051 for(i = 0; i < ls->basicblockcount; i++) {
1052 for(j = 0; j < ls->max_vars; j++) {
1053 if (ls->phi[i][j] != NULL) {
1054 printf("BB %3i %3i = phi(", i, ls->phi[i][j][0]);
1055 for(k = 1; k <= graph_get_num_predecessor(gd, i); k++)
1056 printf("%3i ",ls->phi[i][j][k]);
1066 void ssa_generate_phi_moves(lsradata *ls, graphdata *gd) {
1070 /* count moves to be inserted at the end of each block in moves[] */
1071 ls->num_phi_moves = DMNEW(int, ls->basicblockcount);
1072 for(i = 0; i < ls->basicblockcount; i++)
1073 ls->num_phi_moves[i] = 0;
1074 for(i = 0; i < ls->basicblockcount; i++)
1075 for(a = 0; a < ls->max_vars; a++)
1076 if (ls->phi[i][a] != NULL) {
1077 pred = graph_get_first_predecessor(gd, i, &iter);
1078 for(; pred != -1; pred = graph_get_next(&iter)) {
1079 ls->num_phi_moves[pred]++;
1083 /* allocate ls->phi_moves */
1084 ls->phi_moves = DMNEW( int **, ls->basicblockcount);
1085 for(i = 0; i < ls->basicblockcount; i++) {
1086 ls->phi_moves[i] = DMNEW( int *, ls->num_phi_moves[i]);
1087 for(j = 0; j <ls->num_phi_moves[i]; j++)
1088 ls->phi_moves[i][j] = DMNEW(int, 2);
1091 /* populate ls->phi_moves */
1092 for(i = 0; i < ls->basicblockcount; i++)
1093 ls->num_phi_moves[i] = 0;
1094 for(i = 0; i < ls->basicblockcount; i++)
1095 for(a = 0; a < ls->max_vars; a++)
1096 if (ls->phi[i][a] != NULL) {
1097 pred = graph_get_first_predecessor(gd, i, &iter);
1098 for(j = 0; pred != -1; j++, pred = graph_get_next(&iter)) {
1099 /* target is phi[i][a][0] */
1100 /* source is phi[i][a][j+1] */
1101 if (ls->phi[i][a][j+1] != ls->max_vars_with_indices) {
1103 if (ls->phi[i][a][0] != ls->phi[i][a][j+1]) {
1104 ls->phi_moves[pred][ls->num_phi_moves[pred]][0] =
1106 ls->phi_moves[pred][(ls->num_phi_moves[pred])++][1] =
1115 void ssa(jitdata *jd, graphdata *gd) {
1116 struct dominatordata *dd;
1127 dd = compute_Dominators(gd, ls->basicblockcount);
1128 computeDF(gd, dd, ls->basicblockcount, 0);
1130 ssa_place_phi_functions(cd, ls, gd, dd);
1131 ssa_Rename(m, cd, rd, ls, gd, dd);
1132 #ifdef SSA_DEBUG_VERBOSE
1133 if (compileverbose) {
1134 printf("Phi before Cleanup\n");
1135 ssa_print_phi(ls, gd);
1139 scan_lifetimes(m, cd, rd, ls, gd, dd);
1140 #ifdef SSA_DEBUG_VERBOSE
1141 if (compileverbose) {
1145 dead_code_elimination(m, rd, ls, gd);
1146 #ifdef SSA_DEBUG_VERBOSE
1147 if (compileverbose) {
1148 printf("Phi after dead code elemination\n");
1149 ssa_print_phi(ls, gd);
1153 copy_propagation(m, rd, ls, gd);
1154 #ifdef SSA_DEBUG_VERBOSE
1155 if (compileverbose) {
1156 printf("Phi after copy propagation\n");
1157 ssa_print_phi(ls, gd);
1162 ssa_generate_phi_moves(ls, gd);
1163 transform_BB(jd, gd);
1166 #ifdef SSA_DEBUG_CHECK
1168 int i, j, pred, in_d, out_d;
1169 graphiterator iter_pred;
1173 for(i = 0; i < ls->basicblockcount; i++) {
1174 if (ls->basicblocks[i]->indepth != 0) {
1175 pred = graph_get_first_predecessor(gd, i, &iter_pred);
1176 for (; (pred != -1); pred = graph_get_next(&iter_pred)) {
1177 in_d = ls->basicblocks[i]->indepth;
1178 in = ls->basicblocks[i]->instack;
1179 for (;in_d > 0; in_d--, in = in->prev) {
1181 for (j = 0; (!phi_define) && (j < ls->max_vars); j++) {
1182 if (ls->phi[i][j] != NULL)
1183 if (ls->phi[i][j][0] == in->varnum)
1187 /* in not defined in phi function -> check with outstack(s) */
1188 /* of predecessor(s) */
1189 out_d = ls->basicblocks[pred]->outdepth;
1190 out = ls->basicblocks[pred]->outstack;
1191 _SSA_ASSERT(out_d >= in_d);
1192 for(; out_d > in_d; out_d--, out = out->prev);
1193 if ((in->varnum != out->varnum) ||
1194 (in->varkind != out->varkind)) {
1195 printf("Method: %s %s\n", m->class->name->text, m->name->text);
1196 printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
1198 printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
1200 /* _SSA_ASSERT(0); */
1212 #ifdef SSA_DEBUG_VERBOSE
1214 ssa_print_trees(m,cd,ls, gd, dd);
1218 /****************************************************************************
1220 ****************************************************************************/
1223 /****************************************************************************
1224 Dead Code Elimination
1225 ****************************************************************************/
1226 void dead_code_elimination(methodinfo *m,registerdata *rd, lsradata *ls, graphdata *gd) {
1232 struct lifetime *lt, *s_lt;
1234 bool remove_statement;
1237 W = wl_new(ls->lifetimecount);
1238 if (ls->lifetimecount > 0) {
1239 /* put all lifetimes on Worklist */
1240 for(a = 0; a < ls->lifetimecount; a++) {
1241 if (ls->lifetime[a].type != -1) {
1247 /* Remove unused lifetimes */
1248 while(!wl_is_empty(W)) {
1249 /* take a var out of Worklist */
1252 lt = &(ls->lifetime[a]);
1253 if ((lt->def == NULL) || (lt->type == -1))
1254 /* lifetime was already removed -> no defs anymore */
1257 /* Remove lifetimes, which are only used in a phi function, which
1259 remove_statement = (lt->use != NULL) && (lt->use->iindex < 0);
1260 for(use = lt->use; (remove_statement && (use != NULL));
1263 remove_statement = remove_statement &&
1264 (use->b_index == lt->def->b_index) &&
1265 (use->iindex == lt->def->iindex);
1267 if (remove_statement) {
1268 #ifdef SSA_DEBUG_CHECK
1269 /* def == use can only happen in phi functions */
1270 if (remove_statement)
1271 _SSA_ASSERT(lt->use->iindex < 0);
1273 /* give it free for removal */
1277 if (lt->use == NULL) {
1278 /* Look at statement of definition of a and remove it, */
1279 /* if the Statement has no sideeffects other than the assignemnt */
1281 if (lt->def->iindex < 0 ) {
1283 /* delete use of sources , delete phi functions */
1285 _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] !=
1288 for (i = 1;i <= graph_get_num_predecessor(gd, lt->def->b_index);
1291 source = ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
1292 if ((source != ls->max_vars_with_indices) &&
1293 (source != lt->v_index)) {
1294 /* phi Argument was not already removed (already in
1295 because of selfdefinition) */
1298 s_lt = &(ls->lifetime[ls->maxlifetimes + source]);
1300 /* Interface Stackslot */
1301 s_lt = &(ls->lifetime[-source-1]);
1304 remove_use_site(s_lt,lt->def->b_index, lt->def->iindex);
1305 /* put it on the Worklist */
1308 wl_add(W, ls->maxlifetimes + source);
1310 /* Interface Stackslot */
1311 wl_add(W, -source - 1);
1315 /* now delete phi function itself */
1316 ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
1318 /* "normal" Use by ICMD */
1319 remove_statement = false;
1320 if (lt->def->b_index != 0) {
1321 /* do not look at artificial block 0 (parameter init) */
1322 iptr = ls->basicblocks[lt->def->b_index]->iinstr +
1325 if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI)
1326 remove_statement = false;
1327 /* if ICMD could throw an exception do not remove it! */
1330 if (lt->def->iindex == 0)
1331 src = ls->basicblocks[lt->def->b_index]->instack;
1333 src = (iptr-1)->dst;
1335 remove_statement = true;
1336 /* Statement has side effects? (== ICMD_INVOKE*) */
1337 switch (iptr->opc) {
1338 case ICMD_INVOKEVIRTUAL:
1339 case ICMD_INVOKESPECIAL:
1340 case ICMD_INVOKESTATIC:
1341 case ICMD_INVOKEINTERFACE:
1343 /* check if really a side effect is possible */
1344 case ICMD_MULTIANEWARRAY: /* here, too */
1345 /* side effects by Statement possible ->
1347 remove_statement = false;
1350 /* delete use of vars by these statments: */
1352 /* use of iptr->op1 */
1359 s_lt = &(ls->lifetime[ls->maxlifetimes + iptr->op1]);
1360 remove_use_site(s_lt,lt->def->b_index, lt->def->iindex);
1361 /* put it on the Worklist */
1362 wl_add(W, ls->maxlifetimes + iptr->op1);
1365 /* remove src->prev and src */
1423 /* Remove src->prev and then "fall through" for removal
1425 s_lt = &(ls->lifetime[-src->prev->varnum-1]);
1426 remove_use_site(s_lt,lt->def->b_index, lt->def->iindex);
1427 /* put it on the Worklist */
1428 wl_add(W, -src->prev->varnum - 1);
1435 case ICMD_LADDCONST:
1436 case ICMD_LSUBCONST:
1437 case ICMD_LMULCONST:
1441 case ICMD_LANDCONST:
1443 case ICMD_LXORCONST:
1444 case ICMD_LSHLCONST:
1445 case ICMD_LSHRCONST:
1446 case ICMD_LUSHRCONST:
1448 case ICMD_IADDCONST:
1449 case ICMD_ISUBCONST:
1450 case ICMD_IMULCONST:
1454 case ICMD_IANDCONST:
1456 case ICMD_IXORCONST:
1457 case ICMD_ISHLCONST:
1458 case ICMD_ISHRCONST:
1459 case ICMD_IUSHRCONST:
1461 /* case ICMD_IFEQ_ICONST: */
1462 /* case ICMD_IFNE_ICONST: */
1463 /* case ICMD_IFLT_ICONST: */
1464 /* case ICMD_IFGE_ICONST: */
1465 /* case ICMD_IFGT_ICONST: */
1466 /* case ICMD_IFLE_ICONST: */
1471 case ICMD_INT2SHORT:
1488 case ICMD_CHECKCAST:
1489 case ICMD_ARRAYLENGTH:
1490 case ICMD_INSTANCEOF:
1493 case ICMD_ANEWARRAY:
1496 /* Remove src->prev and then "fall through" for removal
1498 s_lt = &(ls->lifetime[-src->varnum-1]);
1499 remove_use_site(s_lt,lt->def->b_index, lt->def->iindex);
1500 /* put it on the Worklist */
1501 wl_add(W, -src->varnum - 1);
1503 /* ignore these for now */
1511 #ifdef SSA_DEBUG_VERBOSE
1513 printf("INFO2: ICMD_DUPX to be removed\n");
1515 /* DUPX has sideefects - cannot be removed, only because
1516 one of the output vars is unused
1517 TODO: extend the dead code elimination, so that all
1518 output ss are checked*/
1519 remove_statement = false;
1521 } /* switch (iptr->opc) */
1523 if (remove_statement) {
1524 /* remove statement */
1525 #ifdef SSA_DEBUG_VERBOSE
1527 printf("INFO: %s %s:at BB %3i II %3i NOP-<%s\n",
1528 m->class->name->text, m->name->text,
1529 lt->def->b_index, lt->def->iindex,
1530 icmd_table[iptr->opc].name);
1532 iptr->opc = ICMD_NOP;
1534 } /* (lt->def->b_index != 0) */
1535 } /* if (lt->def->iindex < 0 ) else */
1536 /* remove definition of a */
1537 if (lt->v_index >= 0) {
1539 rd->locals[lt->v_index][lt->type].type = -1;
1543 } /* if (lt->use == NULL) */
1545 } /* while(!wl_is_empty(W)) */
1546 } /* dead_code_elimination */
1551 void dead_code_elimination(registerdata *rd, lsradata *ls, graphdata *gd) {
1559 if (ls->max_locals > 0) {
1560 W_stack = DMNEW(int, ls->max_vars);
1561 /* put unused local vars on Worklist */
1562 for(a = 0; a < ls->local_0[ls->max_locals]; a++) {
1563 if (bv_is_empty(ls->use_sites[a], ls->basicblockcount)) {
1565 W_stack[W_top++] = a;
1569 /* Remove unused local vars */
1571 /* take a var out of Worklist */
1572 a = W_stack[--W_top];
1574 if (bv_is_empty(ls->use_sites[a], ls->basicblockcount)) {
1575 for(t = 0; t < 5; t++)
1576 rd->locals[a][t].type = -1;
1578 /* Change and if necessary delete phi functions */
1579 for(n = 0; n < ls->basicblockcount; n++) {
1580 for(A = 0; A < ls->max_vars; A++) {
1581 if (ls->var_to_index[A] >= 0) {
1582 if (ls->phi[n][A] != NULL) {
1584 /* look through the arguments of the phi function */
1585 for(i = 1; i < (graph_get_num_predecessor(gd, n)+1); i++) {
1586 /* check if entry was not already removed */
1587 if (ls->phi[n][A][i] != -1) {
1588 if (bv_is_empty(ls->use_sites[ls->phi[n][A][i]],
1589 ls->basicblockcount))
1591 ls->num_var_use[n][ls->phi[n][A][i]]--;
1592 if (ls->num_var_use[n][ls->phi[n][A][i]] ==
1594 /* this was the only use in this Basic Block */
1596 ls->use_sites[ls->phi[n][A][i]],n);
1598 ls->use_sites[ls->phi[n][A][i]],
1599 ls->basicblockcount))
1601 /* this was the only use in the whole Method */
1602 /* -> put this local var on the Worklist */
1607 ls->phi[n][A][i] = -1;
1612 /* look at the target of the phi function */
1613 /* Remove it,if target is not used or all arguments where */
1615 if (bv_is_empty(ls->use_sites[ls->phi[n][A][0]],
1616 ls->basicblockcount) || is_empty) {
1617 /* phi function can be removed */
1618 ls->phi[n][A] = NULL;
1620 } /* if (ls->phi[n][A] != NULL) */
1621 } /* if (ls->var_to_index[A] >= 0 */
1622 } /* for(li = 0; li < ls->max_locals; li++) */
1623 } /* for(n = 0; n < ls->basicblockcount; n++) */
1624 } /* while(W_top>0) */
1625 /* Remove unused Local Vars from rd->local */
1626 if (ls->max_locals > 0)
1627 for(a = 0; a < ls->local_0[ls->max_locals]; a++) {
1628 if (bv_is_empty(ls->use_sites[a], ls->basicblockcount)) {
1630 for(t = 0; t < 5; t++)
1631 rd->locals[a][t].type = -1;
1636 /****************************************************************************
1637 Simple Constant Propagation
1638 ****************************************************************************/
1640 void simple_constant_propagation() {
1642 /****************************************************************************
1644 *******************************************************************************/
1645 void copy_propagation(methodinfo *m,registerdata *rd, lsradata *ls,
1653 struct lifetime *lt, *s_lt;
1654 struct stackslot *ss;
1657 W = wl_new(ls->lifetimecount);
1658 if (ls->lifetimecount > 0) {
1659 /* put all lifetimes on Worklist */
1660 for(a = 0; a < ls->lifetimecount; a++) {
1661 if (ls->lifetime[a].type != -1) {
1667 while(!wl_is_empty(W)) {
1668 /* take a var out of Worklist */
1671 lt = &(ls->lifetime[a]);
1674 _SSA_ASSERT(lt->def != NULL);
1675 _SSA_ASSERT(lt->use != NULL);
1676 if (lt->def->iindex < 0 ) {
1678 /* look, if phi function degenerated to a x = phi(y) */
1679 /* and if so, substitute y for every use of x */
1681 _SSA_ASSERT(ls->phi[lt->def->b_index][-lt->def->iindex-1] != NULL);
1683 only_source = ls->max_vars_with_indices;
1684 for (i = 1; i <= graph_get_num_predecessor(gd, lt->def->b_index);
1686 source = ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
1687 if (source != ls->max_vars_with_indices) {
1688 if (only_source == ls->max_vars_with_indices) {
1689 /* first valid source argument of phi function */
1690 only_source = source;
1692 /* second valid source argument of phi function */
1694 only_source = ls->max_vars_with_indices;
1699 if (only_source != ls->max_vars_with_indices) {
1700 /* replace all use sites of lt with the var_index only_source */
1701 replace_use_sites( ls, gd, lt, only_source, W);
1703 /* delete def of lt and replace uses of lt with "only_source" */
1704 ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
1706 if (only_source >= 0) {
1708 s_lt = &(ls->lifetime[ls->maxlifetimes + only_source]);
1709 rd->locals[lt->v_index][lt->type].type = -1;
1711 /* Interface Stackslot */
1712 s_lt = &(ls->lifetime[-only_source-1]);
1714 remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
1716 /* move use sites from lt to s_lt */
1717 move_use_sites(lt, s_lt);
1718 move_stackslots(lt, s_lt);
1720 } /* if (only_source != ls->max_vars_with_indices) */
1721 } else { /* if (lt->def->iindex < 0 )*/
1722 /* def in "normal" ICMD */
1723 iptr = ls->basicblocks[lt->def->b_index]->iinstr +
1725 if (lt->v_index >= 0) {
1726 if (lt->def->b_index == 0)
1734 if (lt->def->iindex == 0) {
1735 /* first instruction in bb -> instack==bb->instack */
1736 in = ls->basicblocks[lt->def->b_index]->instack;
1738 /* instack is (iptr-1)->dst */
1742 if (in->varkind != LOCALVAR) {
1743 #ifdef SSA_DEBUG_VERBOSE
1745 printf("copy propagation xstore: BB %3i I %3i: %3i -> %3i\n", lt->def->b_index, lt->def->iindex, iptr->op1, in->varnum);
1747 s_lt = &(ls->lifetime[-in->varnum-1]);
1749 for (ss = s_lt->local_ss; ss != NULL; ss = ss->next) {
1750 ss->s->varkind = LOCALVAR;
1751 ss->s->varnum = iptr->op1;
1754 /* replace all use sites of s_lt with the var_index */
1757 replace_use_sites(ls, gd, s_lt, iptr->op1, W);
1759 /* s_lt->def is the new def site of lt */
1760 /* the old ->def site will get a use site of def */
1761 /* only one def site */
1762 _SSA_ASSERT(lt->def->next == NULL);
1763 _SSA_ASSERT(s_lt->def != NULL);
1764 _SSA_ASSERT(s_lt->def->next == NULL);
1766 /* replace def of s_lt with iptr->op1 */
1767 if (s_lt->def->iindex < 0) {
1769 _SSA_ASSERT(ls->phi[s_lt->def->b_index]
1770 [-s_lt->def->iindex-1]
1772 ls->phi[s_lt->def->b_index][-s_lt->def->iindex-1][0]
1775 if (in->varnum != iptr->op1)
1776 printf("copy propagation: LOCALVAR ss->ISTORE BB %i II %i\n",
1777 lt->def->b_index, lt->def->iindex);
1780 /* move def to use sites of lt */
1781 lt->def->next = lt->use;
1784 lt->def = s_lt->def;
1789 /* move use sites from s_lt to lt */
1790 move_use_sites(s_lt, lt);
1791 move_stackslots(s_lt, lt);
1797 /* Def Interface Stackslot */
1805 only_source = lt->local_ss->s->varnum;
1806 if (lt->local_ss->s->varkind != LOCALVAR) {
1807 #ifdef SSA_DEBUG_VERBOSE
1809 printf("copy propagation xload: BB %3i I %3i: %3i -> %3i\n", lt->def->b_index, lt->def->iindex, iptr->op1, lt->local_ss->s->varnum);
1811 _SSA_ASSERT(iptr->dst->varnum == lt->local_ss->s->varnum);
1812 for (ss = lt->local_ss; ss != NULL; ss = ss->next) {
1813 ss->s->varkind = LOCALVAR;
1814 ss->s->varnum = iptr->op1;
1817 /* replace all use sites of lt with the var_index iptr->op1*/
1819 replace_use_sites( ls, gd, lt, iptr->op1, W);
1823 s_lt = &(ls->lifetime[ls->maxlifetimes + iptr->op1]);
1825 /* move use sites from lt to s_lt */
1826 move_use_sites(lt, s_lt);
1827 move_stackslots(lt, s_lt);
1830 if (lt->local_ss->s->varnum != iptr->op1)
1831 printf("copy propagation: ILOAD -> LOCALVAR ss BB %i II %i\n",
1832 lt->def->b_index, lt->def->iindex);
1841 void replace_use_sites( lsradata *ls, graphdata *gd, struct lifetime *lt,
1842 int new_v_index, worklist *W) {
1846 struct stackslot *ss;
1848 for(s = lt->use; s != NULL; s = s->next) {
1849 if (s->iindex < 0) {
1850 /* Use in phi function */
1851 for (i = 1;i <= graph_get_num_predecessor(gd,s->b_index);
1853 source = ls->phi[s->b_index][-s->iindex-1][i];
1854 if (source == lt->v_index) {
1855 #ifdef SSA_DEBUG_VERBOSE
1858 printf("copy propagation phi: BB %3i I %3i: %3i -> \
1859 %3i\n", s->b_index, s->iindex,
1860 new_v_index, source);
1863 ls->phi[s->b_index][-s->iindex-1][i]
1868 /* Add var, which is defined by this phi function to */
1870 source = ls->phi[s->b_index][-s->iindex-1][0];
1873 wl_add(W, ls->maxlifetimes + source);
1875 /* Interface Stackslot */
1876 wl_add(W, -source - 1);
1882 iptr = ls->basicblocks[s->b_index]->iinstr +
1884 if (lt->v_index >= 0) {
1897 case ICMD_IINC: /* iptr->op1 == USE */
1898 /* TODO: check if for XSTORE not src->varnum has */
1899 /* to be changed instead of iptr->op1 */
1900 _SSA_ASSERT(iptr->op1 == lt->v_index);
1901 #ifdef SSA_DEBUG_VERBOSE
1904 printf("copy propagation loc: BB %3i I %3i: %3i -> \
1905 %3i\n", s->b_index, s->iindex,
1906 new_v_index, iptr->op1);
1909 iptr->op1 = new_v_index;
1915 /* Interface Stackslot Use */
1916 #ifdef SSA_DEBUG_VERBOSE
1918 printf("copy propagation int: BB %3i I %3i: %3i -> \
1919 %3i\n", s->b_index, s->iindex, new_v_index,
1920 lt->local_ss->s->varnum);
1922 for (ss = lt->local_ss; ss != NULL; ss = ss->next) {
1923 ss->s->varkind = LOCALVAR;
1924 ss->s->varnum = new_v_index;
1929 } /* for(s = lt->use; s != NULL; s = s->next) */
1932 #ifdef SSA_DEBUG_VERBOSE
1933 void ssa_print_lt(lsradata *ls) {
1935 struct lifetime *lt;
1938 printf("SSA LT Def/Use\n");
1939 for(i = 0; i < ls->lifetimecount; i++) {
1940 lt = &(ls->lifetime[i]);
1941 if (lt->type != -1) {
1942 printf("VI %3i Type %3i Def: ",lt->v_index, lt->type);
1943 if (lt->def != NULL)
1944 printf("%3i,%3i Use: ",lt->def->b_index, lt->def->iindex);
1946 printf("%3i,%3i Use: ",0,0);
1947 for(use = lt->use; use != NULL; use = use->next)
1948 printf("%3i,%3i ",use->b_index, use->iindex);
1954 /****************************************************************************
1956 ****************************************************************************/
1959 * These are local overrides for various environment variables in Emacs.
1960 * Please do not remove this and leave it at the end of the file, where
1961 * Emacs will automagically detect them.
1962 * ---------------------------------------------------------------------
1965 * indent-tabs-mode: t