/* Control flow graph manipulation code for GNU compiler.
   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2001, 2002, 2003, 2004, 2005
   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.  */

/* This file contains low level functions to manipulate the CFG and
   analyze it.  All other modules should not transform the data structure
   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).

   Available functionality:
     - Initialization/deallocation
	 init_flow, clear_edges
     - Low level basic block manipulation
	 alloc_block, expunge_block
     - Edge manipulation
	 make_edge, make_single_succ_edge, cached_make_edge, remove_edge
	 - Low level edge redirection (without updating instruction chain)
	     redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
     - Dumping and debugging
	 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
     - clear_bb_flags
     - Consistency checking
	 verify_flow_info
     - Dumping and debugging
	 print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
 */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "regs.h"
#include "flags.h"
#include "output.h"
#include "function.h"
#include "except.h"
#include "toplev.h"
#include "tm_p.h"
#include "alloc-pool.h"
#include "timevar.h"
#include "ggc.h"

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

struct bitmap_obstack reg_obstack;

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

int n_basic_blocks;

/* First free basic block number.  */

int last_basic_block;

/* 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.  */
basic_block ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR;

/* Memory alloc pool for bb member rbi.  */
alloc_pool rbi_pool;

void debug_flow_info (void);
static void free_edge (edge);

/* Indicate the presence of the profile.  */
enum profile_status profile_status;

/* Called once at initialization time.  */

void
init_flow (void)
{
  n_edges = 0;

  ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (*ENTRY_BLOCK_PTR));
  ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
  EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (*EXIT_BLOCK_PTR));
  EXIT_BLOCK_PTR->index = EXIT_BLOCK;
  ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
  EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
}

/* Helper function for remove_edge and clear_edges.  Frees edge structure
   without actually unlinking it from the pred/succ lists.  */

static void
free_edge (edge e ATTRIBUTE_UNUSED)
{
  n_edges--;
  ggc_free (e);
}

/* Free the memory associated with the edge structures.  */

void
clear_edges (void)
{
  basic_block bb;
  edge e;
  edge_iterator ei;

  FOR_EACH_BB (bb)
    {
      FOR_EACH_EDGE (e, ei, bb->succs)
	free_edge (e);
      VEC_truncate (edge, bb->succs, 0);
      VEC_truncate (edge, bb->preds, 0);
    }

  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
    free_edge (e);
  VEC_truncate (edge, EXIT_BLOCK_PTR->preds, 0);
  VEC_truncate (edge, ENTRY_BLOCK_PTR->succs, 0);

  gcc_assert (!n_edges);
}

/* Allocate memory for basic_block.  */

basic_block
alloc_block (void)
{
  basic_block bb;
  bb = ggc_alloc_cleared (sizeof (*bb));
  return bb;
}

/* Create memory pool for rbi_pool.  */

void
alloc_rbi_pool (void)
{
  rbi_pool = create_alloc_pool ("rbi pool", 
				sizeof (struct reorder_block_def),
				n_basic_blocks + 2);
}

/* Free rbi_pool.  */

void
free_rbi_pool (void)
{
  free_alloc_pool (rbi_pool);
}

/* Initialize rbi (the structure containing data used by basic block
   duplication and reordering) for the given basic block.  */

void
initialize_bb_rbi (basic_block bb)
{
  gcc_assert (!bb->rbi);
  bb->rbi = pool_alloc (rbi_pool);
  memset (bb->rbi, 0, sizeof (struct reorder_block_def));
}

/* Link block B to chain after AFTER.  */
void
link_block (basic_block b, basic_block after)
{
  b->next_bb = after->next_bb;
  b->prev_bb = after;
  after->next_bb = b;
  b->next_bb->prev_bb = b;
}

/* Unlink block B from chain.  */
void
unlink_block (basic_block b)
{
  b->next_bb->prev_bb = b->prev_bb;
  b->prev_bb->next_bb = b->next_bb;
  b->prev_bb = NULL;
  b->next_bb = NULL;
}

