]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cfg.c
gcc_release (announce_snapshot): Use changedir instead of plain cd.
[thirdparty/gcc.git] / gcc / cfg.c
CommitLineData
402209ff
JH
1/* Control flow graph manipulation code for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
d9221e01 3 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
402209ff
JH
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
9d083c8c 22/* This file contains low level functions to manipulate the CFG and
4d6922ee 23 analyze it. All other modules should not transform the data structure
9d083c8c
RS
24 directly and use abstraction instead. The file is supposed to be
25 ordered bottom-up and should not contain any code dependent on a
26 particular intermediate language (RTL or trees).
402209ff
JH
27
28 Available functionality:
29 - Initialization/deallocation
30 init_flow, clear_edges
ca6c03ca
JH
31 - Low level basic block manipulation
32 alloc_block, expunge_block
402209ff 33 - Edge manipulation
7ded4467 34 make_edge, make_single_succ_edge, cached_make_edge, remove_edge
402209ff
JH
35 - Low level edge redirection (without updating instruction chain)
36 redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
eaec9b3d 37 - Dumping and debugging
ca6c03ca
JH
38 dump_flow_info, debug_flow_info, dump_edge_info
39 - Allocation of AUX fields for basic blocks
40 alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
38c1593d 41 - clear_bb_flags
10e9fecc
JH
42 - Consistency checking
43 verify_flow_info
44 - Dumping and debugging
45 print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
402209ff
JH
46 */
47\f
48#include "config.h"
49#include "system.h"
4977bab6
ZW
50#include "coretypes.h"
51#include "tm.h"
402209ff
JH
52#include "tree.h"
53#include "rtl.h"
54#include "hard-reg-set.h"
55#include "basic-block.h"
56#include "regs.h"
57#include "flags.h"
58#include "output.h"
59#include "function.h"
60#include "except.h"
61#include "toplev.h"
3d9339a9 62#include "tm_p.h"
402209ff 63#include "obstack.h"
f6cb56fa 64#include "alloc-pool.h"
402209ff
JH
65
66/* The obstack on which the flow graph components are allocated. */
67
68struct obstack flow_obstack;
69static char *flow_firstobj;
70
f6cb56fa
DB
71/* Basic block object pool. */
72
73static alloc_pool bb_pool;
74
75/* Edge object pool. */
76
77static alloc_pool edge_pool;
78
402209ff
JH
79/* Number of basic blocks in the current function. */
80
0b17ab2f 81int n_basic_blocks;
402209ff 82
bf77398c
ZD
83/* First free basic block number. */
84
85int last_basic_block;
86
402209ff
JH
87/* Number of edges in the current function. */
88
89int n_edges;
90
91/* The basic block array. */
92
93varray_type basic_block_info;
94
95/* The special entry and exit blocks. */
96
97struct basic_block_def entry_exit_blocks[2]
98= {{NULL, /* head */
99 NULL, /* end */
100 NULL, /* head_tree */
101 NULL, /* end_tree */
102 NULL, /* pred */
103 NULL, /* succ */
104 NULL, /* local_set */
105 NULL, /* cond_local_set */
106 NULL, /* global_live_at_start */
107 NULL, /* global_live_at_end */
108 NULL, /* aux */
109 ENTRY_BLOCK, /* index */
918ed612
ZD
110 NULL, /* prev_bb */
111 EXIT_BLOCK_PTR, /* next_bb */
402209ff 112 0, /* loop_depth */
2ecfd709 113 NULL, /* loop_father */
d47cc544 114 { NULL, NULL }, /* dom */
402209ff
JH
115 0, /* count */
116 0, /* frequency */
bc35512f
JH
117 0, /* flags */
118 NULL /* rbi */
402209ff
JH
119 },
120 {
121 NULL, /* head */
122 NULL, /* end */
123 NULL, /* head_tree */
124 NULL, /* end_tree */
125 NULL, /* pred */
126 NULL, /* succ */
127 NULL, /* local_set */
128 NULL, /* cond_local_set */
129 NULL, /* global_live_at_start */
130 NULL, /* global_live_at_end */
131 NULL, /* aux */
132 EXIT_BLOCK, /* index */
918ed612
ZD
133 ENTRY_BLOCK_PTR, /* prev_bb */
134 NULL, /* next_bb */
402209ff 135 0, /* loop_depth */
2ecfd709 136 NULL, /* loop_father */
d47cc544 137 { NULL, NULL }, /* dom */
402209ff
JH
138 0, /* count */
139 0, /* frequency */
bc35512f
JH
140 0, /* flags */
141 NULL /* rbi */
402209ff
JH
142 }
143};
144
d329e058
AJ
145void debug_flow_info (void);
146static void free_edge (edge);
402209ff 147\f
eaec9b3d 148/* Called once at initialization time. */
402209ff
JH
149
150void
d329e058 151init_flow (void)
402209ff
JH
152{
153 static int initialized;
154
7ded4467
JH
155 n_edges = 0;
156
402209ff
JH
157 if (!initialized)
158 {
159 gcc_obstack_init (&flow_obstack);
703ad42b 160 flow_firstobj = obstack_alloc (&flow_obstack, 0);
402209ff
JH
161 initialized = 1;
162 }
163 else
164 {
f6cb56fa
DB
165 free_alloc_pool (bb_pool);
166 free_alloc_pool (edge_pool);
402209ff 167 obstack_free (&flow_obstack, flow_firstobj);
703ad42b 168 flow_firstobj = obstack_alloc (&flow_obstack, 0);
402209ff 169 }
d329e058 170 bb_pool = create_alloc_pool ("Basic block pool",
f6cb56fa
DB
171 sizeof (struct basic_block_def), 100);
172 edge_pool = create_alloc_pool ("Edge pool",
173 sizeof (struct edge_def), 100);
402209ff
JH
174}
175\f
d39ac0fd
JH
176/* Helper function for remove_edge and clear_edges. Frees edge structure
177 without actually unlinking it from the pred/succ lists. */
178
179static void
d329e058 180free_edge (edge e)
d39ac0fd
JH
181{
182 n_edges--;
f6cb56fa 183 pool_free (edge_pool, e);
d39ac0fd
JH
184}
185
402209ff
JH
186/* Free the memory associated with the edge structures. */
187
188void
d329e058 189clear_edges (void)
402209ff 190{
e0082a72 191 basic_block bb;
d39ac0fd 192 edge e;
402209ff 193
e0082a72 194 FOR_EACH_BB (bb)
402209ff 195 {
d39ac0fd 196 edge e = bb->succ;
402209ff 197
d39ac0fd
JH
198 while (e)
199 {
200 edge next = e->succ_next;
201
202 free_edge (e);
203 e = next;
204 }
4891442b 205
d39ac0fd
JH
206 bb->succ = NULL;
207 bb->pred = NULL;
402209ff
JH
208 }
209
d39ac0fd
JH
210 e = ENTRY_BLOCK_PTR->succ;
211 while (e)
212 {
213 edge next = e->succ_next;
214
215 free_edge (e);
216 e = next;
217 }
4891442b 218
d39ac0fd
JH
219 EXIT_BLOCK_PTR->pred = NULL;
220 ENTRY_BLOCK_PTR->succ = NULL;
402209ff 221
7ded4467
JH
222 if (n_edges)
223 abort ();
402209ff
JH
224}
225\f
ca6c03ca 226/* Allocate memory for basic_block. */
402209ff 227
4262e623 228basic_block
d329e058 229alloc_block (void)
402209ff
JH
230{
231 basic_block bb;
f6cb56fa
DB
232 bb = pool_alloc (bb_pool);
233 memset (bb, 0, sizeof (*bb));
4262e623 234 return bb;
402209ff
JH
235}
236
918ed612
ZD
237/* Link block B to chain after AFTER. */
238void
d329e058 239link_block (basic_block b, basic_block after)
918ed612
ZD
240{
241 b->next_bb = after->next_bb;
242 b->prev_bb = after;
243 after->next_bb = b;
244 b->next_bb->prev_bb = b;
245}
f87c27b4 246
918ed612
ZD
247/* Unlink block B from chain. */
248void
d329e058 249unlink_block (basic_block b)
918ed612
ZD
250{
251 b->next_bb->prev_bb = b->prev_bb;
252 b->prev_bb->next_bb = b->next_bb;
253}
f87c27b4 254
bf77398c
ZD
255/* Sequentially order blocks and compact the arrays. */
256void
d329e058 257compact_blocks (void)
bf77398c
ZD
258{
259 int i;
260 basic_block bb;
d329e058 261
bf77398c
ZD
262 i = 0;
263 FOR_EACH_BB (bb)
264 {
265 BASIC_BLOCK (i) = bb;
266 bb->index = i;
267 i++;
268 }
269
270 if (i != n_basic_blocks)
271 abort ();
272
273 last_basic_block = n_basic_blocks;
274}
275
bf77398c 276/* Remove block B from the basic block array. */
402209ff 277
6a58eee9 278void
d329e058 279expunge_block (basic_block b)
6a58eee9 280{
918ed612 281 unlink_block (b);
bf77398c
ZD
282 BASIC_BLOCK (b->index) = NULL;
283 n_basic_blocks--;
f6cb56fa 284 pool_free (bb_pool, b);
6a58eee9 285}
402209ff 286\f
e0fd3e7a
MM
287/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
288 created edge. Use this only if you are sure that this edge can't
289 possibly already exist. */
290
291edge
d329e058 292unchecked_make_edge (basic_block src, basic_block dst, int flags)
e0fd3e7a
MM
293{
294 edge e;
295 e = pool_alloc (edge_pool);
296 memset (e, 0, sizeof (*e));
297 n_edges++;
298
299 e->succ_next = src->succ;
300 e->pred_next = dst->pred;
301 e->src = src;
302 e->dest = dst;
303 e->flags = flags;
304
305 src->succ = e;
306 dst->pred = e;
307
308 return e;
309}
310
7ded4467 311/* Create an edge connecting SRC and DST with FLAGS optionally using
2ba84f36 312 edge cache CACHE. Return the new edge, NULL if already exist. */
4262e623 313
7ded4467 314edge
d329e058 315cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int flags)
402209ff
JH
316{
317 int use_edge_cache;
318 edge e;
319
4891442b
RK
320 /* Don't bother with edge cache for ENTRY or EXIT, if there aren't that
321 many edges to them, or we didn't allocate memory for it. */
402209ff 322 use_edge_cache = (edge_cache
4891442b 323 && src != ENTRY_BLOCK_PTR && dst != EXIT_BLOCK_PTR);
402209ff
JH
324
325 /* Make sure we don't add duplicate edges. */
326 switch (use_edge_cache)
327 {
328 default:
ff7cc307 329 /* Quick test for non-existence of the edge. */
0b17ab2f 330 if (! TEST_BIT (edge_cache[src->index], dst->index))
402209ff
JH
331 break;
332
333 /* The edge exists; early exit if no work to do. */
334 if (flags == 0)
7ded4467 335 return NULL;
402209ff 336
5d3cc252 337 /* Fall through. */
402209ff
JH
338 case 0:
339 for (e = src->succ; e; e = e->succ_next)
340 if (e->dest == dst)
341 {
342 e->flags |= flags;
7ded4467 343 return NULL;
402209ff
JH
344 }
345 break;
346 }
d329e058 347
e0fd3e7a 348 e = unchecked_make_edge (src, dst, flags);
402209ff
JH
349
350 if (use_edge_cache)
0b17ab2f 351 SET_BIT (edge_cache[src->index], dst->index);
7ded4467
JH
352
353 return e;
354}
355
356/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
357 created edge or NULL if already exist. */
358
359edge
d329e058 360make_edge (basic_block src, basic_block dest, int flags)
7ded4467
JH
361{
362 return cached_make_edge (NULL, src, dest, flags);
363}
364
eaec9b3d 365/* Create an edge connecting SRC to DEST and set probability by knowing
7ded4467
JH
366 that it is the single edge leaving SRC. */
367
368edge
d329e058 369make_single_succ_edge (basic_block src, basic_block dest, int flags)
7ded4467
JH
370{
371 edge e = make_edge (src, dest, flags);
372
373 e->probability = REG_BR_PROB_BASE;
374 e->count = src->count;
375 return e;
402209ff
JH
376}
377
378/* This function will remove an edge from the flow graph. */
379
380void
d329e058 381remove_edge (edge e)
402209ff
JH
382{
383 edge last_pred = NULL;
384 edge last_succ = NULL;
385 edge tmp;
386 basic_block src, dest;
4891442b 387
402209ff
JH
388 src = e->src;
389 dest = e->dest;
390 for (tmp = src->succ; tmp && tmp != e; tmp = tmp->succ_next)
391 last_succ = tmp;
392
393 if (!tmp)
394 abort ();
395 if (last_succ)
396 last_succ->succ_next = e->succ_next;
397 else
398 src->succ = e->succ_next;
399
400 for (tmp = dest->pred; tmp && tmp != e; tmp = tmp->pred_next)
401 last_pred = tmp;
402
403 if (!tmp)
404 abort ();
405 if (last_pred)
406 last_pred->pred_next = e->pred_next;
407 else
408 dest->pred = e->pred_next;
409
d39ac0fd 410 free_edge (e);
402209ff
JH
411}
412
413/* Redirect an edge's successor from one block to another. */
414
415void
d329e058 416redirect_edge_succ (edge e, basic_block new_succ)
402209ff
JH
417{
418 edge *pe;
419
420 /* Disconnect the edge from the old successor block. */
421 for (pe = &e->dest->pred; *pe != e; pe = &(*pe)->pred_next)
422 continue;
423 *pe = (*pe)->pred_next;
424
425 /* Reconnect the edge to the new successor block. */
426 e->pred_next = new_succ->pred;
427 new_succ->pred = e;
428 e->dest = new_succ;
429}
430
eaec9b3d 431/* Like previous but avoid possible duplicate edge. */
402209ff
JH
432
433edge
d329e058 434redirect_edge_succ_nodup (edge e, basic_block new_succ)
402209ff
JH
435{
436 edge s;
4891442b 437
402209ff
JH
438 /* Check whether the edge is already present. */
439 for (s = e->src->succ; s; s = s->succ_next)
440 if (s->dest == new_succ && s != e)
441 break;
4891442b 442
402209ff
JH
443 if (s)
444 {
445 s->flags |= e->flags;
446 s->probability += e->probability;
77abb5d8
JH
447 if (s->probability > REG_BR_PROB_BASE)
448 s->probability = REG_BR_PROB_BASE;
402209ff
JH
449 s->count += e->count;
450 remove_edge (e);
451 e = s;
452 }
453 else
454 redirect_edge_succ (e, new_succ);
4891442b 455
402209ff
JH
456 return e;
457}
458
459/* Redirect an edge's predecessor from one block to another. */
460
461void
d329e058 462redirect_edge_pred (edge e, basic_block new_pred)
402209ff
JH
463{
464 edge *pe;
465
466 /* Disconnect the edge from the old predecessor block. */
467 for (pe = &e->src->succ; *pe != e; pe = &(*pe)->succ_next)
468 continue;
4891442b 469
402209ff
JH
470 *pe = (*pe)->succ_next;
471
472 /* Reconnect the edge to the new predecessor block. */
473 e->succ_next = new_pred->succ;
474 new_pred->succ = e;
475 e->src = new_pred;
476}
38c1593d
JH
477
478void
d329e058 479clear_bb_flags (void)
38c1593d 480{
e0082a72
ZD
481 basic_block bb;
482
483 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
484 bb->flags = 0;
38c1593d 485}
402209ff 486\f
ca6c03ca 487void
d329e058 488dump_flow_info (FILE *file)
402209ff 489{
b3694847 490 int i;
0816bcd2 491 int max_regno = max_reg_num ();
e0082a72 492 basic_block bb;
ca6c03ca
JH
493 static const char * const reg_class_names[] = REG_CLASS_NAMES;
494
495 fprintf (file, "%d registers.\n", max_regno);
7d8405cf
RH
496 if (reg_n_info)
497 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
498 if (REG_N_REFS (i))
499 {
500 enum reg_class class, altclass;
501
502 fprintf (file, "\nRegister %d used %d times across %d insns",
503 i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
504 if (REG_BASIC_BLOCK (i) >= 0)
505 fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
506 if (REG_N_SETS (i))
507 fprintf (file, "; set %d time%s", REG_N_SETS (i),
508 (REG_N_SETS (i) == 1) ? "" : "s");
509 if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
510 fprintf (file, "; user var");
511 if (REG_N_DEATHS (i) != 1)
512 fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
513 if (REG_N_CALLS_CROSSED (i) == 1)
514 fprintf (file, "; crosses 1 call");
515 else if (REG_N_CALLS_CROSSED (i))
516 fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
517 if (regno_reg_rtx[i] != NULL
518 && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
519 fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
520
521 class = reg_preferred_class (i);
522 altclass = reg_alternate_class (i);
523 if (class != GENERAL_REGS || altclass != ALL_REGS)
524 {
525 if (altclass == ALL_REGS || class == ALL_REGS)
526 fprintf (file, "; pref %s", reg_class_names[(int) class]);
527 else if (altclass == NO_REGS)
528 fprintf (file, "; %s or none", reg_class_names[(int) class]);
529 else
530 fprintf (file, "; pref %s, else %s",
531 reg_class_names[(int) class],
532 reg_class_names[(int) altclass]);
533 }
534
535 if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
536 fprintf (file, "; pointer");
537 fprintf (file, ".\n");
538 }
ca6c03ca 539
0b17ab2f 540 fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
e0082a72 541 FOR_EACH_BB (bb)
ca6c03ca 542 {
b3694847 543 edge e;
5a1a3e5e
JH
544 int sum;
545 gcov_type lsum;
ca6c03ca 546
4891442b 547 fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
a813c111 548 bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb)));
918ed612
ZD
549 fprintf (file, "prev %d, next %d, ",
550 bb->prev_bb->index, bb->next_bb->index);
4891442b
RK
551 fprintf (file, "loop_depth %d, count ", bb->loop_depth);
552 fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
0f72964f
JH
553 fprintf (file, ", freq %i", bb->frequency);
554 if (maybe_hot_bb_p (bb))
555 fprintf (file, ", maybe hot");
556 if (probably_never_executed_bb_p (bb))
557 fprintf (file, ", probably never executed");
291cc0fe 558 fprintf (file, ".\n");
402209ff 559
ca6c03ca
JH
560 fprintf (file, "Predecessors: ");
561 for (e = bb->pred; e; e = e->pred_next)
562 dump_edge_info (file, e, 0);
402209ff 563
ca6c03ca
JH
564 fprintf (file, "\nSuccessors: ");
565 for (e = bb->succ; e; e = e->succ_next)
566 dump_edge_info (file, e, 1);
402209ff 567
ca6c03ca
JH
568 fprintf (file, "\nRegisters live at start:");
569 dump_regset (bb->global_live_at_start, file);
402209ff 570
ca6c03ca
JH
571 fprintf (file, "\nRegisters live at end:");
572 dump_regset (bb->global_live_at_end, file);
7ded4467 573
ca6c03ca 574 putc ('\n', file);
5a1a3e5e
JH
575
576 /* Check the consistency of profile information. We can't do that
577 in verify_flow_info, as the counts may get invalid for incompletely
95bd1dd7 578 solved graphs, later eliminating of conditionals or roundoff errors.
5a1a3e5e
JH
579 It is still practical to have them reported for debugging of simple
580 testcases. */
581 sum = 0;
582 for (e = bb->succ; e; e = e->succ_next)
583 sum += e->probability;
584 if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
585 fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
586 sum * 100.0 / REG_BR_PROB_BASE);
587 sum = 0;
588 for (e = bb->pred; e; e = e->pred_next)
589 sum += EDGE_FREQUENCY (e);
590 if (abs (sum - bb->frequency) > 100)
591 fprintf (file,
592 "Invalid sum of incomming frequencies %i, should be %i\n",
593 sum, bb->frequency);
594 lsum = 0;
595 for (e = bb->pred; e; e = e->pred_next)
596 lsum += e->count;
597 if (lsum - bb->count > 100 || lsum - bb->count < -100)
598 fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
599 (int)lsum, (int)bb->count);
600 lsum = 0;
601 for (e = bb->succ; e; e = e->succ_next)
602 lsum += e->count;
603 if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
604 fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
605 (int)lsum, (int)bb->count);
402209ff
JH
606 }
607
ca6c03ca 608 putc ('\n', file);
402209ff
JH
609}
610
ca6c03ca 611void
d329e058 612debug_flow_info (void)
ca6c03ca
JH
613{
614 dump_flow_info (stderr);
615}
402209ff
JH
616
617void
d329e058 618dump_edge_info (FILE *file, edge e, int do_succ)
402209ff 619{
ca6c03ca
JH
620 basic_block side = (do_succ ? e->dest : e->src);
621
622 if (side == ENTRY_BLOCK_PTR)
623 fputs (" ENTRY", file);
624 else if (side == EXIT_BLOCK_PTR)
625 fputs (" EXIT", file);
626 else
0b17ab2f 627 fprintf (file, " %d", side->index);
ca6c03ca
JH
628
629 if (e->probability)
630 fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
402209ff 631
ca6c03ca 632 if (e->count)
402209ff 633 {
ca6c03ca 634 fprintf (file, " count:");
4891442b 635 fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
402209ff
JH
636 }
637
ca6c03ca 638 if (e->flags)
402209ff 639 {
1722c2c8
RH
640 static const char * const bitnames[] = {
641 "fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
4139675b 642 "can_fallthru", "irreducible", "sibcall", "loop_exit"
1722c2c8 643 };
ca6c03ca
JH
644 int comma = 0;
645 int i, flags = e->flags;
402209ff 646
4891442b 647 fputs (" (", file);
402209ff
JH
648 for (i = 0; flags; i++)
649 if (flags & (1 << i))
650 {
651 flags &= ~(1 << i);
652
653 if (comma)
654 fputc (',', file);
655 if (i < (int) ARRAY_SIZE (bitnames))
656 fputs (bitnames[i], file);
657 else
658 fprintf (file, "%d", i);
659 comma = 1;
660 }
4891442b 661
402209ff
JH
662 fputc (')', file);
663 }
664}
665\f
ff7cc307 666/* Simple routines to easily allocate AUX fields of basic blocks. */
4891442b 667
ca6c03ca
JH
668static struct obstack block_aux_obstack;
669static void *first_block_aux_obj = 0;
670static struct obstack edge_aux_obstack;
671static void *first_edge_aux_obj = 0;
402209ff 672
09da1532 673/* Allocate a memory block of SIZE as BB->aux. The obstack must
ca6c03ca 674 be first initialized by alloc_aux_for_blocks. */
402209ff 675
ca6c03ca 676inline void
d329e058 677alloc_aux_for_block (basic_block bb, int size)
402209ff 678{
ca6c03ca
JH
679 /* Verify that aux field is clear. */
680 if (bb->aux || !first_block_aux_obj)
681 abort ();
682 bb->aux = obstack_alloc (&block_aux_obstack, size);
683 memset (bb->aux, 0, size);
402209ff
JH
684}
685
ca6c03ca
JH
686/* Initialize the block_aux_obstack and if SIZE is nonzero, call
687 alloc_aux_for_block for each basic block. */
402209ff
JH
688
689void
d329e058 690alloc_aux_for_blocks (int size)
402209ff 691{
ca6c03ca 692 static int initialized;
402209ff 693
ca6c03ca 694 if (!initialized)
402209ff 695 {
ca6c03ca
JH
696 gcc_obstack_init (&block_aux_obstack);
697 initialized = 1;
402209ff 698 }
4891442b 699
ca6c03ca
JH
700 /* Check whether AUX data are still allocated. */
701 else if (first_block_aux_obj)
702 abort ();
703ad42b 703 first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
ca6c03ca 704 if (size)
402209ff 705 {
e0082a72 706 basic_block bb;
4891442b 707
e0082a72
ZD
708 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
709 alloc_aux_for_block (bb, size);
402209ff
JH
710 }
711}
ca6c03ca 712
108c1afc 713/* Clear AUX pointers of all blocks. */
402209ff
JH
714
715void
d329e058 716clear_aux_for_blocks (void)
402209ff 717{
e0082a72 718 basic_block bb;
4891442b 719
e0082a72
ZD
720 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
721 bb->aux = NULL;
108c1afc
RH
722}
723
724/* Free data allocated in block_aux_obstack and clear AUX pointers
725 of all blocks. */
726
727void
d329e058 728free_aux_for_blocks (void)
108c1afc
RH
729{
730 if (!first_block_aux_obj)
731 abort ();
732 obstack_free (&block_aux_obstack, first_block_aux_obj);
ca6c03ca 733 first_block_aux_obj = NULL;
108c1afc
RH
734
735 clear_aux_for_blocks ();
ca6c03ca 736}
402209ff 737
09da1532 738/* Allocate a memory edge of SIZE as BB->aux. The obstack must
ca6c03ca 739 be first initialized by alloc_aux_for_edges. */
402209ff 740
ca6c03ca 741inline void
d329e058 742alloc_aux_for_edge (edge e, int size)
ca6c03ca
JH
743{
744 /* Verify that aux field is clear. */
745 if (e->aux || !first_edge_aux_obj)
746 abort ();
747 e->aux = obstack_alloc (&edge_aux_obstack, size);
748 memset (e->aux, 0, size);
749}
402209ff 750
ca6c03ca
JH
751/* Initialize the edge_aux_obstack and if SIZE is nonzero, call
752 alloc_aux_for_edge for each basic edge. */
402209ff 753
ca6c03ca 754void
d329e058 755alloc_aux_for_edges (int size)
ca6c03ca
JH
756{
757 static int initialized;
402209ff 758
ca6c03ca
JH
759 if (!initialized)
760 {
761 gcc_obstack_init (&edge_aux_obstack);
762 initialized = 1;
402209ff 763 }
4891442b 764
ca6c03ca
JH
765 /* Check whether AUX data are still allocated. */
766 else if (first_edge_aux_obj)
767 abort ();
4891442b 768
703ad42b 769 first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
ca6c03ca 770 if (size)
402209ff 771 {
e0082a72
ZD
772 basic_block bb;
773
774 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
402209ff 775 {
ca6c03ca
JH
776 edge e;
777
ca6c03ca
JH
778 for (e = bb->succ; e; e = e->succ_next)
779 alloc_aux_for_edge (e, size);
402209ff 780 }
402209ff 781 }
402209ff 782}
402209ff 783
108c1afc 784/* Clear AUX pointers of all edges. */
ca6c03ca
JH
785
786void
d329e058 787clear_aux_for_edges (void)
402209ff 788{
e0082a72
ZD
789 basic_block bb;
790 edge e;
402209ff 791
e0082a72 792 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
402209ff 793 {
ca6c03ca
JH
794 for (e = bb->succ; e; e = e->succ_next)
795 e->aux = NULL;
402209ff 796 }
108c1afc
RH
797}
798
799/* Free data allocated in edge_aux_obstack and clear AUX pointers
800 of all edges. */
801
802void
d329e058 803free_aux_for_edges (void)
108c1afc
RH
804{
805 if (!first_edge_aux_obj)
806 abort ();
807 obstack_free (&edge_aux_obstack, first_edge_aux_obj);
ca6c03ca 808 first_edge_aux_obj = NULL;
108c1afc
RH
809
810 clear_aux_for_edges ();
402209ff 811}
9ee634e3 812
10e9fecc 813void
d329e058 814debug_bb (basic_block bb)
10e9fecc 815{
f470c378 816 dump_bb (bb, stderr, 0);
10e9fecc
JH
817}
818
819basic_block
d329e058 820debug_bb_n (int n)
10e9fecc
JH
821{
822 basic_block bb = BASIC_BLOCK (n);
f470c378 823 dump_bb (bb, stderr, 0);
10e9fecc 824 return bb;
9ee634e3 825}