cfg.c 23.3 KB
Newer Older
1 2
/* Control flow graph manipulation code for GNU compiler.
   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

22
/* This file contains low level functions to manipulate the CFG and
23
   analyze it.  All other modules should not transform the data structure
24 25 26
   directly and use abstraction instead.  The file is supposed to be
   ordered bottom-up and should not contain any code dependent on a
   particular intermediate language (RTL or trees).
27 28 29 30

   Available functionality:
     - Initialization/deallocation
	 init_flow, clear_edges
31 32
     - Low level basic block manipulation
	 alloc_block, expunge_block
33
     - Edge manipulation
34
	 make_edge, make_single_succ_edge, cached_make_edge, remove_edge
35 36
	 - Low level edge redirection (without updating instruction chain)
	     redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
37
     - Dumping and debugging
38 39 40
	 dump_flow_info, debug_flow_info, dump_edge_info
     - Allocation of AUX fields for basic blocks
	 alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
41
     - clear_bb_flags
42 43 44 45
     - Consistency checking
	 verify_flow_info
     - Dumping and debugging
	 print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
46 47 48 49
 */

#include "config.h"
#include "system.h"
50 51
#include "coretypes.h"
#include "tm.h"
52 53 54 55 56 57 58 59 60 61
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "regs.h"
#include "flags.h"
#include "output.h"
#include "function.h"
#include "except.h"
#include "toplev.h"
62
#include "tm_p.h"
63
#include "obstack.h"
64
#include "alloc-pool.h"
65 66 67 68 69 70

/* The obstack on which the flow graph components are allocated.  */

struct obstack flow_obstack;
static char *flow_firstobj;

71 72 73 74 75 76 77 78
/* Basic block object pool.  */

static alloc_pool bb_pool;

/* Edge object pool.  */

static alloc_pool edge_pool;

79 80
/* Number of basic blocks in the current function.  */

81
int n_basic_blocks;
82

83 84 85 86
/* First free basic block number.  */

int last_basic_block;

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/* Number of edges in the current function.  */

int n_edges;

/* The basic block array.  */

varray_type basic_block_info;

/* The special entry and exit blocks.  */

struct basic_block_def entry_exit_blocks[2]
= {{NULL,			/* head */
    NULL,			/* end */
    NULL,			/* head_tree */
    NULL,			/* end_tree */
    NULL,			/* pred */
    NULL,			/* succ */
    NULL,			/* local_set */
    NULL,			/* cond_local_set */
    NULL,			/* global_live_at_start */
    NULL,			/* global_live_at_end */
    NULL,			/* aux */
    ENTRY_BLOCK,		/* index */
110 111
    NULL,			/* prev_bb */
    EXIT_BLOCK_PTR,		/* next_bb */
112
    0,				/* loop_depth */
113
    NULL,                       /* loop_father */
114
    { NULL, NULL },		/* dom */
115 116
    0,				/* count */
    0,				/* frequency */
117 118
    0,				/* flags */
    NULL			/* rbi */
119 120 121 122 123 124 125 126 127 128 129 130 131 132
  },
  {
    NULL,			/* head */
    NULL,			/* end */
    NULL,			/* head_tree */
    NULL,			/* end_tree */
    NULL,			/* pred */
    NULL,			/* succ */
    NULL,			/* local_set */
    NULL,			/* cond_local_set */
    NULL,			/* global_live_at_start */
    NULL,			/* global_live_at_end */
    NULL,			/* aux */
    EXIT_BLOCK,			/* index */
133 134
    ENTRY_BLOCK_PTR,		/* prev_bb */
    NULL,			/* next_bb */
135
    0,				/* loop_depth */
136
    NULL,                       /* loop_father */
137
    { NULL, NULL },		/* dom */
138 139
    0,				/* count */
    0,				/* frequency */
140 141
    0,				/* flags */
    NULL			/* rbi */
142 143 144
  }
};

145 146
void debug_flow_info (void);
static void free_edge (edge);
147

148
/* Called once at initialization time.  */
149 150