/* Sequentially order blocks and compact the arrays.  */
void
compact_blocks (void)
{
  int i;
  basic_block bb;

  i = 0;
  FOR_EACH_BB (bb)
    {
      BASIC_BLOCK (i) = bb;
      bb->index = i;
      i++;
    }

  gcc_assert (i == n_basic_blocks);

  for (; i < last_basic_block; i++)
    BASIC_BLOCK (i) = NULL;

  last_basic_block = n_basic_blocks;
}

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

void
expunge_block (basic_block b)
{
  unlink_block (b);
  BASIC_BLOCK (b->index) = NULL;
  n_basic_blocks--;
  /* We should be able to ggc_free here, but we are not.
     The dead SSA_NAMES are left pointing to dead statements that are pointing
     to dead basic blocks making garbage collector to die.
     We should be able to release all dead SSA_NAMES and at the same time we should
     clear out BB pointer of dead statements consistently.  */
}

/* 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
unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
  edge e;
  e = ggc_alloc_cleared (sizeof (*e));
  n_edges++;

  VEC_safe_push (edge, src->succs, e);
  VEC_safe_push (edge, dst->preds, e);

  e->src = src;
  e->dest = dst;
  e->flags = flags;
  e->dest_idx = EDGE_COUNT (dst->preds) - 1;

  execute_on_growing_pred (e);

  return e;
}

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

edge
cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int flags)
{
  if (edge_cache == NULL
      || src == ENTRY_BLOCK_PTR
      || dst == EXIT_BLOCK_PTR)
    return make_edge (src, dst, flags);

  /* Does the requested edge already exist?  */
  if (! TEST_BIT (edge_cache[src->index], dst->index))
    {
      /* The edge does not exist.  Create one and update the
	 cache.  */
      SET_BIT (edge_cache[src->index], dst->index);
      return unchecked_make_edge (src, dst, flags);
    }

  /* At this point, we know that the requested edge exists.  Adjust
     flags if necessary.  */
  if (flags)
    {
      edge e = find_edge (src, dst);
      e->flags |= flags;
    }

  return NULL;
}

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

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

  /* Make sure we don't add duplicate edges.  */
  if (e)
    {
      e->flags |= flags;
      return NULL;
    }

  return unchecked_make_edge (src, dest, flags);
}

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

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

  e->probability = REG_BR_PROB_BASE;
  e->count = src->count;
  return e;
}

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

void
remove_edge (edge e)
{
  edge tmp;
  basic_block src, dest;
  unsigned int dest_idx;
  bool found = false;
  edge_iterator ei;

  execute_on_shrinking_pred (e);

  src = e->src;
  dest = e->dest;
  dest_idx = e->dest_idx;

  for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
    {
      if (tmp == e)
	{
	  VEC_unordered_remove (edge, src->succs, ei.index);
	  found = true;
	  break;
	}
      else
	ei_next (&ei);
    }

  gcc_assert (found);

  VEC_unordered_remove (edge, dest->preds, dest_idx);

  /* If we removed an edge in the middle of the edge vector, we need
     to update dest_idx of the edge that moved into the "hole".  */
  if (dest_idx < EDGE_COUNT (dest->preds))
    EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;

  free_edge (e);
}

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

void
redirect_edge_succ (edge e, basic_block new_succ)
{
  basic_block dest = e->dest;
  unsigned int dest_idx = e->dest_idx;

  execute_on_shrinking_pred (e);

  VEC_unordered_remove (edge, dest->preds, dest_idx);

  /* If we removed an edge in the middle of the edge vector, we need
     to update dest_idx of the edge that moved into the "hole".  */
  if (dest_idx < EDGE_COUNT (dest->preds))
    EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;

  /* Reconnect the edge to the new successor block.  */
  VEC_safe_push (edge, new_succ->preds, e);
  e->dest = new_succ;
  e->dest_idx = EDGE_COUNT (new_succ->preds) - 1;
  execute_on_growing_pred (e);
}

