/* Data flow analysis 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 the data flow analysis pass of the compiler.  It
   computes data flow information which tells combine_instructions
   which insns to consider combining and controls register allocation.

   Additional data flow information that is too bulky to record is
   generated during the analysis, and is used at that time to create
   autoincrement and autodecrement addressing.

   The first step is dividing the function into basic blocks.
   find_basic_blocks does this.  Then life_analysis determines
   where each register is live and where it is dead.

   ** find_basic_blocks **

   find_basic_blocks divides the current function's rtl into basic
   blocks and constructs the CFG.  The blocks are recorded in the
   basic_block_info array; the CFG exists in the edge structures
   referenced by the blocks.

   find_basic_blocks also finds any unreachable loops and deletes them.

   ** life_analysis **

   life_analysis is called immediately after find_basic_blocks.
   It uses the basic block information to determine where each
   hard or pseudo register is live.

   ** live-register info **

   The information about where each register is live is in two parts:
   the REG_NOTES of insns, and the vector basic_block->global_live_at_start.

   basic_block->global_live_at_start has an element for each basic
   block, and the element is a bit-vector with a bit for each hard or
   pseudo register.  The bit is 1 if the register is live at the
   beginning of the basic block.

   Two types of elements can be added to an insn's REG_NOTES.
   A REG_DEAD note is added to an insn's REG_NOTES for any register
   that meets both of two conditions:  The value in the register is not
   needed in subsequent insns and the insn does not replace the value in
   the register (in the case of multi-word hard registers, the value in
   each register must be replaced by the insn to avoid a REG_DEAD note).

   In the vast majority of cases, an object in a REG_DEAD note will be
   used somewhere in the insn.  The (rare) exception to this is if an
   insn uses a multi-word hard register and only some of the registers are
   needed in subsequent insns.  In that case, REG_DEAD notes will be
   provided for those hard registers that are not subsequently needed.
   Partial REG_DEAD notes of this type do not occur when an insn sets
   only some of the hard registers used in such a multi-word operand;
   omitting REG_DEAD notes for objects stored in an insn is optional and
   the desire to do so does not justify the complexity of the partial
   REG_DEAD notes.

   REG_UNUSED notes are added for each register that is set by the insn
   but is unused subsequently (if every register set by the insn is unused
   and the insn does not reference memory or have some other side-effect,
   the insn is deleted instead).  If only part of a multi-word hard
   register is used in a subsequent insn, REG_UNUSED notes are made for
   the parts that will not be used.

   To determine which registers are live after any insn, one can
   start from the beginning of the basic block and scan insns, noting
   which registers are set by each insn and which die there.

   ** Other actions of life_analysis **

   life_analysis sets up the LOG_LINKS fields of insns because the
   information needed to do so is readily available.

   life_analysis deletes insns whose only effect is to store a value
   that is never used.

   life_analysis notices cases where a reference to a register as
   a memory address can be combined with a preceding or following
   incrementation or decrementation of the register.  The separate
   instruction to increment or decrement is deleted and the address
   is changed to a POST_INC or similar rtx.

   Each time an incrementing or decrementing address is created,
   a REG_INC element is added to the insn's REG_NOTES list.

   life_analysis fills in certain vectors containing information about
   register usage: REG_N_REFS, REG_N_DEATHS, REG_N_SETS, REG_LIVE_LENGTH,
   REG_N_CALLS_CROSSED and REG_BASIC_BLOCK.

   life_analysis sets current_function_sp_is_unchanging if the function
   doesn't modify the stack pointer.  */

/* TODO:

   Split out from life_analysis:
	- local property discovery
	- global property computation
	- log links creation
	- pre/post modify transformation
*/

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
#include "regs.h"
#include "flags.h"
#include "output.h"
#include "function.h"
#include "except.h"
#include "toplev.h"
#include "recog.h"
#include "expr.h"
#include "timevar.h"

#include "obstack.h"
#include "splay-tree.h"

#ifndef HAVE_epilogue
#define HAVE_epilogue 0
#endif
#ifndef HAVE_prologue
#define HAVE_prologue 0
#endif
#ifndef HAVE_sibcall_epilogue
#define HAVE_sibcall_epilogue 0
#endif

#ifndef EPILOGUE_USES
#define EPILOGUE_USES(REGNO)  0
#endif
#ifndef EH_USES
#define EH_USES(REGNO)  0
#endif

#ifdef HAVE_conditional_execution
#ifndef REVERSE_CONDEXEC_PREDICATES_P
#define REVERSE_CONDEXEC_PREDICATES_P(x, y) \
  (GET_CODE ((x)) == reversed_comparison_code ((y), NULL))
#endif
#endif

/* This is the maximum number of times we process any given block if the
   latest loop depth count is smaller than this number.  Only used for the
   failure strategy to avoid infinite loops in calculate_global_regs_live.  */
#define MAX_LIVENESS_ROUNDS 20

/* Nonzero if the second flow pass has completed.  */
int flow2_completed;

/* Maximum register number used in this function, plus one.  */

int max_regno;

/* Indexed by n, giving various register information */

varray_type reg_n_info;

/* Regset of regs live when calls to `setjmp'-like functions happen.  */
/* ??? Does this exist only for the setjmp-clobbered warning message?  */

regset regs_live_at_setjmp;

/* List made of EXPR_LIST rtx's which gives pairs of pseudo registers
   that have to go in the same hard reg.
   The first two regs in the list are a pair, and the next two
   are another pair, etc.  */
rtx regs_may_share;

/* Set of registers that may be eliminable.  These are handled specially
   in updating regs_ever_live.  */

static HARD_REG_SET elim_reg_set;

/* Holds information for tracking conditional register life information.  */
struct reg_cond_life_info
{
  /* A boolean expression of conditions under which a register is dead.  */
  rtx condition;
  /* Conditions under which a register is dead at the basic block end.  */
  rtx orig_condition;

  /* A boolean expression of conditions under which a register has been
     stored into.  */
  rtx stores;

  /* ??? Could store mask of bytes that are dead, so that we could finally
     track lifetimes of multi-word registers accessed via subregs.  */
};

/* For use in communicating between propagate_block and its subroutines.
   Holds all information needed to compute life and def-use information.  */

struct propagate_block_info
{
  /* The basic block we're considering.  */
  basic_block bb;

  /* Bit N is set if register N is conditionally or unconditionally live.  */
  regset reg_live;

  /* Bit N is set if register N is set this insn.  */
  regset new_set;

  /* Element N is the next insn that uses (hard or pseudo) register N
     within the current basic block; or zero, if there is no such insn.  */
  rtx *reg_next_use;

  /* Contains a list of all the MEMs we are tracking for dead store
     elimination.  */
  rtx mem_set_list;

  /* If non-null, record the set of registers set unconditionally in the
     basic block.  */
  regset local_set;

  /* If non-null, record the set of registers set conditionally in the
     basic block.  */
  regset cond_local_set;

#ifdef HAVE_conditional_execution
  /* Indexed by register number, holds a reg_cond_life_info for each
     register that is not unconditionally live or dead.  */
  splay_tree reg_cond_dead;

  /* Bit N is set if register N is in an expression in reg_cond_dead.  */
  regset reg_cond_reg;
#endif

  /* The length of mem_set_list.  */
  int mem_set_list_len;

  /* Nonzero if the value of CC0 is live.  */
  int cc0_live;

  /* Flags controlling the set of information propagate_block collects.  */
  int flags;
  /* Index of instruction being processed.  */
  int insn_num;
};

/* Number of dead insns removed.  */
static int ndead;

/* When PROP_REG_INFO set, array contains pbi->insn_num of instruction
   where given register died.  When the register is marked alive, we use the
   information to compute amount of instructions life range cross.
   (remember, we are walking backward).  This can be computed as current
   pbi->insn_num - reg_deaths[regno].
   At the end of processing each basic block, the remaining live registers
   are inspected and liferanges are increased same way so liverange of global
   registers are computed correctly.
  
   The array is maintained clear for dead registers, so it can be safely reused
   for next basic block without expensive memset of the whole array after
   reseting pbi->insn_num to 0.  */

static int *reg_deaths;

/* Maximum length of pbi->mem_set_list before we start dropping
   new elements on the floor.  */
#define MAX_MEM_SET_LIST_LEN	100

/* Forward declarations */
static int verify_wide_reg_1 (rtx *, void *);
static void verify_wide_reg (int, basic_block);
static void verify_local_live_at_start (regset, basic_block);
static void notice_stack_pointer_modification_1 (rtx, rtx, void *);
static void notice_stack_pointer_modification (void);
static void mark_reg (rtx, void *);
static void mark_regs_live_at_end (regset);
static void calculate_global_regs_live (sbitmap, sbitmap, int);
static void propagate_block_delete_insn (rtx);
static rtx propagate_block_delete_libcall (rtx, rtx);
static int insn_dead_p (struct propagate_block_info *, rtx, int, rtx);
static int libcall_dead_p (struct propagate_block_info *, rtx, rtx);
static void mark_set_regs (struct propagate_block_info *, rtx, rtx);
static void mark_set_1 (struct propagate_block_info *, enum rtx_code, rtx,
			rtx, rtx, int);
static int find_regno_partial (rtx *, void *);

#ifdef HAVE_conditional_execution
static int mark_regno_cond_dead (struct propagate_block_info *, int, rtx);
static void free_reg_cond_life_info (splay_tree_value);
static int flush_reg_cond_reg_1 (splay_tree_node, void *);
static void flush_reg_cond_reg (struct propagate_block_info *, int);
static rtx elim_reg_cond (rtx, unsigned int);
static rtx ior_reg_cond (rtx, rtx, int);
static rtx not_reg_cond (rtx);
static rtx and_reg_cond (rtx, rtx, int);
#endif
#ifdef AUTO_INC_DEC
static void attempt_auto_inc (struct propagate_block_info *, rtx, rtx, rtx,
			      rtx, rtx);
static void find_auto_inc (struct propagate_block_info *, rtx, rtx);
static int try_pre_increment_1 (struct propagate_block_info *, rtx);
static int try_pre_increment (rtx, rtx, HOST_WIDE_INT);
#endif
static void mark_used_reg (struct propagate_block_info *, rtx, rtx, rtx);
static void mark_used_regs (struct propagate_block_info *, rtx, rtx, rtx);
void debug_flow_info (void);
static void add_to_mem_set_list (struct propagate_block_info *, rtx);
static int invalidate_mems_from_autoinc (rtx *, void *);
static void invalidate_mems_from_set (struct propagate_block_info *, rtx);
static void clear_log_links (sbitmap);
static int count_or_remove_death_notes_bb (basic_block, int);
static void allocate_bb_life_data (void);

/* Return the INSN immediately following the NOTE_INSN_BASIC_BLOCK
   note associated with the BLOCK.  */

rtx
first_insn_after_basic_block_note (basic_block block)
{
  rtx insn;

  /* Get the first instruction in the block.  */
  insn = BB_HEAD (block);

  if (insn == NULL_RTX)
    return NULL_RTX;
  if (LABEL_P (insn))
    insn = NEXT_INSN (insn);
  gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));

  return NEXT_INSN (insn);
}

/* Perform data flow analysis for the whole control flow graph.
   FLAGS is a set of PROP_* flags to be used in accumulating flow info.  */

void
life_analysis (FILE *file, int flags)
{
#ifdef ELIMINABLE_REGS
  int i;
  static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif

  /* Record which registers will be eliminated.  We use this in
     mark_used_regs.  */

  CLEAR_HARD_REG_SET (elim_reg_set);

#ifdef ELIMINABLE_REGS
  for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++)
    SET_HARD_REG_BIT (elim_reg_set, eliminables[i].from);
#else
  SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
#endif


#ifdef CANNOT_CHANGE_MODE_CLASS
  if (flags & PROP_REG_INFO)
    init_subregs_of_mode ();
#endif

  if (! optimize)
    flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);

  /* The post-reload life analysis have (on a global basis) the same
     registers live as was computed by reload itself.  elimination
     Otherwise offsets and such may be incorrect.

     Reload will make some registers as live even though they do not
     appear in the rtl.

     We don't want to create new auto-incs after reload, since they
     are unlikely to be useful and can cause problems with shared
     stack slots.  */
  if (reload_completed)
    flags &= ~(PROP_REG_INFO | PROP_AUTOINC);

  /* We want alias analysis information for local dead store elimination.  */
  if (optimize && (flags & PROP_SCAN_DEAD_STORES))
    init_alias_analysis ();

  /* Always remove no-op moves.  Do this before other processing so
     that we don't have to keep re-scanning them.  */
  delete_noop_moves ();

  /* Some targets can emit simpler epilogues if they know that sp was
     not ever modified during the function.  After reload, of course,
     we've already emitted the epilogue so there's no sense searching.  */
  if (! reload_completed)
    notice_stack_pointer_modification ();

  /* Allocate and zero out data structures that will record the
     data from lifetime analysis.  */
  allocate_reg_life_data ();
  allocate_bb_life_data ();

  /* Find the set of registers live on function exit.  */
  mark_regs_live_at_end (EXIT_BLOCK_PTR->global_live_at_start);

  /* "Update" life info from zero.  It'd be nice to begin the
     relaxation with just the exit and noreturn blocks, but that set
     is not immediately handy.  */

  if (flags & PROP_REG_INFO)
    {
      memset (regs_ever_live, 0, sizeof (regs_ever_live));
      memset (regs_asm_clobbered, 0, sizeof (regs_asm_clobbered));
    }
  update_life_info (NULL, UPDATE_LIFE_GLOBAL, flags);
  if (reg_deaths)
    {
      free (reg_deaths);
      reg_deaths = NULL;
    }

  /* Clean up.  */
  if (optimize && (flags & PROP_SCAN_DEAD_STORES))
    end_alias_analysis ();

  if (file)
    dump_flow_info (file);

  /* Removing dead insns should have made jumptables really dead.  */
  delete_dead_jumptables ();
}

/* A subroutine of verify_wide_reg, called through for_each_rtx.
   Search for REGNO.  If found, return 2 if it is not wider than
   word_mode.  */

static int
verify_wide_reg_1 (rtx *px, void *pregno)
{
  rtx x = *px;
  unsigned int regno = *(int *) pregno;

  if (REG_P (x) && REGNO (x) == regno)
    {
      if (GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD)
	return 2;
      return 1;
    }
  return 0;
}

/* A subroutine of verify_local_live_at_start.  Search through insns
   of BB looking for register REGNO.  */

static void
verify_wide_reg (int regno, basic_block bb)
{
  rtx head = BB_HEAD (bb), end = BB_END (bb);

  while (1)
    {
      if (INSN_P (head))
	{
	  int r = for_each_rtx (&PATTERN (head), verify_wide_reg_1, &regno);
	  if (r == 1)
	    return;
	  if (r == 2)
	    break;
	}
      if (head == end)
	break;
      head = NEXT_INSN (head);
    }
  if (dump_file)
    {
      fprintf (dump_file, "Register %d died unexpectedly.\n", regno);
      dump_bb (bb, dump_file, 0);
    }
  fatal_error ("internal consistency failure");
}

/* A subroutine of update_life_info.  Verify that there are no untoward
   changes in live_at_start during a local update.  */

static void
verify_local_live_at_start (regset new_live_at_start, basic_block bb)
{
  if (reload_completed)
    {
      /* After reload, there are no pseudos, nor subregs of multi-word
	 registers.  The regsets should exactly match.  */
      if (! REG_SET_EQUAL_P (new_live_at_start, bb->global_live_at_start))
	{
	  if (dump_file)
	    {
	      fprintf (dump_file,
		       "live_at_start mismatch in bb %d, aborting\nNew:\n",
		       bb->index);
	      debug_bitmap_file (dump_file, new_live_at_start);
	      fputs ("Old:\n", dump_file);
	      dump_bb (bb, dump_file, 0);
	    }
	  fatal_error ("internal consistency failure");
	}
    }
  else
    {
      unsigned i;
      reg_set_iterator rsi;

      /* Find the set of changed registers.  */
      XOR_REG_SET (new_live_at_start, bb->global_live_at_start);

      EXECUTE_IF_SET_IN_REG_SET (new_live_at_start, 0, i, rsi)
	{
	  /* No registers should die.  */
	  if (REGNO_REG_SET_P (bb->global_live_at_start, i))
	    {
	      if (dump_file)
		{
		  fprintf (dump_file,
			   "Register %d died unexpectedly.\n", i);
		  dump_bb (bb, dump_file, 0);
		}
	      fatal_error ("internal consistency failure");
	    }
	  /* Verify that the now-live register is wider than word_mode.  */
	  verify_wide_reg (i, bb);
	}
    }
}

/* Updates life information starting with the basic blocks set in BLOCKS.
   If BLOCKS is null, consider it to be the universal set.

   If EXTENT is UPDATE_LIFE_LOCAL, such as after splitting or peepholing,
   we are only expecting local modifications to basic blocks.  If we find
   extra registers live at the beginning of a block, then we either killed
   useful data, or we have a broken split that wants data not provided.
   If we find registers removed from live_at_start, that means we have
   a broken peephole that is killing a register it shouldn't.

   ??? This is not true in one situation -- when a pre-reload splitter
   generates subregs of a multi-word pseudo, current life analysis will
   lose the kill.  So we _can_ have a pseudo go live.  How irritating.

   It is also not true when a peephole decides that it doesn't need one
   or more of the inputs.

   Including PROP_REG_INFO does not properly refresh regs_ever_live
   unless the caller resets it to zero.  */

