Merged trunk and subtype.
[cacao.git] / src / vm / jit / optimizing / ssa_phi.c
1 /* src/vm/jit/optimizing/ssa.c - static single-assignment form
2
3    Copyright (C) 2005-2007, 2008
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/memory.h"
32
33 #include "toolbox/bitvector.h"
34 #include "toolbox/worklist.h"
35
36 #include "vm/jit/builtin.hpp"
37
38 #include "vm/jit/jit.hpp" /* icmd_table */
39
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"
46
47 #if defined(SSA_DEBUG_VERBOSE)
48 #include "vm/options.h"   /* 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
98 void ssa_place_phi_functions(jitdata *jd, graphdata *gd, dominatordata *dd)
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
170                                 _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
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
203 void ssa_generate_phi_moves(jitdata *jd, graphdata *gd) {
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 = 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
279 void ssa_print_phi(lsradata *ls, graphdata *gd) {
280         int i,j,k;
281
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]);
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  */