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