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

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 23 24 25 26
/* This file contains low level functions to manipulate the CFG and
   analyze it.  All other modules should not transform the datastructure
   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 42 43 44 45 46 47 48 49 50 51 52 53 54
 */

#include "config.h"
#include "system.h"
#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"
55
#include "tm_p.h"
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
#include "obstack.h"

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

struct obstack flow_obstack;
static char *flow_firstobj;

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

int n_basic_blocks;

/* Number of edges in the current function.  */

int n_edges;

71 72 73
/* First edge in the deleted edges chain.  */

edge first_deleted_edge;
74
static basic_block first_deleted_block;
75

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
/* 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 */
    0,				/* loop_depth */
    0,				/* count */
    0,				/* frequency */
    0				/* flags */
  },
  {
    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 */
    0,				/* loop_depth */
    0,				/* count */
    0,				/* frequency */
    0				/* flags */
  }
};

void debug_flow_info			PARAMS ((void));
121
static void free_edge			PARAMS ((edge));
122

123
/* Called once at initialization time.  */
124 125 126 127 128 129

void
init_flow ()
{
  static int initialized;

130
  first_deleted_edge = 0;
131
  first_deleted_block = 0;
132 133
  n_edges = 0;

134 135 136 137 138 139 140 141 142 143 144 145 146
  if (!initialized)
    {
      gcc_obstack_init (&flow_obstack);
      flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
      initialized = 1;
    }
  else
    {
      obstack_free (&flow_obstack, flow_firstobj);
      flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
    }
}

147 148 149 150 151 152 153 154
/* Helper function for remove_edge and clear_edges.  Frees edge structure
   without actually unlinking it from the pred/succ lists.  */

static void
free_edge (e)
     edge e;
{
  n_edges--;
155
  memset (e, 0, sizeof *e);
156 157 158 159
  e->succ_next = first_deleted_edge;
  first_deleted_edge = e;
}

160 161 162 163 164 165
/* Free the memory associated with the edge structures.  */

void
clear_edges ()
{
  int i;
166
  edge e;
167 168 169 170

  for (i = 0; i < n_basic_blocks; ++i)
    {
      basic_block bb = BASIC_BLOCK (i);
171
      edge e = bb->succ;
172

173 174 175 176 177 178 179
      while (e)
	{
	  edge next = e->succ_next;

	  free_edge (e);
	  e = next;
	}
180

181 182
      bb->succ = NULL;
      bb->pred = NULL;
183 184
    }

185 186 187 188 189 190 191 192
  e = ENTRY_BLOCK_PTR->succ;
  while (e)
    {
      edge next = e->succ_next;

      free_edge (e);
      e = next;
    }
193

194 195
  EXIT_BLOCK_PTR->pred = NULL;
  ENTRY_BLOCK_PTR->succ = NULL;
196

197 198
  if (n_edges)
    abort ();
199 200
}

201
/* Allocate memory for basic_block.  */
202

203
basic_block
204
alloc_block ()
205 206 207
{
  basic_block bb;

208
  if (first_deleted_block)
209
    {
210 211 212
      bb = first_deleted_block;
      first_deleted_block = (basic_block) bb->succ;
      bb->succ = NULL;
213 214 215
    }
  else
    {
216 217
      bb = (basic_block) obstack_alloc (&flow_obstack, sizeof *bb);
      memset (bb, 0, sizeof *bb);
218 219
    }
  return bb;
220 221 222 223
}

/* Remove block B from the basic block array and compact behind it.  */

224
void
225 226 227 228 229 230 231 232 233 234 235 236
expunge_block (b)
     basic_block b;
{
  int i, n = n_basic_blocks;

  for (i = b->index; i + 1 < n; ++i)
    {
      basic_block x = BASIC_BLOCK (i + 1);
      BASIC_BLOCK (i) = x;
      x->index = i;
    }

237
  /* Invalidate data to make bughunting easier.  */
238
  memset (b, 0, sizeof *b);
239
  b->index = -3;
240 241
  basic_block_info->num_elements--;
  n_basic_blocks--;
242 243
  b->succ = (edge) first_deleted_block;
  first_deleted_block = (basic_block) b;
244 245
}

246
/* Create an edge connecting SRC and DST with FLAGS optionally using
247
   edge cache CACHE.  Return the new edge, NULL if already exist.  */
248

