1 /* src/vm/cfg.c - build a control-flow graph
3 Copyright (C) 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 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: cacao.c 4357 2006-01-22 23:33:38Z twisti $
42 #include "mm/memory.h"
43 #include "vm/jit/jit.h"
46 /* cfg_allocate_predecessors ***************************************************
48 Allocates the predecessor array, if there is none, and resets the
51 *******************************************************************************/
53 static void cfg_allocate_predecessors(basicblock *bptr)
55 if (bptr->predecessors == NULL) {
56 bptr->predecessors = DMNEW(basicblock*, bptr->predecessorcount);
58 bptr->predecessorcount = 0;
63 /* cfg_allocate_successors *****************************************************
65 Allocates the succecessor array, if there is none, and resets the
68 *******************************************************************************/
70 static void cfg_allocate_successors(basicblock *bptr)
72 if (bptr->successors == NULL) {
73 bptr->successors = DMNEW(basicblock*, bptr->successorcount);
75 bptr->successorcount = 0;
80 /* cfg_insert_predecessor ******************************************************
82 Inserts a predecessor into the array, but checks for duplicate
83 entries. This is used for TABLESWITCH and LOOKUPSWITCH.
85 *******************************************************************************/
87 static void cfg_insert_predecessors(basicblock *bptr, basicblock *pbptr)
92 tbptr = bptr->predecessors;
94 /* check if the predecessors is already stored in the array */
96 for (i = 0; i < bptr->predecessorcount; i++, tbptr++)
100 /* not found, insert it */
102 bptr->predecessors[bptr->predecessorcount] = pbptr;
103 bptr->predecessorcount++;
107 /* cfg_build *******************************************************************
109 Build a control-flow graph in finding all predecessors and
110 successors for the basic blocks.
112 *******************************************************************************/
114 bool cfg_build(jitdata *jd)
125 /* get required compiler data */
129 /* process all basic blocks to find the predecessor/successor counts */
131 bptr = m->basicblocks;
133 for (i = 0; i < m->basicblockcount; i++, bptr++) {
134 if (bptr->icount == 0)
137 iptr = bptr->iinstr + bptr->icount - 1;
169 bptr->successorcount += 2;
171 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
174 tbptr->predecessorcount++;
175 ntbptr->predecessorcount++;
179 bptr->successorcount++;
181 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
182 tbptr->predecessorcount++;
185 case ICMD_TABLESWITCH:
188 bptr->successorcount++;
190 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
191 tbptr->predecessorcount++;
193 n = *s4ptr++; /* low */
194 n = *s4ptr++ - n + 1; /* high */
197 bptr->successorcount++;
199 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
200 tbptr->predecessorcount++;
204 case ICMD_LOOKUPSWITCH:
207 bptr->successorcount++;
209 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
210 tbptr->predecessorcount++;
212 n = *s4ptr++; /* count */
215 bptr->successorcount++;
217 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
218 tbptr->predecessorcount++;
225 bptr->successorcount++;
228 tbptr->predecessorcount++;
233 /* Second iteration to allocate the arrays and insert the basic
236 bptr = m->basicblocks;
238 for (i = 0; i < m->basicblockcount; i++, bptr++) {
239 if (bptr->icount == 0)
242 iptr = bptr->iinstr + bptr->icount - 1;
274 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
277 cfg_allocate_successors(bptr);
279 bptr->successors[0] = tbptr;
280 bptr->successors[1] = ntbptr;
281 bptr->successorcount += 2;
283 cfg_allocate_predecessors(tbptr);
284 cfg_allocate_predecessors(ntbptr);
286 tbptr->predecessors[tbptr->predecessorcount] = bptr;
287 tbptr->predecessorcount++;
289 ntbptr->predecessors[ntbptr->predecessorcount] = bptr;
290 ntbptr->predecessorcount++;
294 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
296 cfg_allocate_successors(bptr);
298 bptr->successors[0] = tbptr;
299 bptr->successorcount++;
301 cfg_allocate_predecessors(tbptr);
303 tbptr->predecessors[tbptr->predecessorcount] = bptr;
304 tbptr->predecessorcount++;
307 case ICMD_TABLESWITCH:
310 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
312 cfg_allocate_successors(bptr);
314 bptr->successors[0] = tbptr;
315 bptr->successorcount++;
317 cfg_allocate_predecessors(tbptr);
319 tbptr->predecessors[tbptr->predecessorcount] = bptr;
320 tbptr->predecessorcount++;
322 n = *s4ptr++; /* low */
323 n = *s4ptr++ - n + 1; /* high */
326 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
328 bptr->successors[bptr->successorcount] = tbptr;
329 bptr->successorcount++;
331 cfg_allocate_predecessors(tbptr);
332 cfg_insert_predecessors(tbptr, bptr);
336 case ICMD_LOOKUPSWITCH:
339 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
341 cfg_allocate_successors(bptr);
343 bptr->successors[0] = tbptr;
344 bptr->successorcount++;
346 cfg_allocate_predecessors(tbptr);
348 tbptr->predecessors[tbptr->predecessorcount] = bptr;
349 tbptr->predecessorcount++;
351 n = *s4ptr++; /* count */
354 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
356 bptr->successors[bptr->successorcount] = tbptr;
357 bptr->successorcount++;
359 cfg_allocate_predecessors(tbptr);
360 cfg_insert_predecessors(tbptr, bptr);
369 cfg_allocate_successors(bptr);
371 bptr->successors[0] = tbptr;
372 bptr->successorcount++;
374 cfg_allocate_predecessors(tbptr);
376 tbptr->predecessors[tbptr->predecessorcount] = bptr;
377 tbptr->predecessorcount++;
382 /* everything's ok */
389 * These are local overrides for various environment variables in Emacs.
390 * Please do not remove this and leave it at the end of the file, where
391 * Emacs will automagically detect them.
392 * ---------------------------------------------------------------------
395 * indent-tabs-mode: t
399 * vim:noexpandtab:sw=4:ts=4: