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