249 250
edge
cached_make_edge (edge_cache, src, dst, flags)
251 252 253 254 255 256 257
     sbitmap *edge_cache;
     basic_block src, dst;
     int flags;
{
  int use_edge_cache;
  edge e;

258 259
  /* 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.  */
260
  use_edge_cache = (edge_cache
261
		    && src != ENTRY_BLOCK_PTR && dst != EXIT_BLOCK_PTR);
262 263 264 265 266

  /* Make sure we don't add duplicate edges.  */
  switch (use_edge_cache)
    {
    default:
267
      /* Quick test for non-existence of the edge.  */
268 269 270 271 272
      if (! TEST_BIT (edge_cache[src->index], dst->index))
	break;

      /* The edge exists; early exit if no work to do.  */
      if (flags == 0)
273
	return NULL;
274 275 276 277 278 279 280

      /* FALLTHRU */
    case 0:
      for (e = src->succ; e; e = e->succ_next)
	if (e->dest == dst)
	  {
	    e->flags |= flags;
281
	    return NULL;
282 283 284 285
	  }
      break;
    }

286 287 288 289 290 291 292
  if (first_deleted_edge)
    {
      e = first_deleted_edge;
      first_deleted_edge = e->succ_next;
    }
  else
    {
293 294
      e = (edge) obstack_alloc (&flow_obstack, sizeof *e);
      memset (e, 0, sizeof *e);
295
    }
296 297 298 299 300 301 302 303 304 305 306 307 308
  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;

  if (use_edge_cache)
    SET_BIT (edge_cache[src->index], dst->index);
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323

  return e;
}

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

edge
make_edge (src, dest, flags)
     basic_block src, dest;
     int flags;
{
  return cached_make_edge (NULL, src, dest, flags);
}

324
/* Create an edge connecting SRC to DEST and set probability by knowing
325 326 327 328 329 330 331 332 333 334 335 336
   that it is the single edge leaving SRC.  */

edge
make_single_succ_edge (src, dest, flags)
     basic_block src, dest;
     int flags;
{
  edge e = make_edge (src, dest, flags);

  e->probability = REG_BR_PROB_BASE;
  e->count = src->count;
  return e;
337 338 339 340 341 342 343 344 345 346 347 348
}

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

void
remove_edge (e)
     edge e;
{
  edge last_pred = NULL;
  edge last_succ = NULL;
  edge tmp;
  basic_block src, dest;
349

350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
  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;

372
  free_edge (e);
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
}

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

void
redirect_edge_succ (e, new_succ)
     edge e;
     basic_block new_succ;
{
  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;
}

395
/* Like previous but avoid possible duplicate edge.  */
396 397 398 399 400 401 402