void
151
init_flow (void)
152 153 154
{
  static int initialized;

155 156
  n_edges = 0;

157 158 159
  if (!initialized)
    {
      gcc_obstack_init (&flow_obstack);
160
      flow_firstobj = obstack_alloc (&flow_obstack, 0);
161 162 163 164
      initialized = 1;
    }
  else
    {
165 166
      free_alloc_pool (bb_pool);
      free_alloc_pool (edge_pool);
167
      obstack_free (&flow_obstack, flow_firstobj);
168
      flow_firstobj = obstack_alloc (&flow_obstack, 0);
169
    }
170
  bb_pool = create_alloc_pool ("Basic block pool",
171 172 173
			       sizeof (struct basic_block_def), 100);
  edge_pool = create_alloc_pool ("Edge pool",
			       sizeof (struct edge_def), 100);
174 175
}

176 177 178 179
/* Helper function for remove_edge and clear_edges.  Frees edge structure
   without actually unlinking it from the pred/succ lists.  */

static void
180
free_edge (edge e)
181 182
{
  n_edges--;
183
  pool_free (edge_pool, e);
184 185
}

186 187 188
/* Free the memory associated with the edge structures.  */

void
189
clear_edges (void)
190
{
191
  basic_block bb;
192
  edge e;
193

194
  FOR_EACH_BB (bb)
195
    {
196
      edge e = bb->succ;
197

198 199 200 201 202 203 204
      while (e)
	{
	  edge next = e->succ_next;

	  free_edge (e);
	  e = next;
	}
205

206 207
      bb->succ = NULL;
      bb->pred = NULL;
208 209
    }

210 211 212 213 214 215 216 217
  e = ENTRY_BLOCK_PTR->succ;
  while (e)
    {
      edge next = e->succ_next;

      free_edge (e);
      e = next;
    }
218

219 220
  EXIT_BLOCK_PTR->pred = NULL;
  ENTRY_BLOCK_PTR->succ = NULL;
221

222 223
  if (n_edges)
    abort ();
224 225
}

226
/* Allocate memory for basic_block.  */
227

228
basic_block
229
alloc_block (void)
230 231
{
  basic_block bb;
232 233
  bb = pool_alloc (bb_pool);
  memset (bb, 0, sizeof (*bb));
234
  return bb;
235 236
}

237 238
/* Link block B to chain after AFTER.  */
void
239
link_block (basic_block b, basic_block after)
240 241 242 243 244 245
{
  b->next_bb = after->next_bb;
  b->prev_bb = after;
  after->next_bb = b;
  b->next_bb->prev_bb = b;
}
246

247 248
/* Unlink block B from chain.  */
void
249
unlink_block (basic_block b)
250 251 252 253
{
  b->next_bb->prev_bb = b->prev_bb;
  b->prev_bb->next_bb = b->next_bb;
}
254

255 256
/* Sequentially order blocks and compact the arrays.  */
void
257
compact_blocks (void)
258 259 260
{
  int i;
  basic_block bb;
261

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  i = 0;
  FOR_EACH_BB (bb)
    {
      BASIC_BLOCK (i) = bb;
      bb->index = i;
      i++;
    }

  if (i != n_basic_blocks)
    abort ();

  last_basic_block = n_basic_blocks;
}

/* Remove block B from the basic block array.  */
277

278
void
279
expunge_block (basic_block b)
280
{
281
  unlink_block (b);
282 283
  BASIC_BLOCK (b->index) = NULL;
  n_basic_blocks--;
284
  pool_free (bb_pool, b);
285
}
286

287 288 289 290 291
/* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
   created edge.  Use this only if you are sure that this edge can't
   possibly already exist.  */

edge
292
unchecked_make_edge (basic_block src, basic_block dst, int flags)
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
{
  edge e;
  e = pool_alloc (edge_pool);
  memset (e, 0, sizeof (*e));
  n_edges++;

  e->succ_next = src->succ;
  e->pred_next = dst->pred;
  e->src = src;
  e->dest = dst;
  e->flags = flags;

  src->succ = e;
  dst->pred = e;

  return e;
}

