OSDN Git Service

Basic block renumbering removal.
[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 num_basic_blocks;
67
68 /* First free basic block number.  */
69 int last_basic_block;
70
71 /* Number of edges in the current function.  */
72
73 int n_edges;
74
75 /* First edge in the deleted edges chain.  */
76
77 edge first_deleted_edge;
78 static basic_block first_deleted_block;
79
80 /* The basic block array.  */
81
82 varray_type basic_block_info;
83
84 /* The special entry and exit blocks.  */
85
86 struct basic_block_def entry_exit_blocks[2]
87 = {{NULL,                       /* head */
88     NULL,                       /* end */
89     NULL,                       /* head_tree */
90     NULL,                       /* end_tree */
91     NULL,                       /* pred */
92     NULL,                       /* succ */
93     NULL,                       /* local_set */
94     NULL,                       /* cond_local_set */
95     NULL,                       /* global_live_at_start */
96     NULL,                       /* global_live_at_end */
97     NULL,                       /* aux */
98     ENTRY_BLOCK,                /* index */
99     NULL,                       /* prev_bb */
100     EXIT_BLOCK_PTR,             /* next_bb */
101     0,                          /* loop_depth */
102     0,                          /* count */
103     0,                          /* frequency */
104     0                           /* flags */
105   },
106   {
107     NULL,                       /* head */
108     NULL,                       /* end */
109     NULL,                       /* head_tree */
110     NULL,                       /* end_tree */
111     NULL,                       /* pred */
112     NULL,                       /* succ */
113     NULL,                       /* local_set */
114     NULL,                       /* cond_local_set */
115     NULL,                       /* global_live_at_start */
116     NULL,                       /* global_live_at_end */
117     NULL,                       /* aux */
118     EXIT_BLOCK,                 /* index */
119     ENTRY_BLOCK_PTR,            /* prev_bb */
120     NULL,                       /* next_bb */
121     0,                          /* loop_depth */
122     0,                          /* count */
123     0,                          /* frequency */
124     0                           /* flags */
125   }
126 };
127
128 void debug_flow_info                    PARAMS ((void));
129 static void free_edge                   PARAMS ((edge));
130 \f
131 /* Called once at initialization time.  */
132
133 void
134 init_flow ()
135 {
136   static int initialized;
137
138   first_deleted_edge = 0;
139   first_deleted_block = 0;
140   n_edges = 0;
141
142   if (!initialized)
143     {
144       gcc_obstack_init (&flow_obstack);
145       flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
146       initialized = 1;
147     }
148   else
149     {
150       obstack_free (&flow_obstack, flow_firstobj);
151       flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
152     }
153 }
154 \f
155 /* Helper function for remove_edge and clear_edges.  Frees edge structure
156    without actually unlinking it from the pred/succ lists.  */
157
158 static void
159 free_edge (e)
160      edge e;
161 {
162   n_edges--;
163   memset (e, 0, sizeof *e);
164   e->succ_next = first_deleted_edge;
165   first_deleted_edge = e;
166 }
167
168 /* Free the memory associated with the edge structures.  */
169
170 void
171 clear_edges ()
172 {
173   basic_block bb;
174   edge e;
175
176   FOR_ALL_BB (bb)
177     {
178       edge e = bb->succ;
179
180       while (e)
181         {
182           edge next = e->succ_next;
183
184           free_edge (e);
185           e = next;
186         }
187
188       bb->succ = NULL;
189       bb->pred = NULL;
190     }
191
192   e = ENTRY_BLOCK_PTR->succ;
193   while (e)
194     {
195       edge next = e->succ_next;
196
197       free_edge (e);
198       e = next;
199     }
200
201   EXIT_BLOCK_PTR->pred = NULL;
202   ENTRY_BLOCK_PTR->succ = NULL;
203
204   if (n_edges)
205     abort ();
206 }
207 \f
208 /* Allocate memory for basic_block.  */
209
210 basic_block
211 alloc_block ()
212 {
213   basic_block bb;
214
215   if (first_deleted_block)
216     {
217       bb = first_deleted_block;
218       first_deleted_block = (basic_block) bb->succ;
219       bb->succ = NULL;
220     }
221   else
222     {
223       bb = (basic_block) obstack_alloc (&flow_obstack, sizeof *bb);
224       memset (bb, 0, sizeof *bb);
225     }
226   return bb;
227 }
228
229 /* Link block B to chain after AFTER.  */
230 void
231 link_block (b, after)
232      basic_block b, after;
233 {
234   b->next_bb = after->next_bb;
235   b->prev_bb = after;
236   after->next_bb = b;
237   b->next_bb->prev_bb = b;
238 }
239
240 /* Unlink block B from chain.  */
241 void
242 unlink_block (b)
243      basic_block b;
244 {
245   b->next_bb->prev_bb = b->prev_bb;
246   b->prev_bb->next_bb = b->next_bb;
247 }
248
249 /* Sequentially order blocks and compact the arrays.  */
250 void
251 compact_blocks ()
252 {
253   basic_block *bbs = xcalloc (num_basic_blocks, sizeof (basic_block));
254   int i;
255   basic_block bb;
256  
257   i = 0;
258   FOR_ALL_BB (bb)
259     bbs[i++] = bb;
260
261   if (i != num_basic_blocks)
262     abort ();
263
264   for (i = 0; i < num_basic_blocks; i++)
265     {
266       bbs[i]->sindex = i;
267       BASIC_BLOCK (i) = bbs[i];
268     }
269   last_basic_block = num_basic_blocks;
270
271   free (bbs);
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->sindex) = NULL;
282   num_basic_blocks--;
283
284   /* Invalidate data to make bughunting easier.  */
285   memset (b, 0, sizeof *b);
286   b->sindex = -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->sindex], dst->sindex))
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->sindex], dst->sindex);
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", num_basic_blocks, n_edges);
551   FOR_ALL_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->sindex, INSN_UID (bb->head), INSN_UID (bb->end));
559       fprintf (file, "prev %d, next %d, ",
560                bb->prev_bb->sindex, bb->next_bb->sindex);
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.\n", bb->frequency);
564
565       fprintf (file, "Predecessors: ");
566       for (e = bb->pred; e; e = e->pred_next)
567         dump_edge_info (file, e, 0);
568
569       fprintf (file, "\nSuccessors: ");
570       for (e = bb->succ; e; e = e->succ_next)
571         dump_edge_info (file, e, 1);
572
573       fprintf (file, "\nRegisters live at start:");
574       dump_regset (bb->global_live_at_start, file);
575
576       fprintf (file, "\nRegisters live at end:");
577       dump_regset (bb->global_live_at_end, file);
578
579       putc ('\n', file);
580
581       /* Check the consistency of profile information.  We can't do that
582          in verify_flow_info, as the counts may get invalid for incompletely
583          solved graphs, later elliminating of conditionals or roundoff errors.
584          It is still practical to have them reported for debugging of simple
585          testcases.  */
586       sum = 0;
587       for (e = bb->succ; e; e = e->succ_next)
588         sum += e->probability;
589       if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
590         fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
591                  sum * 100.0 / REG_BR_PROB_BASE);
592       sum = 0;
593       for (e = bb->pred; e; e = e->pred_next)
594         sum += EDGE_FREQUENCY (e);
595       if (abs (sum - bb->frequency) > 100)
596         fprintf (file,
597                  "Invalid sum of incomming frequencies %i, should be %i\n",
598                  sum, bb->frequency);
599       lsum = 0;
600       for (e = bb->pred; e; e = e->pred_next)
601         lsum += e->count;
602       if (lsum - bb->count > 100 || lsum - bb->count < -100)
603         fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
604                  (int)lsum, (int)bb->count);
605       lsum = 0;
606       for (e = bb->succ; e; e = e->succ_next)
607         lsum += e->count;
608       if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
609         fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
610                  (int)lsum, (int)bb->count);
611     }
612
613   putc ('\n', file);
614 }
615
616 void
617 debug_flow_info ()
618 {
619   dump_flow_info (stderr);
620 }
621
622 void
623 dump_edge_info (file, e, do_succ)
624      FILE *file;
625      edge e;
626      int do_succ;
627 {
628   basic_block side = (do_succ ? e->dest : e->src);
629
630   if (side == ENTRY_BLOCK_PTR)
631     fputs (" ENTRY", file);
632   else if (side == EXIT_BLOCK_PTR)
633     fputs (" EXIT", file);
634   else
635     fprintf (file, " %d", side->sindex);
636
637   if (e->probability)
638     fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
639
640   if (e->count)
641     {
642       fprintf (file, " count:");
643       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
644     }
645
646   if (e->flags)
647     {
648       static const char * const bitnames[]
649         = {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
650       int comma = 0;
651       int i, flags = e->flags;
652
653       fputs (" (", file);
654       for (i = 0; flags; i++)
655         if (flags & (1 << i))
656           {
657             flags &= ~(1 << i);
658
659             if (comma)
660               fputc (',', file);
661             if (i < (int) ARRAY_SIZE (bitnames))
662               fputs (bitnames[i], file);
663             else
664               fprintf (file, "%d", i);
665             comma = 1;
666           }
667
668       fputc (')', file);
669     }
670 }
671 \f
672 /* Simple routines to easily allocate AUX fields of basic blocks.  */
673
674 static struct obstack block_aux_obstack;
675 static void *first_block_aux_obj = 0;
676 static struct obstack edge_aux_obstack;
677 static void *first_edge_aux_obj = 0;
678
679 /* Allocate an memory block of SIZE as BB->aux.  The obstack must
680    be first initialized by alloc_aux_for_blocks.  */
681
682 inline void
683 alloc_aux_for_block (bb, size)
684      basic_block bb;
685      int size;
686 {
687   /* Verify that aux field is clear.  */
688   if (bb->aux || !first_block_aux_obj)
689     abort ();
690   bb->aux = obstack_alloc (&block_aux_obstack, size);
691   memset (bb->aux, 0, size);
692 }
693
694 /* Initialize the block_aux_obstack and if SIZE is nonzero, call
695    alloc_aux_for_block for each basic block.  */
696
697 void
698 alloc_aux_for_blocks (size)
699      int size;
700 {
701   static int initialized;
702
703   if (!initialized)
704     {
705       gcc_obstack_init (&block_aux_obstack);
706       initialized = 1;
707     }
708
709   /* Check whether AUX data are still allocated.  */
710   else if (first_block_aux_obj)
711     abort ();
712   first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
713   if (size)
714     {
715       basic_block bb;
716
717       FOR_ALL_BB (bb)
718         alloc_aux_for_block (bb, size);
719
720       alloc_aux_for_block (ENTRY_BLOCK_PTR, size);
721       alloc_aux_for_block (EXIT_BLOCK_PTR, size);
722     }
723 }
724
725 /* Clear AUX pointers of all blocks.  */
726
727 void
728 clear_aux_for_blocks ()
729 {
730   basic_block bb;
731
732   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
733     bb->aux = NULL;
734 }
735
736 /* Free data allocated in block_aux_obstack and clear AUX pointers
737    of all blocks.  */
738
739 void
740 free_aux_for_blocks ()
741 {
742   if (!first_block_aux_obj)
743     abort ();
744   obstack_free (&block_aux_obstack, first_block_aux_obj);
745   first_block_aux_obj = NULL;
746
747   clear_aux_for_blocks ();
748 }
749
750 /* Allocate an memory edge of SIZE as BB->aux.  The obstack must
751    be first initialized by alloc_aux_for_edges.  */
752
753 inline void
754 alloc_aux_for_edge (e, size)
755      edge e;
756      int size;
757 {
758   /* Verify that aux field is clear.  */
759   if (e->aux || !first_edge_aux_obj)
760     abort ();
761   e->aux = obstack_alloc (&edge_aux_obstack, size);
762   memset (e->aux, 0, size);
763 }
764
765 /* Initialize the edge_aux_obstack and if SIZE is nonzero, call
766    alloc_aux_for_edge for each basic edge.  */
767
768 void
769 alloc_aux_for_edges (size)
770      int size;
771 {
772   static int initialized;
773
774   if (!initialized)
775     {
776       gcc_obstack_init (&edge_aux_obstack);
777       initialized = 1;
778     }
779
780   /* Check whether AUX data are still allocated.  */
781   else if (first_edge_aux_obj)
782     abort ();
783
784   first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
785   if (size)
786     {
787       basic_block bb;
788
789       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
790         {
791           edge e;
792
793           for (e = bb->succ; e; e = e->succ_next)
794             alloc_aux_for_edge (e, size);
795         }
796     }
797 }
798
799 /* Clear AUX pointers of all edges.  */
800
801 void
802 clear_aux_for_edges ()
803 {
804   basic_block bb;
805
806   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
807     {
808       edge e;
809
810       for (e = bb->succ; e; e = e->succ_next)
811         e->aux = NULL;
812     }
813 }
814
815 /* Free data allocated in edge_aux_obstack and clear AUX pointers
816    of all edges.  */
817
818 void
819 free_aux_for_edges ()
820 {
821   if (!first_edge_aux_obj)
822     abort ();
823   obstack_free (&edge_aux_obstack, first_edge_aux_obj);
824   first_edge_aux_obj = NULL;
825
826   clear_aux_for_edges ();
827 }
828
829 /* The same as BASIC_BLOCK, but usable from debugger.  */
830 basic_block
831 debug_num2bb (num)
832      int num;
833 {
834   return BASIC_BLOCK (num);
835 }