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