/* Like previous but avoid possible duplicate edge.  */

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

  s = find_edge (e->src, new_succ);
  if (s && s != e)
    {
      s->flags |= e->flags;
      s->probability += e->probability;
      if (s->probability > REG_BR_PROB_BASE)
	s->probability = REG_BR_PROB_BASE;
      s->count += e->count;
      remove_edge (e);
      e = s;
    }
  else
    redirect_edge_succ (e, new_succ);

  return e;
}

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

void
redirect_edge_pred (edge e, basic_block new_pred)
{
  edge tmp;
  edge_iterator ei;
  bool found = false;

  /* Disconnect the edge from the old predecessor block.  */
  for (ei = ei_start (e->src->succs); (tmp = ei_safe_edge (ei)); )
    {
      if (tmp == e)
	{
	  VEC_unordered_remove (edge, e->src->succs, ei.index);
	  found = true;
	  break;
	}
      else
	ei_next (&ei);
    }

  gcc_assert (found);

  /* Reconnect the edge to the new predecessor block.  */
  VEC_safe_push (edge, new_pred->succs, e);
  e->src = new_pred;
}

/* Clear all basic block flags, with the exception of partitioning.  */
void
clear_bb_flags (void)
{
  basic_block bb;

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    bb->flags = BB_PARTITION (bb);
}

/* Check the consistency of profile information.  We can't do that
   in verify_flow_info, as the counts may get invalid for incompletely
   solved graphs, later eliminating of conditionals or roundoff errors.
   It is still practical to have them reported for debugging of simple
   testcases.  */
void
check_bb_profile (basic_block bb, FILE * file)
{
  edge e;
  int sum = 0;
  gcov_type lsum;
  edge_iterator ei;

  if (profile_status == PROFILE_ABSENT)
    return;

  if (bb != EXIT_BLOCK_PTR)
    {
      FOR_EACH_EDGE (e, ei, bb->succs)
	sum += e->probability;
      if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
	fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
		 sum * 100.0 / REG_BR_PROB_BASE);
      lsum = 0;
      FOR_EACH_EDGE (e, ei, bb->succs)
	lsum += e->count;
      if (EDGE_COUNT (bb->succs)
	  && (lsum - bb->count > 100 || lsum - bb->count < -100))
	fprintf (file, "Invalid sum of outgoing counts %i, should be %i\n",
		 (int) lsum, (int) bb->count);
    }
  if (bb != ENTRY_BLOCK_PTR)
    {
      sum = 0;
      FOR_EACH_EDGE (e, ei, bb->preds)
	sum += EDGE_FREQUENCY (e);
      if (abs (sum - bb->frequency) > 100)
	fprintf (file,
		 "Invalid sum of incoming frequencies %i, should be %i\n",
		 sum, bb->frequency);
      lsum = 0;
      FOR_EACH_EDGE (e, ei, bb->preds)
	lsum += e->count;
      if (lsum - bb->count > 100 || lsum - bb->count < -100)
	fprintf (file, "Invalid sum of incoming counts %i, should be %i\n",
		 (int) lsum, (int) bb->count);
    }
}

