1 /* src/vm/jit/optimizing/ssa.c - static single-assignment form
3 Copyright (C) 2005-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/jit/builtin.hpp"
38 #include "vm/jit/jit.hpp" /* icmd_table */
40 #include "vm/jit/optimizing/dominators.hpp"
41 #include "vm/jit/optimizing/graph.h"
42 #include "vm/jit/optimizing/lifetimes.h"
43 #include "vm/jit/optimizing/lsra.h"
44 #include "vm/jit/optimizing/ssa.h"
45 #include "vm/jit/optimizing/ssa_phi.h"
47 #if defined(SSA_DEBUG_VERBOSE)
48 #include "vm/options.h" /* compileverbose */
51 /* ssa_place_phi_functions *****************************************************
53 Algorithm is based on "modern compiler implementation in C" from andrew
54 w. appel, edition 2004
57 page 441 Algorithm 19.6. Inserting phi-functions:
61 - if Y not element of A phi [n]
62 + if a not element of A phi [n]
63 insert the statment a <- ...
66 - A phi [n] <- A phi [n] join {Y}
67 + A phi [n] <- A phi [n] join {a}
68 - if Y not element of A orig [n]
69 + if a not element of A orig [Y]
73 ls->phi[n][a][p] is created and populated.
75 n in [0..ls->basicblockcount[
76 a in [0..ls->ssavarcount[
77 p in [1..Count of Predecessors of Basicblock n]
79 For each basicblock Y in the dominance frontier of a basicblock n (0 <= n <
80 ls->basicblockcount) in which a variable (0 <= a < ls->ssavarcount) is defined
81 an entry in ls->phi[Y][a] is created.
82 This entry is an array with the number of predecessors of Y elements + 1
84 This elements are all set to the variable a and represent the phi function which
85 will get ai = phi(ai1, ai2, ..., aip) after ssa_rename.
88 ls->phi[n][a] == NULL, if no phi function for Variable a for Basicblock n exists
92 ls->phi[n][a][0] == a, representing the result of the phi function and
93 ls->phi[n][a][p] == a, representing the arguments of the phi function.
95 *******************************************************************************/
98 void ssa_place_phi_functions(jitdata *jd, graphdata *gd, dominatordata *dd)
101 bitvector *def_sites;
102 bitvector *A_phi; /* [0..ls->basicblockcount[ of */
103 /* ls->ssavarcount Bit */
111 W = wl_new(ls->basicblockcount);
113 def_sites = DMNEW(bitvector, ls->ssavarcount);
114 for(a = 0; a < ls->ssavarcount; a++)
115 def_sites[a] = bv_new(ls->basicblockcount);
117 ls->phi = DMNEW(int **, ls->basicblockcount);
118 A_phi = DMNEW(bitvector, ls->basicblockcount);
119 for(i = 0; i < ls->basicblockcount; i++) {
120 ls->phi[i] = DMNEW(int *, ls->ssavarcount);
121 for(j = 0; j < ls->ssavarcount; j++)
122 ls->phi[i][j] = NULL;
123 A_phi[i] = bv_new(ls->ssavarcount);
126 /* copy var_def to def_sites */
127 /* var_def is valid for 0.. jd->basicblockcount (bb 0 for param init) */
129 for(n = 0; n <= jd->basicblockcount; n++)
130 for(a = 0; a < ls->ssavarcount; a++)
131 if (bv_get_bit(ls->var_def[n], a))
132 bv_set_bit(def_sites[a], n);
133 #ifdef SSA_DEBUG_VERBOSE
134 if (compileverbose) {
135 printf("var Definitions:\n");
136 for(i = 0; i < ls->ssavarcount; i++) {
137 printf("def_sites[%3i]=%p:",i,(void *)def_sites[i]);
138 for(j = 0; j < ls->basicblockcount; j++) {
139 if ((j % 5) == 0) printf(" ");
140 if (bv_get_bit(def_sites[i], j))
152 for(a = 0; a < ls->ssavarcount; a++) {
154 /* W<-def_sites(a) */
156 for(n = 0; n < ls->basicblockcount; n++)
157 if (bv_get_bit(def_sites[a],n)) {
161 while (!wl_is_empty(W)) { /* W not empty */
164 for(i = 0; i < dd->num_DF[n]; i++) {
167 /* Node Y is in Dominance Frontier of n -> */
168 /* insert phi function for a at top of Y*/
170 _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
171 if (bv_get_bit( A_phi[Y], a) == 0) {
173 /* a is not a Element of A_phi[Y] */
174 /* a <- phi(a,a...,a) to be inserted at top of Block Y */
175 /* phi has as many arguments, as Y has predecessors */
177 num_pred = graph_get_num_predecessor(gd, Y);
178 ls->phi[Y][a] = DMNEW(int, num_pred + 1);
179 for (j = 0; j < num_pred + 1; j++)
180 ls->phi[Y][a][j] = a;
182 /* increment the number of definitions of a by one */
183 /* for this phi function */
187 bv_set_bit(A_phi[Y], a);
188 if (bv_get_bit(ls->var_def[Y],a)==0) {
190 /* Iterated Dominance Frontier Criterion: */
191 /* if Y had no definition for a, insert it */
192 /* into the Worklist, since now it */
193 /* defines a through the phi function */
203 void ssa_generate_phi_moves(jitdata *jd, graphdata *gd) {
210 /* count moves to be inserted at the end of each block in moves[] */
212 ls->num_phi_moves = DMNEW(int, ls->basicblockcount);
213 for(i = 0; i < ls->basicblockcount; i++)
214 ls->num_phi_moves[i] = 0;
215 for(i = 0; i < ls->basicblockcount; i++)
216 for(a = 0; a < ls->ssavarcount; a++)
217 if (ls->phi[i][a] != NULL) {
219 if (ls->lifetime[ls->phi[i][a][0]].use == NULL) {
220 /* Var defined (only <- SSA Form!) in this phi function */
221 /* and not used anywhere -> delete phi function and set */
224 /* TODO: first delete use sites of arguments of phi */
226 VAR(ls->lifetime[ls->phi[i][a][0]].v_index)->type = UNUSED;
227 ls->lifetime[ls->phi[i][a][0]].def = NULL;
228 ls->phi[i][a] = NULL;
233 pred = graph_get_first_predecessor(gd, i, &iter);
234 for(; pred != -1; pred = graph_get_next(&iter)) {
235 ls->num_phi_moves[pred]++;
240 /* allocate ls->phi_moves */
242 ls->phi_moves = DMNEW( int **, ls->basicblockcount);
243 for(i = 0; i < ls->basicblockcount; i++) {
244 ls->phi_moves[i] = DMNEW( int *, ls->num_phi_moves[i]);
245 for(j = 0; j <ls->num_phi_moves[i]; j++)
246 ls->phi_moves[i][j] = DMNEW(int, 2);
247 #ifdef SSA_DEBUG_VERBOSE
249 printf("ssa_generate_phi_moves: ls_num_phi_moves[%3i] = %3i\n",
250 i, ls->num_phi_moves[i]);
254 /* populate ls->phi_moves */
256 for(i = 0; i < ls->basicblockcount; i++)
257 ls->num_phi_moves[i] = 0;
258 for(i = 0; i < ls->basicblockcount; i++)
259 for(a = 0; a < ls->ssavarcount; a++)
260 if (ls->phi[i][a] != NULL) {
261 pred = graph_get_first_predecessor(gd, i, &iter);
262 for(j = 0; pred != -1; j++, pred = graph_get_next(&iter)) {
263 /* target is phi[i][a][0] */
264 /* source is phi[i][a][j+1] */
265 if (ls->phi[i][a][j+1] != ls->varcount_with_indices) {
267 if (ls->phi[i][a][0] != ls->phi[i][a][j+1]) {
268 ls->phi_moves[pred][ls->num_phi_moves[pred]][0] =
270 ls->phi_moves[pred][(ls->num_phi_moves[pred])++][1]=
278 #ifdef SSA_DEBUG_VERBOSE
279 void ssa_print_phi(lsradata *ls, graphdata *gd) {
282 printf("phi Functions (varcount_with_indices: %3i):\n",
283 ls->varcount_with_indices);
284 for(i = 0; i < ls->basicblockcount; i++) {
285 for(j = 0; j < ls->ssavarcount; j++) {
286 if (ls->phi[i][j] != NULL) {
287 printf("BB %3i %3i = phi(", i, ls->phi[i][j][0]);
288 for(k = 1; k <= graph_get_num_predecessor(gd, i); k++)
289 printf("%3i ",ls->phi[i][j][k]);
299 * These are local overrides for various environment variables in Emacs.
300 * Please do not remove this and leave it at the end of the file, where
301 * Emacs will automagically detect them.
302 * ---------------------------------------------------------------------
305 * indent-tabs-mode: t