311
/* Create an edge connecting SRC and DST with FLAGS optionally using
312
   edge cache CACHE.  Return the new edge, NULL if already exist.  */
313

314
edge
315
cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int flags)
316 317 318 319
{
  int use_edge_cache;
  edge e;

320 321
  /* Don't bother with edge cache for ENTRY or EXIT, if there aren't that
     many edges to them, or we didn't allocate memory for it.  */
322
  use_edge_cache = (edge_cache
323
		    && src != ENTRY_BLOCK_PTR && dst != EXIT_BLOCK_PTR);
324 325 326 327 328

  /* Make sure we don't add duplicate edges.  */
  switch (use_edge_cache)
    {
    default:
329
      /* Quick test for non-existence of the edge.  */
330
      if (! TEST_BIT (edge_cache[src->index], dst->index))
331 332 333 334
	break;

      /* The edge exists; early exit if no work to do.  */
      if (flags == 0)
335
	return NULL;
336 337 338 339 340 341 342

      /* FALLTHRU */
    case 0:
      for (e = src->succ; e; e = e->succ_next)
	if (e->dest == dst)
	  {
	    e->flags |= flags;
343
	    return NULL;
344 345 346
	  }
      break;
    }
347

348
  e = unchecked_make_edge (src, dst, flags);
349 350

  if (use_edge_cache)
351
    SET_BIT (edge_cache[src->index], dst->index);
352 353 354 355 356 357 358 359

  return e;
}

/* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
   created edge or NULL if already exist.  */

edge
360
make_edge (basic_block src, basic_block dest, int flags)
361 362 363 364
{
  return cached_make_edge (NULL, src, dest, flags);
}

365
/* Create an edge connecting SRC to DEST and set probability by knowing
366 367 368
   that it is the single edge leaving SRC.  */

edge
369
make_single_succ_edge (basic_block src, basic_block dest, int flags)
370 371 372 373 374 375
{
  edge e = make_edge (src, dest, flags);

  e->probability = REG_BR_PROB_BASE;
  e->count = src->count;
  return e;
376 377 378 379 380
}

/* This function will remove an edge from the flow graph.  */

void
381
remove_edge (edge e)
382 383 384 385 386
{
  edge last_pred = NULL;
  edge last_succ = NULL;
  edge tmp;
  basic_block src, dest;
387

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
  src = e->src;
  dest = e->dest;
  for (tmp = src->succ; tmp && tmp != e; tmp = tmp->succ_next)
    last_succ = tmp;

  if (!tmp)
    abort ();
  if (last_succ)
    last_succ->succ_next = e->succ_next;
  else
    src->succ = e->succ_next;

  for (tmp = dest->pred; tmp && tmp != e; tmp = tmp->pred_next)
    last_pred = tmp;

  if (!tmp)
    abort ();
  if (last_pred)
    last_pred->pred_next = e->pred_next;
  else
    dest->pred = e->pred_next;

410
  free_edge (e);
411 412 413 414 415
}

/* Redirect an edge's successor from one block to another.  */

void
416
redirect_edge_succ (edge e, basic_block new_succ)
417 418 419 420 421 422 423 424 425 426 427 428 429 430
{
  edge *pe;

  /* Disconnect the edge from the old successor block.  */
  for (pe = &e->dest->pred; *pe != e; pe = &(*pe)->pred_next)
    continue;
  *pe = (*pe)->pred_next;

  /* Reconnect the edge to the new successor block.  */
  e->pred_next = new_succ->pred;
  new_succ->pred = e;
  e->dest = new_succ;
}

431
/* Like previous but avoid possible duplicate edge.  */
432 433

