OSDN Git Service

* regclass.c (init_reg_autoinc): New function.
[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 DST with FLAGS optionally using
284    edge cache CACHE.  Return the new edge, NULL if already exist.  */
285
286 edge
287 cached_make_edge (edge_cache, src, dst, flags)
288      sbitmap *edge_cache;
289      basic_block src, dst;
290      int flags;
291 {
292   int use_edge_cache;
293   edge e;
294
295   /* Don't bother with edge cache for ENTRY or EXIT, if there aren't that
296      many edges to them, or we didn't allocate memory for it.  */
297   use_edge_cache = (edge_cache
298                     && src != ENTRY_BLOCK_PTR && dst != EXIT_BLOCK_PTR);
299
300   /* Make sure we don't add duplicate edges.  */
301   switch (use_edge_cache)
302     {
303     default:
304       /* Quick test for non-existence of the edge.  */
305       if (! TEST_BIT (edge_cache[src->index], dst->index))
306         break;
307
308       /* The edge exists; early exit if no work to do.  */
309       if (flags == 0)
310         return NULL;
311
312       /* FALLTHRU */
313     case 0:
314       for (e = src->succ; e; e = e->succ_next)
315         if (e->dest == dst)
316           {
317             e->flags |= flags;
318             return NULL;
319           }
320       break;
321     }
322   
323   
324   e = pool_alloc (edge_pool);
325   memset (e, 0, sizeof (*e));
326   n_edges++;
327
328   e->succ_next = src->succ;
329   e->pred_next = dst->pred;
330   e->src = src;
331   e->dest = dst;
332   e->flags = flags;
333
334   src->succ = e;
335   dst->pred = e;
336
337   if (use_edge_cache)
338     SET_BIT (edge_cache[src->index], dst->index);
339
340   return e;
341 }
342
343 /* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
344    created edge or NULL if already exist.  */
345
346 edge
347 make_edge (src, dest, flags)
348      basic_block src, dest;
349      int flags;
350 {
351   return cached_make_edge (NULL, src, dest, flags);
352 }
353
354 /* Create an edge connecting SRC to DEST and set probability by knowing
355    that it is the single edge leaving SRC.  */
356
357 edge
358 make_single_succ_edge (src, dest, flags)
359      basic_block src, dest;
360      int flags;
361 {
362   edge e = make_edge (src, dest, flags);
363
364   e->probability = REG_BR_PROB_BASE;
365   e->count = src->count;
366   return e;
367 }
368
369 /* This function will remove an edge from the flow graph.  */
370
371 void
372 remove_edge (e)
373      edge e;
374 {
375   edge last_pred = NULL;
376   edge last_succ = NULL;
377   edge tmp;
378   basic_block src, dest;
379
380   src = e->src;
381   dest = e->dest;
382   for (tmp = src->succ; tmp && tmp != e; tmp = tmp->succ_next)
383     last_succ = tmp;
384
385   if (!tmp)
386     abort ();
387   if (last_succ)
388     last_succ->succ_next = e->succ_next;
389   else
390     src->succ = e->succ_next;
391
392   for (tmp = dest->pred; tmp && tmp != e; tmp = tmp->pred_next)
393     last_pred = tmp;
394
395   if (!tmp)
396     abort ();
397   if (last_pred)
398     last_pred->pred_next = e->pred_next;
399   else
400     dest->pred = e->pred_next;
401
402   free_edge (e);
403 }
404
405 /* Redirect an edge's successor from one block to another.  */
406
407 void
408 redirect_edge_succ (e, new_succ)
409      edge e;
410      basic_block new_succ;
411 {
412   edge *pe;
413
414   /* Disconnect the edge from the old successor block.  */
415   for (pe = &e->dest->pred; *pe != e; pe = &(*pe)->pred_next)
416     continue;
417   *pe = (*pe)->pred_next;
418
419   /* Reconnect the edge to the new successor block.  */
420   e->pred_next = new_succ->pred;
421   new_succ->pred = e;
422   e->dest = new_succ;
423 }
424
425 /* Like previous but avoid possible duplicate edge.  */
426
427 edge
428 redirect_edge_succ_nodup (e, new_succ)
429      edge e;
430      basic_block new_succ;
431 {
432   edge s;
433
434   /* Check whether the edge is already present.  */
435   for (s = e->src->succ; s; s = s->succ_next)
436     if (s->dest == new_succ && s != e)
437       break;
438
439   if (s)
440     {
441       s->flags |= e->flags;
442       s->probability += e->probability;
443       if (s->probability > REG_BR_PROB_BASE)
444         s->probability = REG_BR_PROB_BASE;
445       s->count += e->count;
446       remove_edge (e);
447       e = s;
448     }
449   else
450     redirect_edge_succ (e, new_succ);
451
452   return e;
453 }
454
455 /* Redirect an edge's predecessor from one block to another.  */
456
457 void
458 redirect_edge_pred (e, new_pred)
459      edge e;
460      basic_block new_pred;
461 {
462   edge *pe;
463
464   /* Disconnect the edge from the old predecessor block.  */
465   for (pe = &e->src->succ; *pe != e; pe = &(*pe)->succ_next)
466     continue;
467
468   *pe = (*pe)->succ_next;
469
470   /* Reconnect the edge to the new predecessor block.  */
471   e->succ_next = new_pred->succ;
472   new_pred->succ = e;
473   e->src = new_pred;
474 }
475
476 void
477 clear_bb_flags ()
478 {
479   basic_block bb;
480
481   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
482     bb->flags = 0;
483 }
484 \f
485 void
486 dump_flow_info (file)
487      FILE *file;
488 {
489   int i;
490   basic_block bb;
491   static const char * const reg_class_names[] = REG_CLASS_NAMES;
492
493   fprintf (file, "%d registers.\n", max_regno);
494   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
495     if (REG_N_REFS (i))
496       {
497         enum reg_class class, altclass;
498
499         fprintf (file, "\nRegister %d used %d times across %d insns",
500                  i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
501         if (REG_BASIC_BLOCK (i) >= 0)
502           fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
503         if (REG_N_SETS (i))
504           fprintf (file, "; set %d time%s", REG_N_SETS (i),
505                    (REG_N_SETS (i) == 1) ? "" : "s");
506         if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
507           fprintf (file, "; user var");
508         if (REG_N_DEATHS (i) != 1)
509           fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
510         if (REG_N_CALLS_CROSSED (i) == 1)
511           fprintf (file, "; crosses 1 call");
512         else if (REG_N_CALLS_CROSSED (i))
513           fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
514         if (regno_reg_rtx[i] != NULL
515             && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
516           fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
517
518         class = reg_preferred_class (i);
519         altclass = reg_alternate_class (i);
520         if (class != GENERAL_REGS || altclass != ALL_REGS)
521           {
522             if (altclass == ALL_REGS || class == ALL_REGS)
523               fprintf (file, "; pref %s", reg_class_names[(int) class]);
524             else if (altclass == NO_REGS)
525               fprintf (file, "; %s or none", reg_class_names[(int) class]);
526             else
527               fprintf (file, "; pref %s, else %s",
528                        reg_class_names[(int) class],
529                        reg_class_names[(int) altclass]);
530           }
531
532         if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
533           fprintf (file, "; pointer");
534         fprintf (file, ".\n");
535       }
536
537   fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
538   FOR_EACH_BB (bb)
539     {
540       edge e;
541       int sum;
542       gcov_type lsum;
543
544       fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
545                bb->index, INSN_UID (bb->head), INSN_UID (bb->end));
546       fprintf (file, "prev %d, next %d, ",
547                bb->prev_bb->index, bb->next_bb->index);
548       fprintf (file, "loop_depth %d, count ", bb->loop_depth);
549       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
550       fprintf (file, ", freq %i", bb->frequency);
551       if (maybe_hot_bb_p (bb))
552         fprintf (file, ", maybe hot");
553       if (probably_never_executed_bb_p (bb))
554         fprintf (file, ", probably never executed");
555       fprintf (file, ".\n");
556
557       fprintf (file, "Predecessors: ");
558       for (e = bb->pred; e; e = e->pred_next)
559         dump_edge_info (file, e, 0);
560
561       fprintf (file, "\nSuccessors: ");
562       for (e = bb->succ; e; e = e->succ_next)
563         dump_edge_info (file, e, 1);
564
565       fprintf (file, "\nRegisters live at start:");
566       dump_regset (bb->global_live_at_start, file);
567
568       fprintf (file, "\nRegisters live at end:");
569       dump_regset (bb->global_live_at_end, file);
570
571       putc ('\n', file);
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 eliminating 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);
603     }
604
605   putc ('\n', file);
606 }
607
608 void
609 debug_flow_info ()
610 {
611   dump_flow_info (stderr);
612 }
613
614 void
615 dump_edge_info (file, e, do_succ)
616      FILE *file;
617      edge e;
618      int do_succ;
619 {
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
627     fprintf (file, " %d", side->index);
628
629   if (e->probability)
630     fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
631
632   if (e->count)
633     {
634       fprintf (file, " count:");
635       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
636     }
637
638   if (e->flags)
639     {
640       static const char * const bitnames[]
641         = {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
642       int comma = 0;
643       int i, flags = e->flags;
644
645       fputs (" (", file);
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           }
659
660       fputc (')', file);
661     }
662 }
663 \f
664 /* Simple routines to easily allocate AUX fields of basic blocks.  */
665
666 static struct obstack block_aux_obstack;
667 static void *first_block_aux_obj = 0;
668 static struct obstack edge_aux_obstack;
669 static void *first_edge_aux_obj = 0;
670
671 /* Allocate a memory block of SIZE as BB->aux.  The obstack must
672    be first initialized by alloc_aux_for_blocks.  */
673
674 inline void
675 alloc_aux_for_block (bb, size)
676      basic_block bb;
677      int size;
678 {
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);
684 }
685
686 /* Initialize the block_aux_obstack and if SIZE is nonzero, call
687    alloc_aux_for_block for each basic block.  */
688
689 void
690 alloc_aux_for_blocks (size)
691      int size;
692 {
693   static int initialized;
694
695   if (!initialized)
696     {
697       gcc_obstack_init (&block_aux_obstack);
698       initialized = 1;
699     }
700
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)
706     {
707       basic_block bb;
708
709       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
710         alloc_aux_for_block (bb, size);
711     }
712 }
713
714 /* Clear AUX pointers of all blocks.  */
715
716 void
717 clear_aux_for_blocks ()
718 {
719   basic_block bb;
720
721   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
722     bb->aux = NULL;
723 }
724
725 /* Free data allocated in block_aux_obstack and clear AUX pointers
726    of all blocks.  */
727
728 void
729 free_aux_for_blocks ()
730 {
731   if (!first_block_aux_obj)
732     abort ();
733   obstack_free (&block_aux_obstack, first_block_aux_obj);
734   first_block_aux_obj = NULL;
735
736   clear_aux_for_blocks ();
737 }
738
739 /* Allocate a memory edge of SIZE as BB->aux.  The obstack must
740    be first initialized by alloc_aux_for_edges.  */
741
742 inline void
743 alloc_aux_for_edge (e, size)
744      edge e;
745      int size;
746 {
747   /* Verify that aux field is clear.  */
748   if (e->aux || !first_edge_aux_obj)
749     abort ();
750   e->aux = obstack_alloc (&edge_aux_obstack, size);
751   memset (e->aux, 0, size);
752 }
753
754 /* Initialize the edge_aux_obstack and if SIZE is nonzero, call
755    alloc_aux_for_edge for each basic edge.  */
756
757 void
758 alloc_aux_for_edges (size)
759      int size;
760 {
761   static int initialized;
762
763   if (!initialized)
764     {
765       gcc_obstack_init (&edge_aux_obstack);
766       initialized = 1;
767     }
768
769   /* Check whether AUX data are still allocated.  */
770   else if (first_edge_aux_obj)
771     abort ();
772
773   first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
774   if (size)
775     {
776       basic_block bb;
777
778       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
779         {
780           edge e;
781
782           for (e = bb->succ; e; e = e->succ_next)
783             alloc_aux_for_edge (e, size);
784         }
785     }
786 }
787
788 /* Clear AUX pointers of all edges.  */
789
790 void
791 clear_aux_for_edges ()
792 {
793   basic_block bb;
794   edge e;
795
796   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
797     {
798       for (e = bb->succ; e; e = e->succ_next)
799         e->aux = NULL;
800     }
801 }
802
803 /* Free data allocated in edge_aux_obstack and clear AUX pointers
804    of all edges.  */
805
806 void
807 free_aux_for_edges ()
808 {
809   if (!first_edge_aux_obj)
810     abort ();
811   obstack_free (&edge_aux_obstack, first_edge_aux_obj);
812   first_edge_aux_obj = NULL;
813
814   clear_aux_for_edges ();
815 }