int
update_life_info (sbitmap blocks, enum update_life_extent extent,
		  int prop_flags)
{
  regset tmp;
  unsigned i;
  int stabilized_prop_flags = prop_flags;
  basic_block bb;

  tmp = ALLOC_REG_SET (&reg_obstack);
  ndead = 0;

  if ((prop_flags & PROP_REG_INFO) && !reg_deaths)
    reg_deaths = xcalloc (sizeof (*reg_deaths), max_regno);

  timevar_push ((extent == UPDATE_LIFE_LOCAL || blocks)
		? TV_LIFE_UPDATE : TV_LIFE);

  /* Changes to the CFG are only allowed when
     doing a global update for the entire CFG.  */
  gcc_assert (!(prop_flags & PROP_ALLOW_CFG_CHANGES)
	      || (extent != UPDATE_LIFE_LOCAL && !blocks));

  /* For a global update, we go through the relaxation process again.  */
  if (extent != UPDATE_LIFE_LOCAL)
    {
      for ( ; ; )
	{
	  int changed = 0;

	  calculate_global_regs_live (blocks, blocks,
				prop_flags & (PROP_SCAN_DEAD_CODE
					      | PROP_SCAN_DEAD_STORES
					      | PROP_ALLOW_CFG_CHANGES));

	  if ((prop_flags & (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
	      != (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
	    break;

	  /* Removing dead code may allow the CFG to be simplified which
	     in turn may allow for further dead code detection / removal.  */
	  FOR_EACH_BB_REVERSE (bb)
	    {
	      COPY_REG_SET (tmp, bb->global_live_at_end);
	      changed |= propagate_block (bb, tmp, NULL, NULL,
				prop_flags & (PROP_SCAN_DEAD_CODE
					      | PROP_SCAN_DEAD_STORES
					      | PROP_KILL_DEAD_CODE));
	    }

	  /* Don't pass PROP_SCAN_DEAD_CODE or PROP_KILL_DEAD_CODE to
	     subsequent propagate_block calls, since removing or acting as
	     removing dead code can affect global register liveness, which
	     is supposed to be finalized for this call after this loop.  */
	  stabilized_prop_flags
	    &= ~(PROP_SCAN_DEAD_CODE | PROP_SCAN_DEAD_STORES
		 | PROP_KILL_DEAD_CODE);

	  if (! changed)
	    break;

	  /* We repeat regardless of what cleanup_cfg says.  If there were
	     instructions deleted above, that might have been only a
	     partial improvement (see MAX_MEM_SET_LIST_LEN usage).
	     Further improvement may be possible.  */
	  cleanup_cfg (CLEANUP_EXPENSIVE);

	  /* Zap the life information from the last round.  If we don't
	     do this, we can wind up with registers that no longer appear
	     in the code being marked live at entry.  */
	  FOR_EACH_BB (bb)
	    {
	      CLEAR_REG_SET (bb->global_live_at_start);
	      CLEAR_REG_SET (bb->global_live_at_end);
	    }
	}

      /* If asked, remove notes from the blocks we'll update.  */
      if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
	count_or_remove_death_notes (blocks, 1);
    }

  /* Clear log links in case we are asked to (re)compute them.  */
  if (prop_flags & PROP_LOG_LINKS)
    clear_log_links (blocks);

  if (blocks)
    {
      EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
	{
	  bb = BASIC_BLOCK (i);

	  COPY_REG_SET (tmp, bb->global_live_at_end);
	  propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);

	  if (extent == UPDATE_LIFE_LOCAL)
	    verify_local_live_at_start (tmp, bb);
	});
    }
  else
    {
      FOR_EACH_BB_REVERSE (bb)
	{
	  COPY_REG_SET (tmp, bb->global_live_at_end);

	  propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);

	  if (extent == UPDATE_LIFE_LOCAL)
	    verify_local_live_at_start (tmp, bb);
	}
    }

  FREE_REG_SET (tmp);

  if (prop_flags & PROP_REG_INFO)
    {
      reg_set_iterator rsi;

      /* The only pseudos that are live at the beginning of the function
	 are those that were not set anywhere in the function.  local-alloc
	 doesn't know how to handle these correctly, so mark them as not
	 local to any one basic block.  */
      EXECUTE_IF_SET_IN_REG_SET (ENTRY_BLOCK_PTR->global_live_at_end,
				 FIRST_PSEUDO_REGISTER, i, rsi)
	REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;

      /* We have a problem with any pseudoreg that lives across the setjmp.
	 ANSI says that if a user variable does not change in value between
	 the setjmp and the longjmp, then the longjmp preserves it.  This
	 includes longjmp from a place where the pseudo appears dead.
	 (In principle, the value still exists if it is in scope.)
	 If the pseudo goes in a hard reg, some other value may occupy
	 that hard reg where this pseudo is dead, thus clobbering the pseudo.
	 Conclusion: such a pseudo must not go in a hard reg.  */
      EXECUTE_IF_SET_IN_REG_SET (regs_live_at_setjmp,
				 FIRST_PSEUDO_REGISTER, i, rsi)
	{
	  if (regno_reg_rtx[i] != 0)
	    {
	      REG_LIVE_LENGTH (i) = -1;
	      REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
	    }
	}
    }
  if (reg_deaths)
    {
      free (reg_deaths);
      reg_deaths = NULL;
    }
  timevar_pop ((extent == UPDATE_LIFE_LOCAL || blocks)
	       ? TV_LIFE_UPDATE : TV_LIFE);
  if (ndead && dump_file)
    fprintf (dump_file, "deleted %i dead insns\n", ndead);
  return ndead;
}

/* Update life information in all blocks where BB_DIRTY is set.  */

int
update_life_info_in_dirty_blocks (enum update_life_extent extent, int prop_flags)
{
  sbitmap update_life_blocks = sbitmap_alloc (last_basic_block);
  int n = 0;
  basic_block bb;
  int retval = 0;

  sbitmap_zero (update_life_blocks);
  FOR_EACH_BB (bb)
    {
      if (bb->flags & BB_DIRTY)
	{
	  SET_BIT (update_life_blocks, bb->index);
	  n++;
	}
    }

  if (n)
    retval = update_life_info (update_life_blocks, extent, prop_flags);

  sbitmap_free (update_life_blocks);
  return retval;
}

/* Free the variables allocated by find_basic_blocks.  */

void
free_basic_block_vars (void)
{
  if (basic_block_info)
    {
      clear_edges ();
      basic_block_info = NULL;
    }
  n_basic_blocks = 0;
  last_basic_block = 0;

  ENTRY_BLOCK_PTR->aux = NULL;
  ENTRY_BLOCK_PTR->global_live_at_end = NULL;
  EXIT_BLOCK_PTR->aux = NULL;
  EXIT_BLOCK_PTR->global_live_at_start = NULL;
}

/* Delete any insns that copy a register to itself.  */

int
delete_noop_moves (void)
{
  rtx insn, next;
  basic_block bb;
  int nnoops = 0;

  FOR_EACH_BB (bb)
    {
      for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next)
	{
	  next = NEXT_INSN (insn);
	  if (INSN_P (insn) && noop_move_p (insn))
	    {
	      rtx note;

	      /* If we're about to remove the first insn of a libcall
		 then move the libcall note to the next real insn and
		 update the retval note.  */
	      if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX))
		       && XEXP (note, 0) != insn)
		{
		  rtx new_libcall_insn = next_real_insn (insn);
		  rtx retval_note = find_reg_note (XEXP (note, 0),
						   REG_RETVAL, NULL_RTX);
		  REG_NOTES (new_libcall_insn)
		    = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0),
					 REG_NOTES (new_libcall_insn));
		  XEXP (retval_note, 0) = new_libcall_insn;
		}

	      delete_insn_and_edges (insn);
	      nnoops++;
	    }
	}
    }
  if (nnoops && dump_file)
    fprintf (dump_file, "deleted %i noop moves", nnoops);
  return nnoops;
}

/* Delete any jump tables never referenced.  We can't delete them at the
   time of removing tablejump insn as they are referenced by the preceding
   insns computing the destination, so we delay deleting and garbagecollect
   them once life information is computed.  */
void
delete_dead_jumptables (void)
{
  basic_block bb;

  /* A dead jump table does not belong to any basic block.  Scan insns
     between two adjacent basic blocks.  */
  FOR_EACH_BB (bb)
    {
      rtx insn, next;

      for (insn = NEXT_INSN (BB_END (bb));
	   insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
	   insn = next)
	{
	  next = NEXT_INSN (insn);
	  if (LABEL_P (insn)
	      && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
	      && JUMP_P (next)
	      && (GET_CODE (PATTERN (next)) == ADDR_VEC
		  || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
	    {
	      rtx label = insn, jump = next;

	      if (dump_file)
		fprintf (dump_file, "Dead jumptable %i removed\n",
			 INSN_UID (insn));

	      next = NEXT_INSN (next);
	      delete_insn (jump);
	      delete_insn (label);
	    }
	}
    }
}

/* Determine if the stack pointer is constant over the life of the function.
   Only useful before prologues have been emitted.  */

static void
notice_stack_pointer_modification_1 (rtx x, rtx pat ATTRIBUTE_UNUSED,
				     void *data ATTRIBUTE_UNUSED)
{
  if (x == stack_pointer_rtx
      /* The stack pointer is only modified indirectly as the result
	 of a push until later in flow.  See the comments in rtl.texi
	 regarding Embedded Side-Effects on Addresses.  */
      || (MEM_P (x)
	  && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_AUTOINC
	  && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx))
    current_function_sp_is_unchanging = 0;
}

static void
notice_stack_pointer_modification (void)
{
  basic_block bb;
  rtx insn;

  /* Assume that the stack pointer is unchanging if alloca hasn't
     been used.  */
  current_function_sp_is_unchanging = !current_function_calls_alloca;
  if (! current_function_sp_is_unchanging)
    return;

  FOR_EACH_BB (bb)
    FOR_BB_INSNS (bb, insn)
      {
	if (INSN_P (insn))
	  {
	    /* Check if insn modifies the stack pointer.  */
	    note_stores (PATTERN (insn),
			 notice_stack_pointer_modification_1,
			 NULL);
	    if (! current_function_sp_is_unchanging)
	      return;
	  }
      }
}

/* Mark a register in SET.  Hard registers in large modes get all
   of their component registers set as well.  */

static void
mark_reg (rtx reg, void *xset)
{
  regset set = (regset) xset;
  int regno = REGNO (reg);

  gcc_assert (GET_MODE (reg) != BLKmode);

  SET_REGNO_REG_SET (set, regno);
  if (regno < FIRST_PSEUDO_REGISTER)
    {
      int n = hard_regno_nregs[regno][GET_MODE (reg)];
      while (--n > 0)
	SET_REGNO_REG_SET (set, regno + n);
    }
}

/* Mark those regs which are needed at the end of the function as live
   at the end of the last basic block.  */

static void
mark_regs_live_at_end (regset set)
{
  unsigned int i;

  /* If exiting needs the right stack value, consider the stack pointer
     live at the end of the function.  */
  if ((HAVE_epilogue && epilogue_completed)
      || ! EXIT_IGNORE_STACK
      || (! FRAME_POINTER_REQUIRED
	  && ! current_function_calls_alloca
	  && flag_omit_frame_pointer)
      || current_function_sp_is_unchanging)
    {
      SET_REGNO_REG_SET (set, STACK_POINTER_REGNUM);
    }

  /* Mark the frame pointer if needed at the end of the function.  If
     we end up eliminating it, it will be removed from the live list
     of each basic block by reload.  */

  if (! reload_completed || frame_pointer_needed)
    {
      SET_REGNO_REG_SET (set, FRAME_POINTER_REGNUM);
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
      /* If they are different, also mark the hard frame pointer as live.  */
      if (! LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
	SET_REGNO_REG_SET (set, HARD_FRAME_POINTER_REGNUM);
#endif
    }

#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
  /* Many architectures have a GP register even without flag_pic.
     Assume the pic register is not in use, or will be handled by
     other means, if it is not fixed.  */
  if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
      && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
    SET_REGNO_REG_SET (set, PIC_OFFSET_TABLE_REGNUM);
#endif

  /* Mark all global registers, and all registers used by the epilogue
     as being live at the end of the function since they may be
     referenced by our caller.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (global_regs[i] || EPILOGUE_USES (i))
      SET_REGNO_REG_SET (set, i);

  if (HAVE_epilogue && epilogue_completed)
    {
      /* Mark all call-saved registers that we actually used.  */
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (regs_ever_live[i] && ! LOCAL_REGNO (i)
	    && ! TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
	  SET_REGNO_REG_SET (set, i);
    }

#ifdef EH_RETURN_DATA_REGNO
  /* Mark the registers that will contain data for the handler.  */
  if (reload_completed && current_function_calls_eh_return)
    for (i = 0; ; ++i)
      {
	unsigned regno = EH_RETURN_DATA_REGNO(i);
	if (regno == INVALID_REGNUM)
	  break;
	SET_REGNO_REG_SET (set, regno);
      }
#endif
#ifdef EH_RETURN_STACKADJ_RTX
  if ((! HAVE_epilogue || ! epilogue_completed)
      && current_function_calls_eh_return)
    {
      rtx tmp = EH_RETURN_STACKADJ_RTX;
      if (tmp && REG_P (tmp))
	mark_reg (tmp, set);
    }
#endif
#ifdef EH_RETURN_HANDLER_RTX
  if ((! HAVE_epilogue || ! epilogue_completed)
      && current_function_calls_eh_return)
    {
      rtx tmp = EH_RETURN_HANDLER_RTX;
      if (tmp && REG_P (tmp))
	mark_reg (tmp, set);
    }
#endif

  /* Mark function return value.  */
  diddle_return_value (mark_reg, set);
}

/* Propagate global life info around the graph of basic blocks.  Begin
   considering blocks with their corresponding bit set in BLOCKS_IN.
   If BLOCKS_IN is null, consider it the universal set.

   BLOCKS_OUT is set for every block that was changed.  */

static void
calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
{
  basic_block *queue, *qhead, *qtail, *qend, bb;
  regset tmp, new_live_at_end, invalidated_by_call;
  regset registers_made_dead;
  bool failure_strategy_required = false;
  int *block_accesses;

  /* The registers that are modified within this in block.  */
  regset *local_sets;

  /* The registers that are conditionally modified within this block.
     In other words, regs that are set only as part of a COND_EXEC.  */
  regset *cond_local_sets;

  int i;

  /* Some passes used to forget clear aux field of basic block causing
     sick behavior here.  */
#ifdef ENABLE_CHECKING
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    gcc_assert (!bb->aux);
#endif

  tmp = ALLOC_REG_SET (&reg_obstack);
  new_live_at_end = ALLOC_REG_SET (&reg_obstack);
  invalidated_by_call = ALLOC_REG_SET (&reg_obstack);
  registers_made_dead = ALLOC_REG_SET (&reg_obstack);

  /* Inconveniently, this is only readily available in hard reg set form.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
      SET_REGNO_REG_SET (invalidated_by_call, i);

  /* Allocate space for the sets of local properties.  */
  local_sets = xcalloc (last_basic_block - (INVALID_BLOCK + 1),
			sizeof (regset));
  cond_local_sets = xcalloc (last_basic_block - (INVALID_BLOCK + 1),
			     sizeof (regset));

  /* Create a worklist.  Allocate an extra slot for ENTRY_BLOCK, and one
     because the `head == tail' style test for an empty queue doesn't
     work with a full queue.  */
  queue = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1)) * sizeof (*queue));
  qtail = queue;
  qhead = qend = queue + n_basic_blocks - (INVALID_BLOCK + 1);

  /* Queue the blocks set in the initial mask.  Do this in reverse block
     number order so that we are more likely for the first round to do
     useful work.  We use AUX non-null to flag that the block is queued.  */
  if (blocks_in)
    {
      FOR_EACH_BB (bb)
	if (TEST_BIT (blocks_in, bb->index))
	  {
	    *--qhead = bb;
	    bb->aux = bb;
	  }
    }
  else
    {
      FOR_EACH_BB (bb)
	{
	  *--qhead = bb;
	  bb->aux = bb;
	}
    }

  block_accesses = xcalloc (last_basic_block, sizeof (int));
  
  /* We clean aux when we remove the initially-enqueued bbs, but we
     don't enqueue ENTRY and EXIT initially, so clean them upfront and
     unconditionally.  */
  ENTRY_BLOCK_PTR->aux = EXIT_BLOCK_PTR->aux = NULL;

  if (blocks_out)
    sbitmap_zero (blocks_out);

  /* We work through the queue until there are no more blocks.  What
     is live at the end of this block is precisely the union of what
     is live at the beginning of all its successors.  So, we set its
     GLOBAL_LIVE_AT_END field based on the GLOBAL_LIVE_AT_START field
     for its successors.  Then, we compute GLOBAL_LIVE_AT_START for
     this block by walking through the instructions in this block in
     reverse order and updating as we go.  If that changed
     GLOBAL_LIVE_AT_START, we add the predecessors of the block to the
     queue; they will now need to recalculate GLOBAL_LIVE_AT_END.

     We are guaranteed to terminate, because GLOBAL_LIVE_AT_START
     never shrinks.  If a register appears in GLOBAL_LIVE_AT_START, it
     must either be live at the end of the block, or used within the
     block.  In the latter case, it will certainly never disappear
     from GLOBAL_LIVE_AT_START.  In the former case, the register
     could go away only if it disappeared from GLOBAL_LIVE_AT_START
     for one of the successor blocks.  By induction, that cannot
     occur.

     ??? This reasoning doesn't work if we start from non-empty initial
     GLOBAL_LIVE_AT_START sets.  And there are actually two problems:
       1) Updating may not terminate (endless oscillation).
       2) Even if it does (and it usually does), the resulting information
	  may be inaccurate.  Consider for example the following case:

	  a = ...;
	  while (...) {...}  -- 'a' not mentioned at all
	  ... = a;

	  If the use of 'a' is deleted between two calculations of liveness
	  information and the initial sets are not cleared, the information
	  about a's liveness will get stuck inside the loop and the set will
	  appear not to be dead.

     We do not attempt to solve 2) -- the information is conservatively
     correct (i.e. we never claim that something live is dead) and the
     amount of optimization opportunities missed due to this problem is
     not significant.

     1) is more serious.  In order to fix it, we monitor the number of times
     each block is processed.  Once one of the blocks has been processed more
     times than the maximum number of rounds, we use the following strategy:
     When a register disappears from one of the sets, we add it to a MAKE_DEAD
     set, remove all registers in this set from all GLOBAL_LIVE_AT_* sets and
     add the blocks with changed sets into the queue.  Thus we are guaranteed
     to terminate (the worst case corresponds to all registers in MADE_DEAD,
     in which case the original reasoning above is valid), but in general we
     only fix up a few offending registers.

     The maximum number of rounds for computing liveness is the largest of
     MAX_LIVENESS_ROUNDS and the latest loop depth count for this function.  */

  while (qhead != qtail)
    {
      int rescan, changed;
      basic_block bb;
      edge e;
      edge_iterator ei;

      bb = *qhead++;
      if (qhead == qend)
	qhead = queue;
      bb->aux = NULL;

      /* Should we start using the failure strategy?  */
      if (bb != ENTRY_BLOCK_PTR)
	{
	  int max_liveness_rounds =
	    MAX (MAX_LIVENESS_ROUNDS, cfun->max_loop_depth);

	  block_accesses[bb->index]++;
	  if (block_accesses[bb->index] > max_liveness_rounds)
	    failure_strategy_required = true;
	}

      /* Begin by propagating live_at_start from the successor blocks.  */
      CLEAR_REG_SET (new_live_at_end);

      if (EDGE_COUNT (bb->succs) > 0)
	FOR_EACH_EDGE (e, ei, bb->succs)
	  {
	    basic_block sb = e->dest;

	    /* Call-clobbered registers die across exception and
	       call edges.  */
	    /* ??? Abnormal call edges ignored for the moment, as this gets
	       confused by sibling call edges, which crashes reg-stack.  */
	    if (e->flags & EDGE_EH)
	      bitmap_ior_and_compl_into (new_live_at_end,
					 sb->global_live_at_start,
					 invalidated_by_call);
	    else
	      IOR_REG_SET (new_live_at_end, sb->global_live_at_start);

	    /* If a target saves one register in another (instead of on
	       the stack) the save register will need to be live for EH.  */
	    if (e->flags & EDGE_EH)
	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
		if (EH_USES (i))
		  SET_REGNO_REG_SET (new_live_at_end, i);
	  }
      else
	{
	  /* This might be a noreturn function that throws.  And
	     even if it isn't, getting the unwind info right helps
	     debugging.  */
	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	    if (EH_USES (i))
	      SET_REGNO_REG_SET (new_live_at_end, i);
	}

      /* The all-important stack pointer must always be live.  */
      SET_REGNO_REG_SET (new_live_at_end, STACK_POINTER_REGNUM);

      /* Before reload, there are a few registers that must be forced
	 live everywhere -- which might not already be the case for
	 blocks within infinite loops.  */
      if (! reload_completed)
	{
	  /* Any reference to any pseudo before reload is a potential
	     reference of the frame pointer.  */
	  SET_REGNO_REG_SET (new_live_at_end, FRAME_POINTER_REGNUM);

#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  /* Pseudos with argument area equivalences may require
	     reloading via the argument pointer.  */
	  if (fixed_regs[ARG_POINTER_REGNUM])
	    SET_REGNO_REG_SET (new_live_at_end, ARG_POINTER_REGNUM);
#endif

	  /* Any constant, or pseudo with constant equivalences, may
	     require reloading from memory using the pic register.  */
	  if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
	      && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
	    SET_REGNO_REG_SET (new_live_at_end, PIC_OFFSET_TABLE_REGNUM);
	}

      if (bb == ENTRY_BLOCK_PTR)
	{
	  COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
	  continue;
	}

      /* On our first pass through this block, we'll go ahead and continue.
	 Recognize first pass by checking if local_set is NULL for this
         basic block.  On subsequent passes, we get to skip out early if
	 live_at_end wouldn't have changed.  */

      if (local_sets[bb->index - (INVALID_BLOCK + 1)] == NULL)
	{
	  local_sets[bb->index - (INVALID_BLOCK + 1)]
	    = ALLOC_REG_SET (&reg_obstack);
	  cond_local_sets[bb->index - (INVALID_BLOCK + 1)]
	    = ALLOC_REG_SET (&reg_obstack);
	  rescan = 1;
	}
      else
	{
	  /* If any bits were removed from live_at_end, we'll have to
	     rescan the block.  This wouldn't be necessary if we had
	     precalculated local_live, however with PROP_SCAN_DEAD_CODE
	     local_live is really dependent on live_at_end.  */
	  rescan = bitmap_intersect_compl_p (bb->global_live_at_end,
					     new_live_at_end);

	  if (!rescan)
	    {
	      regset cond_local_set;

	       /* If any of the registers in the new live_at_end set are
		  conditionally set in this basic block, we must rescan.
		  This is because conditional lifetimes at the end of the
		  block do not just take the live_at_end set into
		  account, but also the liveness at the start of each
		  successor block.  We can miss changes in those sets if
		  we only compare the new live_at_end against the
		  previous one.  */
	      cond_local_set = cond_local_sets[bb->index - (INVALID_BLOCK + 1)];
	      rescan = bitmap_intersect_p (new_live_at_end, cond_local_set);
	    }

	  if (!rescan)
	    {
	      regset local_set;

	      /* Find the set of changed bits.  Take this opportunity
		 to notice that this set is empty and early out.  */
	      bitmap_xor (tmp, bb->global_live_at_end, new_live_at_end);
	      if (bitmap_empty_p (tmp))
		continue;
  
	      /* If any of the changed bits overlap with local_sets[bb],
 		 we'll have to rescan the block.  */
	      local_set = local_sets[bb->index - (INVALID_BLOCK + 1)];
	      rescan = bitmap_intersect_p (tmp, local_set);
	    }
	}

      /* Let our caller know that BB changed enough to require its
	 death notes updated.  */
      if (blocks_out)
	SET_BIT (blocks_out, bb->index);

      if (! rescan)
	{
	  /* Add to live_at_start the set of all registers in
	     new_live_at_end that aren't in the old live_at_end.  */
	  
	  changed = bitmap_ior_and_compl_into (bb->global_live_at_start,
					       new_live_at_end,
					       bb->global_live_at_end);
	  COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
	  if (! changed)
	    continue;
	}
      else
	{
	  COPY_REG_SET (bb->global_live_at_end, new_live_at_end);

	  /* Rescan the block insn by insn to turn (a copy of) live_at_end
	     into live_at_start.  */
	  propagate_block (bb, new_live_at_end,
			   local_sets[bb->index - (INVALID_BLOCK + 1)],
			   cond_local_sets[bb->index - (INVALID_BLOCK + 1)],
			   flags);

	  /* If live_at start didn't change, no need to go farther.  */
	  if (REG_SET_EQUAL_P (bb->global_live_at_start, new_live_at_end))
	    continue;

	  if (failure_strategy_required)
	    {
	      /* Get the list of registers that were removed from the
	         bb->global_live_at_start set.  */
	      bitmap_and_compl (tmp, bb->global_live_at_start,
				new_live_at_end);
	      if (!bitmap_empty_p (tmp))
		{
		  bool pbb_changed;
		  basic_block pbb;
                
		  /* It should not happen that one of registers we have
		     removed last time is disappears again before any other
		     register does.  */
		  pbb_changed = bitmap_ior_into (registers_made_dead, tmp);
		  gcc_assert (pbb_changed);

		  /* Now remove the registers from all sets.  */
		  FOR_EACH_BB (pbb)
		    {
		      pbb_changed = false;

		      pbb_changed
			|= bitmap_and_compl_into (pbb->global_live_at_start,
						  registers_made_dead);
		      pbb_changed
			|= bitmap_and_compl_into (pbb->global_live_at_end,
						  registers_made_dead);
		      if (!pbb_changed)
			continue;

		      /* Note the (possible) change.  */
		      if (blocks_out)
			SET_BIT (blocks_out, pbb->index);

		      /* Makes sure to really rescan the block.  */
		      if (local_sets[pbb->index - (INVALID_BLOCK + 1)])
			{
			  FREE_REG_SET (local_sets[pbb->index - (INVALID_BLOCK + 1)]);
			  FREE_REG_SET (cond_local_sets[pbb->index - (INVALID_BLOCK + 1)]);
			  local_sets[pbb->index - (INVALID_BLOCK + 1)] = 0;
			}

		      /* Add it to the queue.  */
		      if (pbb->aux == NULL)
			{
			  *qtail++ = pbb;
			  if (qtail == qend)
			    qtail = queue;
			  pbb->aux = pbb;
			}
		    }
		  continue;
		}
	    } /* end of failure_strategy_required */

	  COPY_REG_SET (bb->global_live_at_start, new_live_at_end);
	}

      /* Queue all predecessors of BB so that we may re-examine
	 their live_at_end.  */
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  basic_block pb = e->src;
	  if (pb->aux == NULL)
	    {
	      *qtail++ = pb;
	      if (qtail == qend)
		qtail = queue;
	      pb->aux = pb;
	    }
	}
    }

  FREE_REG_SET (tmp);
  FREE_REG_SET (new_live_at_end);
  FREE_REG_SET (invalidated_by_call);
  FREE_REG_SET (registers_made_dead);

  if (blocks_out)
    {
      EXECUTE_IF_SET_IN_SBITMAP (blocks_out, 0, i,
	{
	  basic_block bb = BASIC_BLOCK (i);
	  FREE_REG_SET (local_sets[bb->index - (INVALID_BLOCK + 1)]);
	  FREE_REG_SET (cond_local_sets[bb->index - (INVALID_BLOCK + 1)]);
	});
    }
  else
    {
      FOR_EACH_BB (bb)
	{
	  FREE_REG_SET (local_sets[bb->index - (INVALID_BLOCK + 1)]);
	  FREE_REG_SET (cond_local_sets[bb->index - (INVALID_BLOCK + 1)]);
	}
    }

  free (block_accesses);
  free (queue);
  free (cond_local_sets);
  free (local_sets);
}


