OSDN Git Service

* basic-block.h (struct basic_block_def): New field loop_father.
[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 "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"
56 #include "tm_p.h"
57 #include "obstack.h"
58
59 /* The obstack on which the flow graph components are allocated.  */
60
61 struct obstack flow_obstack;
62 static char *flow_firstobj;
63
64 /* Number of basic blocks in the current function.  */
65
66 int n_basic_blocks;
67
68 /* First free basic block number.  */
69
70 int last_basic_block;
71
72 /* Number of edges in the current function.  */
73
74 int n_edges;
75
76 /* First edge in the deleted edges chain.  */
77
78 edge first_deleted_edge;
79 static basic_block first_deleted_block;
80
81 /* The basic block array.  */
82
83 varray_type basic_block_info;
84
85 /* The special entry and exit blocks.  */
86
87 struct 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 */
100     NULL,                       /* prev_bb */
101     EXIT_BLOCK_PTR,             /* next_bb */
102     0,                          /* loop_depth */
103     NULL,                       /* loop_father */
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 */
121     ENTRY_BLOCK_PTR,            /* prev_bb */
122     NULL,                       /* next_bb */
123     0,                          /* loop_depth */
124     NULL,                       /* loop_father */
125     0,                          /* count */
126     0,                          /* frequency */
127     0                           /* flags */
128   }
129 };
130
131 void debug_flow_info                    PARAMS ((void));
132 static void free_edge                   PARAMS ((edge));
133 \f
134 /* Called once at initialization time.  */
135
136 void
137 init_flow ()
138 {
139   static int initialized;
140
141   first_deleted_edge = 0;
142   first_deleted_block = 0;
143   n_edges = 0;
144
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
158 /* Helper function for remove_edge and clear_edges.  Frees edge structure
159    without actually unlinking it from the pred/succ lists.  */
160
161 static void
162 free_edge (e)
163      edge e;
164 {
165   n_edges--;
166   memset (e, 0, sizeof *e);
167   e->succ_next = first_deleted_edge;
168   first_deleted_edge = e;
169 }
170
171 /* Free the memory associated with the edge structures.  */
172
173 void
174 clear_edges ()
175 {
176   basic_block bb;
177   edge e;
178
179   FOR_EACH_BB (bb)
180     {
181       edge e = bb->succ;
182
183       while (e)
184         {
185           edge next = e->succ_next;
186
187           free_edge (e);
188           e = next;
189         }
190
191       bb->succ = NULL;
192       bb->pred = NULL;
193     }
194
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     }
203
204   EXIT_BLOCK_PTR->pred = NULL;
205   ENTRY_BLOCK_PTR->succ = NULL;
206
207   if (n_edges)
208     abort ();
209 }
210 \f
211 /* Allocate memory for basic_block.  */
212
213 basic_block
214 alloc_block ()
215 {
216   basic_block bb;
217
218   if (first_deleted_block)
219     {
220       bb = first_deleted_block;
221       first_deleted_block = (basic_block) bb->succ;
222       bb->succ = NULL;
223     }
224   else
225     {
226       bb = (basic_block) obstack_alloc (&flow_obstack, sizeof *bb);
227       memset (bb, 0, sizeof *bb);
228     }
229   return bb;
230 }
231
232 /* Link block B to chain after AFTER.  */
233 void
234 link_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 }
242
243 /* Unlink block B from chain.  */
244 void
245 unlink_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 }
251
252 /* Sequentially order blocks and compact the arrays.  */
253 void
254 compact_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
273
274 /* Remove block B from the basic block array.  */
275
276 void
277 expunge_block (b)
278      basic_block b;
279 {
280   unlink_block (b);
281   BASIC_BLOCK (b->index) = NULL;
282   n_basic_blocks--;
283
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;
289 }
290 \f
291 /* Create an edge connecting SRC and DST with FLAGS optionally using
292    edge cache CACHE.  Return the new edge, NULL if already exist.  */
293
294 edge
295 cached_make_edge (edge_cache, src, dst, flags)
296      sbitmap *edge_cache;
297      basic_block src, dst;
298      int flags;
299 {
300   int use_edge_cache;
301   edge e;
302
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.  */
305   use_edge_cache = (edge_cache
306                     && src != ENTRY_BLOCK_PTR && dst != EXIT_BLOCK_PTR);
307
308   /* Make sure we don't add duplicate edges.  */
309   switch (use_edge_cache)
310     {
311     default:
312       /* Quick test for non-existence of the edge.  */
313       if (! TEST_BIT (edge_cache[src->index], dst->index))
314         break;
315
316       /* The edge exists; early exit if no work to do.  */
317       if (flags == 0)
318         return NULL;
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;
326             return NULL;
327           }
328       break;
329     }
330
331   if (first_deleted_edge)
332     {
333       e = first_deleted_edge;
334       first_deleted_edge = e->succ_next;
335     }
336   else
337     {
338       e = (edge) obstack_alloc (&flow_obstack, sizeof *e);
339       memset (e, 0, sizeof *e);
340     }
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)
353     SET_BIT (edge_cache[src->index], dst->index);
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
361 edge
362 make_edge (src, dest, flags)
363      basic_block src, dest;
364      int flags;
365 {
366   return cached_make_edge (NULL, src, dest, flags);
367 }
368
369 /* Create an edge connecting SRC to DEST and set probability by knowing
370    that it is the single edge leaving SRC.  */
371
372 edge
373 make_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;
382 }
383
384 /* This function will remove an edge from the flow graph.  */
385
386 void
387 remove_edge (e)
388      edge e;
389 {
390   edge last_pred = NULL;
391   edge last_succ = NULL;
392   edge tmp;
393   basic_block src, dest;
394
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
417   free_edge (e);
418 }
419
420 /* Redirect an edge's successor from one block to another.  */
421
422 void
423 redirect_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
440 /* Like previous but avoid possible duplicate edge.  */
441
442 edge
443 redirect_edge_succ_nodup (e, new_succ)
444      edge e;
445      basic_block new_succ;
446 {
447   edge s;
448
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;
453
454   if (s)
455     {
456       s->flags |= e->flags;
457       s->probability += e->probability;
458       s->count += e->count;
459       remove_edge (e);
460       e = s;
461     }
462   else
463     redirect_edge_succ (e, new_succ);
464
465   return e;
466 }
467
468 /* Redirect an edge's predecessor from one block to another.  */
469
470 void
471 redirect_edge_pred (e, new_pred)
472      edge e;
473      basic_block new_pred;
474 {
475   edge *pe;
476
477   /* Disconnect the edge from the old predecessor block.  */
478   for (pe = &e->src->succ; *pe != e; pe = &(*pe)->succ_next)
479     continue;
480
481   *pe = (*pe)->succ_next;
482
483   /* Reconnect the edge to the new predecessor block.  */
484   e->succ_next = new_pred->succ;
485   new_pred->succ = e;
486   e->src = new_pred;
487 }
488
489 void
490 clear_bb_flags ()
491 {
492   basic_block bb;
493
494   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
495     bb->flags = 0;
496 }
497 \f
498 void
499 dump_flow_info (file)
500      FILE *file;
501 {
502   int i;
503   basic_block bb;
504   static const char * const reg_class_names[] = REG_CLASS_NAMES;
505
506   fprintf (file, "%d registers.\n", max_regno);
507   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
508     if (REG_N_REFS (i))
509       {
510         enum reg_class class, altclass;
511
512         fprintf (file, "\nRegister %d used %d times across %d insns",
513                  i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
514         if (REG_BASIC_BLOCK (i) >= 0)
515           fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
516         if (REG_N_SETS (i))
517           fprintf (file, "; set %d time%s", REG_N_SETS (i),
518                    (REG_N_SETS (i) == 1) ? "" : "s");
519         if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
520           fprintf (file, "; user var");
521         if (REG_N_DEATHS (i) != 1)
522           fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
523         if (REG_N_CALLS_CROSSED (i) == 1)
524           fprintf (file, "; crosses 1 call");
525         else if (REG_N_CALLS_CROSSED (i))
526           fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
527         if (regno_reg_rtx[i] != NULL
528             && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
529           fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
530
531         class = reg_preferred_class (i);
532         altclass = reg_alternate_class (i);
533         if (class != GENERAL_REGS || altclass != ALL_REGS)
534           {
535             if (altclass == ALL_REGS || class == ALL_REGS)
536               fprintf (file, "; pref %s", reg_class_names[(int) class]);
537             else if (altclass == NO_REGS)
538               fprintf (file, "; %s or none", reg_class_names[(int) class]);
539             else
540               fprintf (file, "; pref %s, else %s",
541                        reg_class_names[(int) class],
542                        reg_class_names[(int) altclass]);
543           }
544
545         if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
546           fprintf (file, "; pointer");
547         fprintf (file, ".\n");
548       }
549
550   fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
551   FOR_EACH_BB (bb)
552     {
553       edge e;
554       int sum;
555       gcov_type lsum;
556
557       fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
558                bb->index, INSN_UID (bb->head), INSN_UID (bb->end));
559       fprintf (file, "prev %d, next %d, ",
560                bb->prev_bb->index, bb->next_bb->index);
561       fprintf (file, "loop_depth %d, count ", bb->loop_depth);
562       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
563       fprintf (file, ", freq %i", bb->frequency);
564       if (maybe_hot_bb_p (bb))
565         fprintf (file, ", maybe hot");
566       if (probably_never_executed_bb_p (bb))
567         fprintf (file, ", probably never executed");
568       fprintf (file, ".\n");
569
570       fprintf (file, "Predecessors: ");
571       for (e = bb->pred; e; e = e->pred_next)
572         dump_edge_info (file, e, 0);
573
574       fprintf (file, "\nSuccessors: ");
575       for (e = bb->succ; e; e = e->succ_next)
576         dump_edge_info (file, e, 1);
577
578       fprintf (file, "\nRegisters live at start:");
579       dump_regset (bb->global_live_at_start, file);
580
581       fprintf (file, "\nRegisters live at end:");
582       dump_regset (bb->global_live_at_end, file);
583
584       putc ('\n', file);
585
586       /* Check the consistency of profile information.  We can't do that
587          in verify_flow_info, as the counts may get invalid for incompletely
588          solved graphs, later elliminating of conditionals or roundoff errors.
589          It is still practical to have them reported for debugging of simple
590          testcases.  */
591       sum = 0;
592       for (e = bb->succ; e; e = e->succ_next)
593         sum += e->probability;
594       if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
595         fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
596                  sum * 100.0 / REG_BR_PROB_BASE);
597       sum = 0;
598       for (e = bb->pred; e; e = e->pred_next)
599         sum += EDGE_FREQUENCY (e);
600       if (abs (sum - bb->frequency) > 100)
601         fprintf (file,
602                  "Invalid sum of incomming frequencies %i, should be %i\n",
603                  sum, bb->frequency);
604       lsum = 0;
605       for (e = bb->pred; e; e = e->pred_next)
606         lsum += e->count;
607       if (lsum - bb->count > 100 || lsum - bb->count < -100)
608         fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
609                  (int)lsum, (int)bb->count);
610       lsum = 0;
611       for (e = bb->succ; e; e = e->succ_next)
612         lsum += e->count;
613       if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
614         fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
615                  (int)lsum, (int)bb->count);
616     }
617
618   putc ('\n', file);
619 }
620
621 void
622 debug_flow_info ()
623 {
624   dump_flow_info (stderr);
625 }
626
627 void
628 dump_edge_info (file, e, do_succ)
629      FILE *file;
630      edge e;
631      int do_succ;
632 {
633   basic_block side = (do_succ ? e->dest : e->src);
634
635   if (side == ENTRY_BLOCK_PTR)
636     fputs (" ENTRY", file);
637   else if (side == EXIT_BLOCK_PTR)
638     fputs (" EXIT", file);
639   else
640     fprintf (file, " %d", side->index);
641
642   if (e->probability)
643     fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
644
645   if (e->count)
646     {
647       fprintf (file, " count:");
648       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
649     }
650
651   if (e->flags)
652     {
653       static const char * const bitnames[]
654         = {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
655       int comma = 0;
656       int i, flags = e->flags;
657
658       fputs (" (", file);
659       for (i = 0; flags; i++)
660         if (flags & (1 << i))
661           {
662             flags &= ~(1 << i);
663
664             if (comma)
665               fputc (',', file);
666             if (i < (int) ARRAY_SIZE (bitnames))
667               fputs (bitnames[i], file);
668             else
669               fprintf (file, "%d", i);
670             comma = 1;
671           }
672
673       fputc (')', file);
674     }
675 }
676 \f
677 /* Simple routines to easily allocate AUX fields of basic blocks.  */
678
679 static struct obstack block_aux_obstack;
680 static void *first_block_aux_obj = 0;
681 static struct obstack edge_aux_obstack;
682 static void *first_edge_aux_obj = 0;
683
684 /* Allocate an memory block of SIZE as BB->aux.  The obstack must
685    be first initialized by alloc_aux_for_blocks.  */
686
687 inline void
688 alloc_aux_for_block (bb, size)
689      basic_block bb;
690      int size;
691 {
692   /* Verify that aux field is clear.  */
693   if (bb->aux || !first_block_aux_obj)
694     abort ();
695   bb->aux = obstack_alloc (&block_aux_obstack, size);
696   memset (bb->aux, 0, size);
697 }
698
699 /* Initialize the block_aux_obstack and if SIZE is nonzero, call
700    alloc_aux_for_block for each basic block.  */
701
702 void
703 alloc_aux_for_blocks (size)
704      int size;
705 {
706   static int initialized;
707
708   if (!initialized)
709     {
710       gcc_obstack_init (&block_aux_obstack);
711       initialized = 1;
712     }
713
714   /* Check whether AUX data are still allocated.  */
715   else if (first_block_aux_obj)
716     abort ();
717   first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
718   if (size)
719     {
720       basic_block bb;
721
722       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
723         alloc_aux_for_block (bb, size);
724     }
725 }
726
727 /* Clear AUX pointers of all blocks.  */
728
729 void
730 clear_aux_for_blocks ()
731 {
732   basic_block bb;
733
734   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
735     bb->aux = NULL;
736 }
737
738 /* Free data allocated in block_aux_obstack and clear AUX pointers
739    of all blocks.  */
740
741 void
742 free_aux_for_blocks ()
743 {
744   if (!first_block_aux_obj)
745     abort ();
746   obstack_free (&block_aux_obstack, first_block_aux_obj);
747   first_block_aux_obj = NULL;
748
749   clear_aux_for_blocks ();
750 }
751
752 /* Allocate an memory edge of SIZE as BB->aux.  The obstack must
753    be first initialized by alloc_aux_for_edges.  */
754
755 inline void
756 alloc_aux_for_edge (e, size)
757      edge e;
758      int size;
759 {
760   /* Verify that aux field is clear.  */
761   if (e->aux || !first_edge_aux_obj)
762     abort ();
763   e->aux = obstack_alloc (&edge_aux_obstack, size);
764   memset (e->aux, 0, size);
765 }
766
767 /* Initialize the edge_aux_obstack and if SIZE is nonzero, call
768    alloc_aux_for_edge for each basic edge.  */
769
770 void
771 alloc_aux_for_edges (size)
772      int size;
773 {
774   static int initialized;
775
776   if (!initialized)
777     {
778       gcc_obstack_init (&edge_aux_obstack);
779       initialized = 1;
780     }
781
782   /* Check whether AUX data are still allocated.  */
783   else if (first_edge_aux_obj)
784     abort ();
785
786   first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
787   if (size)
788     {
789       basic_block bb;
790
791       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
792         {
793           edge e;
794
795           for (e = bb->succ; e; e = e->succ_next)
796             alloc_aux_for_edge (e, size);
797         }
798     }
799 }
800
801 /* Clear AUX pointers of all edges.  */
802
803 void
804 clear_aux_for_edges ()
805 {
806   basic_block bb;
807   edge e;
808
809   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
810     {
811       for (e = bb->succ; e; e = e->succ_next)
812         e->aux = NULL;
813     }
814 }
815
816 /* Free data allocated in edge_aux_obstack and clear AUX pointers
817    of all edges.  */
818
819 void
820 free_aux_for_edges ()
821 {
822   if (!first_edge_aux_obj)
823     abort ();
824   obstack_free (&edge_aux_obstack, first_edge_aux_obj);
825   first_edge_aux_obj = NULL;
826
827   clear_aux_for_edges ();
828 }