edge
434
redirect_edge_succ_nodup (edge e, basic_block new_succ)
435 436
{
  edge s;
437

438 439 440 441
  /* Check whether the edge is already present.  */
  for (s = e->src->succ; s; s = s->succ_next)
    if (s->dest == new_succ && s != e)
      break;
442

443 444 445 446
  if (s)
    {
      s->flags |= e->flags;
      s->probability += e->probability;
447 448
      if (s->probability > REG_BR_PROB_BASE)
	s->probability = REG_BR_PROB_BASE;
449 450 451 452 453 454
      s->count += e->count;
      remove_edge (e);
      e = s;
    }
  else
    redirect_edge_succ (e, new_succ);
455

456 457 458 459 460 461
  return e;
}

/* Redirect an edge's predecessor from one block to another.  */

void
462
redirect_edge_pred (edge e, basic_block new_pred)
463 464 465 466 467 468
{
  edge *pe;

  /* Disconnect the edge from the old predecessor block.  */
  for (pe = &e->src->succ; *pe != e; pe = &(*pe)->succ_next)
    continue;
469

470 471 472 473 474 475 476
  *pe = (*pe)->succ_next;

  /* Reconnect the edge to the new predecessor block.  */
  e->succ_next = new_pred->succ;
  new_pred->succ = e;
  e->src = new_pred;
}
477 478

void
479
clear_bb_flags (void)
480
{
481 482 483 484
  basic_block bb;

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    bb->flags = 0;
485
}
486

487
void
488
dump_flow_info (FILE *file)
489
{
490
  int i;
491
  int max_regno = max_reg_num ();
492
  basic_block bb;
493 494 495
  static const char * const reg_class_names[] = REG_CLASS_NAMES;

  fprintf (file, "%d registers.\n", max_regno);
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
  if (reg_n_info)
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      if (REG_N_REFS (i))
	{
	  enum reg_class class, altclass;

	  fprintf (file, "\nRegister %d used %d times across %d insns",
		   i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
	  if (REG_BASIC_BLOCK (i) >= 0)
	    fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
	  if (REG_N_SETS (i))
	    fprintf (file, "; set %d time%s", REG_N_SETS (i),
		     (REG_N_SETS (i) == 1) ? "" : "s");
	  if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
	    fprintf (file, "; user var");
	  if (REG_N_DEATHS (i) != 1)
	    fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
	  if (REG_N_CALLS_CROSSED (i) == 1)
	    fprintf (file, "; crosses 1 call");
	  else if (REG_N_CALLS_CROSSED (i))
	    fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
	  if (regno_reg_rtx[i] != NULL
	      && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
	    fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));

	  class = reg_preferred_class (i);
	  altclass = reg_alternate_class (i);
	  if (class != GENERAL_REGS || altclass != ALL_REGS)
	    {
	      if (altclass == ALL_REGS || class == ALL_REGS)
		fprintf (file, "; pref %s", reg_class_names[(int) class]);
	      else if (altclass == NO_REGS)
		fprintf (file, "; %s or none", reg_class_names[(int) class]);
	      else
		fprintf (file, "; pref %s, else %s",
			 reg_class_names[(int) class],
			 reg_class_names[(int) altclass]);
	    }

	  if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
	    fprintf (file, "; pointer");
	  fprintf (file, ".\n");
	}
539

540
  fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
541
  FOR_EACH_BB (bb)
542
    {
543
      edge e;
544 545
      int sum;
      gcov_type lsum;
546

547
      fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
548
	       bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb)));
549 550
      fprintf (file, "prev %d, next %d, ",
	       bb->prev_bb->index, bb->next_bb->index);
551 552
      fprintf (file, "loop_depth %d, count ", bb->loop_depth);
      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
553 554 555 556 557
      fprintf (file, ", freq %i", bb->frequency);
      if (maybe_hot_bb_p (bb))
	fprintf (file, ", maybe hot");
      if (probably_never_executed_bb_p (bb))
	fprintf (file, ", probably never executed");
558
      fprintf (file, ".\n");
559

560 561 562
      fprintf (file, "Predecessors: ");
      for (e = bb->pred; e; e = e->pred_next)
	dump_edge_info (file, e, 0);
563

564 565 566
      fprintf (file, "\nSuccessors: ");
      for (e = bb->succ; e; e = e->succ_next)
	dump_edge_info (file, e, 1);