/* This structure is used to pass parameters to and from the
   the function find_regno_partial(). It is used to pass in the
   register number we are looking, as well as to return any rtx
   we find.  */

typedef struct {
  unsigned regno_to_find;
  rtx retval;
} find_regno_partial_param;


/* Find the rtx for the reg numbers specified in 'data' if it is
   part of an expression which only uses part of the register.  Return
   it in the structure passed in.  */
static int
find_regno_partial (rtx *ptr, void *data)
{
  find_regno_partial_param *param = (find_regno_partial_param *)data;
  unsigned reg = param->regno_to_find;
  param->retval = NULL_RTX;

  if (*ptr == NULL_RTX)
    return 0;

  switch (GET_CODE (*ptr))
    {
    case ZERO_EXTRACT:
    case SIGN_EXTRACT:
    case STRICT_LOW_PART:
      if (REG_P (XEXP (*ptr, 0)) && REGNO (XEXP (*ptr, 0)) == reg)
	{
	  param->retval = XEXP (*ptr, 0);
	  return 1;
	}
      break;

    case SUBREG:
      if (REG_P (SUBREG_REG (*ptr))
	  && REGNO (SUBREG_REG (*ptr)) == reg)
	{
	  param->retval = SUBREG_REG (*ptr);
	  return 1;
	}
      break;

    default:
      break;
    }

  return 0;
}

/* Process all immediate successors of the entry block looking for pseudo
   registers which are live on entry. Find all of those whose first
   instance is a partial register reference of some kind, and initialize
   them to 0 after the entry block.  This will prevent bit sets within
   registers whose value is unknown, and may contain some kind of sticky
   bits we don't want.  */

int
initialize_uninitialized_subregs (void)
{
  rtx insn;
  edge e;
  unsigned reg, did_something = 0;
  find_regno_partial_param param;
  edge_iterator ei;

  /* APPLE LOCAL begin 4727273 */
  /* This is needed for ia64, since a subreg operation does not guarantee
     that the NaT bit will be cleared.  A discussion of this can be found
     here: http://gcc.gnu.org/ml/gcc-patches/2001-11/msg00429.html
     For the architectures we support, this code isn't needed and can
     generate superfluous code.  */
#ifndef TARGET_MUST_INIT_SUBREG
  return 0;
#endif
  /* APPLE LOCAL end 4727273 */

  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
    {
      basic_block bb = e->dest;
      regset map = bb->global_live_at_start;
      reg_set_iterator rsi;

      EXECUTE_IF_SET_IN_REG_SET (map, FIRST_PSEUDO_REGISTER, reg, rsi)
	{
	  int uid = REGNO_FIRST_UID (reg);
	  rtx i;

	  /* Find an insn which mentions the register we are looking for.
	     Its preferable to have an instance of the register's rtl since
	     there may be various flags set which we need to duplicate.
	     If we can't find it, its probably an automatic whose initial
	     value doesn't matter, or hopefully something we don't care about.  */
	  for (i = get_insns (); i && INSN_UID (i) != uid; i = NEXT_INSN (i))
	    ;
	  if (i != NULL_RTX)
	    {
	      /* Found the insn, now get the REG rtx, if we can.  */
	      param.regno_to_find = reg;
	      for_each_rtx (&i, find_regno_partial, &param);
	      if (param.retval != NULL_RTX)
		{
		  start_sequence ();
		  emit_move_insn (param.retval,
				  CONST0_RTX (GET_MODE (param.retval)));
		  insn = get_insns ();
		  end_sequence ();
		  insert_insn_on_edge (insn, e);
		  did_something = 1;
		}
	    }
	}
    }

  if (did_something)
    commit_edge_insertions ();
  return did_something;
}


/* Subroutines of life analysis.  */

/* Allocate the permanent data structures that represent the results
   of life analysis.  */

static void
allocate_bb_life_data (void)
{
  basic_block bb;

  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
    {
      bb->global_live_at_start = ALLOC_REG_SET (&reg_obstack);
      bb->global_live_at_end = ALLOC_REG_SET (&reg_obstack);
    }

  regs_live_at_setjmp = ALLOC_REG_SET (&reg_obstack);
}

void
allocate_reg_life_data (void)
{
  int i;

  max_regno = max_reg_num ();
  gcc_assert (!reg_deaths);
  reg_deaths = xcalloc (sizeof (*reg_deaths), max_regno);

  /* Recalculate the register space, in case it has grown.  Old style
     vector oriented regsets would set regset_{size,bytes} here also.  */
  allocate_reg_info (max_regno, FALSE, FALSE);

  /* Reset all the data we'll collect in propagate_block and its
     subroutines.  */
  for (i = 0; i < max_regno; i++)
    {
      REG_N_SETS (i) = 0;
      REG_N_REFS (i) = 0;
      REG_N_DEATHS (i) = 0;
      REG_N_CALLS_CROSSED (i) = 0;
      REG_LIVE_LENGTH (i) = 0;
      REG_FREQ (i) = 0;
      REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
    }
}

/* Delete dead instructions for propagate_block.  */