edge
redirect_edge_succ_nodup (e, new_succ)
     edge e;
     basic_block new_succ;
{
  edge s;
403

404 405 406 407
  /* 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;
408

409 410 411 412 413 414 415 416 417 418
  if (s)
    {
      s->flags |= e->flags;
      s->probability += e->probability;
      s->count += e->count;
      remove_edge (e);
      e = s;
    }
  else
    redirect_edge_succ (e, new_succ);
419

420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
  return e;
}

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

void
redirect_edge_pred (e, new_pred)
     edge e;
     basic_block new_pred;
{
  edge *pe;

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

436 437 438 439 440 441 442 443
  *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;
}

444 445 446
void
dump_flow_info (file)
     FILE *file;
447
{
448
  int i;
449 450 451 452 453 454 455
  static const char * const reg_class_names[] = REG_CLASS_NAMES;

  fprintf (file, "%d registers.\n", max_regno);
  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
    if (REG_N_REFS (i))
      {
	enum reg_class class, altclass;
456

457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
	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 (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 (PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
	  fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
474

475 476 477 478 479 480 481 482 483 484 485 486 487
	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]);
	  }
488

489 490 491 492 493 494 495 496
	if (REG_POINTER (regno_reg_rtx[i]))
	  fprintf (file, "; pointer");
	fprintf (file, ".\n");
      }

  fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
  for (i = 0; i < n_basic_blocks; i++)
    {
497 498
      basic_block bb = BASIC_BLOCK (i);
      edge e;
499

500 501 502 503
      fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
	       i, INSN_UID (bb->head), INSN_UID (bb->end));
      fprintf (file, "loop_depth %d, count ", bb->loop_depth);
      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
504
      fprintf (file, ", freq %i.\n", bb->frequency);
505

506 507 508
      fprintf (file, "Predecessors: ");
      for (e = bb->pred; e; e = e->pred_next)
	dump_edge_info (file, e, 0);
509

510 511 512
      fprintf (file, "\nSuccessors: ");
      for (e = bb->succ; e; e = e->succ_next)
	dump_edge_info (file, e, 1);
513

514 515
      fprintf (file, "\nRegisters live at start:");
      dump_regset (bb->global_live_at_start, file);
516

517 518
      fprintf (file, "\nRegisters live at end:");
      dump_regset (bb->global_live_at_end, file);
519

520
      putc ('\n', file);
521 522
    }

523
  putc ('\n', file);
524 525
}

526 527 528 529 530
void
debug_flow_info ()
{
  dump_flow_info (stderr);
}
531 532

void
533 534 535 536
dump_edge_info (file, e, do_succ)
     FILE *file;
     edge e;
     int do_succ;
537
{
538 539 540 541 542 543 544 545 546 547 548
  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
    fprintf (file, " %d", side->index);

  if (e->probability)
    fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE);
549

550
  if (e->count)
551
    {
552
      fprintf (file, " count:");
553
      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
554 555
    }

556
  if (e->flags)
557
    {
558 559
      static const char * const bitnames[]
	= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back"};
560 561
      int comma = 0;
      int i, flags = e->flags;
562

563
      fputs (" (", file);
564 565 566 567 568 569 570 571 572 573 574 575 576
      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;
	  }
577

578 579 580 581
      fputc (')', file);
    }
}

582
/* Simple routines to easily allocate AUX fields of basic blocks.  */
583

584 585 586 587
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;
588

589 590
/* Allocate an memory block of SIZE as BB->aux.  The obstack must
   be first initialized by alloc_aux_for_blocks.  */
591

592 593
inline void
alloc_aux_for_block (bb, size)
594
     basic_block bb;
595
     int size;
596
{
597 598 599 600 601
  /* 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);
602 603
}

604 605
/* Initialize the block_aux_obstack and if SIZE is nonzero, call
   alloc_aux_for_block for each basic block.  */
606 607

void
608 609
alloc_aux_for_blocks (size)
     int size;
610
{
611
  static int initialized;
612

613
  if (!initialized)
614
    {
615 616
      gcc_obstack_init (&block_aux_obstack);
      initialized = 1;
617
    }
618

619 620 621 622 623
  /* Check whether AUX data are still allocated.  */
  else if (first_block_aux_obj)
    abort ();
  first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
  if (size)
624
    {
625
      int i;
626

627 628
      for (i = 0; i < n_basic_blocks; i++)
	alloc_aux_for_block (BASIC_BLOCK (i), size);
629

630 631
      alloc_aux_for_block (ENTRY_BLOCK_PTR, size);
      alloc_aux_for_block (EXIT_BLOCK_PTR, size);
632 633
    }
}
634

635
/* Clear AUX pointers of all blocks.  */
636 637

void
638
clear_aux_for_blocks ()
639
{
640
  int i;
641

642 643
  for (i = 0; i < n_basic_blocks; i++)
    BASIC_BLOCK (i)->aux = NULL;
644

645 646
  ENTRY_BLOCK_PTR->aux = NULL;
  EXIT_BLOCK_PTR->aux = NULL;
647 648 649 650 651 652 653 654 655 656 657
}

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

void
free_aux_for_blocks ()
{
  if (!first_block_aux_obj)
    abort ();
  obstack_free (&block_aux_obstack, first_block_aux_obj);
658
  first_block_aux_obj = NULL;
659 660

  clear_aux_for_blocks ();
661
}
662

663 664
/* Allocate an memory edge of SIZE as BB->aux.  The obstack must
   be first initialized by alloc_aux_for_edges.  */
665

666 667 668 669 670 671 672 673 674 675 676
inline void
alloc_aux_for_edge (e, size)
     edge e;
     int size;
{
  /* 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);
}
677

678 679
/* Initialize the edge_aux_obstack and if SIZE is nonzero, call
   alloc_aux_for_edge for each basic edge.  */
680

681 682 683 684 685
void
alloc_aux_for_edges (size)
     int size;
{
  static int initialized;
686

687 688 689 690
  if (!initialized)
    {
      gcc_obstack_init (&edge_aux_obstack);
      initialized = 1;
691
    }
692

693 694 695
  /* Check whether AUX data are still allocated.  */
  else if (first_edge_aux_obj)
    abort ();
696

697 698
  first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
  if (size)
699
    {
700 701
      int i;
      for (i = -1; i < n_basic_blocks; i++)
702
	{
703 704 705 706 707 708 709
	  basic_block bb;
	  edge e;

	  if (i >= 0)
	    bb = BASIC_BLOCK (i);
	  else
	    bb = ENTRY_BLOCK_PTR;
710

711 712
	  for (e = bb->succ; e; e = e->succ_next)
	    alloc_aux_for_edge (e, size);
713 714 715 716
	}
    }
}

717
/* Clear AUX pointers of all edges.  */
718 719

void
720
clear_aux_for_edges ()
721
{
722
  int i;
723

724
  for (i = -1; i < n_basic_blocks; i++)
725
    {
726 727
      basic_block bb;
      edge e;
728

729 730 731 732
      if (i >= 0)
	bb = BASIC_BLOCK (i);
      else
	bb = ENTRY_BLOCK_PTR;
733

734 735
      for (e = bb->succ; e; e = e->succ_next)
	e->aux = NULL;
736
    }
737 738 739 740 741 742 743 744 745 746 747
}

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

void
free_aux_for_edges ()
{
  if (!first_edge_aux_obj)
    abort ();
  obstack_free (&edge_aux_obstack, first_edge_aux_obj);
748
  first_edge_aux_obj = NULL;
749 750

  clear_aux_for_edges ();
751
}