567

568 569
      fprintf (file, "\nRegisters live at start:");
      dump_regset (bb->global_live_at_start, file);
570

571 572
      fprintf (file, "\nRegisters live at end:");
      dump_regset (bb->global_live_at_end, file);
573

574
      putc ('\n', file);
575 576 577

      /* Check the consistency of profile information.  We can't do that
	 in verify_flow_info, as the counts may get invalid for incompletely
578
	 solved graphs, later eliminating of conditionals or roundoff errors.
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
	 It is still practical to have them reported for debugging of simple
	 testcases.  */
      sum = 0;
      for (e = bb->succ; e; e = e->succ_next)
	sum += e->probability;
      if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
	fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
		 sum * 100.0 / REG_BR_PROB_BASE);
      sum = 0;
      for (e = bb->pred; e; e = e->pred_next)
	sum += EDGE_FREQUENCY (e);
      if (abs (sum - bb->frequency) > 100)
	fprintf (file,
		 "Invalid sum of incomming frequencies %i, should be %i\n",
		 sum, bb->frequency);
      lsum = 0;
      for (e = bb->pred; e; e = e->pred_next)
	lsum += e->count;
      if (lsum - bb->count > 100 || lsum - bb->count < -100)
	fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
		 (int)lsum, (int)bb->count);
      lsum = 0;
      for (e = bb->succ; e; e = e->succ_next)
	lsum += e->count;
      if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
	fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
		 (int)lsum, (int)bb->count);
606 607
    }

608
  putc ('\n', file);
609 610
}

611
void
612
debug_flow_info (void)
613 614 615
{
  dump_flow_info (stderr);
}
616 617

void
618
dump_edge_info (FILE *file, edge e, int do_succ)
619
{
620 621 622 623 624 625 626
  basic_block side = (do_succ ? e->dest : e->src);

  if (side == ENTRY_BLOCK_PTR)
    fputs (" ENTRY", file);
  else if (side == EXIT_BLOCK_PTR)
    fputs (" EXIT", file);
  else
627
    fprintf (file, " %d", side->index);
628 629 630

  if (e->probability)
    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 641
      static const char * const bitnames[] = {
	"fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
642
	"can_fallthru", "irreducible", "sibcall", "loop_exit"
643
      };
644 645
      int comma = 0;
      int i, flags = e->flags;
646

647
      fputs (" (", file);
648 649 650 651 652 653 654 655 656 657 658 659 660
      for (i = 0; flags; i++)
	if (flags & (1 << i))
	  {
	    flags &= ~(1 << i);

	    if (comma)
	      fputc (',', file);
	    if (i < (int) ARRAY_SIZE (bitnames))
	      fputs (bitnames[i], file);
	    else
	      fprintf (file, "%d", i);
	    comma = 1;
	  }
661

662 663 664 665
      fputc (')', file);
    }
}

666
/* Simple routines to easily allocate AUX fields of basic blocks.  */
667

668 669 670 671
static struct obstack block_aux_obstack;
static void *first_block_aux_obj = 0;
static struct obstack edge_aux_obstack;
static void *first_edge_aux_obj = 0;
672

673
/* Allocate a memory block of SIZE as BB->aux.  The obstack must
674
   be first initialized by alloc_aux_for_blocks.  */
675

676
inline void
677
alloc_aux_for_block (basic_block bb, int size)
678
{
679 680 681 682 683
  /* Verify that aux field is clear.  */
  if (bb->aux || !first_block_aux_obj)
    abort ();
  bb->aux = obstack_alloc (&block_aux_obstack, size);
  memset (bb->aux, 0, size);
684 685
}

686 687
/* Initialize the block_aux_obstack and if SIZE is nonzero, call
   alloc_aux_for_block for each basic block.  */
688 689

void
690
alloc_aux_for_blocks (int size)
691
{
692
  static int initialized;
693

694
  if (!initialized)
695
    {
696 697
      gcc_obstack_init (&block_aux_obstack);
      initialized = 1;
698
    }
699

700 701 702
  /* Check whether AUX data are still allocated.  */
  else if (first_block_aux_obj)
    abort ();
703
  first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
704
  if (size)
705
    {
706
      basic_block bb;
707

708 709
      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
	alloc_aux_for_block (bb, size);
710 711
    }
}
712