static void
propagate_block_delete_insn (rtx insn)
{
  rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);

  /* If the insn referred to a label, and that label was attached to
     an ADDR_VEC, it's safe to delete the ADDR_VEC.  In fact, it's
     pretty much mandatory to delete it, because the ADDR_VEC may be
     referencing labels that no longer exist.

     INSN may reference a deleted label, particularly when a jump
     table has been optimized into a direct jump.  There's no
     real good way to fix up the reference to the deleted label
     when the label is deleted, so we just allow it here.  */

  if (inote && LABEL_P (inote))
    {
      rtx label = XEXP (inote, 0);
      rtx next;

      /* The label may be forced if it has been put in the constant
	 pool.  If that is the only use we must discard the table
	 jump following it, but not the label itself.  */
      if (LABEL_NUSES (label) == 1 + LABEL_PRESERVE_P (label)
	  && (next = next_nonnote_insn (label)) != NULL
	  && JUMP_P (next)
	  && (GET_CODE (PATTERN (next)) == ADDR_VEC
	      || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
	{
	  rtx pat = PATTERN (next);
	  int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
	  int len = XVECLEN (pat, diff_vec_p);
	  int i;

	  for (i = 0; i < len; i++)
	    LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;

	  delete_insn_and_edges (next);
	  ndead++;
	}
    }

  delete_insn_and_edges (insn);
  ndead++;
}

/* Delete dead libcalls for propagate_block.  Return the insn
   before the libcall.  */

static rtx
propagate_block_delete_libcall (rtx insn, rtx note)
{
  rtx first = XEXP (note, 0);
  rtx before = PREV_INSN (first);

  delete_insn_chain_and_edges (first, insn);
  ndead++;
  return before;
}

/* Update the life-status of regs for one insn.  Return the previous insn.  */

rtx
propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
{
  rtx prev = PREV_INSN (insn);
  int flags = pbi->flags;
  int insn_is_dead = 0;
  int libcall_is_dead = 0;
  rtx note;
  unsigned i;

  if (! INSN_P (insn))
    return prev;

  note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
  if (flags & PROP_SCAN_DEAD_CODE)
    {
      insn_is_dead = insn_dead_p (pbi, PATTERN (insn), 0, REG_NOTES (insn));
      libcall_is_dead = (insn_is_dead && note != 0
			 && libcall_dead_p (pbi, note, insn));
    }

  /* If an instruction consists of just dead store(s) on final pass,
     delete it.  */
  if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
    {
      /* If we're trying to delete a prologue or epilogue instruction
	 that isn't flagged as possibly being dead, something is wrong.
	 But if we are keeping the stack pointer depressed, we might well
	 be deleting insns that are used to compute the amount to update
	 it by, so they are fine.  */
      if (reload_completed
	  && !(TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
		&& (TYPE_RETURNS_STACK_DEPRESSED
		    (TREE_TYPE (current_function_decl))))
	  && (((HAVE_epilogue || HAVE_prologue)
	       && prologue_epilogue_contains (insn))
	      || (HAVE_sibcall_epilogue
		  && sibcall_epilogue_contains (insn)))
	  && find_reg_note (insn, REG_MAYBE_DEAD, NULL_RTX) == 0)
	fatal_insn ("Attempt to delete prologue/epilogue insn:", insn);

      /* Record sets.  Do this even for dead instructions, since they
	 would have killed the values if they hadn't been deleted.  */
      mark_set_regs (pbi, PATTERN (insn), insn);

      /* CC0 is now known to be dead.  Either this insn used it,
	 in which case it doesn't anymore, or clobbered it,
	 so the next insn can't use it.  */
      pbi->cc0_live = 0;

      if (libcall_is_dead)
	prev = propagate_block_delete_libcall (insn, note);
      else
	{

	/* If INSN contains a RETVAL note and is dead, but the libcall
	   as a whole is not dead, then we want to remove INSN, but
	   not the whole libcall sequence.

	   However, we need to also remove the dangling REG_LIBCALL
	   note so that we do not have mis-matched LIBCALL/RETVAL
	   notes.  In theory we could find a new location for the
	   REG_RETVAL note, but it hardly seems worth the effort.

	   NOTE at this point will be the RETVAL note if it exists.  */
	  if (note)
	    {
	      rtx libcall_note;

	      libcall_note
		= find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
	      remove_note (XEXP (note, 0), libcall_note);
	    }

	  /* Similarly if INSN contains a LIBCALL note, remove the
	     dangling REG_RETVAL note.  */
	  note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
	  if (note)
	    {
	      rtx retval_note;

	      retval_note
		= find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
	      remove_note (XEXP (note, 0), retval_note);
	    }

	  /* Now delete INSN.  */
	  propagate_block_delete_insn (insn);
	}

      return prev;
    }

  /* See if this is an increment or decrement that can be merged into
     a following memory address.  */
#ifdef AUTO_INC_DEC
  {
    rtx x = single_set (insn);

    /* Does this instruction increment or decrement a register?  */
    if ((flags & PROP_AUTOINC)
	&& x != 0
	&& REG_P (SET_DEST (x))
	&& (GET_CODE (SET_SRC (x)) == PLUS
	    || GET_CODE (SET_SRC (x)) == MINUS)
	&& XEXP (SET_SRC (x), 0) == SET_DEST (x)
	&& GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
	/* Ok, look for a following memory ref we can combine with.
	   If one is found, change the memory ref to a PRE_INC
	   or PRE_DEC, cancel this insn, and return 1.
	   Return 0 if nothing has been done.  */
	&& try_pre_increment_1 (pbi, insn))
      return prev;
  }
#endif /* AUTO_INC_DEC */

  CLEAR_REG_SET (pbi->new_set);

  /* If this is not the final pass, and this insn is copying the value of
     a library call and it's dead, don't scan the insns that perform the
     library call, so that the call's arguments are not marked live.  */
  if (libcall_is_dead)
    {
      /* Record the death of the dest reg.  */
      mark_set_regs (pbi, PATTERN (insn), insn);

      insn = XEXP (note, 0);
      return PREV_INSN (insn);
    }
  else if (GET_CODE (PATTERN (insn)) == SET
	   && SET_DEST (PATTERN (insn)) == stack_pointer_rtx
	   && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
	   && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx
	   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
    {
      /* We have an insn to pop a constant amount off the stack.
         (Such insns use PLUS regardless of the direction of the stack,
         and any insn to adjust the stack by a constant is always a pop
	 or part of a push.)
         These insns, if not dead stores, have no effect on life, though
         they do have an effect on the memory stores we are tracking.  */
      invalidate_mems_from_set (pbi, stack_pointer_rtx);
      /* Still, we need to update local_set, lest ifcvt.c:dead_or_predicable
	 concludes that the stack pointer is not modified.  */
      mark_set_regs (pbi, PATTERN (insn), insn);
    }
  else
    {
      rtx note;
      /* Any regs live at the time of a call instruction must not go
	 in a register clobbered by calls.  Find all regs now live and
	 record this for them.  */

      if (CALL_P (insn) && (flags & PROP_REG_INFO))
	{
	  reg_set_iterator rsi;
	  EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi)
	    REG_N_CALLS_CROSSED (i)++;
	}

      /* Record sets.  Do this even for dead instructions, since they
	 would have killed the values if they hadn't been deleted.  */
      mark_set_regs (pbi, PATTERN (insn), insn);

      if (CALL_P (insn))
	{
	  regset live_at_end;
	  bool sibcall_p;
	  rtx note, cond;
	  int i;

	  cond = NULL_RTX;
	  if (GET_CODE (PATTERN (insn)) == COND_EXEC)
	    cond = COND_EXEC_TEST (PATTERN (insn));

	  /* Non-constant calls clobber memory, constant calls do not
	     clobber memory, though they may clobber outgoing arguments
	     on the stack.  */
	  if (! CONST_OR_PURE_CALL_P (insn))
	    {
	      free_EXPR_LIST_list (&pbi->mem_set_list);
	      pbi->mem_set_list_len = 0;
	    }
	  else
	    invalidate_mems_from_set (pbi, stack_pointer_rtx);

	  /* There may be extra registers to be clobbered.  */
	  for (note = CALL_INSN_FUNCTION_USAGE (insn);
	       note;
	       note = XEXP (note, 1))
	    if (GET_CODE (XEXP (note, 0)) == CLOBBER)
	      mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0),
			  cond, insn, pbi->flags);

	  /* Calls change all call-used and global registers; sibcalls do not
	     clobber anything that must be preserved at end-of-function,
	     except for return values.  */

	  sibcall_p = SIBLING_CALL_P (insn);
	  live_at_end = EXIT_BLOCK_PTR->global_live_at_start;
	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
		&& ! (sibcall_p
		      && REGNO_REG_SET_P (live_at_end, i)
		      && ! refers_to_regno_p (i, i+1,
					      current_function_return_rtx,
					      (rtx *) 0)))
	      {
		enum rtx_code code = global_regs[i] ? SET : CLOBBER;
		/* We do not want REG_UNUSED notes for these registers.  */
		mark_set_1 (pbi, code, regno_reg_rtx[i], cond, insn,
			    pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
	      }
	}

      /* If an insn doesn't use CC0, it becomes dead since we assume
	 that every insn clobbers it.  So show it dead here;
	 mark_used_regs will set it live if it is referenced.  */
      pbi->cc0_live = 0;

      /* Record uses.  */
      if (! insn_is_dead)
	mark_used_regs (pbi, PATTERN (insn), NULL_RTX, insn);
      if ((flags & PROP_EQUAL_NOTES)
	  && ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX))
	      || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX))))
	mark_used_regs (pbi, XEXP (note, 0), NULL_RTX, insn);

      /* Sometimes we may have inserted something before INSN (such as a move)
	 when we make an auto-inc.  So ensure we will scan those insns.  */
#ifdef AUTO_INC_DEC
      prev = PREV_INSN (insn);
#endif

      if (! insn_is_dead && CALL_P (insn))
	{
	  int i;
	  rtx note, cond;

	  cond = NULL_RTX;
	  if (GET_CODE (PATTERN (insn)) == COND_EXEC)
	    cond = COND_EXEC_TEST (PATTERN (insn));

	  /* Calls use their arguments, and may clobber memory which
	     address involves some register.  */
	  for (note = CALL_INSN_FUNCTION_USAGE (insn);
	       note;
	       note = XEXP (note, 1))
	    /* We find USE or CLOBBER entities in a FUNCTION_USAGE list: both
	       of which mark_used_regs knows how to handle.  */
	    mark_used_regs (pbi, XEXP (XEXP (note, 0), 0), cond, insn);

	  /* The stack ptr is used (honorarily) by a CALL insn.  */
	  if ((flags & PROP_REG_INFO)
	      && !REGNO_REG_SET_P (pbi->reg_live, STACK_POINTER_REGNUM))
	    reg_deaths[STACK_POINTER_REGNUM] = pbi->insn_num;
	  SET_REGNO_REG_SET (pbi->reg_live, STACK_POINTER_REGNUM);

	  /* Calls may also reference any of the global registers,
	     so they are made live.  */
	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	    if (global_regs[i])
	      mark_used_reg (pbi, regno_reg_rtx[i], cond, insn);
	}
    }

  pbi->insn_num++;

  return prev;
}

/* Initialize a propagate_block_info struct for public consumption.
   Note that the structure itself is opaque to this file, but that
   the user can use the regsets provided here.  */

struct propagate_block_info *
init_propagate_block_info (basic_block bb, regset live, regset local_set,
			   regset cond_local_set, int flags)
{
  struct propagate_block_info *pbi = xmalloc (sizeof (*pbi));

  pbi->bb = bb;
  pbi->reg_live = live;
  pbi->mem_set_list = NULL_RTX;
  pbi->mem_set_list_len = 0;
  pbi->local_set = local_set;
  pbi->cond_local_set = cond_local_set;
  pbi->cc0_live = 0;
  pbi->flags = flags;
  pbi->insn_num = 0;

  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
    pbi->reg_next_use = xcalloc (max_reg_num (), sizeof (rtx));
  else
    pbi->reg_next_use = NULL;

  pbi->new_set = BITMAP_ALLOC (NULL);

#ifdef HAVE_conditional_execution
  pbi->reg_cond_dead = splay_tree_new (splay_tree_compare_ints, NULL,
				       free_reg_cond_life_info);
  pbi->reg_cond_reg = BITMAP_ALLOC (NULL);

  /* If this block ends in a conditional branch, for each register
     live from one side of the branch and not the other, record the
     register as conditionally dead.  */
  if (JUMP_P (BB_END (bb))
      && any_condjump_p (BB_END (bb)))
    {
      regset diff = ALLOC_REG_SET (&reg_obstack);
      basic_block bb_true, bb_false;
      unsigned i;

      /* Identify the successor blocks.  */
      bb_true = EDGE_SUCC (bb, 0)->dest;
      if (EDGE_COUNT (bb->succs) > 1)
	{
	  bb_false = EDGE_SUCC (bb, 1)->dest;

	  if (EDGE_SUCC (bb, 0)->flags & EDGE_FALLTHRU)
	    {
	      basic_block t = bb_false;
	      bb_false = bb_true;
	      bb_true = t;
	    }
	  else
	    gcc_assert (EDGE_SUCC (bb, 1)->flags & EDGE_FALLTHRU);
	}
      else
	{
	  /* This can happen with a conditional jump to the next insn.  */
	  gcc_assert (JUMP_LABEL (BB_END (bb)) == BB_HEAD (bb_true));

	  /* Simplest way to do nothing.  */
	  bb_false = bb_true;
	}

      /* Compute which register lead different lives in the successors.  */
      bitmap_xor (diff, bb_true->global_live_at_start,
		  bb_false->global_live_at_start);
      
      if (!bitmap_empty_p (diff))
	  {
	  /* Extract the condition from the branch.  */
	  rtx set_src = SET_SRC (pc_set (BB_END (bb)));
	  rtx cond_true = XEXP (set_src, 0);
	  rtx reg = XEXP (cond_true, 0);
 	  enum rtx_code inv_cond;

	  if (GET_CODE (reg) == SUBREG)
	    reg = SUBREG_REG (reg);

	  /* We can only track conditional lifetimes if the condition is
 	     in the form of a reversible comparison of a register against
 	     zero.  If the condition is more complex than that, then it is
 	     safe not to record any information.  */
 	  inv_cond = reversed_comparison_code (cond_true, BB_END (bb));
 	  if (inv_cond != UNKNOWN
 	      && REG_P (reg)
	      && XEXP (cond_true, 1) == const0_rtx)
	    {
	      rtx cond_false
		= gen_rtx_fmt_ee (inv_cond,
				  GET_MODE (cond_true), XEXP (cond_true, 0),
				  XEXP (cond_true, 1));
	      reg_set_iterator rsi;

	      if (GET_CODE (XEXP (set_src, 1)) == PC)
		{
		  rtx t = cond_false;
		  cond_false = cond_true;
		  cond_true = t;
		}

	      SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));

	      /* For each such register, mark it conditionally dead.  */
	      EXECUTE_IF_SET_IN_REG_SET (diff, 0, i, rsi)
		{
		  struct reg_cond_life_info *rcli;
		  rtx cond;

		  rcli = xmalloc (sizeof (*rcli));

		  if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
		    cond = cond_false;
		  else
		    cond = cond_true;
		  rcli->condition = cond;
		  rcli->stores = const0_rtx;
		  rcli->orig_condition = cond;

		  splay_tree_insert (pbi->reg_cond_dead, i,
				     (splay_tree_value) rcli);
		}
	    }
	}

      FREE_REG_SET (diff);
    }
#endif

  /* If this block has no successors, any stores to the frame that aren't
     used later in the block are dead.  So make a pass over the block
     recording any such that are made and show them dead at the end.  We do
     a very conservative and simple job here.  */
  if (optimize
      && ! (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
	    && (TYPE_RETURNS_STACK_DEPRESSED
		(TREE_TYPE (current_function_decl))))
      && (flags & PROP_SCAN_DEAD_STORES)
      && (EDGE_COUNT (bb->succs) == 0
	  || (EDGE_COUNT (bb->succs) == 1
	      && EDGE_SUCC (bb, 0)->dest == EXIT_BLOCK_PTR
	      && ! current_function_calls_eh_return)))
    {
      rtx insn, set;
      for (insn = BB_END (bb); insn != BB_HEAD (bb); insn = PREV_INSN (insn))
	if (NONJUMP_INSN_P (insn)
	    && (set = single_set (insn))
	    && MEM_P (SET_DEST (set)))
	  {
	    rtx mem = SET_DEST (set);
	    rtx canon_mem = canon_rtx (mem);

	    if (XEXP (canon_mem, 0) == frame_pointer_rtx
		|| (GET_CODE (XEXP (canon_mem, 0)) == PLUS
		    && XEXP (XEXP (canon_mem, 0), 0) == frame_pointer_rtx
		    && GET_CODE (XEXP (XEXP (canon_mem, 0), 1)) == CONST_INT))
	      add_to_mem_set_list (pbi, canon_mem);
	  }
    }

  return pbi;
}

/* Release a propagate_block_info struct.  */

void
free_propagate_block_info (struct propagate_block_info *pbi)
{
  free_EXPR_LIST_list (&pbi->mem_set_list);

  BITMAP_FREE (pbi->new_set);

#ifdef HAVE_conditional_execution
  splay_tree_delete (pbi->reg_cond_dead);
  BITMAP_FREE (pbi->reg_cond_reg);
#endif

  if (pbi->flags & PROP_REG_INFO)
    {
      int num = pbi->insn_num;
      unsigned i;
      reg_set_iterator rsi;

      EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi)
	{
	  REG_LIVE_LENGTH (i) += num - reg_deaths[i];
	  reg_deaths[i] = 0;
	}
    }
  if (pbi->reg_next_use)
    free (pbi->reg_next_use);

  free (pbi);
}

/* Compute the registers live at the beginning of a basic block BB from
   those live at the end.

   When called, REG_LIVE contains those live at the end.  On return, it
   contains those live at the beginning.

   LOCAL_SET, if non-null, will be set with all registers killed
   unconditionally by this basic block.
   Likewise, COND_LOCAL_SET, if non-null, will be set with all registers
   killed conditionally by this basic block.  If there is any unconditional
   set of a register, then the corresponding bit will be set in LOCAL_SET
   and cleared in COND_LOCAL_SET.
   It is valid for LOCAL_SET and COND_LOCAL_SET to be the same set.  In this
   case, the resulting set will be equal to the union of the two sets that
   would otherwise be computed.

   Return nonzero if an INSN is deleted (i.e. by dead code removal).  */

int
propagate_block (basic_block bb, regset live, regset local_set,
		 regset cond_local_set, int flags)
{
  struct propagate_block_info *pbi;
  rtx insn, prev;
  int changed;

  pbi = init_propagate_block_info (bb, live, local_set, cond_local_set, flags);

  if (flags & PROP_REG_INFO)
    {
      unsigned i;
      reg_set_iterator rsi;

      /* Process the regs live at the end of the block.
	 Mark them as not local to any one basic block.  */
      EXECUTE_IF_SET_IN_REG_SET (live, 0, i, rsi)
	REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
    }

  /* Scan the block an insn at a time from end to beginning.  */

  changed = 0;
  for (insn = BB_END (bb); ; insn = prev)
    {
      /* If this is a call to `setjmp' et al, warn if any
	 non-volatile datum is live.  */
      if ((flags & PROP_REG_INFO)
	  && CALL_P (insn)
	  && find_reg_note (insn, REG_SETJMP, NULL))
	IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);

      prev = propagate_one_insn (pbi, insn);
      if (!prev)
        changed |= insn != get_insns ();
      else
        changed |= NEXT_INSN (prev) != insn;

      if (insn == BB_HEAD (bb))
	break;
    }

  free_propagate_block_info (pbi);

  return changed;
}

/* Return 1 if X (the body of an insn, or part of it) is just dead stores
   (SET expressions whose destinations are registers dead after the insn).
   NEEDED is the regset that says which regs are alive after the insn.

   Unless CALL_OK is nonzero, an insn is needed if it contains a CALL.

   If X is the entire body of an insn, NOTES contains the reg notes
   pertaining to the insn.  */

static int
insn_dead_p (struct propagate_block_info *pbi, rtx x, int call_ok,
	     rtx notes ATTRIBUTE_UNUSED)
{
  enum rtx_code code = GET_CODE (x);

  /* Don't eliminate insns that may trap.  */
  if (flag_non_call_exceptions && may_trap_p (x))
    return 0;

#ifdef AUTO_INC_DEC
  /* As flow is invoked after combine, we must take existing AUTO_INC
     expressions into account.  */
  for (; notes; notes = XEXP (notes, 1))
    {
      if (REG_NOTE_KIND (notes) == REG_INC)
	{
	  int regno = REGNO (XEXP (notes, 0));

	  /* Don't delete insns to set global regs.  */
	  if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
	      || REGNO_REG_SET_P (pbi->reg_live, regno))
	    return 0;
	}
    }
