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