713
/* Clear AUX pointers of all blocks.  */
714 715

void
716
clear_aux_for_blocks (void)
717
{
718
  basic_block bb;
719

720 721
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    bb->aux = NULL;
722 723 724 725 726 727
}

/* Free data allocated in block_aux_obstack and clear AUX pointers
   of all blocks.  */

void
728
free_aux_for_blocks (void)
729 730 731 732
{
  if (!first_block_aux_obj)
    abort ();
  obstack_free (&block_aux_obstack, first_block_aux_obj);
733
  first_block_aux_obj = NULL;
734 735

  clear_aux_for_blocks ();
736
}
737

738
/* Allocate a memory edge of SIZE as BB->aux.  The obstack must
739
   be first initialized by alloc_aux_for_edges.  */
740

741
inline void
742
alloc_aux_for_edge (edge e, int size)
743 744 745 746 747 748 749
{
  /* Verify that aux field is clear.  */
  if (e->aux || !first_edge_aux_obj)
    abort ();
  e->aux = obstack_alloc (&edge_aux_obstack, size);
  memset (e->aux, 0, size);
}
750

751 752
/* Initialize the edge_aux_obstack and if SIZE is nonzero, call
   alloc_aux_for_edge for each basic edge.  */
753

754
void
755
alloc_aux_for_edges (int size)
756 757
{
  static int initialized;
758

759 760 761 762
  if (!initialized)
    {
      gcc_obstack_init (&edge_aux_obstack);
      initialized = 1;
763
    }
764

765 766 767
  /* Check whether AUX data are still allocated.  */
  else if (first_edge_aux_obj)
    abort ();
768

769
  first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
770
  if (size)
771
    {
772 773 774
      basic_block bb;

      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
775
	{
776 777 778 779
	  edge e;

	  for (e = bb->succ; e; e = e->succ_next)
	    alloc_aux_for_edge (e, size);
780 781 782 783
	}
    }
}

784
/* Clear AUX pointers of all edges.  */
785 786

void
787
clear_aux_for_edges (void)
788
{
789 790
  basic_block bb;
  edge e;
791

792
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
793
    {
794 795
      for (e = bb->succ; e; e = e->succ_next)
	e->aux = NULL;
796
    }
797 798 799 800 801 802
}

/* Free data allocated in edge_aux_obstack and clear AUX pointers
   of all edges.  */

void
803
free_aux_for_edges (void)
804 805 806 807
{
  if (!first_edge_aux_obj)
    abort ();
  obstack_free (&edge_aux_obstack, first_edge_aux_obj);
808
  first_edge_aux_obj = NULL;
809 810

  clear_aux_for_edges ();
811
}
812

813 814
/* Verify the CFG consistency.

815 816
   Currently it does following checks edge and basic block list correctness
   and calls into IL dependent checking then.  */