#endif

  /* If setting something that's a reg or part of one,
     see if that register's altered value will be live.  */

  if (code == SET)
    {
      rtx r = SET_DEST (x);

#ifdef HAVE_cc0
      if (GET_CODE (r) == CC0)
	return ! pbi->cc0_live;
#endif

      /* A SET that is a subroutine call cannot be dead.  */
      if (GET_CODE (SET_SRC (x)) == CALL)
	{
	  if (! call_ok)
	    return 0;
	}

      /* Don't eliminate loads from volatile memory or volatile asms.  */
      else if (volatile_refs_p (SET_SRC (x)))
	return 0;

      if (MEM_P (r))
	{
	  rtx temp, canon_r;

	  if (MEM_VOLATILE_P (r) || GET_MODE (r) == BLKmode)
	    return 0;

	  canon_r = canon_rtx (r);

	  /* Walk the set of memory locations we are currently tracking
	     and see if one is an identical match to this memory location.
	     If so, this memory write is dead (remember, we're walking
	     backwards from the end of the block to the start).  Since
	     rtx_equal_p does not check the alias set or flags, we also
	     must have the potential for them to conflict (anti_dependence).  */
	  for (temp = pbi->mem_set_list; temp != 0; temp = XEXP (temp, 1))
	    if (anti_dependence (r, XEXP (temp, 0)))
	      {
		rtx mem = XEXP (temp, 0);

		if (rtx_equal_p (XEXP (canon_r, 0), XEXP (mem, 0))
		    && (GET_MODE_SIZE (GET_MODE (canon_r))
			<= GET_MODE_SIZE (GET_MODE (mem))))
		  return 1;

#ifdef AUTO_INC_DEC
		/* Check if memory reference matches an auto increment. Only
		   post increment/decrement or modify are valid.  */
		if (GET_MODE (mem) == GET_MODE (r)
		    && (GET_CODE (XEXP (mem, 0)) == POST_DEC
			|| GET_CODE (XEXP (mem, 0)) == POST_INC
			|| GET_CODE (XEXP (mem, 0)) == POST_MODIFY)
		    && GET_MODE (XEXP (mem, 0)) == GET_MODE (r)
		    && rtx_equal_p (XEXP (XEXP (mem, 0), 0), XEXP (r, 0)))
		  return 1;
#endif
	      }
	}
      else
	{
	  while (GET_CODE (r) == SUBREG
		 || GET_CODE (r) == STRICT_LOW_PART
		 || GET_CODE (r) == ZERO_EXTRACT)
	    r = XEXP (r, 0);

	  if (REG_P (r))
	    {
	      int regno = REGNO (r);

	      /* Obvious.  */
	      if (REGNO_REG_SET_P (pbi->reg_live, regno))
		return 0;

	      /* If this is a hard register, verify that subsequent
		 words are not needed.  */
	      if (regno < FIRST_PSEUDO_REGISTER)
		{
		  int n = hard_regno_nregs[regno][GET_MODE (r)];

		  while (--n > 0)
		    if (REGNO_REG_SET_P (pbi->reg_live, regno+n))
		      return 0;
		}

	      /* Don't delete insns to set global regs.  */
	      if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
		return 0;

	      /* Make sure insns to set the stack pointer aren't deleted.  */
	      if (regno == STACK_POINTER_REGNUM)
		return 0;

	      /* ??? These bits might be redundant with the force live bits
		 in calculate_global_regs_live.  We would delete from
		 sequential sets; whether this actually affects real code
		 for anything but the stack pointer I don't know.  */
	      /* Make sure insns to set the frame pointer aren't deleted.  */
	      if (regno == FRAME_POINTER_REGNUM
		  && (! reload_completed || frame_pointer_needed))
		return 0;
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
	      if (regno == HARD_FRAME_POINTER_REGNUM
		  && (! reload_completed || frame_pointer_needed))
		return 0;
#endif

#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	      /* Make sure insns to set arg pointer are never deleted
		 (if the arg pointer isn't fixed, there will be a USE
		 for it, so we can treat it normally).  */
	      if (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
		return 0;
#endif

	      /* Otherwise, the set is dead.  */
	      return 1;
	    }
	}
    }

  /* If performing several activities, insn is dead if each activity
     is individually dead.  Also, CLOBBERs and USEs can be ignored; a
     CLOBBER or USE that's inside a PARALLEL doesn't make the insn
     worth keeping.  */
  else if (code == PARALLEL)
    {
      int i = XVECLEN (x, 0);

      for (i--; i >= 0; i--)
	if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
	    && GET_CODE (XVECEXP (x, 0, i)) != USE
	    && ! insn_dead_p (pbi, XVECEXP (x, 0, i), call_ok, NULL_RTX))
	  return 0;

      return 1;
    }

  /* A CLOBBER of a pseudo-register that is dead serves no purpose.  That
     is not necessarily true for hard registers until after reload.  */
  else if (code == CLOBBER)
    {
      if (REG_P (XEXP (x, 0))
	  && (REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER
	      || reload_completed)
	  && ! REGNO_REG_SET_P (pbi->reg_live, REGNO (XEXP (x, 0))))
	return 1;
    }

  /* ??? A base USE is a historical relic.  It ought not be needed anymore.
     Instances where it is still used are either (1) temporary and the USE
     escaped the pass, (2) cruft and the USE need not be emitted anymore,
     or (3) hiding bugs elsewhere that are not properly representing data
     flow.  */

  return 0;
}

/* If INSN is the last insn in a libcall, and assuming INSN is dead,
   return 1 if the entire library call is dead.
   This is true if INSN copies a register (hard or pseudo)
   and if the hard return reg of the call insn is dead.
   (The caller should have tested the destination of the SET inside
   INSN already for death.)

   If this insn doesn't just copy a register, then we don't
   have an ordinary libcall.  In that case, cse could not have
   managed to substitute the source for the dest later on,
   so we can assume the libcall is dead.

   PBI is the block info giving pseudoregs live before this insn.
   NOTE is the REG_RETVAL note of the insn.  */

static int
libcall_dead_p (struct propagate_block_info *pbi, rtx note, rtx insn)
{
  rtx x = single_set (insn);

  if (x)
    {
      rtx r = SET_SRC (x);

      if (REG_P (r) || GET_CODE (r) == SUBREG)
	{
	  rtx call = XEXP (note, 0);
	  rtx call_pat;
	  int i;

	  /* Find the call insn.  */
	  while (call != insn && !CALL_P (call))
	    call = NEXT_INSN (call);

	  /* If there is none, do nothing special,
	     since ordinary death handling can understand these insns.  */
	  if (call == insn)
	    return 0;

	  /* See if the hard reg holding the value is dead.
	     If this is a PARALLEL, find the call within it.  */
	  call_pat = PATTERN (call);
	  if (GET_CODE (call_pat) == PARALLEL)
	    {
	      for (i = XVECLEN (call_pat, 0) - 1; i >= 0; i--)
		if (GET_CODE (XVECEXP (call_pat, 0, i)) == SET
		    && GET_CODE (SET_SRC (XVECEXP (call_pat, 0, i))) == CALL)
		  break;

	      /* This may be a library call that is returning a value
		 via invisible pointer.  Do nothing special, since
		 ordinary death handling can understand these insns.  */
	      if (i < 0)
		return 0;

	      call_pat = XVECEXP (call_pat, 0, i);
	    }

	  if (! insn_dead_p (pbi, call_pat, 1, REG_NOTES (call)))
	    return 0;

	  while ((insn = PREV_INSN (insn)) != call)
	    {
	      if (! INSN_P (insn))
		continue;
	      if (! insn_dead_p (pbi, PATTERN (insn), 0, REG_NOTES (insn)))
		return 0;
	    }
	  return 1;
	}
    }
  return 0;
}

/* 1 if register REGNO was alive at a place where `setjmp' was called
   and was set more than once or is an argument.
   Such regs may be clobbered by `longjmp'.  */

int
regno_clobbered_at_setjmp (int regno)
{
  if (n_basic_blocks == 0)
    return 0;

  return ((REG_N_SETS (regno) > 1
	   || REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno))
	  && REGNO_REG_SET_P (regs_live_at_setjmp, regno));
}

/* Add MEM to PBI->MEM_SET_LIST.  MEM should be canonical.  Respect the
   maximal list size; look for overlaps in mode and select the largest.  */
static void
add_to_mem_set_list (struct propagate_block_info *pbi, rtx mem)
{
  rtx i;

  /* We don't know how large a BLKmode store is, so we must not
     take them into consideration.  */
  if (GET_MODE (mem) == BLKmode)
    return;

  for (i = pbi->mem_set_list; i ; i = XEXP (i, 1))
    {
      rtx e = XEXP (i, 0);
      if (rtx_equal_p (XEXP (mem, 0), XEXP (e, 0)))
	{
	  if (GET_MODE_SIZE (GET_MODE (mem)) > GET_MODE_SIZE (GET_MODE (e)))
	    {
#ifdef AUTO_INC_DEC
	      /* If we must store a copy of the mem, we can just modify
		 the mode of the stored copy.  */
	      if (pbi->flags & PROP_AUTOINC)
	        PUT_MODE (e, GET_MODE (mem));
	      else
#endif
	        XEXP (i, 0) = mem;
	    }
	  return;
	}
    }

  if (pbi->mem_set_list_len < MAX_MEM_SET_LIST_LEN)
    {
#ifdef AUTO_INC_DEC
      /* Store a copy of mem, otherwise the address may be
	 scrogged by find_auto_inc.  */
      if (pbi->flags & PROP_AUTOINC)
	mem = shallow_copy_rtx (mem);
#endif
      pbi->mem_set_list = alloc_EXPR_LIST (0, mem, pbi->mem_set_list);
      pbi->mem_set_list_len++;
    }
}

/* INSN references memory, possibly using autoincrement addressing modes.
   Find any entries on the mem_set_list that need to be invalidated due
   to an address change.  */

static int
invalidate_mems_from_autoinc (rtx *px, void *data)
{
  rtx x = *px;
  struct propagate_block_info *pbi = data;

  if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
    {
      invalidate_mems_from_set (pbi, XEXP (x, 0));
      return -1;
    }

  return 0;
}

/* EXP is a REG.  Remove any dependent entries from pbi->mem_set_list.  */

static void
invalidate_mems_from_set (struct propagate_block_info *pbi, rtx exp)
{
  rtx temp = pbi->mem_set_list;
  rtx prev = NULL_RTX;
  rtx next;

  while (temp)
    {
      next = XEXP (temp, 1);
      if (reg_overlap_mentioned_p (exp, XEXP (temp, 0)))
	{
	  /* Splice this entry out of the list.  */
	  if (prev)
	    XEXP (prev, 1) = next;
	  else
	    pbi->mem_set_list = next;
	  free_EXPR_LIST_node (temp);
	  pbi->mem_set_list_len--;
	}
      else
	prev = temp;
      temp = next;
    }
}

/* Process the registers that are set within X.  Their bits are set to
   1 in the regset DEAD, because they are dead prior to this insn.

   If INSN is nonzero, it is the insn being processed.

   FLAGS is the set of operations to perform.  */

static void
mark_set_regs (struct propagate_block_info *pbi, rtx x, rtx insn)
{
  rtx cond = NULL_RTX;
  rtx link;
  enum rtx_code code;
  int flags = pbi->flags;

  if (insn)
    for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
      {
	if (REG_NOTE_KIND (link) == REG_INC)
	  mark_set_1 (pbi, SET, XEXP (link, 0),
		      (GET_CODE (x) == COND_EXEC
		       ? COND_EXEC_TEST (x) : NULL_RTX),
		      insn, flags);
      }
 retry:
  switch (code = GET_CODE (x))
    {
    case SET:
      if (GET_CODE (XEXP (x, 1)) == ASM_OPERANDS)
	flags |= PROP_ASM_SCAN;
      /* Fall through */
    case CLOBBER:
      mark_set_1 (pbi, code, SET_DEST (x), cond, insn, flags);
      return;

    case COND_EXEC:
      cond = COND_EXEC_TEST (x);
      x = COND_EXEC_CODE (x);
      goto retry;

    case PARALLEL:
      {
	int i;

	/* We must scan forwards.  If we have an asm, we need to set
	   the PROP_ASM_SCAN flag before scanning the clobbers.  */
	for (i = 0; i < XVECLEN (x, 0); i++)
	  {
	    rtx sub = XVECEXP (x, 0, i);
	    switch (code = GET_CODE (sub))
	      {
	      case COND_EXEC:
		gcc_assert (!cond);

		cond = COND_EXEC_TEST (sub);
		sub = COND_EXEC_CODE (sub);
		if (GET_CODE (sub) == SET)
		  goto mark_set;
		if (GET_CODE (sub) == CLOBBER)
		  goto mark_clob;
		break;

	      case SET:
	      mark_set:
		if (GET_CODE (XEXP (sub, 1)) == ASM_OPERANDS)
		  flags |= PROP_ASM_SCAN;
		/* Fall through */
	      case CLOBBER:
	      mark_clob:
		mark_set_1 (pbi, code, SET_DEST (sub), cond, insn, flags);
		break;

	      case ASM_OPERANDS:
		flags |= PROP_ASM_SCAN;
		break;

	      default:
		break;
	      }
	  }
	break;
      }

    default:
      break;
    }
}

/* Process a single set, which appears in INSN.  REG (which may not
   actually be a REG, it may also be a SUBREG, PARALLEL, etc.) is
   being set using the CODE (which may be SET, CLOBBER, or COND_EXEC).
   If the set is conditional (because it appear in a COND_EXEC), COND
   will be the condition.  */

