OSDN Git Service

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