CACAO
ssa_phi.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/ssa.cpp - static single-assignment form
2 
3  Copyright (C) 2005-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 
31 #include "mm/dumpmemory.hpp"
32 
33 #include "toolbox/bitvector.hpp"
34 #include "toolbox/worklist.hpp"
35 
36 #include "vm/jit/builtin.hpp"
37 
38 #include "vm/jit/jit.hpp" /* icmd_table */
39 
46 
47 #if defined(SSA_DEBUG_VERBOSE)
48 #include "vm/options.hpp" /* compileverbose */
49 #endif
50 
51 /* ssa_place_phi_functions *****************************************************
52 
53 Algorithm is based on "modern compiler implementation in C" from andrew
54 w. appel, edition 2004
55 
56 Corrections:
57 page 441 Algorithm 19.6. Inserting phi-functions:
58 
59 ...
60  for each Y in DF[n]
61 - if Y not element of A phi [n]
62 + if a not element of A phi [n]
63  insert the statment a <- ...
64 ...
65 ...
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]
70  W <- W join {Y}
71 
72 
73 ls->phi[n][a][p] is created and populated.
74 
75 n in [0..ls->basicblockcount[
76 a in [0..ls->ssavarcount[
77 p in [1..Count of Predecessors of Basicblock n]
78 
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
83 elements.
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.
86 
87 
88 ls->phi[n][a] == NULL, if no phi function for Variable a for Basicblock n exists
89 
90 or
91 
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.
94 
95 *******************************************************************************/
96 
97 
99 {
100  int a,i,j,n,Y;
101  bitvector *def_sites;
102  bitvector *A_phi; /* [0..ls->basicblockcount[ of */
103  /* ls->ssavarcount Bit */
104  worklist *W;
105  int num_pred;
106 
107  lsradata *ls;
108 
109  ls = jd->ls;
110 
111  W = wl_new(ls->basicblockcount);
112 
113  def_sites = DMNEW(bitvector, ls->ssavarcount);
114  for(a = 0; a < ls->ssavarcount; a++)
115  def_sites[a] = bv_new(ls->basicblockcount);
116 
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);
124  }
125 
126  /* copy var_def to def_sites */
127  /* var_def is valid for 0.. jd->basicblockcount (bb 0 for param init) */
128 
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))
141  printf("1");
142  else
143  printf("0");
144  }
145  printf(" (");
146 
147  printf("\n");
148  }
149  }
150 #endif
151 
152  for(a = 0; a < ls->ssavarcount; a++) {
153 
154  /* W<-def_sites(a) */
155 
156  for(n = 0; n < ls->basicblockcount; n++)
157  if (bv_get_bit(def_sites[a],n)) {
158  wl_add(W, n);
159  }
160 
161  while (!wl_is_empty(W)) { /* W not empty */
162  n = wl_get(W);
163 
164  for(i = 0; i < dd->num_DF[n]; i++) {
165  Y = dd->DF[n][i];
166 
167  /* Node Y is in Dominance Frontier of n -> */
168  /* insert phi function for a at top of Y*/
169 
171  if (bv_get_bit( A_phi[Y], a) == 0) {
172 
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 */
176 
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;
181 
182  /* increment the number of definitions of a by one */
183  /* for this phi function */
184 
185  ls->num_defs[a]++;
186 
187  bv_set_bit(A_phi[Y], a);
188  if (bv_get_bit(ls->var_def[Y],a)==0) {
189 
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 */
194 
195  wl_add(W, Y);
196  }
197  }
198  }
199  }
200  }
201 }
202 
204  int a, i, j, pred;
205  graphiterator iter;
206  lsradata *ls;
207 
208  ls = jd->ls;
209 
210  /* count moves to be inserted at the end of each block in moves[] */
211 
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) {
218 #if 0
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 */
222  /* var to unused */
223 
224  /* TODO: first delete use sites of arguments of phi */
225  /* function */
226  VAR(ls->lifetime[ls->phi[i][a][0]].v_index)->type = jitdata::UNUSED;
227  ls->lifetime[ls->phi[i][a][0]].def = NULL;
228  ls->phi[i][a] = NULL;
229  }
230  else
231 #endif
232  {
233  pred = graph_get_first_predecessor(gd, i, &iter);
234  for(; pred != -1; pred = graph_get_next(&iter)) {
235  ls->num_phi_moves[pred]++;
236  }
237  }
238  }
239 
240  /* allocate ls->phi_moves */
241 
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
248  if (compileverbose)
249  printf("ssa_generate_phi_moves: ls_num_phi_moves[%3i] = %3i\n",
250  i, ls->num_phi_moves[i]);
251 #endif
252  }
253 
254  /* populate ls->phi_moves */
255 
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) {
266  /* valid move */
267  if (ls->phi[i][a][0] != ls->phi[i][a][j+1]) {
268  ls->phi_moves[pred][ls->num_phi_moves[pred]][0] =
269  ls->phi[i][a][0];
270  ls->phi_moves[pred][(ls->num_phi_moves[pred])++][1]=
271  ls->phi[i][a][j+1];
272  }
273  }
274  }
275  }
276 }
277 
278 #ifdef SSA_DEBUG_VERBOSE
280  int i,j,k;
281 
282  printf("phi Functions (varcount_with_indices: %3i):\n",
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]);
290  printf(")\n");
291  }
292  }
293  }
294 
295 }
296 #endif
297 
298 /*
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  * ---------------------------------------------------------------------
303  * Local variables:
304  * mode: c++
305  * indent-tabs-mode: t
306  * c-basic-offset: 4
307  * tab-width: 4
308  * End:
309  * vim:noexpandtab:sw=4:ts=4:
310  */
#define _SSA_CHECK_BOUNDS(i, l, h)
Definition: ssa.hpp:43
int graph_get_next(graphiterator *i)
Definition: graph.cpp:104
int * bitvector
Definition: bitvector.hpp:34
Definition: jit.hpp:126
int *** phi_moves
Definition: lsra.hpp:197
bitvector * var_def
Definition: lsra.hpp:154
int basicblockcount
Definition: lsra.hpp:188
int varcount_with_indices
Definition: lsra.hpp:122
struct site * use
Definition: lsra.hpp:90
int v_index
Definition: lsra.hpp:97
void ssa_print_phi(lsradata *, graphdata *)
Definition: ssa_phi.cpp:279
struct site * def
Definition: lsra.hpp:89
int graph_get_first_predecessor(graphdata *gd, int b_index, graphiterator *i)
Definition: graph.cpp:99
struct lifetime * lifetime
Definition: lsra.hpp:168
bool bv_get_bit(bitvector bv, int bit)
Definition: bitvector.cpp:148
#define VAR(i)
Definition: jit.hpp:259
int * num_phi_moves
Definition: lsra.hpp:196
bool compileverbose
Definition: options.cpp:82
int ssavarcount
Definition: lsra.hpp:115
MIIterator i
bool wl_is_empty(worklist *w)
Definition: worklist.cpp:124
int graph_get_num_predecessor(graphdata *gd, int b_index)
Definition: graph.cpp:84
worklist * wl_new(int size)
Definition: worklist.cpp:68
void ssa_generate_phi_moves(jitdata *jd, graphdata *gd)
Definition: ssa_phi.cpp:203
s4 basicblockcount
Definition: jit.hpp:144
#define DMNEW(type, num)
Definition: dumpmemory.hpp:371
void wl_add(worklist *w, int element)
Definition: worklist.cpp:88
int * num_defs
Definition: lsra.hpp:165
int wl_get(worklist *w)
Definition: worklist.cpp:107
bitvector bv_new(int size)
Definition: bitvector.cpp:122
void bv_set_bit(bitvector bv, int bit)
Definition: bitvector.cpp:166
#define printf(...)
Definition: ssa2.cpp:40
int *** phi
Definition: lsra.hpp:193
static void ssa_place_phi_functions(ssa_info *ssa)
Definition: ssa2.cpp:96