static void
mark_set_1 (struct propagate_block_info *pbi, enum rtx_code code, rtx reg, rtx cond, rtx insn, int flags)
{
  int regno_first = -1, regno_last = -1;
  unsigned long not_dead = 0;
  int i;

  /* Modifying just one hardware register of a multi-reg value or just a
     byte field of a register does not mean the value from before this insn
     is now dead.  Of course, if it was dead after it's unused now.  */

  switch (GET_CODE (reg))
    {
    case PARALLEL:
      /* Some targets place small structures in registers for return values of
	 functions.  We have to detect this case specially here to get correct
	 flow information.  */
      for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
	if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
	  mark_set_1 (pbi, code, XEXP (XVECEXP (reg, 0, i), 0), cond, insn,
		      flags);
      return;

    case SIGN_EXTRACT:
      /* SIGN_EXTRACT cannot be an lvalue.  */
      gcc_unreachable ();

    case ZERO_EXTRACT:
    case STRICT_LOW_PART:
      /* ??? Assumes STRICT_LOW_PART not used on multi-word registers.  */
      do
	reg = XEXP (reg, 0);
      while (GET_CODE (reg) == SUBREG
	     || GET_CODE (reg) == ZERO_EXTRACT
	     || GET_CODE (reg) == STRICT_LOW_PART);
      if (MEM_P (reg))
	break;
      not_dead = (unsigned long) REGNO_REG_SET_P (pbi->reg_live, REGNO (reg));
      /* Fall through.  */

    case REG:
      regno_last = regno_first = REGNO (reg);
      if (regno_first < FIRST_PSEUDO_REGISTER)
	regno_last += hard_regno_nregs[regno_first][GET_MODE (reg)] - 1;
      break;

    case SUBREG:
      if (REG_P (SUBREG_REG (reg)))
	{
	  enum machine_mode outer_mode = GET_MODE (reg);
	  enum machine_mode inner_mode = GET_MODE (SUBREG_REG (reg));

	  /* Identify the range of registers affected.  This is moderately
	     tricky for hard registers.  See alter_subreg.  */

	  regno_last = regno_first = REGNO (SUBREG_REG (reg));
	  if (regno_first < FIRST_PSEUDO_REGISTER)
	    {
	      regno_first += subreg_regno_offset (regno_first, inner_mode,
						  SUBREG_BYTE (reg),
						  outer_mode);
	      regno_last = (regno_first
			    + hard_regno_nregs[regno_first][outer_mode] - 1);

	      /* Since we've just adjusted the register number ranges, make
		 sure REG matches.  Otherwise some_was_live will be clear
		 when it shouldn't have been, and we'll create incorrect
		 REG_UNUSED notes.  */
	      reg = gen_rtx_REG (outer_mode, regno_first);
	    }
	  else
	    {
	      /* If the number of words in the subreg is less than the number
		 of words in the full register, we have a well-defined partial
		 set.  Otherwise the high bits are undefined.

		 This is only really applicable to pseudos, since we just took
		 care of multi-word hard registers.  */
	      if (((GET_MODE_SIZE (outer_mode)
		    + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
		  < ((GET_MODE_SIZE (inner_mode)
		      + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
		not_dead = (unsigned long) REGNO_REG_SET_P (pbi->reg_live,
							    regno_first);

	      reg = SUBREG_REG (reg);
	    }
	}
      else
	reg = SUBREG_REG (reg);
      break;

    default:
      break;
    }

  /* If this set is a MEM, then it kills any aliased writes.
     If this set is a REG, then it kills any MEMs which use the reg.  */
  if (optimize && (flags & PROP_SCAN_DEAD_STORES))
    {
      if (REG_P (reg))
	invalidate_mems_from_set (pbi, reg);

      /* If the memory reference had embedded side effects (autoincrement
	 address modes) then we may need to kill some entries on the
	 memory set list.  */
      if (insn && MEM_P (reg))
	for_each_rtx (&PATTERN (insn), invalidate_mems_from_autoinc, pbi);

      if (MEM_P (reg) && ! side_effects_p (reg)
	  /* ??? With more effort we could track conditional memory life.  */
	  && ! cond)
	add_to_mem_set_list (pbi, canon_rtx (reg));
    }

  if (REG_P (reg)
      && ! (regno_first == FRAME_POINTER_REGNUM
	    && (! reload_completed || frame_pointer_needed))
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
      && ! (regno_first == HARD_FRAME_POINTER_REGNUM
	    && (! reload_completed || frame_pointer_needed))
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
      && ! (regno_first == ARG_POINTER_REGNUM && fixed_regs[regno_first])
#endif
      )
    {
      int some_was_live = 0, some_was_dead = 0;

      for (i = regno_first; i <= regno_last; ++i)
	{
	  int needed_regno = REGNO_REG_SET_P (pbi->reg_live, i);
	  if (pbi->local_set)
	    {
	      /* Order of the set operation matters here since both
		 sets may be the same.  */
	      CLEAR_REGNO_REG_SET (pbi->cond_local_set, i);
	      if (cond != NULL_RTX
		  && ! REGNO_REG_SET_P (pbi->local_set, i))
		SET_REGNO_REG_SET (pbi->cond_local_set, i);
	      else
		SET_REGNO_REG_SET (pbi->local_set, i);
	    }
	  if (code != CLOBBER)
	    SET_REGNO_REG_SET (pbi->new_set, i);

	  some_was_live |= needed_regno;
	  some_was_dead |= ! needed_regno;
	}

#ifdef HAVE_conditional_execution
      /* Consider conditional death in deciding that the register needs
	 a death note.  */
      if (some_was_live && ! not_dead
	  /* The stack pointer is never dead.  Well, not strictly true,
	     but it's very difficult to tell from here.  Hopefully
	     combine_stack_adjustments will fix up the most egregious
	     errors.  */
	  && regno_first != STACK_POINTER_REGNUM)
	{
	  for (i = regno_first; i <= regno_last; ++i)
	    if (! mark_regno_cond_dead (pbi, i, cond))
	      not_dead |= ((unsigned long) 1) << (i - regno_first);
	}
#endif

      /* Additional data to record if this is the final pass.  */
      if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
		   | PROP_DEATH_NOTES | PROP_AUTOINC))
	{
	  rtx y;
	  int blocknum = pbi->bb->index;

	  y = NULL_RTX;
	  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
	    {
	      y = pbi->reg_next_use[regno_first];

	      /* The next use is no longer next, since a store intervenes.  */
	      for (i = regno_first; i <= regno_last; ++i)
		pbi->reg_next_use[i] = 0;
	    }

	  if (flags & PROP_REG_INFO)
	    {
	      for (i = regno_first; i <= regno_last; ++i)
		{
		  /* Count (weighted) references, stores, etc.  This counts a
		     register twice if it is modified, but that is correct.  */
		  REG_N_SETS (i) += 1;
		  REG_N_REFS (i) += 1;
		  REG_FREQ (i) += REG_FREQ_FROM_BB (pbi->bb);

	          /* The insns where a reg is live are normally counted
		     elsewhere, but we want the count to include the insn
		     where the reg is set, and the normal counting mechanism
		     would not count it.  */
		  REG_LIVE_LENGTH (i) += 1;
		}

	      /* If this is a hard reg, record this function uses the reg.  */
	      if (regno_first < FIRST_PSEUDO_REGISTER)
		{
		  for (i = regno_first; i <= regno_last; i++)
		    regs_ever_live[i] = 1;
		  if (flags & PROP_ASM_SCAN)
		    for (i = regno_first; i <= regno_last; i++)
		      regs_asm_clobbered[i] = 1;
		}
	      else
		{
		  /* Keep track of which basic blocks each reg appears in.  */
		  if (REG_BASIC_BLOCK (regno_first) == REG_BLOCK_UNKNOWN)
		    REG_BASIC_BLOCK (regno_first) = blocknum;
		  else if (REG_BASIC_BLOCK (regno_first) != blocknum)
		    REG_BASIC_BLOCK (regno_first) = REG_BLOCK_GLOBAL;
		}
	    }

	  if (! some_was_dead)
	    {
	      if (flags & PROP_LOG_LINKS)
		{
		  /* Make a logical link from the next following insn
		     that uses this register, back to this insn.
		     The following insns have already been processed.

		     We don't build a LOG_LINK for hard registers containing
		     in ASM_OPERANDs.  If these registers get replaced,
		     we might wind up changing the semantics of the insn,
		     even if reload can make what appear to be valid
		     assignments later.

		     We don't build a LOG_LINK for global registers to
		     or from a function call.  We don't want to let
		     combine think that it knows what is going on with
		     global registers.  */
		  if (y && (BLOCK_NUM (y) == blocknum)
		      && (regno_first >= FIRST_PSEUDO_REGISTER
			  || (asm_noperands (PATTERN (y)) < 0
			      && ! ((CALL_P (insn)
				     || CALL_P (y))
				    && global_regs[regno_first]))))
		    LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
		}
	    }
	  else if (not_dead)
	    ;
	  else if (! some_was_live)
	    {
	      if (flags & PROP_REG_INFO)
		REG_N_DEATHS (regno_first) += 1;

	      if (flags & PROP_DEATH_NOTES)
		{
		  /* Note that dead stores have already been deleted
		     when possible.  If we get here, we have found a
		     dead store that cannot be eliminated (because the
		     same insn does something useful).  Indicate this
		     by marking the reg being set as dying here.  */
		  REG_NOTES (insn)
		    = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
		}
	    }
	  else
	    {
	      if (flags & PROP_DEATH_NOTES)
		{
		  /* This is a case where we have a multi-word hard register
		     and some, but not all, of the words of the register are
		     needed in subsequent insns.  Write REG_UNUSED notes
		     for those parts that were not needed.  This case should
		     be rare.  */

		  for (i = regno_first; i <= regno_last; ++i)
		    if (! REGNO_REG_SET_P (pbi->reg_live, i))
		      REG_NOTES (insn)
			= alloc_EXPR_LIST (REG_UNUSED,
					   regno_reg_rtx[i],
					   REG_NOTES (insn));
		}
	    }
	}

      /* Mark the register as being dead.  */
      if (some_was_live
	  /* The stack pointer is never dead.  Well, not strictly true,
	     but it's very difficult to tell from here.  Hopefully
	     combine_stack_adjustments will fix up the most egregious
	     errors.  */
	  && regno_first != STACK_POINTER_REGNUM)
	{
	  for (i = regno_first; i <= regno_last; ++i)
	    if (!(not_dead & (((unsigned long) 1) << (i - regno_first))))
	      {
		if ((pbi->flags & PROP_REG_INFO)
		    && REGNO_REG_SET_P (pbi->reg_live, i))
		  {
		    REG_LIVE_LENGTH (i) += pbi->insn_num - reg_deaths[i];
		    reg_deaths[i] = 0;
		  }
		CLEAR_REGNO_REG_SET (pbi->reg_live, i);
	      }
	}
    }
  else if (REG_P (reg))
    {
      if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
	pbi->reg_next_use[regno_first] = 0;

      if ((flags & PROP_REG_INFO) != 0
	  && (flags & PROP_ASM_SCAN) != 0
	  &&  regno_first < FIRST_PSEUDO_REGISTER)
	{
	  for (i = regno_first; i <= regno_last; i++)
	    regs_asm_clobbered[i] = 1;
	}
    }

  /* If this is the last pass and this is a SCRATCH, show it will be dying
     here and count it.  */
  else if (GET_CODE (reg) == SCRATCH)
    {
      if (flags & PROP_DEATH_NOTES)
	REG_NOTES (insn)
	  = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
    }
}

#ifdef HAVE_conditional_execution
/* Mark REGNO conditionally dead.
   Return true if the register is now unconditionally dead.  */

static int
mark_regno_cond_dead (struct propagate_block_info *pbi, int regno, rtx cond)
{
  /* If this is a store to a predicate register, the value of the
     predicate is changing, we don't know that the predicate as seen
     before is the same as that seen after.  Flush all dependent
     conditions from reg_cond_dead.  This will make all such
     conditionally live registers unconditionally live.  */
  if (REGNO_REG_SET_P (pbi->reg_cond_reg, regno))
    flush_reg_cond_reg (pbi, regno);

  /* If this is an unconditional store, remove any conditional
     life that may have existed.  */
  if (cond == NULL_RTX)
    splay_tree_remove (pbi->reg_cond_dead, regno);
  else
    {
      splay_tree_node node;
      struct reg_cond_life_info *rcli;
      rtx ncond;

      /* Otherwise this is a conditional set.  Record that fact.
	 It may have been conditionally used, or there may be a
	 subsequent set with a complementary condition.  */

      node = splay_tree_lookup (pbi->reg_cond_dead, regno);
      if (node == NULL)
	{
	  /* The register was unconditionally live previously.
	     Record the current condition as the condition under
	     which it is dead.  */
	  rcli = xmalloc (sizeof (*rcli));
	  rcli->condition = cond;
	  rcli->stores = cond;
	  rcli->orig_condition = const0_rtx;
	  splay_tree_insert (pbi->reg_cond_dead, regno,
			     (splay_tree_value) rcli);

	  SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (XEXP (cond, 0)));

	  /* Not unconditionally dead.  */
	  return 0;
	}
      else
	{
	  /* The register was conditionally live previously.
	     Add the new condition to the old.  */
	  rcli = (struct reg_cond_life_info *) node->value;
	  ncond = rcli->condition;
	  ncond = ior_reg_cond (ncond, cond, 1);
	  if (rcli->stores == const0_rtx)
	    rcli->stores = cond;
	  else if (rcli->stores != const1_rtx)
	    rcli->stores = ior_reg_cond (rcli->stores, cond, 1);

	  /* If the register is now unconditionally dead, remove the entry
	     in the splay_tree.  A register is unconditionally dead if the
	     dead condition ncond is true.  A register is also unconditionally
	     dead if the sum of all conditional stores is an unconditional
	     store (stores is true), and the dead condition is identically the
	     same as the original dead condition initialized at the end of
	     the block.  This is a pointer compare, not an rtx_equal_p
	     compare.  */
	  if (ncond == const1_rtx
	      || (ncond == rcli->orig_condition && rcli->stores == const1_rtx))
	    splay_tree_remove (pbi->reg_cond_dead, regno);
	  else
	    {
	      rcli->condition = ncond;

	      SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (XEXP (cond, 0)));

	      /* Not unconditionally dead.  */
	      return 0;
	    }
	}
    }

  return 1;
}

/* Called from splay_tree_delete for pbi->reg_cond_life.  */

static void
free_reg_cond_life_info (splay_tree_value value)
{
  struct reg_cond_life_info *rcli = (struct reg_cond_life_info *) value;
  free (rcli);
}

/* Helper function for flush_reg_cond_reg.  */

static int
flush_reg_cond_reg_1 (splay_tree_node node, void *data)
{
  struct reg_cond_life_info *rcli;
  int *xdata = (int *) data;
  unsigned int regno = xdata[0];

  /* Don't need to search if last flushed value was farther on in
     the in-order traversal.  */
  if (xdata[1] >= (int) node->key)
    return 0;

  /* Splice out portions of the expression that refer to regno.  */
  rcli = (struct reg_cond_life_info *) node->value;
  rcli->condition = elim_reg_cond (rcli->condition, regno);
  if (rcli->stores != const0_rtx && rcli->stores != const1_rtx)
    rcli->stores = elim_reg_cond (rcli->stores, regno);

  /* If the entire condition is now false, signal the node to be removed.  */
  if (rcli->condition == const0_rtx)
    {
      xdata[1] = node->key;
      return -1;
    }
  else
    gcc_assert (rcli->condition != const1_rtx);

  return 0;
}

/* Flush all (sub) expressions referring to REGNO from REG_COND_LIVE.  */

static void
flush_reg_cond_reg (struct propagate_block_info *pbi, int regno)
{
  int pair[2];

  pair[0] = regno;
  pair[1] = -1;
  while (splay_tree_foreach (pbi->reg_cond_dead,
			     flush_reg_cond_reg_1, pair) == -1)
    splay_tree_remove (pbi->reg_cond_dead, pair[1]);

  CLEAR_REGNO_REG_SET (pbi->reg_cond_reg, regno);
}

/* Logical arithmetic on predicate conditions.  IOR, NOT and AND.
   For ior/and, the ADD flag determines whether we want to add the new
   condition X to the old one unconditionally.  If it is zero, we will
   only return a new expression if X allows us to simplify part of
   OLD, otherwise we return NULL to the caller.
   If ADD is nonzero, we will return a new condition in all cases.  The
   toplevel caller of one of these functions should always pass 1 for
   ADD.  */

static rtx
ior_reg_cond (rtx old, rtx x, int add)
{
  rtx op0, op1;

  if (COMPARISON_P (old))
    {
      if (COMPARISON_P (x)
	  && REVERSE_CONDEXEC_PREDICATES_P (x, old)
	  && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
	return const1_rtx;
      if (GET_CODE (x) == GET_CODE (old)
	  && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
	return old;
      if (! add)
	return NULL;
      return gen_rtx_IOR (0, old, x);
    }

  switch (GET_CODE (old))
    {
    case IOR:
      op0 = ior_reg_cond (XEXP (old, 0), x, 0);
      op1 = ior_reg_cond (XEXP (old, 1), x, 0);
      if (op0 != NULL || op1 != NULL)
	{
	  if (op0 == const0_rtx)
	    return op1 ? op1 : gen_rtx_IOR (0, XEXP (old, 1), x);
	  if (op1 == const0_rtx)
	    return op0 ? op0 : gen_rtx_IOR (0, XEXP (old, 0), x);
	  if (op0 == const1_rtx || op1 == const1_rtx)
	    return const1_rtx;
	  if (op0 == NULL)
	    op0 = gen_rtx_IOR (0, XEXP (old, 0), x);
	  else if (rtx_equal_p (x, op0))
	    /* (x | A) | x ~ (x | A).  */
	    return old;
	  if (op1 == NULL)
	    op1 = gen_rtx_IOR (0, XEXP (old, 1), x);
	  else if (rtx_equal_p (x, op1))
	    /* (A | x) | x ~ (A | x).  */
	    return old;
	  return gen_rtx_IOR (0, op0, op1);
	}
      if (! add)
	return NULL;
      return gen_rtx_IOR (0, old, x);

    case AND:
      op0 = ior_reg_cond (XEXP (old, 0), x, 0);
      op1 = ior_reg_cond (XEXP (old, 1), x, 0);
      if (op0 != NULL || op1 != NULL)
	{
	  if (op0 == const1_rtx)
	    return op1 ? op1 : gen_rtx_IOR (0, XEXP (old, 1), x);
	  if (op1 == const1_rtx)
	    return op0 ? op0 : gen_rtx_IOR (0, XEXP (old, 0), x);
	  if (op0 == const0_rtx || op1 == const0_rtx)
	    return const0_rtx;
	  if (op0 == NULL)
	    op0 = gen_rtx_IOR (0, XEXP (old, 0), x);
	  else if (rtx_equal_p (x, op0))
	    /* (x & A) | x ~ x.  */
	    return op0;
	  if (op1 == NULL)
	    op1 = gen_rtx_IOR (0, XEXP (old, 1), x);
	  else if (rtx_equal_p (x, op1))
	    /* (A & x) | x ~ x.  */
	    return op1;
	  return gen_rtx_AND (0, op0, op1);
	}
      if (! add)
	return NULL;
      return gen_rtx_IOR (0, old, x);

    case NOT:
      op0 = and_reg_cond (XEXP (old, 0), not_reg_cond (x), 0);
      if (op0 != NULL)
	return not_reg_cond (op0);
      if (! add)
	return NULL;
      return gen_rtx_IOR (0, old, x);

    default:
      gcc_unreachable ();
    }
}

static rtx
not_reg_cond (rtx x)
{
  if (x == const0_rtx)
    return const1_rtx;
  else if (x == const1_rtx)
    return const0_rtx;
  if (GET_CODE (x) == NOT)
    return XEXP (x, 0);
  if (COMPARISON_P (x)
      && REG_P (XEXP (x, 0)))
    {
      gcc_assert (XEXP (x, 1) == const0_rtx);

      return gen_rtx_fmt_ee (reversed_comparison_code (x, NULL),
			     VOIDmode, XEXP (x, 0), const0_rtx);
    }
  return gen_rtx_NOT (0, x);
}

static rtx
and_reg_cond (rtx old, rtx x, int add)
{
  rtx op0, op1;

  if (COMPARISON_P (old))
    {
      if (COMPARISON_P (x)
	  && GET_CODE (x) == reversed_comparison_code (old, NULL)
	  && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
	return const0_rtx;
      if (GET_CODE (x) == GET_CODE (old)
	  && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
	return old;
      if (! add)
	return NULL;
      return gen_rtx_AND (0, old, x);
    }

  switch (GET_CODE (old))
    {
    case IOR:
      op0 = and_reg_cond (XEXP (old, 0), x, 0);
      op1 = and_reg_cond (XEXP (old, 1), x, 0);
      if (op0 != NULL || op1 != NULL)
	{
	  if (op0 == const0_rtx)
	    return op1 ? op1 : gen_rtx_AND (0, XEXP (old, 1), x);
	  if (op1 == const0_rtx)
	    return op0 ? op0 : gen_rtx_AND (0, XEXP (old, 0), x);
	  if (op0 == const1_rtx || op1 == const1_rtx)
	    return const1_rtx;
	  if (op0 == NULL)
	    op0 = gen_rtx_AND (0, XEXP (old, 0), x);
	  else if (rtx_equal_p (x, op0))
	    /* (x | A) & x ~ x.  */
	    return op0;
	  if (op1 == NULL)
	    op1 = gen_rtx_AND (0, XEXP (old, 1), x);
	  else if (rtx_equal_p (x, op1))
	    /* (A | x) & x ~ x.  */
	    return op1;
	  return gen_rtx_IOR (0, op0, op1);
	}
      if (! add)
	return NULL;
      return gen_rtx_AND (0, old, x);

    case AND:
      op0 = and_reg_cond (XEXP (old, 0), x, 0);
      op1 = and_reg_cond (XEXP (old, 1), x, 0);
      if (op0 != NULL || op1 != NULL)
	{
	  if (op0 == const1_rtx)
	    return op1 ? op1 : gen_rtx_AND (0, XEXP (old, 1), x);
	  if (op1 == const1_rtx)
	    return op0 ? op0 : gen_rtx_AND (0, XEXP (old, 0), x);
	  if (op0 == const0_rtx || op1 == const0_rtx)
	    return const0_rtx;
	  if (op0 == NULL)
	    op0 = gen_rtx_AND (0, XEXP (old, 0), x);
	  else if (rtx_equal_p (x, op0))
	    /* (x & A) & x ~ (x & A).  */
	    return old;
	  if (op1 == NULL)
	    op1 = gen_rtx_AND (0, XEXP (old, 1), x);
	  else if (rtx_equal_p (x, op1))
	    /* (A & x) & x ~ (A & x).  */
	    return old;
	  return gen_rtx_AND (0, op0, op1);
	}
      if (! add)
	return NULL;
      return gen_rtx_AND (0, old, x);

    case NOT:
      op0 = ior_reg_cond (XEXP (old, 0), not_reg_cond (x), 0);
      if (op0 != NULL)
	return not_reg_cond (op0);
      if (! add)
	return NULL;
      return gen_rtx_AND (0, old, x);

    default:
      gcc_unreachable ();
    }
}

/* Given a condition X, remove references to reg REGNO and return the
   new condition.  The removal will be done so that all conditions
   involving REGNO are considered to evaluate to false.  This function
   is used when the value of REGNO changes.  */

static rtx
elim_reg_cond (rtx x, unsigned int regno)
{
  rtx op0, op1;

  if (COMPARISON_P (x))
    {
      if (REGNO (XEXP (x, 0)) == regno)
	return const0_rtx;
      return x;
    }

  switch (GET_CODE (x))
    {
    case AND:
      op0 = elim_reg_cond (XEXP (x, 0), regno);
      op1 = elim_reg_cond (XEXP (x, 1), regno);
      if (op0 == const0_rtx || op1 == const0_rtx)
	return const0_rtx;
      if (op0 == const1_rtx)
	return op1;
      if (op1 == const1_rtx)
	return op0;
      if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
	return x;
      return gen_rtx_AND (0, op0, op1);

    case IOR:
      op0 = elim_reg_cond (XEXP (x, 0), regno);
      op1 = elim_reg_cond (XEXP (x, 1), regno);
      if (op0 == const1_rtx || op1 == const1_rtx)
	return const1_rtx;
      if (op0 == const0_rtx)
	return op1;
      if (op1 == const0_rtx)
	return op0;
      if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
	return x;
      return gen_rtx_IOR (0, op0, op1);

    case NOT:
      op0 = elim_reg_cond (XEXP (x, 0), regno);
      if (op0 == const0_rtx)
	return const1_rtx;
      if (op0 == const1_rtx)
	return const0_rtx;
      if (op0 != XEXP (x, 0))
	return not_reg_cond (op0);
      return x;

    default:
      gcc_unreachable ();
    }
}
#endif /* HAVE_conditional_execution */

#ifdef AUTO_INC_DEC

/* Try to substitute the auto-inc expression INC as the address inside
   MEM which occurs in INSN.  Currently, the address of MEM is an expression
   involving INCR_REG, and INCR is the next use of INCR_REG; it is an insn
   that has a single set whose source is a PLUS of INCR_REG and something
   else.  */

static void
attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn,
		  rtx mem, rtx incr, rtx incr_reg)
{
  int regno = REGNO (incr_reg);
  rtx set = single_set (incr);
  rtx q = SET_DEST (set);
  rtx y = SET_SRC (set);
  int opnum = XEXP (y, 0) == incr_reg ? 0 : 1;
  int changed;

  /* Make sure this reg appears only once in this insn.  */
  if (count_occurrences (PATTERN (insn), incr_reg, 1) != 1)
    return;

  if (dead_or_set_p (incr, incr_reg)
      /* Mustn't autoinc an eliminable register.  */
      && (regno >= FIRST_PSEUDO_REGISTER
	  || ! TEST_HARD_REG_BIT (elim_reg_set, regno)))
    {
      /* This is the simple case.  Try to make the auto-inc.  If
	 we can't, we are done.  Otherwise, we will do any
	 needed updates below.  */
      if (! validate_change (insn, &XEXP (mem, 0), inc, 0))
	return;
    }
  else if (REG_P (q)
	   /* PREV_INSN used here to check the semi-open interval
	      [insn,incr).  */
	   && ! reg_used_between_p (q,  PREV_INSN (insn), incr)
	   /* We must also check for sets of q as q may be
	      a call clobbered hard register and there may
	      be a call between PREV_INSN (insn) and incr.  */
	   && ! reg_set_between_p (q,  PREV_INSN (insn), incr))
    {
      /* We have *p followed sometime later by q = p+size.
	 Both p and q must be live afterward,
	 and q is not used between INSN and its assignment.
	 Change it to q = p, ...*q..., q = q+size.
	 Then fall into the usual case.  */
      rtx insns, temp;

      start_sequence ();
      emit_move_insn (q, incr_reg);
      insns = get_insns ();
      end_sequence ();

      /* If we can't make the auto-inc, or can't make the
	 replacement into Y, exit.  There's no point in making
	 the change below if we can't do the auto-inc and doing
	 so is not correct in the pre-inc case.  */

      XEXP (inc, 0) = q;
      validate_change (insn, &XEXP (mem, 0), inc, 1);
      validate_change (incr, &XEXP (y, opnum), q, 1);
      if (! apply_change_group ())
	return;

      /* We now know we'll be doing this change, so emit the
	 new insn(s) and do the updates.  */
      emit_insn_before (insns, insn);

      if (BB_HEAD (pbi->bb) == insn)
	BB_HEAD (pbi->bb) = insns;

      /* INCR will become a NOTE and INSN won't contain a
	 use of INCR_REG.  If a use of INCR_REG was just placed in
	 the insn before INSN, make that the next use.
	 Otherwise, invalidate it.  */
      if (NONJUMP_INSN_P (PREV_INSN (insn))
	  && GET_CODE (PATTERN (PREV_INSN (insn))) == SET
	  && SET_SRC (PATTERN (PREV_INSN (insn))) == incr_reg)
	pbi->reg_next_use[regno] = PREV_INSN (insn);
      else
	pbi->reg_next_use[regno] = 0;

      incr_reg = q;
      regno = REGNO (q);

      if ((pbi->flags & PROP_REG_INFO)
	  && !REGNO_REG_SET_P (pbi->reg_live, regno))
	reg_deaths[regno] = pbi->insn_num;

      /* REGNO is now used in INCR which is below INSN, but
	 it previously wasn't live here.  If we don't mark
	 it as live, we'll put a REG_DEAD note for it
	 on this insn, which is incorrect.  */
      SET_REGNO_REG_SET (pbi->reg_live, regno);

      /* If there are any calls between INSN and INCR, show
	 that REGNO now crosses them.  */
      for (temp = insn; temp != incr; temp = NEXT_INSN (temp))
	if (CALL_P (temp))
	  REG_N_CALLS_CROSSED (regno)++;

      /* Invalidate alias info for Q since we just changed its value.  */
      clear_reg_alias_info (q);
    }
  else
    return;

  /* If we haven't returned, it means we were able to make the
     auto-inc, so update the status.  First, record that this insn
     has an implicit side effect.  */

  REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, incr_reg, REG_NOTES (insn));

  /* Modify the old increment-insn to simply copy
     the already-incremented value of our register.  */
  changed = validate_change (incr, &SET_SRC (set), incr_reg, 0);
  gcc_assert (changed);

  /* If that makes it a no-op (copying the register into itself) delete
     it so it won't appear to be a "use" and a "set" of this
     register.  */
  if (REGNO (SET_DEST (set)) == REGNO (incr_reg))
    {
      /* If the original source was dead, it's dead now.  */
      rtx note;

      while ((note = find_reg_note (incr, REG_DEAD, NULL_RTX)) != NULL_RTX)
	{
	  remove_note (incr, note);
	  if (XEXP (note, 0) != incr_reg)
	    {
	      unsigned int regno = REGNO (XEXP (note, 0));

	      if ((pbi->flags & PROP_REG_INFO)
		  && REGNO_REG_SET_P (pbi->reg_live, regno))
		{
		  REG_LIVE_LENGTH (regno) += pbi->insn_num - reg_deaths[regno];
		  reg_deaths[regno] = 0;
		}
	      CLEAR_REGNO_REG_SET (pbi->reg_live, REGNO (XEXP (note, 0)));
	    }
	}

      SET_INSN_DELETED (incr);
    }

  if (regno >= FIRST_PSEUDO_REGISTER)
    {
      /* Count an extra reference to the reg.  When a reg is
	 incremented, spilling it is worse, so we want to make
	 that less likely.  */
      REG_FREQ (regno) += REG_FREQ_FROM_BB (pbi->bb);

      /* Count the increment as a setting of the register,
	 even though it isn't a SET in rtl.  */
      REG_N_SETS (regno)++;
    }
}

/* X is a MEM found in INSN.  See if we can convert it into an auto-increment
   reference.  */

static void
find_auto_inc (struct propagate_block_info *pbi, rtx x, rtx insn)
{
  rtx addr = XEXP (x, 0);
  HOST_WIDE_INT offset = 0;
  rtx set, y, incr, inc_val;
  int regno;
  int size = GET_MODE_SIZE (GET_MODE (x));

  if (JUMP_P (insn))
    return;

  /* Here we detect use of an index register which might be good for
     postincrement, postdecrement, preincrement, or predecrement.  */

  if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
    offset = INTVAL (XEXP (addr, 1)), addr = XEXP (addr, 0);

  if (!REG_P (addr))
    return;

  regno = REGNO (addr);

  /* Is the next use an increment that might make auto-increment? */
  incr = pbi->reg_next_use[regno];
  if (incr == 0 || BLOCK_NUM (incr) != BLOCK_NUM (insn))
    return;
  set = single_set (incr);
  if (set == 0 || GET_CODE (set) != SET)
    return;
  y = SET_SRC (set);

  if (GET_CODE (y) != PLUS)
    return;

  if (REG_P (XEXP (y, 0)) && REGNO (XEXP (y, 0)) == REGNO (addr))
    inc_val = XEXP (y, 1);
  else if (REG_P (XEXP (y, 1)) && REGNO (XEXP (y, 1)) == REGNO (addr))
    inc_val = XEXP (y, 0);
  else
    return;

  if (GET_CODE (inc_val) == CONST_INT)
    {
      if (HAVE_POST_INCREMENT
	  && (INTVAL (inc_val) == size && offset == 0))
	attempt_auto_inc (pbi, gen_rtx_POST_INC (Pmode, addr), insn, x,
			  incr, addr);
      else if (HAVE_POST_DECREMENT
	       && (INTVAL (inc_val) == -size && offset == 0))
	attempt_auto_inc (pbi, gen_rtx_POST_DEC (Pmode, addr), insn, x,
			  incr, addr);
      else if (HAVE_PRE_INCREMENT
	       && (INTVAL (inc_val) == size && offset == size))
	attempt_auto_inc (pbi, gen_rtx_PRE_INC (Pmode, addr), insn, x,
			  incr, addr);
      else if (HAVE_PRE_DECREMENT
	       && (INTVAL (inc_val) == -size && offset == -size))
	attempt_auto_inc (pbi, gen_rtx_PRE_DEC (Pmode, addr), insn, x,
			  incr, addr);
      else if (HAVE_POST_MODIFY_DISP && offset == 0)
	attempt_auto_inc (pbi, gen_rtx_POST_MODIFY (Pmode, addr,
						    gen_rtx_PLUS (Pmode,
								  addr,
								  inc_val)),
			  insn, x, incr, addr);
      else if (HAVE_PRE_MODIFY_DISP && offset == INTVAL (inc_val))
	attempt_auto_inc (pbi, gen_rtx_PRE_MODIFY (Pmode, addr,
						    gen_rtx_PLUS (Pmode,
								  addr,
								  inc_val)),
			  insn, x, incr, addr);
    }
  else if (REG_P (inc_val)
	   && ! reg_set_between_p (inc_val, PREV_INSN (insn),
				   NEXT_INSN (incr)))

    {
      if (HAVE_POST_MODIFY_REG && offset == 0)
	attempt_auto_inc (pbi, gen_rtx_POST_MODIFY (Pmode, addr,
						    gen_rtx_PLUS (Pmode,
								  addr,
								  inc_val)),
			  insn, x, incr, addr);
    }
}

#endif /* AUTO_INC_DEC */

static void
mark_used_reg (struct propagate_block_info *pbi, rtx reg,
	       rtx cond ATTRIBUTE_UNUSED, rtx insn)
{
  unsigned int regno_first, regno_last, i;
  int some_was_live, some_was_dead, some_not_set;

  regno_last = regno_first = REGNO (reg);
  if (regno_first < FIRST_PSEUDO_REGISTER)
    regno_last += hard_regno_nregs[regno_first][GET_MODE (reg)] - 1;

  /* Find out if any of this register is live after this instruction.  */
  some_was_live = some_was_dead = 0;
  for (i = regno_first; i <= regno_last; ++i)
    {
      int needed_regno = REGNO_REG_SET_P (pbi->reg_live, i);
      some_was_live |= needed_regno;
      some_was_dead |= ! needed_regno;
    }

  /* Find out if any of the register was set this insn.  */
  some_not_set = 0;
  for (i = regno_first; i <= regno_last; ++i)
    some_not_set |= ! REGNO_REG_SET_P (pbi->new_set, i);

  if (pbi->flags & (PROP_LOG_LINKS | PROP_AUTOINC))
    {
      /* Record where each reg is used, so when the reg is set we know
	 the next insn that uses it.  */
      pbi->reg_next_use[regno_first] = insn;
    }

  if (pbi->flags & PROP_REG_INFO)
    {
      if (regno_first < FIRST_PSEUDO_REGISTER)
	{
	  /* If this is a register we are going to try to eliminate,
	     don't mark it live here.  If we are successful in
	     eliminating it, it need not be live unless it is used for
	     pseudos, in which case it will have been set live when it
	     was allocated to the pseudos.  If the register will not
	     be eliminated, reload will set it live at that point.

	     Otherwise, record that this function uses this register.  */
	  /* ??? The PPC backend tries to "eliminate" on the pic
	     register to itself.  This should be fixed.  In the mean
	     time, hack around it.  */

	  if (! (TEST_HARD_REG_BIT (elim_reg_set, regno_first)
	         && (regno_first == FRAME_POINTER_REGNUM
		     || regno_first == ARG_POINTER_REGNUM)))
	    for (i = regno_first; i <= regno_last; ++i)
	      regs_ever_live[i] = 1;
	}
      else
	{
	  /* Keep track of which basic block each reg appears in.  */

	  int blocknum = pbi->bb->index;
	  if (REG_BASIC_BLOCK (regno_first) == REG_BLOCK_UNKNOWN)
	    REG_BASIC_BLOCK (regno_first) = blocknum;
	  else if (REG_BASIC_BLOCK (regno_first) != blocknum)
	    REG_BASIC_BLOCK (regno_first) = REG_BLOCK_GLOBAL;

	  /* Count (weighted) number of uses of each reg.  */
	  REG_FREQ (regno_first) += REG_FREQ_FROM_BB (pbi->bb);
	  REG_N_REFS (regno_first)++;
	}
      for (i = regno_first; i <= regno_last; ++i)
	if (! REGNO_REG_SET_P (pbi->reg_live, i))
	  {
	    gcc_assert (!reg_deaths[i]);
	    reg_deaths[i] = pbi->insn_num;
	  }
    }

  /* Record and count the insns in which a reg dies.  If it is used in
     this insn and was dead below the insn then it dies in this insn.
     If it was set in this insn, we do not make a REG_DEAD note;
     likewise if we already made such a note.  */
  if ((pbi->flags & (PROP_DEATH_NOTES | PROP_REG_INFO))
      && some_was_dead
      && some_not_set)
    {
      /* Check for the case where the register dying partially
	 overlaps the register set by this insn.  */
      if (regno_first != regno_last)
	for (i = regno_first; i <= regno_last; ++i)
	  some_was_live |= REGNO_REG_SET_P (pbi->new_set, i);

      /* If none of the words in X is needed, make a REG_DEAD note.
	 Otherwise, we must make partial REG_DEAD notes.  */
      if (! some_was_live)
	{
	  if ((pbi->flags & PROP_DEATH_NOTES)
	      && ! find_regno_note (insn, REG_DEAD, regno_first))
	    REG_NOTES (insn)
	      = alloc_EXPR_LIST (REG_DEAD, reg, REG_NOTES (insn));

	  if (pbi->flags & PROP_REG_INFO)
	    REG_N_DEATHS (regno_first)++;
	}
      else
	{
	  /* Don't make a REG_DEAD note for a part of a register
	     that is set in the insn.  */
	  for (i = regno_first; i <= regno_last; ++i)
	    if (! REGNO_REG_SET_P (pbi->reg_live, i)
		&& ! dead_or_set_regno_p (insn, i))
	      REG_NOTES (insn)
		= alloc_EXPR_LIST (REG_DEAD,
				   regno_reg_rtx[i],
				   REG_NOTES (insn));
	}
    }

  /* Mark the register as being live.  */
  for (i = regno_first; i <= regno_last; ++i)
    {
#ifdef HAVE_conditional_execution
      int this_was_live = REGNO_REG_SET_P (pbi->reg_live, i);
#endif

      SET_REGNO_REG_SET (pbi->reg_live, i);

#ifdef HAVE_conditional_execution
      /* If this is a conditional use, record that fact.  If it is later
	 conditionally set, we'll know to kill the register.  */
      if (cond != NULL_RTX)
	{
	  splay_tree_node node;
	  struct reg_cond_life_info *rcli;
	  rtx ncond;

	  if (this_was_live)
	    {
	      node = splay_tree_lookup (pbi->reg_cond_dead, i);
	      if (node == NULL)
		{
		  /* The register was unconditionally live previously.
		     No need to do anything.  */
		}
	      else
		{
		  /* The register was conditionally live previously.
		     Subtract the new life cond from the old death cond.  */
		  rcli = (struct reg_cond_life_info *) node->value;
		  ncond = rcli->condition;
		  ncond = and_reg_cond (ncond, not_reg_cond (cond), 1);

		  /* If the register is now unconditionally live,
		     remove the entry in the splay_tree.  */
		  if (ncond == const0_rtx)
		    splay_tree_remove (pbi->reg_cond_dead, i);
		  else
		    {
		      rcli->condition = ncond;
		      SET_REGNO_REG_SET (pbi->reg_cond_reg,
					 REGNO (XEXP (cond, 0)));
		    }
		}
	    }
	  else
	    {
	      /* The register was not previously live at all.  Record
		 the condition under which it is still dead.  */
	      rcli = xmalloc (sizeof (*rcli));
	      rcli->condition = not_reg_cond (cond);
	      rcli->stores = const0_rtx;
	      rcli->orig_condition = const0_rtx;
	      splay_tree_insert (pbi->reg_cond_dead, i,
				 (splay_tree_value) rcli);

	      SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (XEXP (cond, 0)));
	    }
	}
      else if (this_was_live)
	{
	  /* The register may have been conditionally live previously, but
	     is now unconditionally live.  Remove it from the conditionally
	     dead list, so that a conditional set won't cause us to think
	     it dead.  */
	  splay_tree_remove (pbi->reg_cond_dead, i);
	}
#endif
    }
}

/* Scan expression X and store a 1-bit in NEW_LIVE for each reg it uses.
   This is done assuming the registers needed from X are those that
   have 1-bits in PBI->REG_LIVE.

   INSN is the containing instruction.  If INSN is dead, this function
   is not called.  */

static void
mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
{
  RTX_CODE code;
  int regno;
  int flags = pbi->flags;

 retry:
  if (!x)
    return;
  code = GET_CODE (x);
  switch (code)
    {
    case LABEL_REF:
    case SYMBOL_REF:
    case CONST_INT:
    case CONST:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case PC:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
      return;

#ifdef HAVE_cc0
    case CC0:
      pbi->cc0_live = 1;
      return;
#endif

    case CLOBBER:
      /* If we are clobbering a MEM, mark any registers inside the address
	 as being used.  */
      if (MEM_P (XEXP (x, 0)))
	mark_used_regs (pbi, XEXP (XEXP (x, 0), 0), cond, insn);
      return;

    case MEM:
      /* Don't bother watching stores to mems if this is not the
	 final pass.  We'll not be deleting dead stores this round.  */
      if (optimize && (flags & PROP_SCAN_DEAD_STORES))
	{
	  /* Invalidate the data for the last MEM stored, but only if MEM is
	     something that can be stored into.  */
	  if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
	      && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
	    /* Needn't clear the memory set list.  */
	    ;
	  else
	    {
	      rtx temp = pbi->mem_set_list;
	      rtx prev = NULL_RTX;
	      rtx next;

	      while (temp)
		{
		  next = XEXP (temp, 1);
		  if (anti_dependence (XEXP (temp, 0), x))
		    {
		      /* Splice temp out of the list.  */
		      if (prev)
			XEXP (prev, 1) = next;
		      else
			pbi->mem_set_list = next;
		      free_EXPR_LIST_node (temp);
		      pbi->mem_set_list_len--;
		    }
		  else
		    prev = temp;
		  temp = next;
		}
	    }

	  /* If the memory reference had embedded side effects (autoincrement
	     address modes.  Then we may need to kill some entries on the
	     memory set list.  */
	  if (insn)
	    for_each_rtx (&PATTERN (insn), invalidate_mems_from_autoinc, pbi);
	}

#ifdef AUTO_INC_DEC
      if (flags & PROP_AUTOINC)
	find_auto_inc (pbi, x, insn);
#endif
      break;

    case SUBREG:
#ifdef CANNOT_CHANGE_MODE_CLASS
      if (flags & PROP_REG_INFO)
	record_subregs_of_mode (x);
#endif

      /* While we're here, optimize this case.  */
      x = SUBREG_REG (x);
      if (!REG_P (x))
	goto retry;
      /* Fall through.  */

    case REG:
      /* See a register other than being set => mark it as needed.  */
      mark_used_reg (pbi, x, cond, insn);
      return;

    case SET:
      {
	rtx testreg = SET_DEST (x);
	int mark_dest = 0;

	/* If storing into MEM, don't show it as being used.  But do
	   show the address as being used.  */
	if (MEM_P (testreg))
	  {
#ifdef AUTO_INC_DEC
	    if (flags & PROP_AUTOINC)
	      find_auto_inc (pbi, testreg, insn);
#endif
	    mark_used_regs (pbi, XEXP (testreg, 0), cond, insn);
	    mark_used_regs (pbi, SET_SRC (x), cond, insn);
	    return;
	  }

	/* Storing in STRICT_LOW_PART is like storing in a reg
	   in that this SET might be dead, so ignore it in TESTREG.
	   but in some other ways it is like using the reg.

	   Storing in a SUBREG or a bit field is like storing the entire
	   register in that if the register's value is not used
	   then this SET is not needed.  */
	while (GET_CODE (testreg) == STRICT_LOW_PART
	       || GET_CODE (testreg) == ZERO_EXTRACT
	       || GET_CODE (testreg) == SUBREG)
	  {
#ifdef CANNOT_CHANGE_MODE_CLASS
	    if ((flags & PROP_REG_INFO) && GET_CODE (testreg) == SUBREG)
	      record_subregs_of_mode (testreg);
#endif

	    /* Modifying a single register in an alternate mode
	       does not use any of the old value.  But these other
	       ways of storing in a register do use the old value.  */
	    if (GET_CODE (testreg) == SUBREG
		&& !((REG_BYTES (SUBREG_REG (testreg))
		      + UNITS_PER_WORD - 1) / UNITS_PER_WORD
		     > (REG_BYTES (testreg)
			+ UNITS_PER_WORD - 1) / UNITS_PER_WORD))
	      ;
	    else
	      mark_dest = 1;

	    testreg = XEXP (testreg, 0);
	  }

	/* If this is a store into a register or group of registers,
	   recursively scan the value being stored.  */

	if ((GET_CODE (testreg) == PARALLEL
	     && GET_MODE (testreg) == BLKmode)
	    || (REG_P (testreg)
		&& (regno = REGNO (testreg),
		    ! (regno == FRAME_POINTER_REGNUM
		       && (! reload_completed || frame_pointer_needed)))
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
		&& ! (regno == HARD_FRAME_POINTER_REGNUM
		      && (! reload_completed || frame_pointer_needed))
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
		&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
#endif
		))
	  {
	    if (mark_dest)
	      mark_used_regs (pbi, SET_DEST (x), cond, insn);
	    mark_used_regs (pbi, SET_SRC (x), cond, insn);
	    return;
	  }
      }
      break;

    case ASM_OPERANDS:
    case UNSPEC_VOLATILE:
    case TRAP_IF:
    case ASM_INPUT:
      {
	/* Traditional and volatile asm instructions must be considered to use
	   and clobber all hard registers, all pseudo-registers and all of
	   memory.  So must TRAP_IF and UNSPEC_VOLATILE operations.

	   Consider for instance a volatile asm that changes the fpu rounding
	   mode.  An insn should not be moved across this even if it only uses
	   pseudo-regs because it might give an incorrectly rounded result.

	   ?!? Unfortunately, marking all hard registers as live causes massive
	   problems for the register allocator and marking all pseudos as live
	   creates mountains of uninitialized variable warnings.

	   So for now, just clear the memory set list and mark any regs
	   we can find in ASM_OPERANDS as used.  */
	if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
	  {
	    free_EXPR_LIST_list (&pbi->mem_set_list);
	    pbi->mem_set_list_len = 0;
	  }

	/* For all ASM_OPERANDS, we must traverse the vector of input operands.
	   We can not just fall through here since then we would be confused
	   by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
	   traditional asms unlike their normal usage.  */
	if (code == ASM_OPERANDS)
	  {
	    int j;

	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
	      mark_used_regs (pbi, ASM_OPERANDS_INPUT (x, j), cond, insn);
	  }
	break;
      }

    case COND_EXEC:
      gcc_assert (!cond);

      mark_used_regs (pbi, COND_EXEC_TEST (x), NULL_RTX, insn);

      cond = COND_EXEC_TEST (x);
      x = COND_EXEC_CODE (x);
      goto retry;

    default:
      break;
    }

  /* Recursively scan the operands of this expression.  */

  {
    const char * const fmt = GET_RTX_FORMAT (code);
    int i;

    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
	if (fmt[i] == 'e')
	  {
	    /* Tail recursive case: save a function call level.  */
	    if (i == 0)
	      {
		x = XEXP (x, 0);
		goto retry;
	      }
	    mark_used_regs (pbi, XEXP (x, i), cond, insn);
	  }
	else if (fmt[i] == 'E')
	  {
	    int j;
	    for (j = 0; j < XVECLEN (x, i); j++)
	      mark_used_regs (pbi, XVECEXP (x, i, j), cond, insn);
	  }
      }
  }
}

#ifdef AUTO_INC_DEC

static int
try_pre_increment_1 (struct propagate_block_info *pbi, rtx insn)
{
  /* Find the next use of this reg.  If in same basic block,
     make it do pre-increment or pre-decrement if appropriate.  */
  rtx x = single_set (insn);
  HOST_WIDE_INT amount = ((GET_CODE (SET_SRC (x)) == PLUS ? 1 : -1)
			  * INTVAL (XEXP (SET_SRC (x), 1)));
  int regno = REGNO (SET_DEST (x));
  rtx y = pbi->reg_next_use[regno];
  if (y != 0
      && SET_DEST (x) != stack_pointer_rtx
      && BLOCK_NUM (y) == BLOCK_NUM (insn)
      /* Don't do this if the reg dies, or gets set in y; a standard addressing
	 mode would be better.  */
      && ! dead_or_set_p (y, SET_DEST (x))
      && try_pre_increment (y, SET_DEST (x), amount))
    {
      /* We have found a suitable auto-increment and already changed
	 insn Y to do it.  So flush this increment instruction.  */
      propagate_block_delete_insn (insn);

      /* Count a reference to this reg for the increment insn we are
	 deleting.  When a reg is incremented, spilling it is worse,
	 so we want to make that less likely.  */
      if (regno >= FIRST_PSEUDO_REGISTER)
	{
	  REG_FREQ (regno) += REG_FREQ_FROM_BB (pbi->bb);
	  REG_N_SETS (regno)++;
	}

      /* Flush any remembered memories depending on the value of
	 the incremented register.  */
      invalidate_mems_from_set (pbi, SET_DEST (x));

      return 1;
    }
  return 0;
}

/* Try to change INSN so that it does pre-increment or pre-decrement
   addressing on register REG in order to add AMOUNT to REG.
   AMOUNT is negative for pre-decrement.
   Returns 1 if the change could be made.
   This checks all about the validity of the result of modifying INSN.  */

static int
try_pre_increment (rtx insn, rtx reg, HOST_WIDE_INT amount)
{
  rtx use;

  /* Nonzero if we can try to make a pre-increment or pre-decrement.
     For example, addl $4,r1; movl (r1),... can become movl +(r1),...  */
  int pre_ok = 0;
  /* Nonzero if we can try to make a post-increment or post-decrement.
     For example, addl $4,r1; movl -4(r1),... can become movl (r1)+,...
     It is possible for both PRE_OK and POST_OK to be nonzero if the machine
     supports both pre-inc and post-inc, or both pre-dec and post-dec.  */
  int post_ok = 0;

  /* Nonzero if the opportunity actually requires post-inc or post-dec.  */
  int do_post = 0;

  /* From the sign of increment, see which possibilities are conceivable
     on this target machine.  */
  if (HAVE_PRE_INCREMENT && amount > 0)
    pre_ok = 1;
  if (HAVE_POST_INCREMENT && amount > 0)
    post_ok = 1;

  if (HAVE_PRE_DECREMENT && amount < 0)
    pre_ok = 1;
  if (HAVE_POST_DECREMENT && amount < 0)
    post_ok = 1;

  if (! (pre_ok || post_ok))
    return 0;

  /* It is not safe to add a side effect to a jump insn
     because if the incremented register is spilled and must be reloaded
     there would be no way to store the incremented value back in memory.  */

  if (JUMP_P (insn))
    return 0;

  use = 0;
  if (pre_ok)
    use = find_use_as_address (PATTERN (insn), reg, 0);
  if (post_ok && (use == 0 || use == (rtx) (size_t) 1))
    {
      use = find_use_as_address (PATTERN (insn), reg, -amount);
      do_post = 1;
    }

  if (use == 0 || use == (rtx) (size_t) 1)
    return 0;

  if (GET_MODE_SIZE (GET_MODE (use)) != (amount > 0 ? amount : - amount))
    return 0;

  /* See if this combination of instruction and addressing mode exists.  */
  if (! validate_change (insn, &XEXP (use, 0),
			 gen_rtx_fmt_e (amount > 0
					? (do_post ? POST_INC : PRE_INC)
					: (do_post ? POST_DEC : PRE_DEC),
					Pmode, reg), 0))
    return 0;

  /* Record that this insn now has an implicit side effect on X.  */
  REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, reg, REG_NOTES (insn));
  return 1;
}