void
dump_flow_info (FILE *file)
{
  int i;
  basic_block bb;

  /* There are no pseudo registers after reload.  Don't dump them.  */
  if (reg_n_info && !reload_completed)
    {
      int max_regno = max_reg_num ();
      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;

	    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");
	  }
    }

  fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
  FOR_EACH_BB (bb)
    {
      edge e;
      edge_iterator ei;

      fprintf (file, "\nBasic block %d ", bb->index);
      fprintf (file, "prev %d, next %d, ",
	       bb->prev_bb->index, bb->next_bb->index);
      fprintf (file, "loop_depth %d, count ", bb->loop_depth);
      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
      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");
      fprintf (file, ".\n");

      fprintf (file, "Predecessors: ");
      FOR_EACH_EDGE (e, ei, bb->preds)
	dump_edge_info (file, e, 0);

      fprintf (file, "\nSuccessors: ");
      FOR_EACH_EDGE (e, ei, bb->succs)
	dump_edge_info (file, e, 1);

      if (bb->global_live_at_start)
	{
	  fprintf (file, "\nRegisters live at start:");
	  dump_regset (bb->global_live_at_start, file);
	}

      if (bb->global_live_at_end)
	{
	  fprintf (file, "\nRegisters live at end:");
	  dump_regset (bb->global_live_at_end, file);
	}

      putc ('\n', file);
      check_bb_profile (bb, file);
    }

  putc ('\n', file);
}

void
debug_flow_info (void)
{
  dump_flow_info (stderr);
}

void
dump_edge_info (FILE *file, edge e, int do_succ)
{
  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);

  if (e->count)
    {
      fprintf (file, " count:");
      fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
    }

  if (e->flags)
    {
      static const char * const bitnames[] = {
	"fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
	"can_fallthru", "irreducible", "sibcall", "loop_exit",
	"true", "false", "exec"
      };
      int comma = 0;
      int i, flags = e->flags;

      fputs (" (", file);
      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;
	  }

      fputc (')', file);
    }
}

/* Simple routines to easily allocate AUX fields of basic blocks.  */

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;

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

inline void
alloc_aux_for_block (basic_block bb, int size)
{
  /* Verify that aux field is clear.  */
  gcc_assert (!bb->aux && first_block_aux_obj);
  bb->aux = obstack_alloc (&block_aux_obstack, size);
  memset (bb->aux, 0, size);
}

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

void
alloc_aux_for_blocks (int size)
{
  static int initialized;

  if (!initialized)
    {
      gcc_obstack_init (&block_aux_obstack);
      initialized = 1;
    }
  else
    /* Check whether AUX data are still allocated.  */
    gcc_assert (!first_block_aux_obj);
  
  first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
  if (size)
    {
      basic_block bb;

      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
	alloc_aux_for_block (bb, size);
    }
}

/* Clear AUX pointers of all blocks.  */

void
clear_aux_for_blocks (void)
{
  basic_block bb;

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    bb->aux = NULL;
}

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

void
free_aux_for_blocks (void)
{
  gcc_assert (first_block_aux_obj);
  obstack_free (&block_aux_obstack, first_block_aux_obj);
  first_block_aux_obj = NULL;

  clear_aux_for_blocks ();
}

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

inline void
alloc_aux_for_edge (edge e, int size)
{
  /* Verify that aux field is clear.  */
  gcc_assert (!e->aux && first_edge_aux_obj);
  e->aux = obstack_alloc (&edge_aux_obstack, size);
  memset (e->aux, 0, size);
}

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

void
alloc_aux_for_edges (int size)
{
  static int initialized;

  if (!initialized)
    {
      gcc_obstack_init (&edge_aux_obstack);
      initialized = 1;
    }
  else
    /* Check whether AUX data are still allocated.  */
    gcc_assert (!first_edge_aux_obj);

  first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
  if (size)
    {
      basic_block bb;

      FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
	{
	  edge e;
	  edge_iterator ei;

	  FOR_EACH_EDGE (e, ei, bb->succs)
	    alloc_aux_for_edge (e, size);
	}
    }
}

/* Clear AUX pointers of all edges.  */

void
clear_aux_for_edges (void)
{
  basic_block bb;
  edge e;

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
    {
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->succs)
	e->aux = NULL;
    }
}

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

void
free_aux_for_edges (void)
{
  gcc_assert (first_edge_aux_obj);
  obstack_free (&edge_aux_obstack, first_edge_aux_obj);
  first_edge_aux_obj = NULL;

  clear_aux_for_edges ();
}