817
void
818
verify_flow_info (void)
819
{
820 821 822 823 824
  size_t *edge_checksum;
  int num_bb_notes, err = 0;
  basic_block bb, last_bb_seen;
  basic_block *last_visited;

825 826
  last_visited = xcalloc (last_basic_block + 2, sizeof (basic_block));
  edge_checksum = xcalloc (last_basic_block + 2, sizeof (size_t));
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960

  /* Check bb chain & numbers.  */
  last_bb_seen = ENTRY_BLOCK_PTR;
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
    {
      if (bb != EXIT_BLOCK_PTR
	  && bb != BASIC_BLOCK (bb->index))
	{
	  error ("bb %d on wrong place", bb->index);
	  err = 1;
	}

      if (bb->prev_bb != last_bb_seen)
	{
	  error ("prev_bb of %d should be %d, not %d",
		 bb->index, last_bb_seen->index, bb->prev_bb->index);
	  err = 1;
	}

      last_bb_seen = bb;
    }

  /* Now check the basic blocks (boundaries etc.) */
  FOR_EACH_BB_REVERSE (bb)
    {
      int n_fallthru = 0;
      edge e;

      if (bb->count < 0)
	{
	  error ("verify_flow_info: Wrong count of block %i %i",
	         bb->index, (int)bb->count);
	  err = 1;
	}
      if (bb->frequency < 0)
	{
	  error ("verify_flow_info: Wrong frequency of block %i %i",
	         bb->index, bb->frequency);
	  err = 1;
	}
      for (e = bb->succ; e; e = e->succ_next)
	{
	  if (last_visited [e->dest->index + 2] == bb)
	    {
	      error ("verify_flow_info: Duplicate edge %i->%i",
		     e->src->index, e->dest->index);
	      err = 1;
	    }
	  if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
	    {
	      error ("verify_flow_info: Wrong probability of edge %i->%i %i",
		     e->src->index, e->dest->index, e->probability);
	      err = 1;
	    }
	  if (e->count < 0)
	    {
	      error ("verify_flow_info: Wrong count of edge %i->%i %i",
		     e->src->index, e->dest->index, (int)e->count);
	      err = 1;
	    }

	  last_visited [e->dest->index + 2] = bb;

	  if (e->flags & EDGE_FALLTHRU)
	    n_fallthru++;

	  if (e->src != bb)
	    {
	      error ("verify_flow_info: Basic block %d succ edge is corrupted",
		     bb->index);
	      fprintf (stderr, "Predecessor: ");
	      dump_edge_info (stderr, e, 0);
	      fprintf (stderr, "\nSuccessor: ");
	      dump_edge_info (stderr, e, 1);
	      fprintf (stderr, "\n");
	      err = 1;
	    }

	  edge_checksum[e->dest->index + 2] += (size_t) e;
	}
      if (n_fallthru > 1)
	{
	  error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
	  err = 1;
	}

      for (e = bb->pred; e; e = e->pred_next)
	{
	  if (e->dest != bb)
	    {
	      error ("basic block %d pred edge is corrupted", bb->index);
	      fputs ("Predecessor: ", stderr);
	      dump_edge_info (stderr, e, 0);
	      fputs ("\nSuccessor: ", stderr);
	      dump_edge_info (stderr, e, 1);
	      fputc ('\n', stderr);
	      err = 1;
	    }
	  edge_checksum[e->dest->index + 2] -= (size_t) e;
	}
    }

  /* Complete edge checksumming for ENTRY and EXIT.  */
  {
    edge e;

    for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
      edge_checksum[e->dest->index + 2] += (size_t) e;

    for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
      edge_checksum[e->dest->index + 2] -= (size_t) e;
  }

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    if (edge_checksum[bb->index + 2])
      {
	error ("basic block %i edge lists are corrupted", bb->index);
	err = 1;
      }

  num_bb_notes = 0;
  last_bb_seen = ENTRY_BLOCK_PTR;

  /* Clean up.  */
  free (last_visited);
  free (edge_checksum);
  err |= cfg_hooks->cfgh_verify_flow_info ();
  if (err)
    internal_error ("verify_flow_info failed");
}

/* Print out one basic block with live information at start and end.  */

void
961
dump_bb (basic_block bb, FILE *outf)
962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
{
  edge e;

  fprintf (outf, ";; Basic block %d, loop depth %d, count ",
	   bb->index, bb->loop_depth);
  fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
  putc ('\n', outf);

  cfg_hooks->dump_bb (bb, outf);

  fputs (";; Successors: ", outf);
  for (e = bb->succ; e; e = e->succ_next)
    dump_edge_info (outf, e, 1);
  putc ('\n', outf);
}

void
979
debug_bb (basic_block bb)
980 981 982 983 984
{
  dump_bb (bb, stderr);
}

basic_block
985
debug_bb_n (int n)
986 987 988 989
{
  basic_block bb = BASIC_BLOCK (n);
  dump_bb (bb, stderr);
  return bb;
990
}