#endif /* AUTO_INC_DEC */

/* Find the place in the rtx X where REG is used as a memory address.
   Return the MEM rtx that so uses it.
   If PLUSCONST is nonzero, search instead for a memory address equivalent to
   (plus REG (const_int PLUSCONST)).

   If such an address does not appear, return 0.
   If REG appears more than once, or is used other than in such an address,
   return (rtx) 1.  */

rtx
find_use_as_address (rtx x, rtx reg, HOST_WIDE_INT plusconst)
{
  enum rtx_code code = GET_CODE (x);
  const char * const fmt = GET_RTX_FORMAT (code);
  int i;
  rtx value = 0;
  rtx tem;

  if (code == MEM && XEXP (x, 0) == reg && plusconst == 0)
    return x;

  if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS
      && XEXP (XEXP (x, 0), 0) == reg
      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
      && INTVAL (XEXP (XEXP (x, 0), 1)) == plusconst)
    return x;

  if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
    {
      /* If REG occurs inside a MEM used in a bit-field reference,
	 that is unacceptable.  */
      if (find_use_as_address (XEXP (x, 0), reg, 0) != 0)
	return (rtx) (size_t) 1;
    }

  if (x == reg)
    return (rtx) (size_t) 1;

  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  tem = find_use_as_address (XEXP (x, i), reg, plusconst);
	  if (value == 0)
	    value = tem;
	  else if (tem != 0)
	    return (rtx) (size_t) 1;
	}
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    {
	      tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst);
	      if (value == 0)
		value = tem;
	      else if (tem != 0)
		return (rtx) (size_t) 1;
	    }
	}
    }

  return value;
}