void
debug_bb (basic_block bb)
{
  dump_bb (bb, stderr, 0);
}

basic_block
debug_bb_n (int n)
{
  basic_block bb = BASIC_BLOCK (n);
  dump_bb (bb, stderr, 0);
  return bb;
}

/* Dumps cfg related information about basic block BB to FILE.  */

static void
dump_cfg_bb_info (FILE *file, basic_block bb)
{
  unsigned i;
  edge_iterator ei;
  bool first = true;
  static const char * const bb_bitnames[] =
    {
      "dirty", "new", "reachable", "visited", "irreducible_loop", "superblock"
    };
  const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *);
  edge e;

  fprintf (file, "Basic block %d", bb->index);
  for (i = 0; i < n_bitnames; i++)
    if (bb->flags & (1 << i))
      {
	if (first)
	  fprintf (file, " (");
	else
	  fprintf (file, ", ");
	first = false;
	fprintf (file, bb_bitnames[i]);
      }
  if (!first)
    fprintf (file, ")");
  fprintf (file, "\n");

  fprintf (file, "Predecessors: ");
  FOR_EACH_EDGE (e, ei, bb->preds)
    dump_edge_info (file, e, 0);

  fprintf (file, "\nSuccessors: ");
  FOR_EACH_EDGE (e, ei, bb->succs)
    dump_edge_info (file, e, 1);
  fprintf (file, "\n\n");
}

/* Dumps a brief description of cfg to FILE.  */

void
brief_dump_cfg (FILE *file)
{
  basic_block bb;

  FOR_EACH_BB (bb)
    {
      dump_cfg_bb_info (file, bb);
    }
}

/* An edge originally destinating BB of FREQUENCY and COUNT has been proved to
   leave the block by TAKEN_EDGE.  Update profile of BB such that edge E can be
   redirected to destination of TAKEN_EDGE. 

   This function may leave the profile inconsistent in the case TAKEN_EDGE
   frequency or count is believed to be lower than FREQUENCY or COUNT
   respectively.  */
void
update_bb_profile_for_threading (basic_block bb, int edge_frequency,
				 gcov_type count, edge taken_edge)
{
  edge c;
  int prob;
  edge_iterator ei;

  bb->count -= count;
  if (bb->count < 0)
    bb->count = 0;

  /* Compute the probability of TAKEN_EDGE being reached via threaded edge.
     Watch for overflows.  */
  if (bb->frequency)
    prob = edge_frequency * REG_BR_PROB_BASE / bb->frequency;
  else
    prob = 0;
  if (prob > taken_edge->probability)
    {
      if (dump_file)
	fprintf (dump_file, "Jump threading proved probability of edge "
		 "%i->%i too small (it is %i, should be %i).\n",
		 taken_edge->src->index, taken_edge->dest->index,
		 taken_edge->probability, prob);
      prob = taken_edge->probability;
    }

  /* Now rescale the probabilities.  */
  taken_edge->probability -= prob;
  prob = REG_BR_PROB_BASE - prob;
  bb->frequency -= edge_frequency;
  if (bb->frequency < 0)
    bb->frequency = 0;
  if (prob <= 0)
    {
      if (dump_file)
	fprintf (dump_file, "Edge frequencies of bb %i has been reset, "
		 "frequency of block should end up being 0, it is %i\n",
		 bb->index, bb->frequency);
      EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
      ei = ei_start (bb->succs);
      ei_next (&ei);
      for (; (c = ei_safe_edge (ei)); ei_next (&ei))
	c->probability = 0;
    }
  else if (prob != REG_BR_PROB_BASE)
    {
      int scale = REG_BR_PROB_BASE / prob;

      FOR_EACH_EDGE (c, ei, bb->succs)
	c->probability *= scale;
    }

  if (bb != taken_edge->src)
    abort ();
  taken_edge->count -= count;
  if (taken_edge->count < 0)
    taken_edge->count = 0;
}
