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