/* Write information about registers and basic blocks into FILE.
   This is part of making a debugging dump.  */

void
dump_regset (regset r, FILE *outf)
{
  unsigned i;
  reg_set_iterator rsi;

  if (r == NULL)
    {
      fputs (" (nil)", outf);
      return;
    }

  EXECUTE_IF_SET_IN_REG_SET (r, 0, i, rsi)
    {
      fprintf (outf, " %d", i);
      if (i < FIRST_PSEUDO_REGISTER)
	fprintf (outf, " [%s]",
		 reg_names[i]);
    }
}

/* Print a human-readable representation of R on the standard error
   stream.  This function is designed to be used from within the
   debugger.  */

void
debug_regset (regset r)
{
  dump_regset (r, stderr);
  putc ('\n', stderr);
}

/* Recompute register set/reference counts immediately prior to register
   allocation.

   This avoids problems with set/reference counts changing to/from values
   which have special meanings to the register allocators.

   Additionally, the reference counts are the primary component used by the
   register allocators to prioritize pseudos for allocation to hard regs.
   More accurate reference counts generally lead to better register allocation.

   It might be worthwhile to update REG_LIVE_LENGTH, REG_BASIC_BLOCK and
   possibly other information which is used by the register allocators.  */

void
recompute_reg_usage (void)
{
  allocate_reg_life_data ();
  /* distribute_notes in combiner fails to convert some of the REG_UNUSED notes
   to REG_DEAD notes.  This causes CHECK_DEAD_NOTES in sched1 to abort.  To 
   solve this update the DEATH_NOTES here.  */
  update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO | PROP_DEATH_NOTES);
}

/* Optionally removes all the REG_DEAD and REG_UNUSED notes from a set of
   blocks.  If BLOCKS is NULL, assume the universal set.  Returns a count
   of the number of registers that died.  */

int
count_or_remove_death_notes (sbitmap blocks, int kill)
{
  int count = 0;
  int i;
  basic_block bb;

  /* This used to be a loop over all the blocks with a membership test
     inside the loop.  That can be amazingly expensive on a large CFG
     when only a small number of bits are set in BLOCKs (for example,
     the calls from the scheduler typically have very few bits set).

     For extra credit, someone should convert BLOCKS to a bitmap rather
     than an sbitmap.  */
  if (blocks)
    {
      EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
	{
	  count += count_or_remove_death_notes_bb (BASIC_BLOCK (i), kill);
	});
    }
  else
    {
      FOR_EACH_BB (bb)
	{
	  count += count_or_remove_death_notes_bb (bb, kill);
	}
    }

  return count;
}
  
/* Optionally removes all the REG_DEAD and REG_UNUSED notes from basic
   block BB.  Returns a count of the number of registers that died.  */

static int
count_or_remove_death_notes_bb (basic_block bb, int kill)
{
  int count = 0;
  rtx insn;

  for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
    {
      if (INSN_P (insn))
	{
	  rtx *pprev = &REG_NOTES (insn);
	  rtx link = *pprev;

	  while (link)
	    {
	      switch (REG_NOTE_KIND (link))
		{
		case REG_DEAD:
		  if (REG_P (XEXP (link, 0)))
		    {
		      rtx reg = XEXP (link, 0);
		      int n;

		      if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
		        n = 1;
		      else
		        n = hard_regno_nregs[REGNO (reg)][GET_MODE (reg)];
		      count += n;
		    }

		  /* Fall through.  */

		case REG_UNUSED:
		  if (kill)
		    {
		      rtx next = XEXP (link, 1);
		      free_EXPR_LIST_node (link);
		      *pprev = link = next;
		      break;
		    }
		  /* Fall through.  */

		default:
		  pprev = &XEXP (link, 1);
		  link = *pprev;
		  break;
		}
	    }
	}

      if (insn == BB_END (bb))
	break;
    }

  return count;
}

/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
   if blocks is NULL.  */

static void
clear_log_links (sbitmap blocks)
{
  rtx insn;
  int i;

  if (!blocks)
    {
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
	if (INSN_P (insn))
	  free_INSN_LIST_list (&LOG_LINKS (insn));
    }
  else
    EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
      {
	basic_block bb = BASIC_BLOCK (i);

	for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
	     insn = NEXT_INSN (insn))
	  if (INSN_P (insn))
	    free_INSN_LIST_list (&LOG_LINKS (insn));
      });
}

/* Given a register bitmap, turn on the bits in a HARD_REG_SET that
   correspond to the hard registers, if any, set in that map.  This
   could be done far more efficiently by having all sorts of special-cases
   with moving single words, but probably isn't worth the trouble.  */

void
reg_set_to_hard_reg_set (HARD_REG_SET *to, bitmap from)
{
  unsigned i;
  bitmap_iterator bi;

  EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
    {
      if (i >= FIRST_PSEUDO_REGISTER)
	return;
      SET_HARD_REG_BIT (*to, i);
    }
}
