/* Expands front end tree to back end RTL for GNU C-Compiler
   Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
   1998, 1999, 2000, 2001, 2002 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 handles the generation of rtl code from tree structure
   at the level of the function as a whole.
   It creates the rtl expressions for parameters and auto variables
   and has full responsibility for allocating stack slots.

   `expand_function_start' is called at the beginning of a function,
   before the function body is parsed, and `expand_function_end' is
   called after parsing the body.

   Call `assign_stack_local' to allocate a stack slot for a local variable.
   This is usually done during the RTL generation for the function body,
   but it can also be done in the reload pass when a pseudo-register does
   not get a hard register.

   Call `put_var_into_stack' when you learn, belatedly, that a variable
   previously given a pseudo-register must in fact go in the stack.
   This function changes the DECL_RTL to be a stack slot instead of a reg
   then scans all the RTL instructions so far generated to correct them.  */

#include "config.h"
#include "system.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
#include "except.h"
#include "function.h"
#include "expr.h"
#include "libfuncs.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "insn-config.h"
#include "recog.h"
#include "output.h"
#include "basic-block.h"
#include "toplev.h"
#include "hashtab.h"
#include "ggc.h"
#include "tm_p.h"
#include "integrate.h"
#include "langhooks.h"

#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
#endif

#ifndef LOCAL_ALIGNMENT
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
#endif

/* Some systems use __main in a way incompatible with its use in gcc, in these
   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
   give the same symbol without quotes for an alternative entry point.  You
   must define both, or neither.  */
#ifndef NAME__MAIN
#define NAME__MAIN "__main"
#endif

/* Round a value to the lowest integer less than it that is a multiple of
   the required alignment.  Avoid using division in case the value is
   negative.  Assume the alignment is a power of two.  */
#define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))

/* Similar, but round to the next highest integer that meets the
   alignment.  */
#define CEIL_ROUND(VALUE,ALIGN)	(((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))

/* NEED_SEPARATE_AP means that we cannot derive ap from the value of fp
   during rtl generation.  If they are different register numbers, this is
   always true.  It may also be true if
   FIRST_PARM_OFFSET - STARTING_FRAME_OFFSET is not a constant during rtl
   generation.  See fix_lexical_addr for details.  */

#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
#define NEED_SEPARATE_AP
#endif

/* Nonzero if function being compiled doesn't contain any calls
   (ignoring the prologue and epilogue).  This is set prior to
   local register allocation and is valid for the remaining
   compiler passes.  */
int current_function_is_leaf;

/* Nonzero if function being compiled doesn't contain any instructions
   that can throw an exception.  This is set prior to final.  */

int current_function_nothrow;

/* Nonzero if function being compiled doesn't modify the stack pointer
   (ignoring the prologue and epilogue).  This is only valid after
   life_analysis has run.  */
int current_function_sp_is_unchanging;

/* Nonzero if the function being compiled is a leaf function which only
   uses leaf registers.  This is valid after reload (specifically after
   sched2) and is useful only if the port defines LEAF_REGISTERS.  */
int current_function_uses_only_leaf_regs;

/* Nonzero once virtual register instantiation has been done.
   assign_stack_local uses frame_pointer_rtx when this is nonzero.
   calls.c:emit_library_call_value_1 uses it to set up
   post-instantiation libcalls.  */
int virtuals_instantiated;

/* Nonzero if at least one trampoline has been created.  */
int trampolines_created;

/* Assign unique numbers to labels generated for profiling, debugging, etc.  */
static int funcdef_no;

/* These variables hold pointers to functions to create and destroy
   target specific, per-function data structures.  */
struct machine_function * (*init_machine_status) PARAMS ((void));

/* The FUNCTION_DECL for an inline function currently being expanded.  */
tree inline_function_decl;

/* The currently compiled function.  */
struct function *cfun = 0;

/* These arrays record the INSN_UIDs of the prologue and epilogue insns.  */
static GTY(()) varray_type prologue;
static GTY(()) varray_type epilogue;

/* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
   in this function.  */
static GTY(()) varray_type sibcall_epilogue;

/* In order to evaluate some expressions, such as function calls returning
   structures in memory, we need to temporarily allocate stack locations.
   We record each allocated temporary in the following structure.

   Associated with each temporary slot is a nesting level.  When we pop up
   one level, all temporaries associated with the previous level are freed.
   Normally, all temporaries are freed after the execution of the statement
   in which they were created.  However, if we are inside a ({...}) grouping,
   the result may be in a temporary and hence must be preserved.  If the
   result could be in a temporary, we preserve it if we can determine which
   one it is in.  If we cannot determine which temporary may contain the
   result, all temporaries are preserved.  A temporary is preserved by
   pretending it was allocated at the previous nesting level.

   Automatic variables are also assigned temporary slots, at the nesting
   level where they are defined.  They are marked a "kept" so that
   free_temp_slots will not free them.  */

struct temp_slot GTY(())
{
  /* Points to next temporary slot.  */
  struct temp_slot *next;
  /* The rtx to used to reference the slot.  */
  rtx slot;
  /* The rtx used to represent the address if not the address of the
     slot above.  May be an EXPR_LIST if multiple addresses exist.  */
  rtx address;
  /* The alignment (in bits) of the slot.  */
  unsigned int align;
  /* The size, in units, of the slot.  */
  HOST_WIDE_INT size;
  /* The type of the object in the slot, or zero if it doesn't correspond
     to a type.  We use this to determine whether a slot can be reused.
     It can be reused if objects of the type of the new slot will always
     conflict with objects of the type of the old slot.  */
  tree type;
  /* The value of `sequence_rtl_expr' when this temporary is allocated.  */
  tree rtl_expr;
  /* Nonzero if this temporary is currently in use.  */
  char in_use;
  /* Nonzero if this temporary has its address taken.  */
  char addr_taken;
  /* Nesting level at which this slot is being used.  */
  int level;
  /* Nonzero if this should survive a call to free_temp_slots.  */
  int keep;
  /* The offset of the slot from the frame_pointer, including extra space
     for alignment.  This info is for combine_temp_slots.  */
  HOST_WIDE_INT base_offset;
  /* The size of the slot, including extra space for alignment.  This
     info is for combine_temp_slots.  */
  HOST_WIDE_INT full_size;
};

/* This structure is used to record MEMs or pseudos used to replace VAR, any
   SUBREGs of VAR, and any MEMs containing VAR as an address.  We need to
   maintain this list in case two operands of an insn were required to match;
   in that case we must ensure we use the same replacement.  */

struct fixup_replacement GTY(())
{
  rtx old;
  rtx new;
  struct fixup_replacement *next;
};

struct insns_for_mem_entry
{
  /* A MEM.  */
  rtx key;
  /* These are the INSNs which reference the MEM.  */
  rtx insns;
};

/* Forward declarations.  */

static rtx assign_stack_local_1 PARAMS ((enum machine_mode, HOST_WIDE_INT,
					 int, struct function *));
static struct temp_slot *find_temp_slot_from_address  PARAMS ((rtx));
static void put_reg_into_stack	PARAMS ((struct function *, rtx, tree,
					 enum machine_mode, enum machine_mode,
					 int, unsigned int, int,
					 htab_t));
static void schedule_fixup_var_refs PARAMS ((struct function *, rtx, tree,
					     enum machine_mode,
					     htab_t));
static void fixup_var_refs	PARAMS ((rtx, enum machine_mode, int, rtx,
					 htab_t));
static struct fixup_replacement
  *find_fixup_replacement	PARAMS ((struct fixup_replacement **, rtx));
static void fixup_var_refs_insns PARAMS ((rtx, rtx, enum machine_mode,
					  int, int, rtx));
static void fixup_var_refs_insns_with_hash
				PARAMS ((htab_t, rtx,
					 enum machine_mode, int, rtx));
static void fixup_var_refs_insn PARAMS ((rtx, rtx, enum machine_mode,
					 int, int, rtx));
static void fixup_var_refs_1	PARAMS ((rtx, enum machine_mode, rtx *, rtx,
					 struct fixup_replacement **, rtx));
static rtx fixup_memory_subreg	PARAMS ((rtx, rtx, enum machine_mode, int));
static rtx walk_fixup_memory_subreg  PARAMS ((rtx, rtx, enum machine_mode,
					      int));
static rtx fixup_stack_1	PARAMS ((rtx, rtx));
static void optimize_bit_field	PARAMS ((rtx, rtx, rtx *));
static void instantiate_decls	PARAMS ((tree, int));
static void instantiate_decls_1	PARAMS ((tree, int));
static void instantiate_decl	PARAMS ((rtx, HOST_WIDE_INT, int));
static rtx instantiate_new_reg	PARAMS ((rtx, HOST_WIDE_INT *));
static int instantiate_virtual_regs_1 PARAMS ((rtx *, rtx, int));
static void delete_handlers	PARAMS ((void));
static void pad_to_arg_alignment PARAMS ((struct args_size *, int,
					  struct args_size *));
static void pad_below		PARAMS ((struct args_size *, enum machine_mode,
					 tree));
static rtx round_trampoline_addr PARAMS ((rtx));
static rtx adjust_trampoline_addr PARAMS ((rtx));
static tree *identify_blocks_1	PARAMS ((rtx, tree *, tree *, tree *));
static void reorder_blocks_0	PARAMS ((tree));
static void reorder_blocks_1	PARAMS ((rtx, tree, varray_type *));
static void reorder_fix_fragments PARAMS ((tree));
static tree blocks_nreverse	PARAMS ((tree));
static int all_blocks		PARAMS ((tree, tree *));
static tree *get_block_vector   PARAMS ((tree, int *));
extern tree debug_find_var_in_block_tree PARAMS ((tree, tree));
/* We always define `record_insns' even if its not used so that we
   can always export `prologue_epilogue_contains'.  */
static void record_insns	PARAMS ((rtx, varray_type *)) ATTRIBUTE_UNUSED;
static int contains		PARAMS ((rtx, varray_type));
#ifdef HAVE_return
static void emit_return_into_block PARAMS ((basic_block, rtx));
#endif
static void put_addressof_into_stack PARAMS ((rtx, htab_t));
static bool purge_addressof_1 PARAMS ((rtx *, rtx, int, int,
					  htab_t));
static void purge_single_hard_subreg_set PARAMS ((rtx));
#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
static rtx keep_stack_depressed PARAMS ((rtx));
#endif
static int is_addressof		PARAMS ((rtx *, void *));
static hashval_t insns_for_mem_hash PARAMS ((const void *));
static int insns_for_mem_comp PARAMS ((const void *, const void *));
static int insns_for_mem_walk   PARAMS ((rtx *, void *));
static void compute_insns_for_mem PARAMS ((rtx, rtx, htab_t));
static void prepare_function_start PARAMS ((void));
static void do_clobber_return_reg PARAMS ((rtx, void *));
static void do_use_return_reg PARAMS ((rtx, void *));
static void instantiate_virtual_regs_lossage PARAMS ((rtx));

/* Pointer to chain of `struct function' for containing functions.  */
static GTY(()) struct function *outer_function_chain;

/* Given a function decl for a containing function,
   return the `struct function' for it.  */

struct function *
find_function_data (decl)
     tree decl;
{
  struct function *p;

  for (p = outer_function_chain; p; p = p->outer)
    if (p->decl == decl)
      return p;

  abort ();
}

/* Save the current context for compilation of a nested function.
   This is called from language-specific code.  The caller should use
   the enter_nested langhook to save any language-specific state,
   since this function knows only about language-independent
   variables.  */

void
push_function_context_to (context)
     tree context;
{
  struct function *p;

  if (context)
    {
      if (context == current_function_decl)
	cfun->contains_functions = 1;
      else
	{
	  struct function *containing = find_function_data (context);
	  containing->contains_functions = 1;
	}
    }

  if (cfun == 0)
    init_dummy_function_start ();
  p = cfun;

  p->outer = outer_function_chain;
  outer_function_chain = p;
  p->fixup_var_refs_queue = 0;

  (*lang_hooks.function.enter_nested) (p);

  cfun = 0;
}

void
push_function_context ()
{
  push_function_context_to (current_function_decl);
}

/* Restore the last saved context, at the end of a nested function.
   This function is called from language-specific code.  */

void
pop_function_context_from (context)
     tree context ATTRIBUTE_UNUSED;
{
  struct function *p = outer_function_chain;
  struct var_refs_queue *queue;

  cfun = p;
  outer_function_chain = p->outer;

  current_function_decl = p->decl;
  reg_renumber = 0;

  restore_emit_status (p);

  (*lang_hooks.function.leave_nested) (p);

  /* Finish doing put_var_into_stack for any of our variables which became
     addressable during the nested function.  If only one entry has to be
     fixed up, just do that one.  Otherwise, first make a list of MEMs that
     are not to be unshared.  */
  if (p->fixup_var_refs_queue == 0)
    ;
  else if (p->fixup_var_refs_queue->next == 0)
    fixup_var_refs (p->fixup_var_refs_queue->modified,
		    p->fixup_var_refs_queue->promoted_mode,
		    p->fixup_var_refs_queue->unsignedp,
		    p->fixup_var_refs_queue->modified, 0);
  else
    {
      rtx list = 0;

      for (queue = p->fixup_var_refs_queue; queue; queue = queue->next)
	list = gen_rtx_EXPR_LIST (VOIDmode, queue->modified, list);

      for (queue = p->fixup_var_refs_queue; queue; queue = queue->next)
	fixup_var_refs (queue->modified, queue->promoted_mode,
			queue->unsignedp, list, 0);

    }

  p->fixup_var_refs_queue = 0;

  /* Reset variables that have known state during rtx generation.  */
  rtx_equal_function_value_matters = 1;
  virtuals_instantiated = 0;
  generating_concat_p = 1;
}

void
pop_function_context ()
{
  pop_function_context_from (current_function_decl);
}

/* Clear out all parts of the state in F that can safely be discarded
   after the function has been parsed, but not compiled, to let
   garbage collection reclaim the memory.  */

void
free_after_parsing (f)
     struct function *f;
{
  /* f->expr->forced_labels is used by code generation.  */
  /* f->emit->regno_reg_rtx is used by code generation.  */
  /* f->varasm is used by code generation.  */
  /* f->eh->eh_return_stub_label is used by code generation.  */

  (*lang_hooks.function.final) (f);
  f->stmt = NULL;
}

/* Clear out all parts of the state in F that can safely be discarded
   after the function has been compiled, to let garbage collection
   reclaim the memory.  */

void
free_after_compilation (f)
     struct function *f;
{
  f->eh = NULL;
  f->expr = NULL;
  f->emit = NULL;
  f->varasm = NULL;
  f->machine = NULL;

  f->x_temp_slots = NULL;
  f->arg_offset_rtx = NULL;
  f->return_rtx = NULL;
  f->internal_arg_pointer = NULL;
  f->x_nonlocal_labels = NULL;
  f->x_nonlocal_goto_handler_slots = NULL;
  f->x_nonlocal_goto_handler_labels = NULL;
  f->x_nonlocal_goto_stack_level = NULL;
  f->x_cleanup_label = NULL;
  f->x_return_label = NULL;
  f->computed_goto_common_label = NULL;
  f->computed_goto_common_reg = NULL;
  f->x_save_expr_regs = NULL;
  f->x_stack_slot_list = NULL;
  f->x_rtl_expr_chain = NULL;
  f->x_tail_recursion_label = NULL;
  f->x_tail_recursion_reentry = NULL;
  f->x_arg_pointer_save_area = NULL;
  f->x_clobber_return_insn = NULL;
  f->x_context_display = NULL;
  f->x_trampoline_list = NULL;
  f->x_parm_birth_insn = NULL;
  f->x_last_parm_insn = NULL;
  f->x_parm_reg_stack_loc = NULL;
  f->fixup_var_refs_queue = NULL;
  f->original_arg_vector = NULL;
  f->original_decl_initial = NULL;
  f->inl_last_parm_insn = NULL;
  f->epilogue_delay_list = NULL;
}

/* Allocate fixed slots in the stack frame of the current function.  */

/* Return size needed for stack frame based on slots so far allocated in
   function F.
   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
   the caller may have to do that.  */

HOST_WIDE_INT
get_func_frame_size (f)
     struct function *f;
{
#ifdef FRAME_GROWS_DOWNWARD
  return -f->x_frame_offset;
#else
  return f->x_frame_offset;
#endif
}

/* Return size needed for stack frame based on slots so far allocated.
   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
   the caller may have to do that.  */
HOST_WIDE_INT
get_frame_size ()
{
  return get_func_frame_size (cfun);
}

/* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
   with machine mode MODE.

   ALIGN controls the amount of alignment for the address of the slot:
   0 means according to MODE,
   -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
   positive specifies alignment boundary in bits.

   We do not round to stack_boundary here.

   FUNCTION specifies the function to allocate in.  */

static rtx
assign_stack_local_1 (mode, size, align, function)
     enum machine_mode mode;
     HOST_WIDE_INT size;
     int align;
     struct function *function;
{
  rtx x, addr;
  int bigend_correction = 0;
  int alignment;
  int frame_off, frame_alignment, frame_phase;

  if (align == 0)
    {
      tree type;

      if (mode == BLKmode)
	alignment = BIGGEST_ALIGNMENT;
      else
	alignment = GET_MODE_ALIGNMENT (mode);

      /* Allow the target to (possibly) increase the alignment of this
	 stack slot.  */
      type = (*lang_hooks.types.type_for_mode) (mode, 0);
      if (type)
	alignment = LOCAL_ALIGNMENT (type, alignment);

      alignment /= BITS_PER_UNIT;
    }
  else if (align == -1)
    {
      alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
      size = CEIL_ROUND (size, alignment);
    }
  else
    alignment = align / BITS_PER_UNIT;

#ifdef FRAME_GROWS_DOWNWARD
  function->x_frame_offset -= size;
#endif

  /* Ignore alignment we can't do with expected alignment of the boundary.  */
  if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
    alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;

  if (function->stack_alignment_needed < alignment * BITS_PER_UNIT)
    function->stack_alignment_needed = alignment * BITS_PER_UNIT;

  /* Calculate how many bytes the start of local variables is off from
     stack alignment.  */
  frame_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
  frame_off = STARTING_FRAME_OFFSET % frame_alignment;
  frame_phase = frame_off ? frame_alignment - frame_off : 0;

  /* Round frame offset to that alignment.
     We must be careful here, since FRAME_OFFSET might be negative and
     division with a negative dividend isn't as well defined as we might
     like.  So we instead assume that ALIGNMENT is a power of two and
     use logical operations which are unambiguous.  */
#ifdef FRAME_GROWS_DOWNWARD
  function->x_frame_offset = FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
#else
  function->x_frame_offset = CEIL_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
#endif

  /* On a big-endian machine, if we are allocating more space than we will use,
     use the least significant bytes of those that are allocated.  */
  if (BYTES_BIG_ENDIAN && mode != BLKmode)
    bigend_correction = size - GET_MODE_SIZE (mode);

  /* If we have already instantiated virtual registers, return the actual
     address relative to the frame pointer.  */
  if (function == cfun && virtuals_instantiated)
    addr = plus_constant (frame_pointer_rtx,
			  (frame_offset + bigend_correction
			   + STARTING_FRAME_OFFSET));
  else
    addr = plus_constant (virtual_stack_vars_rtx,
			  function->x_frame_offset + bigend_correction);

#ifndef FRAME_GROWS_DOWNWARD
  function->x_frame_offset += size;
#endif

  x = gen_rtx_MEM (mode, addr);

  function->x_stack_slot_list
    = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);

  return x;
}

/* Wrapper around assign_stack_local_1;  assign a local stack slot for the
   current function.  */

rtx
assign_stack_local (mode, size, align)
     enum machine_mode mode;
     HOST_WIDE_INT size;
     int align;
{
  return assign_stack_local_1 (mode, size, align, cfun);
}

/* Allocate a temporary stack slot and record it for possible later
   reuse.

   MODE is the machine mode to be given to the returned rtx.

   SIZE is the size in units of the space required.  We do no rounding here
   since assign_stack_local will do any required rounding.

   KEEP is 1 if this slot is to be retained after a call to
   free_temp_slots.  Automatic variables for a block are allocated
   with this flag.  KEEP is 2 if we allocate a longer term temporary,
   whose lifetime is controlled by CLEANUP_POINT_EXPRs.  KEEP is 3
   if we are to allocate something at an inner level to be treated as
   a variable in the block (e.g., a SAVE_EXPR).

   TYPE is the type that will be used for the stack slot.  */

rtx
assign_stack_temp_for_type (mode, size, keep, type)
     enum machine_mode mode;
     HOST_WIDE_INT size;
     int keep;
     tree type;
{
  unsigned int align;
  struct temp_slot *p, *best_p = 0;
  rtx slot;

  /* If SIZE is -1 it means that somebody tried to allocate a temporary
     of a variable size.  */
  if (size == -1)
    abort ();

  if (mode == BLKmode)
    align = BIGGEST_ALIGNMENT;
  else
    align = GET_MODE_ALIGNMENT (mode);

  if (! type)
    type = (*lang_hooks.types.type_for_mode) (mode, 0);

  if (type)
    align = LOCAL_ALIGNMENT (type, align);

  /* Try to find an available, already-allocated temporary of the proper
     mode which meets the size and alignment requirements.  Choose the
     smallest one with the closest alignment.  */
  for (p = temp_slots; p; p = p->next)
    if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode
	&& ! p->in_use
	&& objects_must_conflict_p (p->type, type)
	&& (best_p == 0 || best_p->size > p->size
	    || (best_p->size == p->size && best_p->align > p->align)))
      {
	if (p->align == align && p->size == size)
	  {
	    best_p = 0;
	    break;
	  }
	best_p = p;
      }

  /* Make our best, if any, the one to use.  */
  if (best_p)
    {
      /* If there are enough aligned bytes left over, make them into a new
	 temp_slot so that the extra bytes don't get wasted.  Do this only
	 for BLKmode slots, so that we can be sure of the alignment.  */
      if (GET_MODE (best_p->slot) == BLKmode)
	{
	  int alignment = best_p->align / BITS_PER_UNIT;
	  HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);

	  if (best_p->size - rounded_size >= alignment)
	    {
	      p = (struct temp_slot *) ggc_alloc (sizeof (struct temp_slot));
	      p->in_use = p->addr_taken = 0;
	      p->size = best_p->size - rounded_size;
	      p->base_offset = best_p->base_offset + rounded_size;
	      p->full_size = best_p->full_size - rounded_size;
	      p->slot = gen_rtx_MEM (BLKmode,
				     plus_constant (XEXP (best_p->slot, 0),
						    rounded_size));
	      p->align = best_p->align;
	      p->address = 0;
	      p->rtl_expr = 0;
	      p->type = best_p->type;
	      p->next = temp_slots;
	      temp_slots = p;

	      stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, p->slot,
						   stack_slot_list);

	      best_p->size = rounded_size;
	      best_p->full_size = rounded_size;
	    }
	}

      p = best_p;
    }

  /* If we still didn't find one, make a new temporary.  */
  if (p == 0)
    {
      HOST_WIDE_INT frame_offset_old = frame_offset;

      p = (struct temp_slot *) ggc_alloc (sizeof (struct temp_slot));

      /* We are passing an explicit alignment request to assign_stack_local.
	 One side effect of that is assign_stack_local will not round SIZE
	 to ensure the frame offset remains suitably aligned.

	 So for requests which depended on the rounding of SIZE, we go ahead
	 and round it now.  We also make sure ALIGNMENT is at least
	 BIGGEST_ALIGNMENT.  */
      if (mode == BLKmode && align < BIGGEST_ALIGNMENT)
	abort ();
      p->slot = assign_stack_local (mode,
				    (mode == BLKmode
				     ? CEIL_ROUND (size, align / BITS_PER_UNIT)
				     : size),
				    align);

      p->align = align;

      /* The following slot size computation is necessary because we don't
	 know the actual size of the temporary slot until assign_stack_local
	 has performed all the frame alignment and size rounding for the
	 requested temporary.  Note that extra space added for alignment
	 can be either above or below this stack slot depending on which
	 way the frame grows.  We include the extra space if and only if it
	 is above this slot.  */
#ifdef FRAME_GROWS_DOWNWARD
      p->size = frame_offset_old - frame_offset;
#else
      p->size = size;
#endif

      /* Now define the fields used by combine_temp_slots.  */
#ifdef FRAME_GROWS_DOWNWARD
      p->base_offset = frame_offset;
      p->full_size = frame_offset_old - frame_offset;
#else
      p->base_offset = frame_offset_old;
      p->full_size = frame_offset - frame_offset_old;
#endif
      p->address = 0;
      p->next = temp_slots;
      temp_slots = p;
    }

  p->in_use = 1;
  p->addr_taken = 0;
  p->rtl_expr = seq_rtl_expr;
  p->type = type;

  if (keep == 2)
    {
      p->level = target_temp_slot_level;
      p->keep = 1;
    }
  else if (keep == 3)
    {
      p->level = var_temp_slot_level;
      p->keep = 0;
    }
  else
    {
      p->level = temp_slot_level;
      p->keep = keep;
    }


  /* Create a new MEM rtx to avoid clobbering MEM flags of old slots.  */
  slot = gen_rtx_MEM (mode, XEXP (p->slot, 0));
  stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, slot, stack_slot_list);

  /* If we know the alias set for the memory that will be used, use
     it.  If there's no TYPE, then we don't know anything about the
     alias set for the memory.  */
  set_mem_alias_set (slot, type ? get_alias_set (type) : 0);
  set_mem_align (slot, align);

  /* If a type is specified, set the relevant flags.  */
  if (type != 0)
    {
      RTX_UNCHANGING_P (slot) = (lang_hooks.honor_readonly 
				 && TYPE_READONLY (type));
      MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type);
      MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type));
    }

  return slot;
}

/* Allocate a temporary stack slot and record it for possible later
   reuse.  First three arguments are same as in preceding function.  */

rtx
assign_stack_temp (mode, size, keep)
     enum machine_mode mode;
     HOST_WIDE_INT size;
     int keep;
{
  return assign_stack_temp_for_type (mode, size, keep, NULL_TREE);
}

/* Assign a temporary.
   If TYPE_OR_DECL is a decl, then we are doing it on behalf of the decl
   and so that should be used in error messages.  In either case, we
   allocate of the given type.
   KEEP is as for assign_stack_temp.
   MEMORY_REQUIRED is 1 if the result must be addressable stack memory;
   it is 0 if a register is OK.
   DONT_PROMOTE is 1 if we should not promote values in register
   to wider modes.  */

rtx
assign_temp (type_or_decl, keep, memory_required, dont_promote)
     tree type_or_decl;
     int keep;
     int memory_required;
     int dont_promote ATTRIBUTE_UNUSED;
{
  tree type, decl;
  enum machine_mode mode;
#ifndef PROMOTE_FOR_CALL_ONLY
  int unsignedp;
#endif

  if (DECL_P (type_or_decl))
    decl = type_or_decl, type = TREE_TYPE (decl);
  else
    decl = NULL, type = type_or_decl;

  mode = TYPE_MODE (type);
#ifndef PROMOTE_FOR_CALL_ONLY
  unsignedp = TREE_UNSIGNED (type);
#endif

  if (mode == BLKmode || memory_required)
    {
      HOST_WIDE_INT size = int_size_in_bytes (type);
      rtx tmp;

      /* Zero sized arrays are GNU C extension.  Set size to 1 to avoid
	 problems with allocating the stack space.  */
      if (size == 0)
	size = 1;

      /* Unfortunately, we don't yet know how to allocate variable-sized
	 temporaries.  However, sometimes we have a fixed upper limit on
	 the size (which is stored in TYPE_ARRAY_MAX_SIZE) and can use that
	 instead.  This is the case for Chill variable-sized strings.  */
      if (size == -1 && TREE_CODE (type) == ARRAY_TYPE
	  && TYPE_ARRAY_MAX_SIZE (type) != NULL_TREE
	  && host_integerp (TYPE_ARRAY_MAX_SIZE (type), 1))
	size = tree_low_cst (TYPE_ARRAY_MAX_SIZE (type), 1);

      /* The size of the temporary may be too large to fit into an integer.  */
      /* ??? Not sure this should happen except for user silliness, so limit
	 this to things that aren't compiler-generated temporaries.  The
	 rest of the time we'll abort in assign_stack_temp_for_type.  */
      if (decl && size == -1
	  && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
	{
	  error_with_decl (decl, "size of variable `%s' is too large");
	  size = 1;
	}

      tmp = assign_stack_temp_for_type (mode, size, keep, type);
      return tmp;
    }

#ifndef PROMOTE_FOR_CALL_ONLY
  if (! dont_promote)
    mode = promote_mode (type, mode, &unsignedp, 0);
#endif

  return gen_reg_rtx (mode);
}

/* Combine temporary stack slots which are adjacent on the stack.

   This allows for better use of already allocated stack space.  This is only
   done for BLKmode slots because we can be sure that we won't have alignment
   problems in this case.  */

void
combine_temp_slots ()
{
  struct temp_slot *p, *q;
  struct temp_slot *prev_p, *prev_q;
  int num_slots;

  /* We can't combine slots, because the information about which slot
     is in which alias set will be lost.  */
  if (flag_strict_aliasing)
    return;

  /* If there are a lot of temp slots, don't do anything unless
     high levels of optimization.  */
  if (! flag_expensive_optimizations)
    for (p = temp_slots, num_slots = 0; p; p = p->next, num_slots++)
      if (num_slots > 100 || (num_slots > 10 && optimize == 0))
	return;

  for (p = temp_slots, prev_p = 0; p; p = prev_p ? prev_p->next : temp_slots)
    {
      int delete_p = 0;

      if (! p->in_use && GET_MODE (p->slot) == BLKmode)
	for (q = p->next, prev_q = p; q; q = prev_q->next)
	  {
	    int delete_q = 0;
	    if (! q->in_use && GET_MODE (q->slot) == BLKmode)
	      {
		if (p->base_offset + p->full_size == q->base_offset)
		  {
		    /* Q comes after P; combine Q into P.  */
		    p->size += q->size;
		    p->full_size += q->full_size;
		    delete_q = 1;
		  }
		else if (q->base_offset + q->full_size == p->base_offset)
		  {
		    /* P comes after Q; combine P into Q.  */
		    q->size += p->size;
		    q->full_size += p->full_size;
		    delete_p = 1;
		    break;
		  }
	      }
	    /* Either delete Q or advance past it.  */
	    if (delete_q)
	      prev_q->next = q->next;
	    else
	      prev_q = q;
	  }
      /* Either delete P or advance past it.  */
      if (delete_p)
	{
	  if (prev_p)
	    prev_p->next = p->next;
	  else
	    temp_slots = p->next;
	}
      else
	prev_p = p;
    }
}

/* Find the temp slot corresponding to the object at address X.  */

static struct temp_slot *
find_temp_slot_from_address (x)
     rtx x;
{
  struct temp_slot *p;
  rtx next;

  for (p = temp_slots; p; p = p->next)
    {
      if (! p->in_use)
	continue;

      else if (XEXP (p->slot, 0) == x
	       || p->address == x
	       || (GET_CODE (x) == PLUS
		   && XEXP (x, 0) == virtual_stack_vars_rtx
		   && GET_CODE (XEXP (x, 1)) == CONST_INT
		   && INTVAL (XEXP (x, 1)) >= p->base_offset
		   && INTVAL (XEXP (x, 1)) < p->base_offset + p->full_size))
	return p;

      else if (p->address != 0 && GET_CODE (p->address) == EXPR_LIST)
	for (next = p->address; next; next = XEXP (next, 1))
	  if (XEXP (next, 0) == x)
	    return p;
    }

  /* If we have a sum involving a register, see if it points to a temp
     slot.  */
  if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG
      && (p = find_temp_slot_from_address (XEXP (x, 0))) != 0)
    return p;
  else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG
	   && (p = find_temp_slot_from_address (XEXP (x, 1))) != 0)
    return p;

  return 0;
}

/* Indicate that NEW is an alternate way of referring to the temp slot
   that previously was known by OLD.  */

void
update_temp_slot_address (old, new)
     rtx old, new;
{
  struct temp_slot *p;

  if (rtx_equal_p (old, new))
    return;

  p = find_temp_slot_from_address (old);

  /* If we didn't find one, see if both OLD is a PLUS.  If so, and NEW
     is a register, see if one operand of the PLUS is a temporary
     location.  If so, NEW points into it.  Otherwise, if both OLD and
     NEW are a PLUS and if there is a register in common between them.
     If so, try a recursive call on those values.  */
  if (p == 0)
    {
      if (GET_CODE (old) != PLUS)
	return;

      if (GET_CODE (new) == REG)
	{
	  update_temp_slot_address (XEXP (old, 0), new);
	  update_temp_slot_address (XEXP (old, 1), new);
	  return;
	}
      else if (GET_CODE (new) != PLUS)
	return;

      if (rtx_equal_p (XEXP (old, 0), XEXP (new, 0)))
	update_temp_slot_address (XEXP (old, 1), XEXP (new, 1));
      else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 0)))
	update_temp_slot_address (XEXP (old, 0), XEXP (new, 1));
      else if (rtx_equal_p (XEXP (old, 0), XEXP (new, 1)))
	update_temp_slot_address (XEXP (old, 1), XEXP (new, 0));
      else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 1)))
	update_temp_slot_address (XEXP (old, 0), XEXP (new, 0));

      return;
    }

  /* Otherwise add an alias for the temp's address.  */
  else if (p->address == 0)
    p->address = new;
  else
    {
      if (GET_CODE (p->address) != EXPR_LIST)
	p->address = gen_rtx_EXPR_LIST (VOIDmode, p->address, NULL_RTX);

      p->address = gen_rtx_EXPR_LIST (VOIDmode, new, p->address);
    }
}

/* If X could be a reference to a temporary slot, mark the fact that its
   address was taken.  */

void
mark_temp_addr_taken (x)
     rtx x;
{
  struct temp_slot *p;

  if (x == 0)
    return;

  /* If X is not in memory or is at a constant address, it cannot be in
     a temporary slot.  */
  if (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
    return;

  p = find_temp_slot_from_address (XEXP (x, 0));
  if (p != 0)
    p->addr_taken = 1;
}

/* If X could be a reference to a temporary slot, mark that slot as
   belonging to the to one level higher than the current level.  If X
   matched one of our slots, just mark that one.  Otherwise, we can't
   easily predict which it is, so upgrade all of them.  Kept slots
   need not be touched.

   This is called when an ({...}) construct occurs and a statement
   returns a value in memory.  */

void
preserve_temp_slots (x)
     rtx x;
{
  struct temp_slot *p = 0;

  /* If there is no result, we still might have some objects whose address
     were taken, so we need to make sure they stay around.  */
  if (x == 0)
    {
      for (p = temp_slots; p; p = p->next)
	if (p->in_use && p->level == temp_slot_level && p->addr_taken)
	  p->level--;

      return;
    }

  /* If X is a register that is being used as a pointer, see if we have
     a temporary slot we know it points to.  To be consistent with
     the code below, we really should preserve all non-kept slots
     if we can't find a match, but that seems to be much too costly.  */
  if (GET_CODE (x) == REG && REG_POINTER (x))
    p = find_temp_slot_from_address (x);

  /* If X is not in memory or is at a constant address, it cannot be in
     a temporary slot, but it can contain something whose address was
     taken.  */
  if (p == 0 && (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0))))
    {
      for (p = temp_slots; p; p = p->next)
	if (p->in_use && p->level == temp_slot_level && p->addr_taken)
	  p->level--;

      return;
    }

  /* First see if we can find a match.  */
  if (p == 0)
    p = find_temp_slot_from_address (XEXP (x, 0));

  if (p != 0)
    {
      /* Move everything at our level whose address was taken to our new
	 level in case we used its address.  */
      struct temp_slot *q;

      if (p->level == temp_slot_level)
	{
	  for (q = temp_slots; q; q = q->next)
	    if (q != p && q->addr_taken && q->level == p->level)
	      q->level--;

	  p->level--;
	  p->addr_taken = 0;
	}
      return;
    }

  /* Otherwise, preserve all non-kept slots at this level.  */
  for (p = temp_slots; p; p = p->next)
    if (p->in_use && p->level == temp_slot_level && ! p->keep)
      p->level--;
}

/* X is the result of an RTL_EXPR.  If it is a temporary slot associated
   with that RTL_EXPR, promote it into a temporary slot at the present
   level so it will not be freed when we free slots made in the
   RTL_EXPR.  */

void
preserve_rtl_expr_result (x)
     rtx x;
{
  struct temp_slot *p;

  /* If X is not in memory or is at a constant address, it cannot be in
     a temporary slot.  */
  if (x == 0 || GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
    return;

  /* If we can find a match, move it to our level unless it is already at
     an upper level.  */
  p = find_temp_slot_from_address (XEXP (x, 0));
  if (p != 0)
    {
      p->level = MIN (p->level, temp_slot_level);
      p->rtl_expr = 0;
    }

  return;
}

/* Free all temporaries used so far.  This is normally called at the end
   of generating code for a statement.  Don't free any temporaries
   currently in use for an RTL_EXPR that hasn't yet been emitted.
   We could eventually do better than this since it can be reused while
   generating the same RTL_EXPR, but this is complex and probably not
   worthwhile.  */

void
free_temp_slots ()
{
  struct temp_slot *p;

  for (p = temp_slots; p; p = p->next)
    if (p->in_use && p->level == temp_slot_level && ! p->keep
	&& p->rtl_expr == 0)
      p->in_use = 0;

  combine_temp_slots ();
}

/* Free all temporary slots used in T, an RTL_EXPR node.  */

void
free_temps_for_rtl_expr (t)
     tree t;
{
  struct temp_slot *p;

  for (p = temp_slots; p; p = p->next)
    if (p->rtl_expr == t)
      {
	/* If this slot is below the current TEMP_SLOT_LEVEL, then it
	   needs to be preserved.  This can happen if a temporary in
	   the RTL_EXPR was addressed; preserve_temp_slots will move
	   the temporary into a higher level.  */
	if (temp_slot_level <= p->level)
	  p->in_use = 0;
	else
	  p->rtl_expr = NULL_TREE;
      }

  combine_temp_slots ();
}

/* Mark all temporaries ever allocated in this function as not suitable
   for reuse until the current level is exited.  */

void
mark_all_temps_used ()
{
  struct temp_slot *p;

  for (p = temp_slots; p; p = p->next)
    {
      p->in_use = p->keep = 1;
      p->level = MIN (p->level, temp_slot_level);
    }
}

/* Push deeper into the nesting level for stack temporaries.  */

void
push_temp_slots ()
{
  temp_slot_level++;
}

/* Likewise, but save the new level as the place to allocate variables
   for blocks.  */

#if 0
void
push_temp_slots_for_block ()
{
  push_temp_slots ();

  var_temp_slot_level = temp_slot_level;
}

/* Likewise, but save the new level as the place to allocate temporaries
   for TARGET_EXPRs.  */

void
push_temp_slots_for_target ()
{
  push_temp_slots ();

  target_temp_slot_level = temp_slot_level;
}

/* Set and get the value of target_temp_slot_level.  The only
   permitted use of these functions is to save and restore this value.  */

int
get_target_temp_slot_level ()
{
  return target_temp_slot_level;
}

void
set_target_temp_slot_level (level)
     int level;
{
  target_temp_slot_level = level;
}
#endif

/* Pop a temporary nesting level.  All slots in use in the current level
   are freed.  */

void
pop_temp_slots ()
{
  struct temp_slot *p;

  for (p = temp_slots; p; p = p->next)
    if (p->in_use && p->level == temp_slot_level && p->rtl_expr == 0)
      p->in_use = 0;

  combine_temp_slots ();

  temp_slot_level--;
}

/* Initialize temporary slots.  */

void
init_temp_slots ()
{
  /* We have not allocated any temporaries yet.  */
  temp_slots = 0;
  temp_slot_level = 0;
  var_temp_slot_level = 0;
  target_temp_slot_level = 0;
}

/* Retroactively move an auto variable from a register to a stack
   slot.  This is done when an address-reference to the variable is
   seen.  If RESCAN is true, all previously emitted instructions are
   examined and modified to handle the fact that DECL is now
   addressable.  */

void
put_var_into_stack (decl, rescan)
     tree decl;
     int rescan;
{
  rtx reg;
  enum machine_mode promoted_mode, decl_mode;
  struct function *function = 0;
  tree context;
  int can_use_addressof;
  int volatilep = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
  int usedp = (TREE_USED (decl)
	       || (TREE_CODE (decl) != SAVE_EXPR && DECL_INITIAL (decl) != 0));

  context = decl_function_context (decl);

  /* Get the current rtl used for this object and its original mode.  */
  reg = (TREE_CODE (decl) == SAVE_EXPR
	 ? SAVE_EXPR_RTL (decl)
	 : DECL_RTL_IF_SET (decl));

  /* No need to do anything if decl has no rtx yet
     since in that case caller is setting TREE_ADDRESSABLE
     and a stack slot will be assigned when the rtl is made.  */
  if (reg == 0)
    return;

  /* Get the declared mode for this object.  */
  decl_mode = (TREE_CODE (decl) == SAVE_EXPR ? TYPE_MODE (TREE_TYPE (decl))
	       : DECL_MODE (decl));
  /* Get the mode it's actually stored in.  */
  promoted_mode = GET_MODE (reg);

  /* If this variable comes from an outer function, find that
     function's saved context.  Don't use find_function_data here,
     because it might not be in any active function.
     FIXME: Is that really supposed to happen?
     It does in ObjC at least.  */
  if (context != current_function_decl && context != inline_function_decl)
    for (function = outer_function_chain; function; function = function->outer)
      if (function->decl == context)
	break;

  /* If this is a variable-sized object or a structure passed by invisible
     reference, with a pseudo to address it, put that pseudo into the stack
     if the var is non-local.  */
  if (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl)
      && GET_CODE (reg) == MEM
      && GET_CODE (XEXP (reg, 0)) == REG
      && REGNO (XEXP (reg, 0)) > LAST_VIRTUAL_REGISTER)
    {
      reg = XEXP (reg, 0);
      decl_mode = promoted_mode = GET_MODE (reg);
    }

  /* If this variable lives in the current function and we don't need to put it
     in the stack for the sake of setjmp or the non-locality, try to keep it in
     a register until we know we actually need the address.  */
  can_use_addressof
    = (function == 0
       && ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
       && optimize > 0
       /* FIXME make it work for promoted modes too */
       && decl_mode == promoted_mode
#ifdef NON_SAVING_SETJMP
       && ! (NON_SAVING_SETJMP && current_function_calls_setjmp)
#endif
       );

  /* If we can't use ADDRESSOF, make sure we see through one we already
     generated.  */
  if (! can_use_addressof && GET_CODE (reg) == MEM
      && GET_CODE (XEXP (reg, 0)) == ADDRESSOF)
    reg = XEXP (XEXP (reg, 0), 0);

  /* Now we should have a value that resides in one or more pseudo regs.  */

  if (GET_CODE (reg) == REG)
    {
      if (can_use_addressof)
	gen_mem_addressof (reg, decl, rescan);
      else
	put_reg_into_stack (function, reg, TREE_TYPE (decl), promoted_mode,
			    decl_mode, volatilep, 0, usedp, 0);
    }
  else if (GET_CODE (reg) == CONCAT)
    {
      /* A CONCAT contains two pseudos; put them both in the stack.
	 We do it so they end up consecutive.
	 We fixup references to the parts only after we fixup references
	 to the whole CONCAT, lest we do double fixups for the latter
	 references.  */
      enum machine_mode part_mode = GET_MODE (XEXP (reg, 0));
      tree part_type = (*lang_hooks.types.type_for_mode) (part_mode, 0);
      rtx lopart = XEXP (reg, 0);
      rtx hipart = XEXP (reg, 1);
#ifdef FRAME_GROWS_DOWNWARD
      /* Since part 0 should have a lower address, do it second.  */
      put_reg_into_stack (function, hipart, part_type, part_mode,
			  part_mode, volatilep, 0, 0, 0);
      put_reg_into_stack (function, lopart, part_type, part_mode,
			  part_mode, volatilep, 0, 0, 0);
#else
      put_reg_into_stack (function, lopart, part_type, part_mode,
			  part_mode, volatilep, 0, 0, 0);
      put_reg_into_stack (function, hipart, part_type, part_mode,
			  part_mode, volatilep, 0, 0, 0);
#endif

      /* Change the CONCAT into a combined MEM for both parts.  */
      PUT_CODE (reg, MEM);
      MEM_ATTRS (reg) = 0;

      /* set_mem_attributes uses DECL_RTL to avoid re-generating of
         already computed alias sets.  Here we want to re-generate.  */
      if (DECL_P (decl))
	SET_DECL_RTL (decl, NULL);
      set_mem_attributes (reg, decl, 1);
      if (DECL_P (decl))
	SET_DECL_RTL (decl, reg);

      /* The two parts are in memory order already.
	 Use the lower parts address as ours.  */
      XEXP (reg, 0) = XEXP (XEXP (reg, 0), 0);
      /* Prevent sharing of rtl that might lose.  */
      if (GET_CODE (XEXP (reg, 0)) == PLUS)
	XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
      if (usedp && rescan)
	{
	  schedule_fixup_var_refs (function, reg, TREE_TYPE (decl),
				   promoted_mode, 0);
	  schedule_fixup_var_refs (function, lopart, part_type, part_mode, 0);
	  schedule_fixup_var_refs (function, hipart, part_type, part_mode, 0);
	}
    }
  else
    return;
}

/* Subroutine of put_var_into_stack.  This puts a single pseudo reg REG
   into the stack frame of FUNCTION (0 means the current function).
   DECL_MODE is the machine mode of the user-level data type.
   PROMOTED_MODE is the machine mode of the register.
   VOLATILE_P is nonzero if this is for a "volatile" decl.
   USED_P is nonzero if this reg might have already been used in an insn.  */

static void
put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
		    original_regno, used_p, ht)
     struct function *function;
     rtx reg;
     tree type;
     enum machine_mode promoted_mode, decl_mode;
     int volatile_p;
     unsigned int original_regno;
     int used_p;
     htab_t ht;
{
  struct function *func = function ? function : cfun;
  rtx new = 0;
  unsigned int regno = original_regno;

  if (regno == 0)
    regno = REGNO (reg);

  if (regno < func->x_max_parm_reg)
    {
      if (!func->x_parm_reg_stack_loc)
	abort ();
      new = func->x_parm_reg_stack_loc[regno];
    }

  if (new == 0)
    new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);

  PUT_CODE (reg, MEM);
  PUT_MODE (reg, decl_mode);
  XEXP (reg, 0) = XEXP (new, 0);
  MEM_ATTRS (reg) = 0;
  /* `volatil' bit means one thing for MEMs, another entirely for REGs.  */
  MEM_VOLATILE_P (reg) = volatile_p;

  /* If this is a memory ref that contains aggregate components,
     mark it as such for cse and loop optimize.  If we are reusing a
     previously generated stack slot, then we need to copy the bit in
     case it was set for other reasons.  For instance, it is set for
     __builtin_va_alist.  */
  if (type)
    {
      MEM_SET_IN_STRUCT_P (reg,
			   AGGREGATE_TYPE_P (type) || MEM_IN_STRUCT_P (new));
      set_mem_alias_set (reg, get_alias_set (type));
    }

  if (used_p)
    schedule_fixup_var_refs (function, reg, type, promoted_mode, ht);
}

/* Make sure that all refs to the variable, previously made
   when it was a register, are fixed up to be valid again.
   See function above for meaning of arguments.  */

static void
schedule_fixup_var_refs (function, reg, type, promoted_mode, ht)
     struct function *function;
     rtx reg;
     tree type;
     enum machine_mode promoted_mode;
     htab_t ht;
{
  int unsigned_p = type ? TREE_UNSIGNED (type) : 0;

  if (function != 0)
    {
      struct var_refs_queue *temp;

      temp
	= (struct var_refs_queue *) ggc_alloc (sizeof (struct var_refs_queue));
      temp->modified = reg;
      temp->promoted_mode = promoted_mode;
      temp->unsignedp = unsigned_p;
      temp->next = function->fixup_var_refs_queue;
      function->fixup_var_refs_queue = temp;
    }
  else
    /* Variable is local; fix it up now.  */
    fixup_var_refs (reg, promoted_mode, unsigned_p, reg, ht);
}

static void
fixup_var_refs (var, promoted_mode, unsignedp, may_share, ht)
     rtx var;
     enum machine_mode promoted_mode;
     int unsignedp;
     htab_t ht;
     rtx may_share;
{
  tree pending;
  rtx first_insn = get_insns ();
  struct sequence_stack *stack = seq_stack;
  tree rtl_exps = rtl_expr_chain;

  /* If there's a hash table, it must record all uses of VAR.  */
  if (ht)
    {
      if (stack != 0)
	abort ();
      fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp,
				      may_share);
      return;
    }

  fixup_var_refs_insns (first_insn, var, promoted_mode, unsignedp,
			stack == 0, may_share);

  /* Scan all pending sequences too.  */
  for (; stack; stack = stack->next)
    {
      push_to_full_sequence (stack->first, stack->last);
      fixup_var_refs_insns (stack->first, var, promoted_mode, unsignedp,
			    stack->next != 0, may_share);
      /* Update remembered end of sequence
	 in case we added an insn at the end.  */
      stack->last = get_last_insn ();
      end_sequence ();
    }

  /* Scan all waiting RTL_EXPRs too.  */
  for (pending = rtl_exps; pending; pending = TREE_CHAIN (pending))
    {
      rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
      if (seq != const0_rtx && seq != 0)
	{
	  push_to_sequence (seq);
	  fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0,
				may_share);
	  end_sequence ();
	}
    }
}

/* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is
   some part of an insn.  Return a struct fixup_replacement whose OLD
   value is equal to X.  Allocate a new structure if no such entry exists.  */

static struct fixup_replacement *
find_fixup_replacement (replacements, x)
     struct fixup_replacement **replacements;
     rtx x;
{
  struct fixup_replacement *p;

  /* See if we have already replaced this.  */
  for (p = *replacements; p != 0 && ! rtx_equal_p (p->old, x); p = p->next)
    ;

  if (p == 0)
    {
      p = (struct fixup_replacement *) xmalloc (sizeof (struct fixup_replacement));
      p->old = x;
      p->new = 0;
      p->next = *replacements;
      *replacements = p;
    }

  return p;
}

/* Scan the insn-chain starting with INSN for refs to VAR and fix them
   up.  TOPLEVEL is nonzero if this chain is the main chain of insns
   for the current function.  MAY_SHARE is either a MEM that is not
   to be unshared or a list of them.  */

static void
fixup_var_refs_insns (insn, var, promoted_mode, unsignedp, toplevel, may_share)
     rtx insn;
     rtx var;
     enum machine_mode promoted_mode;
     int unsignedp;
     int toplevel;
     rtx may_share;
{
  while (insn)
    {
      /* fixup_var_refs_insn might modify insn, so save its next
         pointer now.  */
      rtx next = NEXT_INSN (insn);

      /* CALL_PLACEHOLDERs are special; we have to switch into each of
	 the three sequences they (potentially) contain, and process
	 them recursively.  The CALL_INSN itself is not interesting.  */

      if (GET_CODE (insn) == CALL_INSN
	  && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
	{
	  int i;

	  /* Look at the Normal call, sibling call and tail recursion
	     sequences attached to the CALL_PLACEHOLDER.  */
	  for (i = 0; i < 3; i++)
	    {
	      rtx seq = XEXP (PATTERN (insn), i);
	      if (seq)
		{
		  push_to_sequence (seq);
		  fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0,
					may_share);
		  XEXP (PATTERN (insn), i) = get_insns ();
		  end_sequence ();
		}
	    }
	}

      else if (INSN_P (insn))
	fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel,
			     may_share);

      insn = next;
    }
}

/* Look up the insns which reference VAR in HT and fix them up.  Other
   arguments are the same as fixup_var_refs_insns.

   N.B. No need for special processing of CALL_PLACEHOLDERs here,
   because the hash table will point straight to the interesting insn
   (inside the CALL_PLACEHOLDER).  */

static void
fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp, may_share)
     htab_t ht;
     rtx var;
     enum machine_mode promoted_mode;
     int unsignedp;
     rtx may_share;
{
  struct insns_for_mem_entry tmp;
  struct insns_for_mem_entry *ime;
  rtx insn_list;

  tmp.key = var;
  ime = (struct insns_for_mem_entry *) htab_find (ht, &tmp);
  for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
    if (INSN_P (XEXP (insn_list, 0)))
      fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
			   unsignedp, 1, may_share);
}


/* Per-insn processing by fixup_var_refs_insns(_with_hash).  INSN is
   the insn under examination, VAR is the variable to fix up
   references to, PROMOTED_MODE and UNSIGNEDP describe VAR, and
   TOPLEVEL is nonzero if this is the main insn chain for this
   function.  */

static void
fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel, no_share)
     rtx insn;
     rtx var;
     enum machine_mode promoted_mode;
     int unsignedp;
     int toplevel;
     rtx no_share;
{
  rtx call_dest = 0;
  rtx set, prev, prev_set;
  rtx note;

  /* Remember the notes in case we delete the insn.  */
  note = REG_NOTES (insn);

  /* If this is a CLOBBER of VAR, delete it.

     If it has a REG_LIBCALL note, delete the REG_LIBCALL
     and REG_RETVAL notes too.  */
  if (GET_CODE (PATTERN (insn)) == CLOBBER
      && (XEXP (PATTERN (insn), 0) == var
	  || (GET_CODE (XEXP (PATTERN (insn), 0)) == CONCAT
	      && (XEXP (XEXP (PATTERN (insn), 0), 0) == var
		  || XEXP (XEXP (PATTERN (insn), 0), 1) == var))))
    {
      if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0)
	/* The REG_LIBCALL note will go away since we are going to
	   turn INSN into a NOTE, so just delete the
	   corresponding REG_RETVAL note.  */
	remove_note (XEXP (note, 0),
		     find_reg_note (XEXP (note, 0), REG_RETVAL,
				    NULL_RTX));

      delete_insn (insn);
    }

  /* The insn to load VAR from a home in the arglist
     is now a no-op.  When we see it, just delete it.
     Similarly if this is storing VAR from a register from which
     it was loaded in the previous insn.  This will occur
     when an ADDRESSOF was made for an arglist slot.  */
  else if (toplevel
	   && (set = single_set (insn)) != 0
	   && SET_DEST (set) == var
	   /* If this represents the result of an insn group,
	      don't delete the insn.  */
	   && find_reg_note (insn, REG_RETVAL, NULL_RTX) == 0
	   && (rtx_equal_p (SET_SRC (set), var)
	       || (GET_CODE (SET_SRC (set)) == REG
		   && (prev = prev_nonnote_insn (insn)) != 0
		   && (prev_set = single_set (prev)) != 0
		   && SET_DEST (prev_set) == SET_SRC (set)
		   && rtx_equal_p (SET_SRC (prev_set), var))))
    {
      delete_insn (insn);
    }
  else
    {
      struct fixup_replacement *replacements = 0;
      rtx next_insn = NEXT_INSN (insn);

      if (SMALL_REGISTER_CLASSES)
	{
	  /* If the insn that copies the results of a CALL_INSN
	     into a pseudo now references VAR, we have to use an
	     intermediate pseudo since we want the life of the
	     return value register to be only a single insn.

	     If we don't use an intermediate pseudo, such things as
	     address computations to make the address of VAR valid
	     if it is not can be placed between the CALL_INSN and INSN.

	     To make sure this doesn't happen, we record the destination
	     of the CALL_INSN and see if the next insn uses both that
	     and VAR.  */

	  if (call_dest != 0 && GET_CODE (insn) == INSN
	      && reg_mentioned_p (var, PATTERN (insn))
	      && reg_mentioned_p (call_dest, PATTERN (insn)))
	    {
	      rtx temp = gen_reg_rtx (GET_MODE (call_dest));

	      emit_insn_before (gen_move_insn (temp, call_dest), insn);

	      PATTERN (insn) = replace_rtx (PATTERN (insn),
					    call_dest, temp);
	    }

	  if (GET_CODE (insn) == CALL_INSN
	      && GET_CODE (PATTERN (insn)) == SET)
	    call_dest = SET_DEST (PATTERN (insn));
	  else if (GET_CODE (insn) == CALL_INSN
		   && GET_CODE (PATTERN (insn)) == PARALLEL
		   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
	    call_dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
	  else
	    call_dest = 0;
	}

      /* See if we have to do anything to INSN now that VAR is in
	 memory.  If it needs to be loaded into a pseudo, use a single
	 pseudo for the entire insn in case there is a MATCH_DUP
	 between two operands.  We pass a pointer to the head of
	 a list of struct fixup_replacements.  If fixup_var_refs_1
	 needs to allocate pseudos or replacement MEMs (for SUBREGs),
	 it will record them in this list.

	 If it allocated a pseudo for any replacement, we copy into
	 it here.  */

      fixup_var_refs_1 (var, promoted_mode, &PATTERN (insn), insn,
			&replacements, no_share);

      /* If this is last_parm_insn, and any instructions were output
	 after it to fix it up, then we must set last_parm_insn to
	 the last such instruction emitted.  */
      if (insn == last_parm_insn)
	last_parm_insn = PREV_INSN (next_insn);

      while (replacements)
	{
	  struct fixup_replacement *next;

	  if (GET_CODE (replacements->new) == REG)
	    {
	      rtx insert_before;
	      rtx seq;

	      /* OLD might be a (subreg (mem)).  */
	      if (GET_CODE (replacements->old) == SUBREG)
		replacements->old
		  = fixup_memory_subreg (replacements->old, insn,
					 promoted_mode, 0);
	      else
		replacements->old
		  = fixup_stack_1 (replacements->old, insn);

	      insert_before = insn;

	      /* If we are changing the mode, do a conversion.
		 This might be wasteful, but combine.c will
		 eliminate much of the waste.  */

	      if (GET_MODE (replacements->new)
		  != GET_MODE (replacements->old))
		{
		  start_sequence ();
		  convert_move (replacements->new,
				replacements->old, unsignedp);
		  seq = get_insns ();
		  end_sequence ();
		}
	      else
		seq = gen_move_insn (replacements->new,
				     replacements->old);

	      emit_insn_before (seq, insert_before);
	    }

	  next = replacements->next;
	  free (replacements);
	  replacements = next;
	}
    }

  /* Also fix up any invalid exprs in the REG_NOTES of this insn.
     But don't touch other insns referred to by reg-notes;
     we will get them elsewhere.  */
  while (note)
    {
      if (GET_CODE (note) != INSN_LIST)
	XEXP (note, 0)
	  = walk_fixup_memory_subreg (XEXP (note, 0), insn,
				      promoted_mode, 1);
      note = XEXP (note, 1);
    }
}

/* VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.
   See if the rtx expression at *LOC in INSN needs to be changed.

   REPLACEMENTS is a pointer to a list head that starts out zero, but may
   contain a list of original rtx's and replacements. If we find that we need
   to modify this insn by replacing a memory reference with a pseudo or by
   making a new MEM to implement a SUBREG, we consult that list to see if
   we have already chosen a replacement. If none has already been allocated,
   we allocate it and update the list.  fixup_var_refs_insn will copy VAR
   or the SUBREG, as appropriate, to the pseudo.  */

static void
fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
     rtx var;
     enum machine_mode promoted_mode;
     rtx *loc;
     rtx insn;
     struct fixup_replacement **replacements;
     rtx no_share;
{
  int i;
  rtx x = *loc;
  RTX_CODE code = GET_CODE (x);
  const char *fmt;
  rtx tem, tem1;
  struct fixup_replacement *replacement;

  switch (code)
    {
    case ADDRESSOF:
      if (XEXP (x, 0) == var)
	{
	  /* Prevent sharing of rtl that might lose.  */
	  rtx sub = copy_rtx (XEXP (var, 0));

	  if (! validate_change (insn, loc, sub, 0))
	    {
	      rtx y = gen_reg_rtx (GET_MODE (sub));
	      rtx seq, new_insn;

	      /* We should be able to replace with a register or all is lost.
		 Note that we can't use validate_change to verify this, since
		 we're not caring for replacing all dups simultaneously.  */
	      if (! validate_replace_rtx (*loc, y, insn))
		abort ();

	      /* Careful!  First try to recognize a direct move of the
		 value, mimicking how things are done in gen_reload wrt
		 PLUS.  Consider what happens when insn is a conditional
		 move instruction and addsi3 clobbers flags.  */

	      start_sequence ();
	      new_insn = emit_insn (gen_rtx_SET (VOIDmode, y, sub));
	      seq = get_insns ();
	      end_sequence ();

	      if (recog_memoized (new_insn) < 0)
		{
		  /* That failed.  Fall back on force_operand and hope.  */

		  start_sequence ();
		  sub = force_operand (sub, y);
		  if (sub != y)
		    emit_insn (gen_move_insn (y, sub));
		  seq = get_insns ();
		  end_sequence ();
		}

#ifdef HAVE_cc0
	      /* Don't separate setter from user.  */
	      if (PREV_INSN (insn) && sets_cc0_p (PREV_INSN (insn)))
		insn = PREV_INSN (insn);
#endif

	      emit_insn_before (seq, insn);
	    }
	}
      return;

    case MEM:
      if (var == x)
	{
	  /* If we already have a replacement, use it.  Otherwise,
	     try to fix up this address in case it is invalid.  */

	  replacement = find_fixup_replacement (replacements, var);
	  if (replacement->new)
	    {
	      *loc = replacement->new;
	      return;
	    }

	  *loc = replacement->new = x = fixup_stack_1 (x, insn);

	  /* Unless we are forcing memory to register or we changed the mode,
	     we can leave things the way they are if the insn is valid.  */

	  INSN_CODE (insn) = -1;
	  if (! flag_force_mem && GET_MODE (x) == promoted_mode
	      && recog_memoized (insn) >= 0)
	    return;

	  *loc = replacement->new = gen_reg_rtx (promoted_mode);
	  return;
	}

      /* If X contains VAR, we need to unshare it here so that we update
	 each occurrence separately.  But all identical MEMs in one insn
	 must be replaced with the same rtx because of the possibility of
	 MATCH_DUPs.  */

      if (reg_mentioned_p (var, x))
	{
	  replacement = find_fixup_replacement (replacements, x);
	  if (replacement->new == 0)
	    replacement->new = copy_most_rtx (x, no_share);

	  *loc = x = replacement->new;
	  code = GET_CODE (x);
	}
      break;

    case REG:
    case CC0:
    case PC:
    case CONST_INT:
    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
    case CONST_DOUBLE:
    case CONST_VECTOR:
      return;

    case SIGN_EXTRACT:
    case ZERO_EXTRACT:
      /* Note that in some cases those types of expressions are altered
	 by optimize_bit_field, and do not survive to get here.  */
      if (XEXP (x, 0) == var
	  || (GET_CODE (XEXP (x, 0)) == SUBREG
	      && SUBREG_REG (XEXP (x, 0)) == var))
	{
	  /* Get TEM as a valid MEM in the mode presently in the insn.

	     We don't worry about the possibility of MATCH_DUP here; it
	     is highly unlikely and would be tricky to handle.  */

	  tem = XEXP (x, 0);
	  if (GET_CODE (tem) == SUBREG)
	    {
	      if (GET_MODE_BITSIZE (GET_MODE (tem))
		  > GET_MODE_BITSIZE (GET_MODE (var)))
		{
		  replacement = find_fixup_replacement (replacements, var);
		  if (replacement->new == 0)
		    replacement->new = gen_reg_rtx (GET_MODE (var));
		  SUBREG_REG (tem) = replacement->new;

		  /* The following code works only if we have a MEM, so we
		     need to handle the subreg here.  We directly substitute
		     it assuming that a subreg must be OK here.  We already
		     scheduled a replacement to copy the mem into the
		     subreg.  */
		  XEXP (x, 0) = tem;
		  return;
		}
	      else
		tem = fixup_memory_subreg (tem, insn, promoted_mode, 0);
	    }
	  else
	    tem = fixup_stack_1 (tem, insn);

	  /* Unless we want to load from memory, get TEM into the proper mode
	     for an extract from memory.  This can only be done if the
	     extract is at a constant position and length.  */

	  if (! flag_force_mem && GET_CODE (XEXP (x, 1)) == CONST_INT
	      && GET_CODE (XEXP (x, 2)) == CONST_INT
	      && ! mode_dependent_address_p (XEXP (tem, 0))
	      && ! MEM_VOLATILE_P (tem))
	    {
	      enum machine_mode wanted_mode = VOIDmode;
	      enum machine_mode is_mode = GET_MODE (tem);
	      HOST_WIDE_INT pos = INTVAL (XEXP (x, 2));

	      if (GET_CODE (x) == ZERO_EXTRACT)
		{
		  enum machine_mode new_mode
		    = mode_for_extraction (EP_extzv, 1);
		  if (new_mode != MAX_MACHINE_MODE)
		    wanted_mode = new_mode;
		}
	      else if (GET_CODE (x) == SIGN_EXTRACT)
		{
		  enum machine_mode new_mode
		    = mode_for_extraction (EP_extv, 1);
		  if (new_mode != MAX_MACHINE_MODE)
		    wanted_mode = new_mode;
		}

	      /* If we have a narrower mode, we can do something.  */
	      if (wanted_mode != VOIDmode
		  && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
		{
		  HOST_WIDE_INT offset = pos / BITS_PER_UNIT;
		  rtx old_pos = XEXP (x, 2);
		  rtx newmem;

		  /* If the bytes and bits are counted differently, we
		     must adjust the offset.  */
		  if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
		    offset = (GET_MODE_SIZE (is_mode)
			      - GET_MODE_SIZE (wanted_mode) - offset);

		  pos %= GET_MODE_BITSIZE (wanted_mode);

		  newmem = adjust_address_nv (tem, wanted_mode, offset);

		  /* Make the change and see if the insn remains valid.  */
		  INSN_CODE (insn) = -1;
		  XEXP (x, 0) = newmem;
		  XEXP (x, 2) = GEN_INT (pos);

		  if (recog_memoized (insn) >= 0)
		    return;

		  /* Otherwise, restore old position.  XEXP (x, 0) will be
		     restored later.  */
		  XEXP (x, 2) = old_pos;
		}
	    }

	  /* If we get here, the bitfield extract insn can't accept a memory
	     reference.  Copy the input into a register.  */

	  tem1 = gen_reg_rtx (GET_MODE (tem));
	  emit_insn_before (gen_move_insn (tem1, tem), insn);
	  XEXP (x, 0) = tem1;
	  return;
	}
      break;

    case SUBREG:
      if (SUBREG_REG (x) == var)
	{
	  /* If this is a special SUBREG made because VAR was promoted
	     from a wider mode, replace it with VAR and call ourself
	     recursively, this time saying that the object previously
	     had its current mode (by virtue of the SUBREG).  */

	  if (SUBREG_PROMOTED_VAR_P (x))
	    {
	      *loc = var;
	      fixup_var_refs_1 (var, GET_MODE (var), loc, insn, replacements,
				no_share);
	      return;
	    }

	  /* If this SUBREG makes VAR wider, it has become a paradoxical
	     SUBREG with VAR in memory, but these aren't allowed at this
	     stage of the compilation.  So load VAR into a pseudo and take
	     a SUBREG of that pseudo.  */
	  if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (var)))
	    {
	      replacement = find_fixup_replacement (replacements, var);
	      if (replacement->new == 0)
		replacement->new = gen_reg_rtx (promoted_mode);
	      SUBREG_REG (x) = replacement->new;
	      return;
	    }

	  /* See if we have already found a replacement for this SUBREG.
	     If so, use it.  Otherwise, make a MEM and see if the insn
	     is recognized.  If not, or if we should force MEM into a register,
	     make a pseudo for this SUBREG.  */
	  replacement = find_fixup_replacement (replacements, x);
	  if (replacement->new)
	    {
	      enum machine_mode mode = GET_MODE (x);
	      *loc = replacement->new;

	      /* Careful!  We may have just replaced a SUBREG by a MEM, which
		 means that the insn may have become invalid again.  We can't
		 in this case make a new replacement since we already have one
		 and we must deal with MATCH_DUPs.  */
	      if (GET_CODE (replacement->new) == MEM)
		{
		  INSN_CODE (insn) = -1;
		  if (recog_memoized (insn) >= 0)
		    return;

		  fixup_var_refs_1 (replacement->new, mode, &PATTERN (insn),
				    insn, replacements, no_share);
		}

	      return;
	    }

	  replacement->new = *loc = fixup_memory_subreg (x, insn,
							 promoted_mode, 0);

	  INSN_CODE (insn) = -1;
	  if (! flag_force_mem && recog_memoized (insn) >= 0)
	    return;

	  *loc = replacement->new = gen_reg_rtx (GET_MODE (x));
	  return;
	}
      break;

    case SET:
      /* First do special simplification of bit-field references.  */
      if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
	  || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
	optimize_bit_field (x, insn, 0);
      if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
	  || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
	optimize_bit_field (x, insn, 0);

      /* For a paradoxical SUBREG inside a ZERO_EXTRACT, load the object
	 into a register and then store it back out.  */
      if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
	  && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG
	  && SUBREG_REG (XEXP (SET_DEST (x), 0)) == var
	  && (GET_MODE_SIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
	      > GET_MODE_SIZE (GET_MODE (var))))
	{
	  replacement = find_fixup_replacement (replacements, var);
	  if (replacement->new == 0)
	    replacement->new = gen_reg_rtx (GET_MODE (var));

	  SUBREG_REG (XEXP (SET_DEST (x), 0)) = replacement->new;
	  emit_insn_after (gen_move_insn (var, replacement->new), insn);
	}

      /* If SET_DEST is now a paradoxical SUBREG, put the result of this
	 insn into a pseudo and store the low part of the pseudo into VAR.  */
      if (GET_CODE (SET_DEST (x)) == SUBREG
	  && SUBREG_REG (SET_DEST (x)) == var
	  && (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
	      > GET_MODE_SIZE (GET_MODE (var))))
	{
	  SET_DEST (x) = tem = gen_reg_rtx (GET_MODE (SET_DEST (x)));
	  emit_insn_after (gen_move_insn (var, gen_lowpart (GET_MODE (var),
							    tem)),
			   insn);
	  break;
	}

      {
	rtx dest = SET_DEST (x);
	rtx src = SET_SRC (x);
	rtx outerdest = dest;

	while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
	       || GET_CODE (dest) == SIGN_EXTRACT
	       || GET_CODE (dest) == ZERO_EXTRACT)
	  dest = XEXP (dest, 0);

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

	/* If VAR does not appear at the top level of the SET
	   just scan the lower levels of the tree.  */

	if (src != var && dest != var)
	  break;

	/* We will need to rerecognize this insn.  */
	INSN_CODE (insn) = -1;

	if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var
	    && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
	  {
	    /* Since this case will return, ensure we fixup all the
	       operands here.  */
	    fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 1),
			      insn, replacements, no_share);
	    fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 2),
			      insn, replacements, no_share);
	    fixup_var_refs_1 (var, promoted_mode, &SET_SRC (x),
			      insn, replacements, no_share);

	    tem = XEXP (outerdest, 0);

	    /* Clean up (SUBREG:SI (MEM:mode ...) 0)
	       that may appear inside a ZERO_EXTRACT.
	       This was legitimate when the MEM was a REG.  */
	    if (GET_CODE (tem) == SUBREG
		&& SUBREG_REG (tem) == var)
	      tem = fixup_memory_subreg (tem, insn, promoted_mode, 0);
	    else
	      tem = fixup_stack_1 (tem, insn);

	    if (GET_CODE (XEXP (outerdest, 1)) == CONST_INT
		&& GET_CODE (XEXP (outerdest, 2)) == CONST_INT
		&& ! mode_dependent_address_p (XEXP (tem, 0))
		&& ! MEM_VOLATILE_P (tem))
	      {
		enum machine_mode wanted_mode;
		enum machine_mode is_mode = GET_MODE (tem);
		HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));

		wanted_mode = mode_for_extraction (EP_insv, 0);

		/* If we have a narrower mode, we can do something.  */
		if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
		  {
		    HOST_WIDE_INT offset = pos / BITS_PER_UNIT;
		    rtx old_pos = XEXP (outerdest, 2);
		    rtx newmem;

		    if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
		      offset = (GET_MODE_SIZE (is_mode)
				- GET_MODE_SIZE (wanted_mode) - offset);

		    pos %= GET_MODE_BITSIZE (wanted_mode);

		    newmem = adjust_address_nv (tem, wanted_mode, offset);

		    /* Make the change and see if the insn remains valid.  */
		    INSN_CODE (insn) = -1;
		    XEXP (outerdest, 0) = newmem;
		    XEXP (outerdest, 2) = GEN_INT (pos);

		    if (recog_memoized (insn) >= 0)
		      return;

		    /* Otherwise, restore old position.  XEXP (x, 0) will be
		       restored later.  */
		    XEXP (outerdest, 2) = old_pos;
		  }
	      }

	    /* If we get here, the bit-field store doesn't allow memory
	       or isn't located at a constant position.  Load the value into
	       a register, do the store, and put it back into memory.  */

	    tem1 = gen_reg_rtx (GET_MODE (tem));
	    emit_insn_before (gen_move_insn (tem1, tem), insn);
	    emit_insn_after (gen_move_insn (tem, tem1), insn);
	    XEXP (outerdest, 0) = tem1;
	    return;
	  }

	/* STRICT_LOW_PART is a no-op on memory references
	   and it can cause combinations to be unrecognizable,
	   so eliminate it.  */

	if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
	  SET_DEST (x) = XEXP (SET_DEST (x), 0);

	/* A valid insn to copy VAR into or out of a register
	   must be left alone, to avoid an infinite loop here.
	   If the reference to VAR is by a subreg, fix that up,
	   since SUBREG is not valid for a memref.
	   Also fix up the address of the stack slot.

	   Note that we must not try to recognize the insn until
	   after we know that we have valid addresses and no
	   (subreg (mem ...) ...) constructs, since these interfere
	   with determining the validity of the insn.  */

	if ((SET_SRC (x) == var
	     || (GET_CODE (SET_SRC (x)) == SUBREG
		 && SUBREG_REG (SET_SRC (x)) == var))
	    && (GET_CODE (SET_DEST (x)) == REG
		|| (GET_CODE (SET_DEST (x)) == SUBREG
		    && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
	    && GET_MODE (var) == promoted_mode
	    && x == single_set (insn))
	  {
	    rtx pat, last;

	    if (GET_CODE (SET_SRC (x)) == SUBREG
		&& (GET_MODE_SIZE (GET_MODE (SET_SRC (x)))
		    > GET_MODE_SIZE (GET_MODE (var))))
	      {
		/* This (subreg VAR) is now a paradoxical subreg.  We need
		   to replace VAR instead of the subreg.  */
		replacement = find_fixup_replacement (replacements, var);
		if (replacement->new == NULL_RTX)
		  replacement->new = gen_reg_rtx (GET_MODE (var));
		SUBREG_REG (SET_SRC (x)) = replacement->new;
	      }
	    else
	      {
		replacement = find_fixup_replacement (replacements, SET_SRC (x));
		if (replacement->new)
		  SET_SRC (x) = replacement->new;
		else if (GET_CODE (SET_SRC (x)) == SUBREG)
		  SET_SRC (x) = replacement->new
		    = fixup_memory_subreg (SET_SRC (x), insn, promoted_mode,
					   0);
		else
		  SET_SRC (x) = replacement->new
		    = fixup_stack_1 (SET_SRC (x), insn);
	      }

	    if (recog_memoized (insn) >= 0)
	      return;

	    /* INSN is not valid, but we know that we want to
	       copy SET_SRC (x) to SET_DEST (x) in some way.  So
	       we generate the move and see whether it requires more
	       than one insn.  If it does, we emit those insns and
	       delete INSN.  Otherwise, we can just replace the pattern
	       of INSN; we have already verified above that INSN has
	       no other function that to do X.  */

	    pat = gen_move_insn (SET_DEST (x), SET_SRC (x));
	    if (NEXT_INSN (pat) != NULL_RTX)
	      {
		last = emit_insn_before (pat, insn);

		/* INSN might have REG_RETVAL or other important notes, so
		   we need to store the pattern of the last insn in the
		   sequence into INSN similarly to the normal case.  LAST
		   should not have REG_NOTES, but we allow them if INSN has
		   no REG_NOTES.  */
		if (REG_NOTES (last) && REG_NOTES (insn))
		  abort ();
		if (REG_NOTES (last))
		  REG_NOTES (insn) = REG_NOTES (last);
		PATTERN (insn) = PATTERN (last);

		delete_insn (last);
	      }
	    else
	      PATTERN (insn) = PATTERN (pat);

	    return;
	  }

	if ((SET_DEST (x) == var
	     || (GET_CODE (SET_DEST (x)) == SUBREG
		 && SUBREG_REG (SET_DEST (x)) == var))
	    && (GET_CODE (SET_SRC (x)) == REG
		|| (GET_CODE (SET_SRC (x)) == SUBREG
		    && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG))
	    && GET_MODE (var) == promoted_mode
	    && x == single_set (insn))
	  {
	    rtx pat, last;

	    if (GET_CODE (SET_DEST (x)) == SUBREG)
	      SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn,
						  promoted_mode, 0);
	    else
	      SET_DEST (x) = fixup_stack_1 (SET_DEST (x), insn);

	    if (recog_memoized (insn) >= 0)
	      return;

	    pat = gen_move_insn (SET_DEST (x), SET_SRC (x));
	    if (NEXT_INSN (pat) != NULL_RTX)
	      {
		last = emit_insn_before (pat, insn);

		/* INSN might have REG_RETVAL or other important notes, so
		   we need to store the pattern of the last insn in the
		   sequence into INSN similarly to the normal case.  LAST
		   should not have REG_NOTES, but we allow them if INSN has
		   no REG_NOTES.  */
		if (REG_NOTES (last) && REG_NOTES (insn))
		  abort ();
		if (REG_NOTES (last))
		  REG_NOTES (insn) = REG_NOTES (last);
		PATTERN (insn) = PATTERN (last);

		delete_insn (last);
	      }
	    else
	      PATTERN (insn) = PATTERN (pat);

	    return;
	  }

	/* Otherwise, storing into VAR must be handled specially
	   by storing into a temporary and copying that into VAR
	   with a new insn after this one.  Note that this case
	   will be used when storing into a promoted scalar since
	   the insn will now have different modes on the input
	   and output and hence will be invalid (except for the case
	   of setting it to a constant, which does not need any
	   change if it is valid).  We generate extra code in that case,
	   but combine.c will eliminate it.  */

	if (dest == var)
	  {
	    rtx temp;
	    rtx fixeddest = SET_DEST (x);
	    enum machine_mode temp_mode;

	    /* STRICT_LOW_PART can be discarded, around a MEM.  */
	    if (GET_CODE (fixeddest) == STRICT_LOW_PART)
	      fixeddest = XEXP (fixeddest, 0);
	    /* Convert (SUBREG (MEM)) to a MEM in a changed mode.  */
	    if (GET_CODE (fixeddest) == SUBREG)
	      {
		fixeddest = fixup_memory_subreg (fixeddest, insn,
						 promoted_mode, 0);
		temp_mode = GET_MODE (fixeddest);
	      }
	    else
	      {
		fixeddest = fixup_stack_1 (fixeddest, insn);
		temp_mode = promoted_mode;
	      }

	    temp = gen_reg_rtx (temp_mode);

	    emit_insn_after (gen_move_insn (fixeddest,
					    gen_lowpart (GET_MODE (fixeddest),
							 temp)),
			     insn);

	    SET_DEST (x) = temp;
	  }
      }

    default:
      break;
    }

  /* Nothing special about this RTX; fix its operands.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	fixup_var_refs_1 (var, promoted_mode, &XEXP (x, i), insn, replacements,
			  no_share);
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = 0; j < XVECLEN (x, i); j++)
	    fixup_var_refs_1 (var, promoted_mode, &XVECEXP (x, i, j),
			      insn, replacements, no_share);
	}
    }
}

/* Previously, X had the form (SUBREG:m1 (REG:PROMOTED_MODE ...)).
   The REG  was placed on the stack, so X now has the form (SUBREG:m1
   (MEM:m2 ...)).

   Return an rtx (MEM:m1 newaddr) which is equivalent.  If any insns
   must be emitted to compute NEWADDR, put them before INSN.

   UNCRITICAL nonzero means accept paradoxical subregs.
   This is used for subregs found inside REG_NOTES.  */

static rtx
fixup_memory_subreg (x, insn, promoted_mode, uncritical)
     rtx x;
     rtx insn;
     enum machine_mode promoted_mode;
     int uncritical;
{
  int offset;
  rtx mem = SUBREG_REG (x);
  rtx addr = XEXP (mem, 0);
  enum machine_mode mode = GET_MODE (x);
  rtx result, seq;

  /* Paradoxical SUBREGs are usually invalid during RTL generation.  */
  if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (mem)) && ! uncritical)
    abort ();

  offset = SUBREG_BYTE (x);
  if (BYTES_BIG_ENDIAN)
    /* If the PROMOTED_MODE is wider than the mode of the MEM, adjust
       the offset so that it points to the right location within the
       MEM.  */
    offset -= (GET_MODE_SIZE (promoted_mode) - GET_MODE_SIZE (GET_MODE (mem)));

  if (!flag_force_addr
      && memory_address_p (mode, plus_constant (addr, offset)))
    /* Shortcut if no insns need be emitted.  */
    return adjust_address (mem, mode, offset);

  start_sequence ();
  result = adjust_address (mem, mode, offset);
  seq = get_insns ();
  end_sequence ();

  emit_insn_before (seq, insn);
  return result;
}

/* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
   Replace subexpressions of X in place.
   If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
   Otherwise return X, with its contents possibly altered.

   INSN, PROMOTED_MODE and UNCRITICAL are as for
   fixup_memory_subreg.  */

static rtx
walk_fixup_memory_subreg (x, insn, promoted_mode, uncritical)
     rtx x;
     rtx insn;
     enum machine_mode promoted_mode;
     int uncritical;
{
  enum rtx_code code;
  const char *fmt;
  int i;

  if (x == 0)
    return 0;

  code = GET_CODE (x);

  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
    return fixup_memory_subreg (x, insn, promoted_mode, uncritical);

  /* Nothing special about this RTX; fix its operands.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn,
						promoted_mode, uncritical);
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = 0; j < XVECLEN (x, i); j++)
	    XVECEXP (x, i, j)
	      = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn,
					  promoted_mode, uncritical);
	}
    }
  return x;
}

/* For each memory ref within X, if it refers to a stack slot
   with an out of range displacement, put the address in a temp register
   (emitting new insns before INSN to load these registers)
   and alter the memory ref to use that register.
   Replace each such MEM rtx with a copy, to avoid clobberage.  */

static rtx
fixup_stack_1 (x, insn)
     rtx x;
     rtx insn;
{
  int i;
  RTX_CODE code = GET_CODE (x);
  const char *fmt;

  if (code == MEM)
    {
      rtx ad = XEXP (x, 0);
      /* If we have address of a stack slot but it's not valid
	 (displacement is too large), compute the sum in a register.  */
      if (GET_CODE (ad) == PLUS
	  && GET_CODE (XEXP (ad, 0)) == REG
	  && ((REGNO (XEXP (ad, 0)) >= FIRST_VIRTUAL_REGISTER
	       && REGNO (XEXP (ad, 0)) <= LAST_VIRTUAL_REGISTER)
	      || REGNO (XEXP (ad, 0)) == FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
	      || REGNO (XEXP (ad, 0)) == HARD_FRAME_POINTER_REGNUM
#endif
	      || REGNO (XEXP (ad, 0)) == STACK_POINTER_REGNUM
	      || REGNO (XEXP (ad, 0)) == ARG_POINTER_REGNUM
	      || XEXP (ad, 0) == current_function_internal_arg_pointer)
	  && GET_CODE (XEXP (ad, 1)) == CONST_INT)
	{
	  rtx temp, seq;
	  if (memory_address_p (GET_MODE (x), ad))
	    return x;

	  start_sequence ();
	  temp = copy_to_reg (ad);
	  seq = get_insns ();
	  end_sequence ();
	  emit_insn_before (seq, insn);
	  return replace_equiv_address (x, temp);
	}
      return x;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = 0; j < XVECLEN (x, i); j++)
	    XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
	}
    }
  return x;
}

/* Optimization: a bit-field instruction whose field
   happens to be a byte or halfword in memory
   can be changed to a move instruction.

   We call here when INSN is an insn to examine or store into a bit-field.
   BODY is the SET-rtx to be altered.

   EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
   (Currently this is called only from function.c, and EQUIV_MEM
   is always 0.)  */

static void
optimize_bit_field (body, insn, equiv_mem)
     rtx body;
     rtx insn;
     rtx *equiv_mem;
{
  rtx bitfield;
  int destflag;
  rtx seq = 0;
  enum machine_mode mode;

  if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
      || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
    bitfield = SET_DEST (body), destflag = 1;
  else
    bitfield = SET_SRC (body), destflag = 0;

  /* First check that the field being stored has constant size and position
     and is in fact a byte or halfword suitably aligned.  */

  if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
      && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
      && ((mode = mode_for_size (INTVAL (XEXP (bitfield, 1)), MODE_INT, 1))
	  != BLKmode)
      && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
    {
      rtx memref = 0;

      /* Now check that the containing word is memory, not a register,
	 and that it is safe to change the machine mode.  */

      if (GET_CODE (XEXP (bitfield, 0)) == MEM)
	memref = XEXP (bitfield, 0);
      else if (GET_CODE (XEXP (bitfield, 0)) == REG
	       && equiv_mem != 0)
	memref = equiv_mem[REGNO (XEXP (bitfield, 0))];
      else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
	       && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
	memref = SUBREG_REG (XEXP (bitfield, 0));
      else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
	       && equiv_mem != 0
	       && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG)
	memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))];

      if (memref
	  && ! mode_dependent_address_p (XEXP (memref, 0))
	  && ! MEM_VOLATILE_P (memref))
	{
	  /* Now adjust the address, first for any subreg'ing
	     that we are now getting rid of,
	     and then for which byte of the word is wanted.  */

	  HOST_WIDE_INT offset = INTVAL (XEXP (bitfield, 2));
	  rtx insns;

	  /* Adjust OFFSET to count bits from low-address byte.  */
	  if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
	    offset = (GET_MODE_BITSIZE (GET_MODE (XEXP (bitfield, 0)))
		      - offset - INTVAL (XEXP (bitfield, 1)));

	  /* Adjust OFFSET to count bytes from low-address byte.  */
	  offset /= BITS_PER_UNIT;
	  if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
	    {
	      offset += (SUBREG_BYTE (XEXP (bitfield, 0))
			 / UNITS_PER_WORD) * UNITS_PER_WORD;
	      if (BYTES_BIG_ENDIAN)
		offset -= (MIN (UNITS_PER_WORD,
				GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
			   - MIN (UNITS_PER_WORD,
				  GET_MODE_SIZE (GET_MODE (memref))));
	    }

	  start_sequence ();
	  memref = adjust_address (memref, mode, offset);
	  insns = get_insns ();
	  end_sequence ();
	  emit_insn_before (insns, insn);

	  /* Store this memory reference where
	     we found the bit field reference.  */

	  if (destflag)
	    {
	      validate_change (insn, &SET_DEST (body), memref, 1);
	      if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
		{
		  rtx src = SET_SRC (body);
		  while (GET_CODE (src) == SUBREG
			 && SUBREG_BYTE (src) == 0)
		    src = SUBREG_REG (src);
		  if (GET_MODE (src) != GET_MODE (memref))
		    src = gen_lowpart (GET_MODE (memref), SET_SRC (body));
		  validate_change (insn, &SET_SRC (body), src, 1);
		}
	      else if (GET_MODE (SET_SRC (body)) != VOIDmode
		       && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
		/* This shouldn't happen because anything that didn't have
		   one of these modes should have got converted explicitly
		   and then referenced through a subreg.
		   This is so because the original bit-field was
		   handled by agg_mode and so its tree structure had
		   the same mode that memref now has.  */
		abort ();
	    }
	  else
	    {
	      rtx dest = SET_DEST (body);

	      while (GET_CODE (dest) == SUBREG
		     && SUBREG_BYTE (dest) == 0
		     && (GET_MODE_CLASS (GET_MODE (dest))
			 == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest))))
		     && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
			 <= UNITS_PER_WORD))
		dest = SUBREG_REG (dest);

	      validate_change (insn, &SET_DEST (body), dest, 1);

	      if (GET_MODE (dest) == GET_MODE (memref))
		validate_change (insn, &SET_SRC (body), memref, 1);
	      else
		{
		  /* Convert the mem ref to the destination mode.  */
		  rtx newreg = gen_reg_rtx (GET_MODE (dest));

		  start_sequence ();
		  convert_move (newreg, memref,
				GET_CODE (SET_SRC (body)) == ZERO_EXTRACT);
		  seq = get_insns ();
		  end_sequence ();

		  validate_change (insn, &SET_SRC (body), newreg, 1);
		}
	    }

	  /* See if we can convert this extraction or insertion into
	     a simple move insn.  We might not be able to do so if this
	     was, for example, part of a PARALLEL.

	     If we succeed, write out any needed conversions.  If we fail,
	     it is hard to guess why we failed, so don't do anything
	     special; just let the optimization be suppressed.  */

	  if (apply_change_group () && seq)
	    emit_insn_before (seq, insn);
	}
    }
}

/* These routines are responsible for converting virtual register references
   to the actual hard register references once RTL generation is complete.

   The following four variables are used for communication between the
   routines.  They contain the offsets of the virtual registers from their
   respective hard registers.  */

static int in_arg_offset;
static int var_offset;
static int dynamic_offset;
static int out_arg_offset;
static int cfa_offset;

/* In most machines, the stack pointer register is equivalent to the bottom
   of the stack.  */

#ifndef STACK_POINTER_OFFSET
#define STACK_POINTER_OFFSET	0
#endif

/* If not defined, pick an appropriate default for the offset of dynamically
   allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
   REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE.  */

#ifndef STACK_DYNAMIC_OFFSET

/* The bottom of the stack points to the actual arguments.  If
   REG_PARM_STACK_SPACE is defined, this includes the space for the register
   parameters.  However, if OUTGOING_REG_PARM_STACK space is not defined,
   stack space for register parameters is not pushed by the caller, but
   rather part of the fixed stack areas and hence not included in
   `current_function_outgoing_args_size'.  Nevertheless, we must allow
   for it when allocating stack dynamic objects.  */

#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
#define STACK_DYNAMIC_OFFSET(FNDECL)	\
((ACCUMULATE_OUTGOING_ARGS						      \
  ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL)) : 0)\
 + (STACK_POINTER_OFFSET))						      \

#else
#define STACK_DYNAMIC_OFFSET(FNDECL)	\
((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0)	      \
 + (STACK_POINTER_OFFSET))
#endif
#endif

/* On most machines, the CFA coincides with the first incoming parm.  */

#ifndef ARG_POINTER_CFA_OFFSET
#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
#endif

/* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just
   had its address taken.  DECL is the decl or SAVE_EXPR for the
   object stored in the register, for later use if we do need to force
   REG into the stack.  REG is overwritten by the MEM like in
   put_reg_into_stack.  RESCAN is true if previously emitted
   instructions must be rescanned and modified now that the REG has
   been transformed.  */

rtx
gen_mem_addressof (reg, decl, rescan)
     rtx reg;
     tree decl;
     int rescan;
{
  rtx r = gen_rtx_ADDRESSOF (Pmode, gen_reg_rtx (GET_MODE (reg)),
			     REGNO (reg), decl);

  /* Calculate this before we start messing with decl's RTL.  */
  HOST_WIDE_INT set = decl ? get_alias_set (decl) : 0;

  /* If the original REG was a user-variable, then so is the REG whose
     address is being taken.  Likewise for unchanging.  */
  REG_USERVAR_P (XEXP (r, 0)) = REG_USERVAR_P (reg);
  RTX_UNCHANGING_P (XEXP (r, 0)) = RTX_UNCHANGING_P (reg);

  PUT_CODE (reg, MEM);
  MEM_ATTRS (reg) = 0;
  XEXP (reg, 0) = r;

  if (decl)
    {
      tree type = TREE_TYPE (decl);
      enum machine_mode decl_mode
	= (DECL_P (decl) ? DECL_MODE (decl) : TYPE_MODE (TREE_TYPE (decl)));
      rtx decl_rtl = (TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl)
		      : DECL_RTL_IF_SET (decl));

      PUT_MODE (reg, decl_mode);

      /* Clear DECL_RTL momentarily so functions below will work
	 properly, then set it again.  */
      if (DECL_P (decl) && decl_rtl == reg)
	SET_DECL_RTL (decl, 0);

      set_mem_attributes (reg, decl, 1);
      set_mem_alias_set (reg, set);

      if (DECL_P (decl) && decl_rtl == reg)
	SET_DECL_RTL (decl, reg);

      if (rescan 
	  && (TREE_USED (decl) || (DECL_P (decl) && DECL_INITIAL (decl) != 0)))
	fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), reg, 0);
    }
  else if (rescan)
    fixup_var_refs (reg, GET_MODE (reg), 0, reg, 0);

  return reg;
}

/* If DECL has an RTL that is an ADDRESSOF rtx, put it into the stack.  */

void
flush_addressof (decl)
     tree decl;
{
  if ((TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == VAR_DECL)
      && DECL_RTL (decl) != 0
      && GET_CODE (DECL_RTL (decl)) == MEM
      && GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF
      && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == REG)
    put_addressof_into_stack (XEXP (DECL_RTL (decl), 0), 0);
}

/* Force the register pointed to by R, an ADDRESSOF rtx, into the stack.  */

static void
put_addressof_into_stack (r, ht)
     rtx r;
     htab_t ht;
{
  tree decl, type;
  int volatile_p, used_p;

  rtx reg = XEXP (r, 0);

  if (GET_CODE (reg) != REG)
    abort ();

  decl = ADDRESSOF_DECL (r);
  if (decl)
    {
      type = TREE_TYPE (decl);
      volatile_p = (TREE_CODE (decl) != SAVE_EXPR
		    && TREE_THIS_VOLATILE (decl));
      used_p = (TREE_USED (decl)
		|| (DECL_P (decl) && DECL_INITIAL (decl) != 0));
    }
  else
    {
      type = NULL_TREE;
      volatile_p = 0;
      used_p = 1;
    }

  put_reg_into_stack (0, reg, type, GET_MODE (reg), GET_MODE (reg),
		      volatile_p, ADDRESSOF_REGNO (r), used_p, ht);
}

/* List of replacements made below in purge_addressof_1 when creating
   bitfield insertions.  */
static rtx purge_bitfield_addressof_replacements;

/* List of replacements made below in purge_addressof_1 for patterns
   (MEM (ADDRESSOF (REG ...))).  The key of the list entry is the
   corresponding (ADDRESSOF (REG ...)) and value is a substitution for
   the all pattern.  List PURGE_BITFIELD_ADDRESSOF_REPLACEMENTS is not
   enough in complex cases, e.g. when some field values can be
   extracted by usage MEM with narrower mode.  */
static rtx purge_addressof_replacements;

/* Helper function for purge_addressof.  See if the rtx expression at *LOC
   in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
   the stack.  If the function returns FALSE then the replacement could not
   be made.  */

static bool
purge_addressof_1 (loc, insn, force, store, ht)
     rtx *loc;
     rtx insn;
     int force, store;
     htab_t ht;
{
  rtx x;
  RTX_CODE code;
  int i, j;
  const char *fmt;
  bool result = true;

  /* Re-start here to avoid recursion in common cases.  */
 restart:

  x = *loc;
  if (x == 0)
    return true;

  code = GET_CODE (x);

  /* If we don't return in any of the cases below, we will recurse inside
     the RTX, which will normally result in any ADDRESSOF being forced into
     memory.  */
  if (code == SET)
    {
      result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
      result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
      return result;
    }
  else if (code == ADDRESSOF)
    {
      rtx sub, insns;

      if (GET_CODE (XEXP (x, 0)) != MEM)
	put_addressof_into_stack (x, ht);

      /* We must create a copy of the rtx because it was created by
	 overwriting a REG rtx which is always shared.  */
      sub = copy_rtx (XEXP (XEXP (x, 0), 0));
      if (validate_change (insn, loc, sub, 0)
	  || validate_replace_rtx (x, sub, insn))
	return true;

      start_sequence ();
      sub = force_operand (sub, NULL_RTX);
      if (! validate_change (insn, loc, sub, 0)
	  && ! validate_replace_rtx (x, sub, insn))
	abort ();

      insns = get_insns ();
      end_sequence ();
      emit_insn_before (insns, insn);
      return true;
    }

  else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
    {
      rtx sub = XEXP (XEXP (x, 0), 0);

      if (GET_CODE (sub) == MEM)
	sub = adjust_address_nv (sub, GET_MODE (x), 0);
      else if (GET_CODE (sub) == REG
	       && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
	;
      else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
	{
	  int size_x, size_sub;

	  if (!insn)
	    {
	      /* When processing REG_NOTES look at the list of
		 replacements done on the insn to find the register that X
		 was replaced by.  */
	      rtx tem;

	      for (tem = purge_bitfield_addressof_replacements;
		   tem != NULL_RTX;
		   tem = XEXP (XEXP (tem, 1), 1))
		if (rtx_equal_p (x, XEXP (tem, 0)))
		  {
		    *loc = XEXP (XEXP (tem, 1), 0);
		    return true;
		  }

	      /* See comment for purge_addressof_replacements.  */
	      for (tem = purge_addressof_replacements;
		   tem != NULL_RTX;
		   tem = XEXP (XEXP (tem, 1), 1))
		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
		  {
		    rtx z = XEXP (XEXP (tem, 1), 0);

		    if (GET_MODE (x) == GET_MODE (z)
			|| (GET_CODE (XEXP (XEXP (tem, 1), 0)) != REG
			    && GET_CODE (XEXP (XEXP (tem, 1), 0)) != SUBREG))
		      abort ();

		    /* It can happen that the note may speak of things
		       in a wider (or just different) mode than the
		       code did.  This is especially true of
		       REG_RETVAL.  */

		    if (GET_CODE (z) == SUBREG && SUBREG_BYTE (z) == 0)
		      z = SUBREG_REG (z);

		    if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
			&& (GET_MODE_SIZE (GET_MODE (x))
			    > GET_MODE_SIZE (GET_MODE (z))))
		      {
			/* This can occur as a result in invalid
			   pointer casts, e.g. float f; ...
			   *(long long int *)&f.
			   ??? We could emit a warning here, but
			   without a line number that wouldn't be
			   very helpful.  */
			z = gen_rtx_SUBREG (GET_MODE (x), z, 0);
		      }
		    else
		      z = gen_lowpart (GET_MODE (x), z);

		    *loc = z;
		    return true;
		  }

	      /* Sometimes we may not be able to find the replacement.  For
		 example when the original insn was a MEM in a wider mode,
		 and the note is part of a sign extension of a narrowed
		 version of that MEM.  Gcc testcase compile/990829-1.c can
		 generate an example of this situation.  Rather than complain
		 we return false, which will prompt our caller to remove the
		 offending note.  */
	      return false;
	    }

	  size_x = GET_MODE_BITSIZE (GET_MODE (x));
	  size_sub = GET_MODE_BITSIZE (GET_MODE (sub));

	  /* Do not frob unchanging MEMs.  If a later reference forces the
	     pseudo to the stack, we can wind up with multiple writes to
	     an unchanging memory, which is invalid.  */
	  if (RTX_UNCHANGING_P (x) && size_x != size_sub)
	    ;

	  /* Don't even consider working with paradoxical subregs,
	     or the moral equivalent seen here.  */
	  else if (size_x <= size_sub
	           && int_mode_for_mode (GET_MODE (sub)) != BLKmode)
	    {
	      /* Do a bitfield insertion to mirror what would happen
		 in memory.  */

	      rtx val, seq;

	      if (store)
		{
		  rtx p = PREV_INSN (insn);

		  start_sequence ();
		  val = gen_reg_rtx (GET_MODE (x));
		  if (! validate_change (insn, loc, val, 0))
		    {
		      /* Discard the current sequence and put the
			 ADDRESSOF on stack.  */
		      end_sequence ();
		      goto give_up;
		    }
		  seq = get_insns ();
		  end_sequence ();
		  emit_insn_before (seq, insn);
		  compute_insns_for_mem (p ? NEXT_INSN (p) : get_insns (),
					 insn, ht);

		  start_sequence ();
		  store_bit_field (sub, size_x, 0, GET_MODE (x),
				   val, GET_MODE_SIZE (GET_MODE (sub)));

		  /* Make sure to unshare any shared rtl that store_bit_field
		     might have created.  */
		  unshare_all_rtl_again (get_insns ());

		  seq = get_insns ();
		  end_sequence ();
		  p = emit_insn_after (seq, insn);
		  if (NEXT_INSN (insn))
		    compute_insns_for_mem (NEXT_INSN (insn),
					   p ? NEXT_INSN (p) : NULL_RTX,
					   ht);
		}
	      else
		{
		  rtx p = PREV_INSN (insn);

		  start_sequence ();
		  val = extract_bit_field (sub, size_x, 0, 1, NULL_RTX,
					   GET_MODE (x), GET_MODE (x),
					   GET_MODE_SIZE (GET_MODE (sub)));

		  if (! validate_change (insn, loc, val, 0))
		    {
		      /* Discard the current sequence and put the
			 ADDRESSOF on stack.  */
		      end_sequence ();
		      goto give_up;
		    }

		  seq = get_insns ();
		  end_sequence ();
		  emit_insn_before (seq, insn);
		  compute_insns_for_mem (p ? NEXT_INSN (p) : get_insns (),
					 insn, ht);
		}

	      /* Remember the replacement so that the same one can be done
		 on the REG_NOTES.  */
	      purge_bitfield_addressof_replacements
		= gen_rtx_EXPR_LIST (VOIDmode, x,
				     gen_rtx_EXPR_LIST
				     (VOIDmode, val,
				      purge_bitfield_addressof_replacements));

	      /* We replaced with a reg -- all done.  */
	      return true;
	    }
	}

      else if (validate_change (insn, loc, sub, 0))
	{
	  /* Remember the replacement so that the same one can be done
	     on the REG_NOTES.  */
	  if (GET_CODE (sub) == REG || GET_CODE (sub) == SUBREG)
	    {
	      rtx tem;

	      for (tem = purge_addressof_replacements;
		   tem != NULL_RTX;
		   tem = XEXP (XEXP (tem, 1), 1))
		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
		  {
		    XEXP (XEXP (tem, 1), 0) = sub;
		    return true;
		  }
	      purge_addressof_replacements
		= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
			   gen_rtx_EXPR_LIST (VOIDmode, sub,
					      purge_addressof_replacements));
	      return true;
	    }
	  goto restart;
	}
    }

 give_up:
  /* Scan all subexpressions.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    {
      if (*fmt == 'e')
	result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
      else if (*fmt == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
    }

  return result;
}

/* Return a hash value for K, a REG.  */

static hashval_t
insns_for_mem_hash (k)
     const void * k;
{
  /* Use the address of the key for the hash value.  */
  struct insns_for_mem_entry *m = (struct insns_for_mem_entry *) k;
  return htab_hash_pointer (m->key);
}

/* Return nonzero if K1 and K2 (two REGs) are the same.  */

static int
insns_for_mem_comp (k1, k2)
     const void * k1;
     const void * k2;
{
  struct insns_for_mem_entry *m1 = (struct insns_for_mem_entry *) k1;
  struct insns_for_mem_entry *m2 = (struct insns_for_mem_entry *) k2;
  return m1->key == m2->key;
}

struct insns_for_mem_walk_info
{
  /* The hash table that we are using to record which INSNs use which
     MEMs.  */
  htab_t ht;

  /* The INSN we are currently processing.  */
  rtx insn;

  /* Zero if we are walking to find ADDRESSOFs, one if we are walking
     to find the insns that use the REGs in the ADDRESSOFs.  */
  int pass;
};

/* Called from compute_insns_for_mem via for_each_rtx.  If R is a REG
   that might be used in an ADDRESSOF expression, record this INSN in
   the hash table given by DATA (which is really a pointer to an
   insns_for_mem_walk_info structure).  */

static int
insns_for_mem_walk (r, data)
     rtx *r;
     void *data;
{
  struct insns_for_mem_walk_info *ifmwi
    = (struct insns_for_mem_walk_info *) data;
  struct insns_for_mem_entry tmp;
  tmp.insns = NULL_RTX;

  if (ifmwi->pass == 0 && *r && GET_CODE (*r) == ADDRESSOF
      && GET_CODE (XEXP (*r, 0)) == REG)
    {
      PTR *e;
      tmp.key = XEXP (*r, 0);
      e = htab_find_slot (ifmwi->ht, &tmp, INSERT);
      if (*e == NULL)
	{
	  *e = ggc_alloc (sizeof (tmp));
	  memcpy (*e, &tmp, sizeof (tmp));
	}
    }
  else if (ifmwi->pass == 1 && *r && GET_CODE (*r) == REG)
    {
      struct insns_for_mem_entry *ifme;
      tmp.key = *r;
      ifme = (struct insns_for_mem_entry *) htab_find (ifmwi->ht, &tmp);

      /* If we have not already recorded this INSN, do so now.  Since
	 we process the INSNs in order, we know that if we have
	 recorded it it must be at the front of the list.  */
      if (ifme && (!ifme->insns || XEXP (ifme->insns, 0) != ifmwi->insn))
	ifme->insns = gen_rtx_EXPR_LIST (VOIDmode, ifmwi->insn,
					 ifme->insns);
    }

  return 0;
}

/* Walk the INSNS, until we reach LAST_INSN, recording which INSNs use
   which REGs in HT.  */

static void
compute_insns_for_mem (insns, last_insn, ht)
     rtx insns;
     rtx last_insn;
     htab_t ht;
{
  rtx insn;
  struct insns_for_mem_walk_info ifmwi;
  ifmwi.ht = ht;

  for (ifmwi.pass = 0; ifmwi.pass < 2; ++ifmwi.pass)
    for (insn = insns; insn != last_insn; insn = NEXT_INSN (insn))
      if (INSN_P (insn))
	{
	  ifmwi.insn = insn;
	  for_each_rtx (&insn, insns_for_mem_walk, &ifmwi);
	}
}

/* Helper function for purge_addressof called through for_each_rtx.
   Returns true iff the rtl is an ADDRESSOF.  */

static int
is_addressof (rtl, data)
     rtx *rtl;
     void *data ATTRIBUTE_UNUSED;
{
  return GET_CODE (*rtl) == ADDRESSOF;
}

/* Eliminate all occurrences of ADDRESSOF from INSNS.  Elide any remaining
   (MEM (ADDRESSOF)) patterns, and force any needed registers into the
   stack.  */

void
purge_addressof (insns)
     rtx insns;
{
  rtx insn;
  htab_t ht;

  /* When we actually purge ADDRESSOFs, we turn REGs into MEMs.  That
     requires a fixup pass over the instruction stream to correct
     INSNs that depended on the REG being a REG, and not a MEM.  But,
     these fixup passes are slow.  Furthermore, most MEMs are not
     mentioned in very many instructions.  So, we speed up the process
     by pre-calculating which REGs occur in which INSNs; that allows
     us to perform the fixup passes much more quickly.  */
  ht = htab_create_ggc (1000, insns_for_mem_hash, insns_for_mem_comp, NULL);
  compute_insns_for_mem (insns, NULL_RTX, ht);

  for (insn = insns; insn; insn = NEXT_INSN (insn))
    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
	|| GET_CODE (insn) == CALL_INSN)
      {
	if (! purge_addressof_1 (&PATTERN (insn), insn,
				 asm_noperands (PATTERN (insn)) > 0, 0, ht))
	  /* If we could not replace the ADDRESSOFs in the insn,
	     something is wrong.  */
	  abort ();

	if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, ht))
	  {
	    /* If we could not replace the ADDRESSOFs in the insn's notes,
	       we can just remove the offending notes instead.  */
	    rtx note;

	    for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	      {
		/* If we find a REG_RETVAL note then the insn is a libcall.
		   Such insns must have REG_EQUAL notes as well, in order
		   for later passes of the compiler to work.  So it is not
		   safe to delete the notes here, and instead we abort.  */
		if (REG_NOTE_KIND (note) == REG_RETVAL)
		  abort ();
		if (for_each_rtx (&note, is_addressof, NULL))
		  remove_note (insn, note);
	      }
	  }
      }

  /* Clean up.  */
  purge_bitfield_addressof_replacements = 0;
  purge_addressof_replacements = 0;

  /* REGs are shared.  purge_addressof will destructively replace a REG
     with a MEM, which creates shared MEMs.

     Unfortunately, the children of put_reg_into_stack assume that MEMs
     referring to the same stack slot are shared (fixup_var_refs and
     the associated hash table code).

     So, we have to do another unsharing pass after we have flushed any
     REGs that had their address taken into the stack.

     It may be worth tracking whether or not we converted any REGs into
     MEMs to avoid this overhead when it is not needed.  */
  unshare_all_rtl_again (get_insns ());
}

/* Convert a SET of a hard subreg to a set of the appropriate hard
   register.  A subroutine of purge_hard_subreg_sets.  */

static void
purge_single_hard_subreg_set (pattern)
     rtx pattern;
{
  rtx reg = SET_DEST (pattern);
  enum machine_mode mode = GET_MODE (SET_DEST (pattern));
  int offset = 0;

  if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG
      && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
    {
      offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
				    GET_MODE (SUBREG_REG (reg)),
				    SUBREG_BYTE (reg),
				    GET_MODE (reg));
      reg = SUBREG_REG (reg);
    }


  if (GET_CODE (reg) == REG && REGNO (reg) < FIRST_PSEUDO_REGISTER)
    {
      reg = gen_rtx_REG (mode, REGNO (reg) + offset);
      SET_DEST (pattern) = reg;
    }
}

/* Eliminate all occurrences of SETs of hard subregs from INSNS.  The
   only such SETs that we expect to see are those left in because
   integrate can't handle sets of parts of a return value register.

   We don't use alter_subreg because we only want to eliminate subregs
   of hard registers.  */

void
purge_hard_subreg_sets (insn)
     rtx insn;
{
  for (; insn; insn = NEXT_INSN (insn))
    {
      if (INSN_P (insn))
	{
	  rtx pattern = PATTERN (insn);
	  switch (GET_CODE (pattern))
	    {
	    case SET:
	      if (GET_CODE (SET_DEST (pattern)) == SUBREG)
		purge_single_hard_subreg_set (pattern);
	      break;
	    case PARALLEL:
	      {
		int j;
		for (j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
		  {
		    rtx inner_pattern = XVECEXP (pattern, 0, j);
		    if (GET_CODE (inner_pattern) == SET
			&& GET_CODE (SET_DEST (inner_pattern)) == SUBREG)
		      purge_single_hard_subreg_set (inner_pattern);
		  }
	      }
	      break;
	    default:
	      break;
	    }
	}
    }
}

/* Pass through the INSNS of function FNDECL and convert virtual register
   references to hard register references.  */

void
instantiate_virtual_regs (fndecl, insns)
     tree fndecl;
     rtx insns;
{
  rtx insn;
  unsigned int i;

  /* Compute the offsets to use for this function.  */
  in_arg_offset = FIRST_PARM_OFFSET (fndecl);
  var_offset = STARTING_FRAME_OFFSET;
  dynamic_offset = STACK_DYNAMIC_OFFSET (fndecl);
  out_arg_offset = STACK_POINTER_OFFSET;
  cfa_offset = ARG_POINTER_CFA_OFFSET (fndecl);

  /* Scan all variables and parameters of this function.  For each that is
     in memory, instantiate all virtual registers if the result is a valid
     address.  If not, we do it later.  That will handle most uses of virtual
     regs on many machines.  */
  instantiate_decls (fndecl, 1);

  /* Initialize recognition, indicating that volatile is OK.  */
  init_recog ();

  /* Scan through all the insns, instantiating every virtual register still
     present.  */
  for (insn = insns; insn; insn = NEXT_INSN (insn))
    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
	|| GET_CODE (insn) == CALL_INSN)
      {
	instantiate_virtual_regs_1 (&PATTERN (insn), insn, 1);
	if (INSN_DELETED_P (insn))
	  continue;
	instantiate_virtual_regs_1 (&REG_NOTES (insn), NULL_RTX, 0);
	/* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE.  */
	if (GET_CODE (insn) == CALL_INSN)
	  instantiate_virtual_regs_1 (&CALL_INSN_FUNCTION_USAGE (insn),
				      NULL_RTX, 0);

	/* Past this point all ASM statements should match.  Verify that
	   to avoid failures later in the compilation process.  */
        if (asm_noperands (PATTERN (insn)) >= 0
	    && ! check_asm_operands (PATTERN (insn)))
          instantiate_virtual_regs_lossage (insn);
      }

  /* Instantiate the stack slots for the parm registers, for later use in
     addressof elimination.  */
  for (i = 0; i < max_parm_reg; ++i)
    if (parm_reg_stack_loc[i])
      instantiate_virtual_regs_1 (&parm_reg_stack_loc[i], NULL_RTX, 0);

  /* Now instantiate the remaining register equivalences for debugging info.
     These will not be valid addresses.  */
  instantiate_decls (fndecl, 0);

  /* Indicate that, from now on, assign_stack_local should use
     frame_pointer_rtx.  */
  virtuals_instantiated = 1;
}

/* Scan all decls in FNDECL (both variables and parameters) and instantiate
   all virtual registers in their DECL_RTL's.

   If VALID_ONLY, do this only if the resulting address is still valid.
   Otherwise, always do it.  */

static void
instantiate_decls (fndecl, valid_only)
     tree fndecl;
     int valid_only;
{
  tree decl;

  /* Process all parameters of the function.  */
  for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
    {
      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
      HOST_WIDE_INT size_rtl;

      instantiate_decl (DECL_RTL (decl), size, valid_only);

      /* If the parameter was promoted, then the incoming RTL mode may be
	 larger than the declared type size.  We must use the larger of
	 the two sizes.  */
      size_rtl = GET_MODE_SIZE (GET_MODE (DECL_INCOMING_RTL (decl)));
      size = MAX (size_rtl, size);
      instantiate_decl (DECL_INCOMING_RTL (decl), size, valid_only);
    }

  /* Now process all variables defined in the function or its subblocks.  */
  instantiate_decls_1 (DECL_INITIAL (fndecl), valid_only);
}

/* Subroutine of instantiate_decls: Process all decls in the given
   BLOCK node and all its subblocks.  */

static void
instantiate_decls_1 (let, valid_only)
     tree let;
     int valid_only;
{
  tree t;

  for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
    if (DECL_RTL_SET_P (t))
      instantiate_decl (DECL_RTL (t),
			int_size_in_bytes (TREE_TYPE (t)),
			valid_only);

  /* Process all subblocks.  */
  for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
    instantiate_decls_1 (t, valid_only);
}

/* Subroutine of the preceding procedures: Given RTL representing a
   decl and the size of the object, do any instantiation required.

   If VALID_ONLY is nonzero, it means that the RTL should only be
   changed if the new address is valid.  */

static void
instantiate_decl (x, size, valid_only)
     rtx x;
     HOST_WIDE_INT size;
     int valid_only;
{
  enum machine_mode mode;
  rtx addr;

  /* If this is not a MEM, no need to do anything.  Similarly if the
     address is a constant or a register that is not a virtual register.  */

  if (x == 0 || GET_CODE (x) != MEM)
    return;

  addr = XEXP (x, 0);
  if (CONSTANT_P (addr)
      || (GET_CODE (addr) == ADDRESSOF && GET_CODE (XEXP (addr, 0)) == REG)
      || (GET_CODE (addr) == REG
	  && (REGNO (addr) < FIRST_VIRTUAL_REGISTER
	      || REGNO (addr) > LAST_VIRTUAL_REGISTER)))
    return;

  /* If we should only do this if the address is valid, copy the address.
     We need to do this so we can undo any changes that might make the
     address invalid.  This copy is unfortunate, but probably can't be
     avoided.  */

  if (valid_only)
    addr = copy_rtx (addr);

  instantiate_virtual_regs_1 (&addr, NULL_RTX, 0);

  if (valid_only && size >= 0)
    {
      unsigned HOST_WIDE_INT decl_size = size;

      /* Now verify that the resulting address is valid for every integer or
	 floating-point mode up to and including SIZE bytes long.  We do this
	 since the object might be accessed in any mode and frame addresses
	 are shared.  */

      for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
	   mode != VOIDmode && GET_MODE_SIZE (mode) <= decl_size;
	   mode = GET_MODE_WIDER_MODE (mode))
	if (! memory_address_p (mode, addr))
	  return;

      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
	   mode != VOIDmode && GET_MODE_SIZE (mode) <= decl_size;
	   mode = GET_MODE_WIDER_MODE (mode))
	if (! memory_address_p (mode, addr))
	  return;
    }

  /* Put back the address now that we have updated it and we either know
     it is valid or we don't care whether it is valid.  */

  XEXP (x, 0) = addr;
}

/* Given a piece of RTX and a pointer to a HOST_WIDE_INT, if the RTX
   is a virtual register, return the equivalent hard register and set the
   offset indirectly through the pointer.  Otherwise, return 0.  */

static rtx
instantiate_new_reg (x, poffset)
     rtx x;
     HOST_WIDE_INT *poffset;
{
  rtx new;
  HOST_WIDE_INT offset;

  if (x == virtual_incoming_args_rtx)
    new = arg_pointer_rtx, offset = in_arg_offset;
  else if (x == virtual_stack_vars_rtx)
    new = frame_pointer_rtx, offset = var_offset;
  else if (x == virtual_stack_dynamic_rtx)
    new = stack_pointer_rtx, offset = dynamic_offset;
  else if (x == virtual_outgoing_args_rtx)
    new = stack_pointer_rtx, offset = out_arg_offset;
  else if (x == virtual_cfa_rtx)
    new = arg_pointer_rtx, offset = cfa_offset;
  else
    return 0;

  *poffset = offset;
  return new;
}


/* Called when instantiate_virtual_regs has failed to update the instruction.
   Usually this means that non-matching instruction has been emit, however for
   asm statements it may be the problem in the constraints.  */
static void
instantiate_virtual_regs_lossage (insn)
     rtx insn;
{
  if (asm_noperands (PATTERN (insn)) >= 0)
    {
      error_for_asm (insn, "impossible constraint in `asm'");
      delete_insn (insn);
    }
  else
    abort ();
}
/* Given a pointer to a piece of rtx and an optional pointer to the
   containing object, instantiate any virtual registers present in it.

   If EXTRA_INSNS, we always do the replacement and generate
   any extra insns before OBJECT.  If it zero, we do nothing if replacement
   is not valid.

   Return 1 if we either had nothing to do or if we were able to do the
   needed replacement.  Return 0 otherwise; we only return zero if
   EXTRA_INSNS is zero.

   We first try some simple transformations to avoid the creation of extra
   pseudos.  */

static int
instantiate_virtual_regs_1 (loc, object, extra_insns)
     rtx *loc;
     rtx object;
     int extra_insns;
{
  rtx x;
  RTX_CODE code;
  rtx new = 0;
  HOST_WIDE_INT offset = 0;
  rtx temp;
  rtx seq;
  int i, j;
  const char *fmt;

  /* Re-start here to avoid recursion in common cases.  */
 restart:

  x = *loc;
  if (x == 0)
    return 1;

  /* We may have detected and deleted invalid asm statements.  */
  if (object && INSN_P (object) && INSN_DELETED_P (object))
    return 1;

  code = GET_CODE (x);

  /* Check for some special cases.  */
  switch (code)
    {
    case CONST_INT:
    case CONST_DOUBLE:
    case CONST_VECTOR:
    case CONST:
    case SYMBOL_REF:
    case CODE_LABEL:
    case PC:
    case CC0:
    case ASM_INPUT:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
    case RETURN:
      return 1;

    case SET:
      /* We are allowed to set the virtual registers.  This means that
	 the actual register should receive the source minus the
	 appropriate offset.  This is used, for example, in the handling
	 of non-local gotos.  */
      if ((new = instantiate_new_reg (SET_DEST (x), &offset)) != 0)
	{
	  rtx src = SET_SRC (x);

	  /* We are setting the register, not using it, so the relevant
	     offset is the negative of the offset to use were we using
	     the register.  */
	  offset = - offset;
	  instantiate_virtual_regs_1 (&src, NULL_RTX, 0);

	  /* The only valid sources here are PLUS or REG.  Just do
	     the simplest possible thing to handle them.  */
	  if (GET_CODE (src) != REG && GET_CODE (src) != PLUS)
	    {
	      instantiate_virtual_regs_lossage (object);
	      return 1;
	    }

	  start_sequence ();
	  if (GET_CODE (src) != REG)
	    temp = force_operand (src, NULL_RTX);
	  else
	    temp = src;
	  temp = force_operand (plus_constant (temp, offset), NULL_RTX);
	  seq = get_insns ();
	  end_sequence ();

	  emit_insn_before (seq, object);
	  SET_DEST (x) = new;

	  if (! validate_change (object, &SET_SRC (x), temp, 0)
	      || ! extra_insns)
	    instantiate_virtual_regs_lossage (object);

	  return 1;
	}

      instantiate_virtual_regs_1 (&SET_DEST (x), object, extra_insns);
      loc = &SET_SRC (x);
      goto restart;

    case PLUS:
      /* Handle special case of virtual register plus constant.  */
      if (CONSTANT_P (XEXP (x, 1)))
	{
	  rtx old, new_offset;

	  /* Check for (plus (plus VIRT foo) (const_int)) first.  */
	  if (GET_CODE (XEXP (x, 0)) == PLUS)
	    {
	      if ((new = instantiate_new_reg (XEXP (XEXP (x, 0), 0), &offset)))
		{
		  instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 1), object,
					      extra_insns);
		  new = gen_rtx_PLUS (Pmode, new, XEXP (XEXP (x, 0), 1));
		}
	      else
		{
		  loc = &XEXP (x, 0);
		  goto restart;
		}
	    }

#ifdef POINTERS_EXTEND_UNSIGNED
	  /* If we have (plus (subreg (virtual-reg)) (const_int)), we know
	     we can commute the PLUS and SUBREG because pointers into the
	     frame are well-behaved.  */
	  else if (GET_CODE (XEXP (x, 0)) == SUBREG && GET_MODE (x) == ptr_mode
		   && GET_CODE (XEXP (x, 1)) == CONST_INT
		   && 0 != (new
			    = instantiate_new_reg (SUBREG_REG (XEXP (x, 0)),
						   &offset))
		   && validate_change (object, loc,
				       plus_constant (gen_lowpart (ptr_mode,
								   new),
						      offset
						      + INTVAL (XEXP (x, 1))),
				       0))
		return 1;
#endif
	  else if ((new = instantiate_new_reg (XEXP (x, 0), &offset)) == 0)
	    {
	      /* We know the second operand is a constant.  Unless the
		 first operand is a REG (which has been already checked),
		 it needs to be checked.  */
	      if (GET_CODE (XEXP (x, 0)) != REG)
		{
		  loc = &XEXP (x, 0);
		  goto restart;
		}
	      return 1;
	    }

	  new_offset = plus_constant (XEXP (x, 1), offset);

	  /* If the new constant is zero, try to replace the sum with just
	     the register.  */
	  if (new_offset == const0_rtx
	      && validate_change (object, loc, new, 0))
	    return 1;

	  /* Next try to replace the register and new offset.
	     There are two changes to validate here and we can't assume that
	     in the case of old offset equals new just changing the register
	     will yield a valid insn.  In the interests of a little efficiency,
	     however, we only call validate change once (we don't queue up the
	     changes and then call apply_change_group).  */

	  old = XEXP (x, 0);
	  if (offset == 0
	      ? ! validate_change (object, &XEXP (x, 0), new, 0)
	      : (XEXP (x, 0) = new,
		 ! validate_change (object, &XEXP (x, 1), new_offset, 0)))
	    {
	      if (! extra_insns)
		{
		  XEXP (x, 0) = old;
		  return 0;
		}

	      /* Otherwise copy the new constant into a register and replace
		 constant with that register.  */
	      temp = gen_reg_rtx (Pmode);
	      XEXP (x, 0) = new;
	      if (validate_change (object, &XEXP (x, 1), temp, 0))
		emit_insn_before (gen_move_insn (temp, new_offset), object);
	      else
		{
		  /* If that didn't work, replace this expression with a
		     register containing the sum.  */

		  XEXP (x, 0) = old;
		  new = gen_rtx_PLUS (Pmode, new, new_offset);

		  start_sequence ();
		  temp = force_operand (new, NULL_RTX);
		  seq = get_insns ();
		  end_sequence ();

		  emit_insn_before (seq, object);
		  if (! validate_change (object, loc, temp, 0)
		      && ! validate_replace_rtx (x, temp, object))
		    {
		      instantiate_virtual_regs_lossage (object);
		      return 1;
		    }
		}
	    }

	  return 1;
	}

      /* Fall through to generic two-operand expression case.  */
    case EXPR_LIST:
    case CALL:
    case COMPARE:
    case MINUS:
    case MULT:
    case DIV:      case UDIV:
    case MOD:      case UMOD:
    case AND:      case IOR:      case XOR:
    case ROTATERT: case ROTATE:
    case ASHIFTRT: case LSHIFTRT: case ASHIFT:
    case NE:       case EQ:
    case GE:       case GT:       case GEU:    case GTU:
    case LE:       case LT:       case LEU:    case LTU:
      if (XEXP (x, 1) && ! CONSTANT_P (XEXP (x, 1)))
	instantiate_virtual_regs_1 (&XEXP (x, 1), object, extra_insns);
      loc = &XEXP (x, 0);
      goto restart;

    case MEM:
      /* Most cases of MEM that convert to valid addresses have already been
	 handled by our scan of decls.  The only special handling we
	 need here is to make a copy of the rtx to ensure it isn't being
	 shared if we have to change it to a pseudo.

	 If the rtx is a simple reference to an address via a virtual register,
	 it can potentially be shared.  In such cases, first try to make it
	 a valid address, which can also be shared.  Otherwise, copy it and
	 proceed normally.

	 First check for common cases that need no processing.  These are
	 usually due to instantiation already being done on a previous instance
	 of a shared rtx.  */

      temp = XEXP (x, 0);
      if (CONSTANT_ADDRESS_P (temp)
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  || temp == arg_pointer_rtx
#endif
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
	  || temp == hard_frame_pointer_rtx
#endif
	  || temp == frame_pointer_rtx)
	return 1;

      if (GET_CODE (temp) == PLUS
	  && CONSTANT_ADDRESS_P (XEXP (temp, 1))
	  && (XEXP (temp, 0) == frame_pointer_rtx
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
	      || XEXP (temp, 0) == hard_frame_pointer_rtx
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	      || XEXP (temp, 0) == arg_pointer_rtx
#endif
	      ))
	return 1;

      if (temp == virtual_stack_vars_rtx
	  || temp == virtual_incoming_args_rtx
	  || (GET_CODE (temp) == PLUS
	      && CONSTANT_ADDRESS_P (XEXP (temp, 1))
	      && (XEXP (temp, 0) == virtual_stack_vars_rtx
		  || XEXP (temp, 0) == virtual_incoming_args_rtx)))
	{
	  /* This MEM may be shared.  If the substitution can be done without
	     the need to generate new pseudos, we want to do it in place
	     so all copies of the shared rtx benefit.  The call below will
	     only make substitutions if the resulting address is still
	     valid.

	     Note that we cannot pass X as the object in the recursive call
	     since the insn being processed may not allow all valid
	     addresses.  However, if we were not passed on object, we can
	     only modify X without copying it if X will have a valid
	     address.

	     ??? Also note that this can still lose if OBJECT is an insn that
	     has less restrictions on an address that some other insn.
	     In that case, we will modify the shared address.  This case
	     doesn't seem very likely, though.  One case where this could
	     happen is in the case of a USE or CLOBBER reference, but we
	     take care of that below.  */

	  if (instantiate_virtual_regs_1 (&XEXP (x, 0),
					  object ? object : x, 0))
	    return 1;

	  /* Otherwise make a copy and process that copy.  We copy the entire
	     RTL expression since it might be a PLUS which could also be
	     shared.  */
	  *loc = x = copy_rtx (x);
	}

      /* Fall through to generic unary operation case.  */
    case PREFETCH:
    case SUBREG:
    case STRICT_LOW_PART:
    case NEG:          case NOT:
    case PRE_DEC:      case PRE_INC:      case POST_DEC:    case POST_INC:
    case SIGN_EXTEND:  case ZERO_EXTEND:
    case TRUNCATE:     case FLOAT_EXTEND: case FLOAT_TRUNCATE:
    case FLOAT:        case FIX:
    case UNSIGNED_FIX: case UNSIGNED_FLOAT:
    case ABS:
    case SQRT:
    case FFS:
      /* These case either have just one operand or we know that we need not
	 check the rest of the operands.  */
      loc = &XEXP (x, 0);
      goto restart;

    case USE:
    case CLOBBER:
      /* If the operand is a MEM, see if the change is a valid MEM.  If not,
	 go ahead and make the invalid one, but do it to a copy.  For a REG,
	 just make the recursive call, since there's no chance of a problem.  */

      if ((GET_CODE (XEXP (x, 0)) == MEM
	   && instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 0), XEXP (x, 0),
					  0))
	  || (GET_CODE (XEXP (x, 0)) == REG
	      && instantiate_virtual_regs_1 (&XEXP (x, 0), object, 0)))
	return 1;

      XEXP (x, 0) = copy_rtx (XEXP (x, 0));
      loc = &XEXP (x, 0);
      goto restart;

    case REG:
      /* Try to replace with a PLUS.  If that doesn't work, compute the sum
	 in front of this insn and substitute the temporary.  */
      if ((new = instantiate_new_reg (x, &offset)) != 0)
	{
	  temp = plus_constant (new, offset);
	  if (!validate_change (object, loc, temp, 0))
	    {
	      if (! extra_insns)
		return 0;

	      start_sequence ();
	      temp = force_operand (temp, NULL_RTX);
	      seq = get_insns ();
	      end_sequence ();

	      emit_insn_before (seq, object);
	      if (! validate_change (object, loc, temp, 0)
		  && ! validate_replace_rtx (x, temp, object))
	        instantiate_virtual_regs_lossage (object);
	    }
	}

      return 1;

    case ADDRESSOF:
      if (GET_CODE (XEXP (x, 0)) == REG)
	return 1;

      else if (GET_CODE (XEXP (x, 0)) == MEM)
	{
	  /* If we have a (addressof (mem ..)), do any instantiation inside
	     since we know we'll be making the inside valid when we finally
	     remove the ADDRESSOF.  */
	  instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 0), NULL_RTX, 0);
	  return 1;
	}
      break;

    default:
      break;
    }

  /* Scan all subexpressions.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    if (*fmt == 'e')
      {
	if (!instantiate_virtual_regs_1 (&XEXP (x, i), object, extra_insns))
	  return 0;
      }
    else if (*fmt == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	if (! instantiate_virtual_regs_1 (&XVECEXP (x, i, j), object,
					  extra_insns))
	  return 0;

  return 1;
}

/* Optimization: assuming this function does not receive nonlocal gotos,
   delete the handlers for such, as well as the insns to establish
   and disestablish them.  */

static void
delete_handlers ()
{
  rtx insn;
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      /* Delete the handler by turning off the flag that would
	 prevent jump_optimize from deleting it.
	 Also permit deletion of the nonlocal labels themselves
	 if nothing local refers to them.  */
      if (GET_CODE (insn) == CODE_LABEL)
	{
	  tree t, last_t;

	  LABEL_PRESERVE_P (insn) = 0;

	  /* Remove it from the nonlocal_label list, to avoid confusing
	     flow.  */
	  for (t = nonlocal_labels, last_t = 0; t;
	       last_t = t, t = TREE_CHAIN (t))
	    if (DECL_RTL (TREE_VALUE (t)) == insn)
	      break;
	  if (t)
	    {
	      if (! last_t)
		nonlocal_labels = TREE_CHAIN (nonlocal_labels);
	      else
		TREE_CHAIN (last_t) = TREE_CHAIN (t);
	    }
	}
      if (GET_CODE (insn) == INSN)
	{
	  int can_delete = 0;
	  rtx t;
	  for (t = nonlocal_goto_handler_slots; t != 0; t = XEXP (t, 1))
	    if (reg_mentioned_p (t, PATTERN (insn)))
	      {
		can_delete = 1;
		break;
	      }
	  if (can_delete
	      || (nonlocal_goto_stack_level != 0
		  && reg_mentioned_p (nonlocal_goto_stack_level,
				      PATTERN (insn))))
	    delete_related_insns (insn);
	}
    }
}

int
max_parm_reg_num ()
{
  return max_parm_reg;
}

/* Return the first insn following those generated by `assign_parms'.  */

rtx
get_first_nonparm_insn ()
{
  if (last_parm_insn)
    return NEXT_INSN (last_parm_insn);
  return get_insns ();
}

/* Return the first NOTE_INSN_BLOCK_BEG note in the function.
   Crash if there is none.  */

rtx
get_first_block_beg ()
{
  rtx searcher;
  rtx insn = get_first_nonparm_insn ();

  for (searcher = insn; searcher; searcher = NEXT_INSN (searcher))
    if (GET_CODE (searcher) == NOTE
	&& NOTE_LINE_NUMBER (searcher) == NOTE_INSN_BLOCK_BEG)
      return searcher;

  abort ();	/* Invalid call to this function.  (See comments above.)  */
  return NULL_RTX;
}

/* Return 1 if EXP is an aggregate type (or a value with aggregate type).
   This means a type for which function calls must pass an address to the
   function or get an address back from the function.
   EXP may be a type node or an expression (whose type is tested).  */

int
aggregate_value_p (exp)
     tree exp;
{
  int i, regno, nregs;
  rtx reg;

  tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);

  if (TREE_CODE (type) == VOID_TYPE)
    return 0;
  if (RETURN_IN_MEMORY (type))
    return 1;
  /* Types that are TREE_ADDRESSABLE must be constructed in memory,
     and thus can't be returned in registers.  */
  if (TREE_ADDRESSABLE (type))
    return 1;
  if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
    return 1;
  /* Make sure we have suitable call-clobbered regs to return
     the value in; if not, we must return it in memory.  */
  reg = hard_function_value (type, 0, 0);

  /* If we have something other than a REG (e.g. a PARALLEL), then assume
     it is OK.  */
  if (GET_CODE (reg) != REG)
    return 0;

  regno = REGNO (reg);
  nregs = HARD_REGNO_NREGS (regno, TYPE_MODE (type));
  for (i = 0; i < nregs; i++)
    if (! call_used_regs[regno + i])
      return 1;
  return 0;
}

/* Assign RTL expressions to the function's parameters.
   This may involve copying them into registers and using
   those registers as the RTL for them.  */

void
assign_parms (fndecl)
     tree fndecl;
{
  tree parm;
  rtx entry_parm = 0;
  rtx stack_parm = 0;
  CUMULATIVE_ARGS args_so_far;
  enum machine_mode promoted_mode, passed_mode;
  enum machine_mode nominal_mode, promoted_nominal_mode;
  int unsignedp;
  /* Total space needed so far for args on the stack,
     given as a constant and a tree-expression.  */
  struct args_size stack_args_size;
  tree fntype = TREE_TYPE (fndecl);
  tree fnargs = DECL_ARGUMENTS (fndecl);
  /* This is used for the arg pointer when referring to stack args.  */
  rtx internal_arg_pointer;
  /* This is a dummy PARM_DECL that we used for the function result if
     the function returns a structure.  */
  tree function_result_decl = 0;
#ifdef SETUP_INCOMING_VARARGS
  int varargs_setup = 0;
#endif
  rtx conversion_insns = 0;
  struct args_size alignment_pad;

  /* Nonzero if function takes extra anonymous args.
     This means the last named arg must be on the stack
     right before the anonymous ones.  */
  int stdarg
    = (TYPE_ARG_TYPES (fntype) != 0
       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
	   != void_type_node));

  current_function_stdarg = stdarg;

  /* If the reg that the virtual arg pointer will be translated into is
     not a fixed reg or is the stack pointer, make a copy of the virtual
     arg pointer, and address parms via the copy.  The frame pointer is
     considered fixed even though it is not marked as such.

     The second time through, simply use ap to avoid generating rtx.  */

  if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
       || ! (fixed_regs[ARG_POINTER_REGNUM]
	     || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
    internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
  else
    internal_arg_pointer = virtual_incoming_args_rtx;
  current_function_internal_arg_pointer = internal_arg_pointer;

  stack_args_size.constant = 0;
  stack_args_size.var = 0;

  /* If struct value address is treated as the first argument, make it so.  */
  if (aggregate_value_p (DECL_RESULT (fndecl))
      && ! current_function_returns_pcc_struct
      && struct_value_incoming_rtx == 0)
    {
      tree type = build_pointer_type (TREE_TYPE (fntype));

      function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);

      DECL_ARG_TYPE (function_result_decl) = type;
      TREE_CHAIN (function_result_decl) = fnargs;
      fnargs = function_result_decl;
    }

  max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
  parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));

#ifdef INIT_CUMULATIVE_INCOMING_ARGS
  INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
#else
  INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0);
#endif

  /* We haven't yet found an argument that we must push and pretend the
     caller did.  */
  current_function_pretend_args_size = 0;

  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
    {
      struct args_size stack_offset;
      struct args_size arg_size;
      int passed_pointer = 0;
      int did_conversion = 0;
      tree passed_type = DECL_ARG_TYPE (parm);
      tree nominal_type = TREE_TYPE (parm);
      int pretend_named;
      int last_named = 0, named_arg;

      /* Set LAST_NAMED if this is last named arg before last
	 anonymous args.  */
      if (stdarg)
	{
	  tree tem;

	  for (tem = TREE_CHAIN (parm); tem; tem = TREE_CHAIN (tem))
	    if (DECL_NAME (tem))
	      break;

	  if (tem == 0)
	    last_named = 1;
	}
      /* Set NAMED_ARG if this arg should be treated as a named arg.  For
	 most machines, if this is a varargs/stdarg function, then we treat
	 the last named arg as if it were anonymous too.  */
      named_arg = STRICT_ARGUMENT_NAMING ? 1 : ! last_named;

      if (TREE_TYPE (parm) == error_mark_node
	  /* This can happen after weird syntax errors
	     or if an enum type is defined among the parms.  */
	  || TREE_CODE (parm) != PARM_DECL
	  || passed_type == NULL)
	{
	  SET_DECL_RTL (parm, gen_rtx_MEM (BLKmode, const0_rtx));
	  DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
	  TREE_USED (parm) = 1;
	  continue;
	}

      /* Find mode of arg as it is passed, and mode of arg
	 as it should be during execution of this function.  */
      passed_mode = TYPE_MODE (passed_type);
      nominal_mode = TYPE_MODE (nominal_type);

      /* If the parm's mode is VOID, its value doesn't matter,
	 and avoid the usual things like emit_move_insn that could crash.  */
      if (nominal_mode == VOIDmode)
	{
	  SET_DECL_RTL (parm, const0_rtx);
	  DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
	  continue;
	}

      /* If the parm is to be passed as a transparent union, use the
	 type of the first field for the tests below.  We have already
	 verified that the modes are the same.  */
      if (DECL_TRANSPARENT_UNION (parm)
	  || (TREE_CODE (passed_type) == UNION_TYPE
	      && TYPE_TRANSPARENT_UNION (passed_type)))
	passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));

      /* See if this arg was passed by invisible reference.  It is if
	 it is an object whose size depends on the contents of the
	 object itself or if the machine requires these objects be passed
	 that way.  */

      if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
	   && contains_placeholder_p (TYPE_SIZE (passed_type)))
	  || TREE_ADDRESSABLE (passed_type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
	  || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
					      passed_type, named_arg)
#endif
	  )
	{
	  passed_type = nominal_type = build_pointer_type (passed_type);
	  passed_pointer = 1;
	  passed_mode = nominal_mode = Pmode;
	}
      /* See if the frontend wants to pass this by invisible reference.  */
      else if (passed_type != nominal_type
	       && POINTER_TYPE_P (passed_type)
	       && TREE_TYPE (passed_type) == nominal_type)
	{
	  nominal_type = passed_type;
	  passed_pointer = 1;
	  passed_mode = nominal_mode = Pmode;
	}

      promoted_mode = passed_mode;

#ifdef PROMOTE_FUNCTION_ARGS
      /* Compute the mode in which the arg is actually extended to.  */
      unsignedp = TREE_UNSIGNED (passed_type);
      promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
#endif

      /* Let machine desc say which reg (if any) the parm arrives in.
	 0 means it arrives on the stack.  */
#ifdef FUNCTION_INCOMING_ARG
      entry_parm = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
					  passed_type, named_arg);
#else
      entry_parm = FUNCTION_ARG (args_so_far, promoted_mode,
				 passed_type, named_arg);
#endif

      if (entry_parm == 0)
	promoted_mode = passed_mode;

#ifdef SETUP_INCOMING_VARARGS
      /* If this is the last named parameter, do any required setup for
	 varargs or stdargs.  We need to know about the case of this being an
	 addressable type, in which case we skip the registers it
	 would have arrived in.

	 For stdargs, LAST_NAMED will be set for two parameters, the one that
	 is actually the last named, and the dummy parameter.  We only
	 want to do this action once.

	 Also, indicate when RTL generation is to be suppressed.  */
      if (last_named && !varargs_setup)
	{
	  SETUP_INCOMING_VARARGS (args_so_far, promoted_mode, passed_type,
				  current_function_pretend_args_size, 0);
	  varargs_setup = 1;
	}
#endif

      /* Determine parm's home in the stack,
	 in case it arrives in the stack or we should pretend it did.

	 Compute the stack position and rtx where the argument arrives
	 and its size.

	 There is one complexity here:  If this was a parameter that would
	 have been passed in registers, but wasn't only because it is
	 __builtin_va_alist, we want locate_and_pad_parm to treat it as if
	 it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
	 In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
	 0 as it was the previous time.  */

      pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
      locate_and_pad_parm (promoted_mode, passed_type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
			   1,
#else
#ifdef FUNCTION_INCOMING_ARG
			   FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
						  passed_type,
						  pretend_named) != 0,
#else
			   FUNCTION_ARG (args_so_far, promoted_mode,
					 passed_type,
					 pretend_named) != 0,
#endif
#endif
			   fndecl, &stack_args_size, &stack_offset, &arg_size,
			   &alignment_pad);

      {
	rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);

	if (offset_rtx == const0_rtx)
	  stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
	else
	  stack_parm = gen_rtx_MEM (promoted_mode,
				    gen_rtx_PLUS (Pmode,
						  internal_arg_pointer,
						  offset_rtx));

	set_mem_attributes (stack_parm, parm, 1);
      }

      /* If this parameter was passed both in registers and in the stack,
	 use the copy on the stack.  */
      if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
	entry_parm = 0;

#ifdef FUNCTION_ARG_PARTIAL_NREGS
      /* If this parm was passed part in regs and part in memory,
	 pretend it arrived entirely in memory
	 by pushing the register-part onto the stack.

	 In the special case of a DImode or DFmode that is split,
	 we could put it together in a pseudoreg directly,
	 but for now that's not worth bothering with.  */

      if (entry_parm)
	{
	  int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
						  passed_type, named_arg);

	  if (nregs > 0)
	    {
#if defined (REG_PARM_STACK_SPACE) && !defined (MAYBE_REG_PARM_STACK_SPACE)
	      /* When REG_PARM_STACK_SPACE is nonzero, stack space for
		 split parameters was allocated by our caller, so we
		 won't be pushing it in the prolog.  */
	      if (REG_PARM_STACK_SPACE (fndecl) == 0)
#endif
	      current_function_pretend_args_size
		= (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
		   / (PARM_BOUNDARY / BITS_PER_UNIT)
		   * (PARM_BOUNDARY / BITS_PER_UNIT));

	      /* Handle calls that pass values in multiple non-contiguous
		 locations.  The Irix 6 ABI has examples of this.  */
	      if (GET_CODE (entry_parm) == PARALLEL)
		emit_group_store (validize_mem (stack_parm), entry_parm,
				  int_size_in_bytes (TREE_TYPE (parm)));

	      else
		move_block_from_reg (REGNO (entry_parm),
				     validize_mem (stack_parm), nregs,
				     int_size_in_bytes (TREE_TYPE (parm)));

	      entry_parm = stack_parm;
	    }
	}
#endif

      /* If we didn't decide this parm came in a register,
	 by default it came on the stack.  */
      if (entry_parm == 0)
	entry_parm = stack_parm;

      /* Record permanently how this parm was passed.  */
      DECL_INCOMING_RTL (parm) = entry_parm;

      /* If there is actually space on the stack for this parm,
	 count it in stack_args_size; otherwise set stack_parm to 0
	 to indicate there is no preallocated stack slot for the parm.  */

      if (entry_parm == stack_parm
	  || (GET_CODE (entry_parm) == PARALLEL
	      && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
#if defined (REG_PARM_STACK_SPACE) && ! defined (MAYBE_REG_PARM_STACK_SPACE)
	  /* On some machines, even if a parm value arrives in a register
	     there is still an (uninitialized) stack slot allocated for it.

	     ??? When MAYBE_REG_PARM_STACK_SPACE is defined, we can't tell
	     whether this parameter already has a stack slot allocated,
	     because an arg block exists only if current_function_args_size
	     is larger than some threshold, and we haven't calculated that
	     yet.  So, for now, we just assume that stack slots never exist
	     in this case.  */
	  || REG_PARM_STACK_SPACE (fndecl) > 0
#endif
	  )
	{
	  stack_args_size.constant += arg_size.constant;
	  if (arg_size.var)
	    ADD_PARM_SIZE (stack_args_size, arg_size.var);
	}
      else
	/* No stack slot was pushed for this parm.  */
	stack_parm = 0;

      /* Update info on where next arg arrives in registers.  */

      FUNCTION_ARG_ADVANCE (args_so_far, promoted_mode,
			    passed_type, named_arg);

      /* If we can't trust the parm stack slot to be aligned enough
	 for its ultimate type, don't use that slot after entry.
	 We'll make another stack slot, if we need one.  */
      {
	unsigned int thisparm_boundary
	  = FUNCTION_ARG_BOUNDARY (promoted_mode, passed_type);

	if (GET_MODE_ALIGNMENT (nominal_mode) > thisparm_boundary)
	  stack_parm = 0;
      }

      /* If parm was passed in memory, and we need to convert it on entry,
	 don't store it back in that same slot.  */
      if (entry_parm != 0
	  && nominal_mode != BLKmode && nominal_mode != passed_mode)
	stack_parm = 0;

      /* When an argument is passed in multiple locations, we can't
	 make use of this information, but we can save some copying if
	 the whole argument is passed in a single register.  */
      if (GET_CODE (entry_parm) == PARALLEL
	  && nominal_mode != BLKmode && passed_mode != BLKmode)
	{
	  int i, len = XVECLEN (entry_parm, 0);

	  for (i = 0; i < len; i++)
	    if (XEXP (XVECEXP (entry_parm, 0, i), 0) != NULL_RTX
		&& GET_CODE (XEXP (XVECEXP (entry_parm, 0, i), 0)) == REG
		&& (GET_MODE (XEXP (XVECEXP (entry_parm, 0, i), 0))
		    == passed_mode)
		&& INTVAL (XEXP (XVECEXP (entry_parm, 0, i), 1)) == 0)
	      {
		entry_parm = XEXP (XVECEXP (entry_parm, 0, i), 0);
		DECL_INCOMING_RTL (parm) = entry_parm;
		break;
	      }
	}

      /* ENTRY_PARM is an RTX for the parameter as it arrives,
	 in the mode in which it arrives.
	 STACK_PARM is an RTX for a stack slot where the parameter can live
	 during the function (in case we want to put it there).
	 STACK_PARM is 0 if no stack slot was pushed for it.

	 Now output code if necessary to convert ENTRY_PARM to
	 the type in which this function declares it,
	 and store that result in an appropriate place,
	 which may be a pseudo reg, may be STACK_PARM,
	 or may be a local stack slot if STACK_PARM is 0.

	 Set DECL_RTL to that place.  */

      if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL)
	{
	  /* If a BLKmode arrives in registers, copy it to a stack slot.
	     Handle calls that pass values in multiple non-contiguous
	     locations.  The Irix 6 ABI has examples of this.  */
	  if (GET_CODE (entry_parm) == REG
	      || GET_CODE (entry_parm) == PARALLEL)
	    {
	      int size_stored
		= CEIL_ROUND (int_size_in_bytes (TREE_TYPE (parm)),
			      UNITS_PER_WORD);

	      /* Note that we will be storing an integral number of words.
		 So we have to be careful to ensure that we allocate an
		 integral number of words.  We do this below in the
		 assign_stack_local if space was not allocated in the argument
		 list.  If it was, this will not work if PARM_BOUNDARY is not
		 a multiple of BITS_PER_WORD.  It isn't clear how to fix this
		 if it becomes a problem.  */

	      if (stack_parm == 0)
		{
		  stack_parm
		    = assign_stack_local (GET_MODE (entry_parm),
					  size_stored, 0);
		  set_mem_attributes (stack_parm, parm, 1);
		}

	      else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
		abort ();

	      /* Handle calls that pass values in multiple non-contiguous
		 locations.  The Irix 6 ABI has examples of this.  */
	      if (GET_CODE (entry_parm) == PARALLEL)
		emit_group_store (validize_mem (stack_parm), entry_parm,
				  int_size_in_bytes (TREE_TYPE (parm)));
	      else
		move_block_from_reg (REGNO (entry_parm),
				     validize_mem (stack_parm),
				     size_stored / UNITS_PER_WORD,
				     int_size_in_bytes (TREE_TYPE (parm)));
	    }
	  SET_DECL_RTL (parm, stack_parm);
	}
      else if (! ((! optimize
		   && ! DECL_REGISTER (parm))
		  || TREE_SIDE_EFFECTS (parm)
		  /* If -ffloat-store specified, don't put explicit
		     float variables into registers.  */
		  || (flag_float_store
		      && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))
	       /* Always assign pseudo to structure return or item passed
		  by invisible reference.  */
	       || passed_pointer || parm == function_result_decl)
	{
	  /* Store the parm in a pseudoregister during the function, but we
	     may need to do it in a wider mode.  */

	  rtx parmreg;
	  unsigned int regno, regnoi = 0, regnor = 0;

	  unsignedp = TREE_UNSIGNED (TREE_TYPE (parm));

	  promoted_nominal_mode
	    = promote_mode (TREE_TYPE (parm), nominal_mode, &unsignedp, 0);

	  parmreg = gen_reg_rtx (promoted_nominal_mode);
	  mark_user_reg (parmreg);

	  /* If this was an item that we received a pointer to, set DECL_RTL
	     appropriately.  */
	  if (passed_pointer)
	    {
	      rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)),
				   parmreg);
	      set_mem_attributes (x, parm, 1);
	      SET_DECL_RTL (parm, x);
	    }
	  else
	    {
	      SET_DECL_RTL (parm, parmreg);
	      maybe_set_unchanging (DECL_RTL (parm), parm);
	    }

	  /* Copy the value into the register.  */
	  if (nominal_mode != passed_mode
	      || promoted_nominal_mode != promoted_mode)
	    {
	      int save_tree_used;
	      /* ENTRY_PARM has been converted to PROMOTED_MODE, its
		 mode, by the caller.  We now have to convert it to
		 NOMINAL_MODE, if different.  However, PARMREG may be in
		 a different mode than NOMINAL_MODE if it is being stored
		 promoted.

		 If ENTRY_PARM is a hard register, it might be in a register
		 not valid for operating in its mode (e.g., an odd-numbered
		 register for a DFmode).  In that case, moves are the only
		 thing valid, so we can't do a convert from there.  This
		 occurs when the calling sequence allow such misaligned
		 usages.

		 In addition, the conversion may involve a call, which could
		 clobber parameters which haven't been copied to pseudo
		 registers yet.  Therefore, we must first copy the parm to
		 a pseudo reg here, and save the conversion until after all
		 parameters have been moved.  */

	      rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));

	      emit_move_insn (tempreg, validize_mem (entry_parm));

	      push_to_sequence (conversion_insns);
	      tempreg = convert_to_mode (nominal_mode, tempreg, unsignedp);

	      if (GET_CODE (tempreg) == SUBREG
		  && GET_MODE (tempreg) == nominal_mode
		  && GET_CODE (SUBREG_REG (tempreg)) == REG
		  && nominal_mode == passed_mode
		  && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (entry_parm)
		  && GET_MODE_SIZE (GET_MODE (tempreg))
		     < GET_MODE_SIZE (GET_MODE (entry_parm)))
		{
		  /* The argument is already sign/zero extended, so note it
		     into the subreg.  */
		  SUBREG_PROMOTED_VAR_P (tempreg) = 1;
		  SUBREG_PROMOTED_UNSIGNED_SET (tempreg, unsignedp);
		}

	      /* TREE_USED gets set erroneously during expand_assignment.  */
	      save_tree_used = TREE_USED (parm);
	      expand_assignment (parm,
				 make_tree (nominal_type, tempreg), 0, 0);
	      TREE_USED (parm) = save_tree_used;
	      conversion_insns = get_insns ();
	      did_conversion = 1;
	      end_sequence ();
	    }
	  else
	    emit_move_insn (parmreg, validize_mem (entry_parm));

	  /* If we were passed a pointer but the actual value
	     can safely live in a register, put it in one.  */
	  if (passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
	      /* If by-reference argument was promoted, demote it.  */
	      && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
		  || ! ((! optimize
			 && ! DECL_REGISTER (parm))
			|| TREE_SIDE_EFFECTS (parm)
			/* If -ffloat-store specified, don't put explicit
			   float variables into registers.  */
			|| (flag_float_store
			    && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))))
	    {
	      /* We can't use nominal_mode, because it will have been set to
		 Pmode above.  We must use the actual mode of the parm.  */
	      parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
	      mark_user_reg (parmreg);
	      if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm)))
		{
		  rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm)));
		  int unsigned_p = TREE_UNSIGNED (TREE_TYPE (parm));
		  push_to_sequence (conversion_insns);
		  emit_move_insn (tempreg, DECL_RTL (parm));
		  SET_DECL_RTL (parm,
				convert_to_mode (GET_MODE (parmreg),
						 tempreg,
						 unsigned_p));
		  emit_move_insn (parmreg, DECL_RTL (parm));
		  conversion_insns = get_insns();
		  did_conversion = 1;
		  end_sequence ();
		}
	      else
		emit_move_insn (parmreg, DECL_RTL (parm));
	      SET_DECL_RTL (parm, parmreg);
	      /* STACK_PARM is the pointer, not the parm, and PARMREG is
		 now the parm.  */
	      stack_parm = 0;
	    }
#ifdef FUNCTION_ARG_CALLEE_COPIES
	  /* If we are passed an arg by reference and it is our responsibility
	     to make a copy, do it now.
	     PASSED_TYPE and PASSED mode now refer to the pointer, not the
	     original argument, so we must recreate them in the call to
	     FUNCTION_ARG_CALLEE_COPIES.  */
	  /* ??? Later add code to handle the case that if the argument isn't
	     modified, don't do the copy.  */

	  else if (passed_pointer
		   && FUNCTION_ARG_CALLEE_COPIES (args_so_far,
						  TYPE_MODE (DECL_ARG_TYPE (parm)),
						  DECL_ARG_TYPE (parm),
						  named_arg)
		   && ! TREE_ADDRESSABLE (DECL_ARG_TYPE (parm)))
	    {
	      rtx copy;
	      tree type = DECL_ARG_TYPE (parm);

	      /* This sequence may involve a library call perhaps clobbering
		 registers that haven't been copied to pseudos yet.  */

	      push_to_sequence (conversion_insns);

	      if (!COMPLETE_TYPE_P (type)
		  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
		/* This is a variable sized object.  */
		copy = gen_rtx_MEM (BLKmode,
				    allocate_dynamic_stack_space
				    (expr_size (parm), NULL_RTX,
				     TYPE_ALIGN (type)));
	      else
		copy = assign_stack_temp (TYPE_MODE (type),
					  int_size_in_bytes (type), 1);
	      set_mem_attributes (copy, parm, 1);

	      store_expr (parm, copy, 0);
	      emit_move_insn (parmreg, XEXP (copy, 0));
	      conversion_insns = get_insns ();
	      did_conversion = 1;
	      end_sequence ();
	    }
#endif /* FUNCTION_ARG_CALLEE_COPIES */

	  /* In any case, record the parm's desired stack location
	     in case we later discover it must live in the stack.

	     If it is a COMPLEX value, store the stack location for both
	     halves.  */

	  if (GET_CODE (parmreg) == CONCAT)
	    regno = MAX (REGNO (XEXP (parmreg, 0)), REGNO (XEXP (parmreg, 1)));
	  else
	    regno = REGNO (parmreg);

	  if (regno >= max_parm_reg)
	    {
	      rtx *new;
	      int old_max_parm_reg = max_parm_reg;

	      /* It's slow to expand this one register at a time,
		 but it's also rare and we need max_parm_reg to be
		 precisely correct.  */
	      max_parm_reg = regno + 1;
	      new = (rtx *) ggc_realloc (parm_reg_stack_loc,
				      max_parm_reg * sizeof (rtx));
	      memset ((char *) (new + old_max_parm_reg), 0,
		     (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
	      parm_reg_stack_loc = new;
	    }

	  if (GET_CODE (parmreg) == CONCAT)
	    {
	      enum machine_mode submode = GET_MODE (XEXP (parmreg, 0));

	      regnor = REGNO (gen_realpart (submode, parmreg));
	      regnoi = REGNO (gen_imagpart (submode, parmreg));

	      if (stack_parm != 0)
		{
		  parm_reg_stack_loc[regnor]
		    = gen_realpart (submode, stack_parm);
		  parm_reg_stack_loc[regnoi]
		    = gen_imagpart (submode, stack_parm);
		}
	      else
		{
		  parm_reg_stack_loc[regnor] = 0;
		  parm_reg_stack_loc[regnoi] = 0;
		}
	    }
	  else
	    parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;

	  /* Mark the register as eliminable if we did no conversion
	     and it was copied from memory at a fixed offset,
	     and the arg pointer was not copied to a pseudo-reg.
	     If the arg pointer is a pseudo reg or the offset formed
	     an invalid address, such memory-equivalences
	     as we make here would screw up life analysis for it.  */
	  if (nominal_mode == passed_mode
	      && ! did_conversion
	      && stack_parm != 0
	      && GET_CODE (stack_parm) == MEM
	      && stack_offset.var == 0
	      && reg_mentioned_p (virtual_incoming_args_rtx,
				  XEXP (stack_parm, 0)))
	    {
	      rtx linsn = get_last_insn ();
	      rtx sinsn, set;

	      /* Mark complex types separately.  */
	      if (GET_CODE (parmreg) == CONCAT)
		/* Scan backwards for the set of the real and
		   imaginary parts.  */
		for (sinsn = linsn; sinsn != 0;
		     sinsn = prev_nonnote_insn (sinsn))
		  {
		    set = single_set (sinsn);
		    if (set != 0
			&& SET_DEST (set) == regno_reg_rtx [regnoi])
		      REG_NOTES (sinsn)
			= gen_rtx_EXPR_LIST (REG_EQUIV,
					     parm_reg_stack_loc[regnoi],
					     REG_NOTES (sinsn));
		    else if (set != 0
			     && SET_DEST (set) == regno_reg_rtx [regnor])
		      REG_NOTES (sinsn)
			= gen_rtx_EXPR_LIST (REG_EQUIV,
					     parm_reg_stack_loc[regnor],
					     REG_NOTES (sinsn));
		  }
	      else if ((set = single_set (linsn)) != 0
		       && SET_DEST (set) == parmreg)
		REG_NOTES (linsn)
		  = gen_rtx_EXPR_LIST (REG_EQUIV,
				       stack_parm, REG_NOTES (linsn));
	    }

	  /* For pointer data type, suggest pointer register.  */
	  if (POINTER_TYPE_P (TREE_TYPE (parm)))
	    mark_reg_pointer (parmreg,
			      TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));

	  /* If something wants our address, try to use ADDRESSOF.  */
	  if (TREE_ADDRESSABLE (parm))
	    {
	      /* If we end up putting something into the stack,
		 fixup_var_refs_insns will need to make a pass over
		 all the instructions.  It looks through the pending
		 sequences -- but it can't see the ones in the
		 CONVERSION_INSNS, if they're not on the sequence
		 stack.  So, we go back to that sequence, just so that
		 the fixups will happen.  */
	      push_to_sequence (conversion_insns);
	      put_var_into_stack (parm, /*rescan=*/true);
	      conversion_insns = get_insns ();
	      end_sequence ();
	    }
	}
      else
	{
	  /* Value must be stored in the stack slot STACK_PARM
	     during function execution.  */

	  if (promoted_mode != nominal_mode)
	    {
	      /* Conversion is required.  */
	      rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));

	      emit_move_insn (tempreg, validize_mem (entry_parm));

	      push_to_sequence (conversion_insns);
	      entry_parm = convert_to_mode (nominal_mode, tempreg,
					    TREE_UNSIGNED (TREE_TYPE (parm)));
	      if (stack_parm)
		/* ??? This may need a big-endian conversion on sparc64.  */
		stack_parm = adjust_address (stack_parm, nominal_mode, 0);

	      conversion_insns = get_insns ();
	      did_conversion = 1;
	      end_sequence ();
	    }

	  if (entry_parm != stack_parm)
	    {
	      if (stack_parm == 0)
		{
		  stack_parm
		    = assign_stack_local (GET_MODE (entry_parm),
					  GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
		  set_mem_attributes (stack_parm, parm, 1);
		}

	      if (promoted_mode != nominal_mode)
		{
		  push_to_sequence (conversion_insns);
		  emit_move_insn (validize_mem (stack_parm),
				  validize_mem (entry_parm));
		  conversion_insns = get_insns ();
		  end_sequence ();
		}
	      else
		emit_move_insn (validize_mem (stack_parm),
				validize_mem (entry_parm));
	    }

	  SET_DECL_RTL (parm, stack_parm);
	}

      /* If this "parameter" was the place where we are receiving the
	 function's incoming structure pointer, set up the result.  */
      if (parm == function_result_decl)
	{
	  tree result = DECL_RESULT (fndecl);
	  rtx addr = DECL_RTL (parm);
	  rtx x;

#ifdef POINTERS_EXTEND_UNSIGNED
	  if (GET_MODE (addr) != Pmode)
	    addr = convert_memory_address (Pmode, addr);
#endif

	  x = gen_rtx_MEM (DECL_MODE (result), addr);
	  set_mem_attributes (x, result, 1);
	  SET_DECL_RTL (result, x);
	}

      if (GET_CODE (DECL_RTL (parm)) == REG)
	REGNO_DECL (REGNO (DECL_RTL (parm))) = parm;
      else if (GET_CODE (DECL_RTL (parm)) == CONCAT)
	{
	  REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 0))) = parm;
	  REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 1))) = parm;
	}

    }

  /* Output all parameter conversion instructions (possibly including calls)
     now that all parameters have been copied out of hard registers.  */
  emit_insn (conversion_insns);

  last_parm_insn = get_last_insn ();

  current_function_args_size = stack_args_size.constant;

  /* Adjust function incoming argument size for alignment and
     minimum length.  */

#ifdef REG_PARM_STACK_SPACE
#ifndef MAYBE_REG_PARM_STACK_SPACE
  current_function_args_size = MAX (current_function_args_size,
				    REG_PARM_STACK_SPACE (fndecl));
#endif
#endif

#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)

  current_function_args_size
    = ((current_function_args_size + STACK_BYTES - 1)
       / STACK_BYTES) * STACK_BYTES;

#ifdef ARGS_GROW_DOWNWARD
  current_function_arg_offset_rtx
    = (stack_args_size.var == 0 ? GEN_INT (-stack_args_size.constant)
       : expand_expr (size_diffop (stack_args_size.var,
				   size_int (-stack_args_size.constant)),
		      NULL_RTX, VOIDmode, 0));
#else
  current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size);
#endif

  /* See how many bytes, if any, of its args a function should try to pop
     on return.  */

  current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl),
						 current_function_args_size);

  /* For stdarg.h function, save info about
     regs and stack space used by the named args.  */

  current_function_args_info = args_so_far;

  /* Set the rtx used for the function return value.  Put this in its
     own variable so any optimizers that need this information don't have
     to include tree.h.  Do this here so it gets done when an inlined
     function gets output.  */

  current_function_return_rtx
    = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
       ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);

  /* If scalar return value was computed in a pseudo-reg, or was a named
     return value that got dumped to the stack, copy that to the hard
     return register.  */
  if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
    {
      tree decl_result = DECL_RESULT (fndecl);
      rtx decl_rtl = DECL_RTL (decl_result);

      if (REG_P (decl_rtl)
	  ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
	  : DECL_REGISTER (decl_result))
	{
	  rtx real_decl_rtl;

#ifdef FUNCTION_OUTGOING_VALUE
	  real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
						   fndecl);
#else
	  real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
					  fndecl);
#endif
	  REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
	  /* The delay slot scheduler assumes that current_function_return_rtx
	     holds the hard register containing the return value, not a
	     temporary pseudo.  */
	  current_function_return_rtx = real_decl_rtl;
	}
    }
}

/* Indicate whether REGNO is an incoming argument to the current function
   that was promoted to a wider mode.  If so, return the RTX for the
   register (to get its mode).  PMODE and PUNSIGNEDP are set to the mode
   that REGNO is promoted from and whether the promotion was signed or
   unsigned.  */

#ifdef PROMOTE_FUNCTION_ARGS

rtx
promoted_input_arg (regno, pmode, punsignedp)
     unsigned int regno;
     enum machine_mode *pmode;
     int *punsignedp;
{
  tree arg;

  for (arg = DECL_ARGUMENTS (current_function_decl); arg;
       arg = TREE_CHAIN (arg))
    if (GET_CODE (DECL_INCOMING_RTL (arg)) == REG
	&& REGNO (DECL_INCOMING_RTL (arg)) == regno
	&& TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
      {
	enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
	int unsignedp = TREE_UNSIGNED (TREE_TYPE (arg));

	mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1);
	if (mode == GET_MODE (DECL_INCOMING_RTL (arg))
	    && mode != DECL_MODE (arg))
	  {
	    *pmode = DECL_MODE (arg);
	    *punsignedp = unsignedp;
	    return DECL_INCOMING_RTL (arg);
	  }
      }

  return 0;
}

#endif

/* Compute the size and offset from the start of the stacked arguments for a
   parm passed in mode PASSED_MODE and with type TYPE.

   INITIAL_OFFSET_PTR points to the current offset into the stacked
   arguments.

   The starting offset and size for this parm are returned in *OFFSET_PTR
   and *ARG_SIZE_PTR, respectively.

   IN_REGS is nonzero if the argument will be passed in registers.  It will
   never be set if REG_PARM_STACK_SPACE is not defined.

   FNDECL is the function in which the argument was defined.

   There are two types of rounding that are done.  The first, controlled by
   FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument
   list to be aligned to the specific boundary (in bits).  This rounding
   affects the initial and starting offsets, but not the argument size.

   The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
   optionally rounds the size of the parm to PARM_BOUNDARY.  The
   initial offset is not affected by this rounding, while the size always
   is and the starting offset may be.  */

/*  offset_ptr will be negative for ARGS_GROW_DOWNWARD case;
    initial_offset_ptr is positive because locate_and_pad_parm's
    callers pass in the total size of args so far as
    initial_offset_ptr. arg_size_ptr is always positive.  */

void
locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
		     initial_offset_ptr, offset_ptr, arg_size_ptr,
		     alignment_pad)
     enum machine_mode passed_mode;
     tree type;
     int in_regs ATTRIBUTE_UNUSED;
     tree fndecl ATTRIBUTE_UNUSED;
     struct args_size *initial_offset_ptr;
     struct args_size *offset_ptr;
     struct args_size *arg_size_ptr;
     struct args_size *alignment_pad;

{
  tree sizetree
    = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
  enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
  int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
#ifdef ARGS_GROW_DOWNWARD
  tree s2 = sizetree;
#endif

#ifdef REG_PARM_STACK_SPACE
  /* If we have found a stack parm before we reach the end of the
     area reserved for registers, skip that area.  */
  if (! in_regs)
    {
      int reg_parm_stack_space = 0;

#ifdef MAYBE_REG_PARM_STACK_SPACE
      reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
#else
      reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
#endif
      if (reg_parm_stack_space > 0)
	{
	  if (initial_offset_ptr->var)
	    {
	      initial_offset_ptr->var
		= size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
			      ssize_int (reg_parm_stack_space));
	      initial_offset_ptr->constant = 0;
	    }
	  else if (initial_offset_ptr->constant < reg_parm_stack_space)
	    initial_offset_ptr->constant = reg_parm_stack_space;
	}
    }
#endif /* REG_PARM_STACK_SPACE */

  arg_size_ptr->var = 0;
  arg_size_ptr->constant = 0;
  alignment_pad->var = 0;
  alignment_pad->constant = 0;

#ifdef ARGS_GROW_DOWNWARD
  if (initial_offset_ptr->var)
    {
      offset_ptr->constant = 0;
      offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0),
				    initial_offset_ptr->var);
    }
  else
    {
      offset_ptr->constant = -initial_offset_ptr->constant;
      offset_ptr->var = 0;
    }

  if (where_pad != none
      && (!host_integerp (sizetree, 1)
	  || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
    s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
  SUB_PARM_SIZE (*offset_ptr, s2);

  if (!in_regs
#ifdef REG_PARM_STACK_SPACE
      || REG_PARM_STACK_SPACE (fndecl) > 0
#endif
     )
    pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);

  if (initial_offset_ptr->var)
    arg_size_ptr->var = size_binop (MINUS_EXPR,
				    size_binop (MINUS_EXPR,
						ssize_int (0),
						initial_offset_ptr->var),
				    offset_ptr->var);

  else
    arg_size_ptr->constant = (-initial_offset_ptr->constant
			      - offset_ptr->constant);

  /* Pad_below needs the pre-rounded size to know how much to pad below.
     We only pad parameters which are not in registers as they have their
     padding done elsewhere.  */
  if (where_pad == downward
      && !in_regs)
    pad_below (offset_ptr, passed_mode, sizetree);

#else /* !ARGS_GROW_DOWNWARD */
  if (!in_regs
#ifdef REG_PARM_STACK_SPACE
      || REG_PARM_STACK_SPACE (fndecl) > 0
#endif
      )
    pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
  *offset_ptr = *initial_offset_ptr;

#ifdef PUSH_ROUNDING
  if (passed_mode != BLKmode)
    sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree)));
#endif

  /* Pad_below needs the pre-rounded size to know how much to pad below
     so this must be done before rounding up.  */
  if (where_pad == downward
    /* However, BLKmode args passed in regs have their padding done elsewhere.
       The stack slot must be able to hold the entire register.  */
      && !(in_regs && passed_mode == BLKmode))
    pad_below (offset_ptr, passed_mode, sizetree);

  if (where_pad != none
      && (!host_integerp (sizetree, 1)
	  || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
    sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);

  ADD_PARM_SIZE (*arg_size_ptr, sizetree);
#endif /* ARGS_GROW_DOWNWARD */
}

/* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
   BOUNDARY is measured in bits, but must be a multiple of a storage unit.  */

static void
pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
     struct args_size *offset_ptr;
     int boundary;
     struct args_size *alignment_pad;
{
  tree save_var = NULL_TREE;
  HOST_WIDE_INT save_constant = 0;

  int boundary_in_bytes = boundary / BITS_PER_UNIT;

  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
    {
      save_var = offset_ptr->var;
      save_constant = offset_ptr->constant;
    }

  alignment_pad->var = NULL_TREE;
  alignment_pad->constant = 0;

  if (boundary > BITS_PER_UNIT)
    {
      if (offset_ptr->var)
	{
	  offset_ptr->var =
#ifdef ARGS_GROW_DOWNWARD
	    round_down
#else
	    round_up
#endif
	      (ARGS_SIZE_TREE (*offset_ptr),
	       boundary / BITS_PER_UNIT);
	  offset_ptr->constant = 0; /*?*/
	  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
	    alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
					     save_var);
	}
      else
	{
	  offset_ptr->constant =
#ifdef ARGS_GROW_DOWNWARD
	    FLOOR_ROUND (offset_ptr->constant, boundary_in_bytes);
#else
	    CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
#endif
	    if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
	      alignment_pad->constant = offset_ptr->constant - save_constant;
	}
    }
}

static void
pad_below (offset_ptr, passed_mode, sizetree)
     struct args_size *offset_ptr;
     enum machine_mode passed_mode;
     tree sizetree;
{
  if (passed_mode != BLKmode)
    {
      if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
	offset_ptr->constant
	  += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
	       / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
	      - GET_MODE_SIZE (passed_mode));
    }
  else
    {
      if (TREE_CODE (sizetree) != INTEGER_CST
	  || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)
	{
	  /* Round the size up to multiple of PARM_BOUNDARY bits.  */
	  tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
	  /* Add it in.  */
	  ADD_PARM_SIZE (*offset_ptr, s2);
	  SUB_PARM_SIZE (*offset_ptr, sizetree);
	}
    }
}

/* Walk the tree of blocks describing the binding levels within a function
   and warn about uninitialized variables.
   This is done after calling flow_analysis and before global_alloc
   clobbers the pseudo-regs to hard regs.  */

void
uninitialized_vars_warning (block)
     tree block;
{
  tree decl, sub;
  for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
    {
      if (warn_uninitialized
	  && TREE_CODE (decl) == VAR_DECL
	  /* These warnings are unreliable for and aggregates
	     because assigning the fields one by one can fail to convince
	     flow.c that the entire aggregate was initialized.
	     Unions are troublesome because members may be shorter.  */
	  && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
	  && DECL_RTL (decl) != 0
	  && GET_CODE (DECL_RTL (decl)) == REG
	  /* Global optimizations can make it difficult to determine if a
	     particular variable has been initialized.  However, a VAR_DECL
	     with a nonzero DECL_INITIAL had an initializer, so do not
	     claim it is potentially uninitialized.

	     We do not care about the actual value in DECL_INITIAL, so we do
	     not worry that it may be a dangling pointer.  */
	  && DECL_INITIAL (decl) == NULL_TREE
	  && regno_uninitialized (REGNO (DECL_RTL (decl))))
	warning_with_decl (decl,
			   "`%s' might be used uninitialized in this function");
      if (extra_warnings
	  && TREE_CODE (decl) == VAR_DECL
	  && DECL_RTL (decl) != 0
	  && GET_CODE (DECL_RTL (decl)) == REG
	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
	warning_with_decl (decl,
			   "variable `%s' might be clobbered by `longjmp' or `vfork'");
    }
  for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
    uninitialized_vars_warning (sub);
}

/* Do the appropriate part of uninitialized_vars_warning
   but for arguments instead of local variables.  */

void
setjmp_args_warning ()
{
  tree decl;
  for (decl = DECL_ARGUMENTS (current_function_decl);
       decl; decl = TREE_CHAIN (decl))
    if (DECL_RTL (decl) != 0
	&& GET_CODE (DECL_RTL (decl)) == REG
	&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
      warning_with_decl (decl,
			 "argument `%s' might be clobbered by `longjmp' or `vfork'");
}

/* If this function call setjmp, put all vars into the stack
   unless they were declared `register'.  */

void
setjmp_protect (block)
     tree block;
{
  tree decl, sub;
  for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
    if ((TREE_CODE (decl) == VAR_DECL
	 || TREE_CODE (decl) == PARM_DECL)
	&& DECL_RTL (decl) != 0
	&& (GET_CODE (DECL_RTL (decl)) == REG
	    || (GET_CODE (DECL_RTL (decl)) == MEM
		&& GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF))
	/* If this variable came from an inline function, it must be
	   that its life doesn't overlap the setjmp.  If there was a
	   setjmp in the function, it would already be in memory.  We
	   must exclude such variable because their DECL_RTL might be
	   set to strange things such as virtual_stack_vars_rtx.  */
	&& ! DECL_FROM_INLINE (decl)
	&& (
#ifdef NON_SAVING_SETJMP
	    /* If longjmp doesn't restore the registers,
	       don't put anything in them.  */
	    NON_SAVING_SETJMP
	    ||
#endif
	    ! DECL_REGISTER (decl)))
      put_var_into_stack (decl, /*rescan=*/true);
  for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
    setjmp_protect (sub);
}

/* Like the previous function, but for args instead of local variables.  */

void
setjmp_protect_args ()
{
  tree decl;
  for (decl = DECL_ARGUMENTS (current_function_decl);
       decl; decl = TREE_CHAIN (decl))
    if ((TREE_CODE (decl) == VAR_DECL
	 || TREE_CODE (decl) == PARM_DECL)
	&& DECL_RTL (decl) != 0
	&& (GET_CODE (DECL_RTL (decl)) == REG
	    || (GET_CODE (DECL_RTL (decl)) == MEM
		&& GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF))
	&& (
	    /* If longjmp doesn't restore the registers,
	       don't put anything in them.  */
#ifdef NON_SAVING_SETJMP
	    NON_SAVING_SETJMP
	    ||
#endif
	    ! DECL_REGISTER (decl)))
      put_var_into_stack (decl, /*rescan=*/true);
}

/* Return the context-pointer register corresponding to DECL,
   or 0 if it does not need one.  */

rtx
lookup_static_chain (decl)
     tree decl;
{
  tree context = decl_function_context (decl);
  tree link;

  if (context == 0
      || (TREE_CODE (decl) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (decl)))
    return 0;

  /* We treat inline_function_decl as an alias for the current function
     because that is the inline function whose vars, types, etc.
     are being merged into the current function.
     See expand_inline_function.  */
  if (context == current_function_decl || context == inline_function_decl)
    return virtual_stack_vars_rtx;

  for (link = context_display; link; link = TREE_CHAIN (link))
    if (TREE_PURPOSE (link) == context)
      return RTL_EXPR_RTL (TREE_VALUE (link));

  abort ();
}

/* Convert a stack slot address ADDR for variable VAR
   (from a containing function)
   into an address valid in this function (using a static chain).  */

rtx
fix_lexical_addr (addr, var)
     rtx addr;
     tree var;
{
  rtx basereg;
  HOST_WIDE_INT displacement;
  tree context = decl_function_context (var);
  struct function *fp;
  rtx base = 0;

  /* If this is the present function, we need not do anything.  */
  if (context == current_function_decl || context == inline_function_decl)
    return addr;

  fp = find_function_data (context);

  if (GET_CODE (addr) == ADDRESSOF && GET_CODE (XEXP (addr, 0)) == MEM)
    addr = XEXP (XEXP (addr, 0), 0);

  /* Decode given address as base reg plus displacement.  */
  if (GET_CODE (addr) == REG)
    basereg = addr, displacement = 0;
  else if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
    basereg = XEXP (addr, 0), displacement = INTVAL (XEXP (addr, 1));
  else
    abort ();

  /* We accept vars reached via the containing function's
     incoming arg pointer and via its stack variables pointer.  */
  if (basereg == fp->internal_arg_pointer)
    {
      /* If reached via arg pointer, get the arg pointer value
	 out of that function's stack frame.

	 There are two cases:  If a separate ap is needed, allocate a
	 slot in the outer function for it and dereference it that way.
	 This is correct even if the real ap is actually a pseudo.
	 Otherwise, just adjust the offset from the frame pointer to
	 compensate.  */

#ifdef NEED_SEPARATE_AP
      rtx addr;

      addr = get_arg_pointer_save_area (fp);
      addr = fix_lexical_addr (XEXP (addr, 0), var);
      addr = memory_address (Pmode, addr);

      base = gen_rtx_MEM (Pmode, addr);
      set_mem_alias_set (base, get_frame_alias_set ());
      base = copy_to_reg (base);
#else
      displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
      base = lookup_static_chain (var);
#endif
    }

  else if (basereg == virtual_stack_vars_rtx)
    {
      /* This is the same code as lookup_static_chain, duplicated here to
	 avoid an extra call to decl_function_context.  */
      tree link;

      for (link = context_display; link; link = TREE_CHAIN (link))
	if (TREE_PURPOSE (link) == context)
	  {
	    base = RTL_EXPR_RTL (TREE_VALUE (link));
	    break;
	  }
    }

  if (base == 0)
    abort ();

  /* Use same offset, relative to appropriate static chain or argument
     pointer.  */
  return plus_constant (base, displacement);
}

/* Return the address of the trampoline for entering nested fn FUNCTION.
   If necessary, allocate a trampoline (in the stack frame)
   and emit rtl to initialize its contents (at entry to this function).  */

rtx
trampoline_address (function)
     tree function;
{
  tree link;
  tree rtlexp;
  rtx tramp;
  struct function *fp;
  tree fn_context;

  /* Find an existing trampoline and return it.  */
  for (link = trampoline_list; link; link = TREE_CHAIN (link))
    if (TREE_PURPOSE (link) == function)
      return
	adjust_trampoline_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0));

  for (fp = outer_function_chain; fp; fp = fp->outer)
    for (link = fp->x_trampoline_list; link; link = TREE_CHAIN (link))
      if (TREE_PURPOSE (link) == function)
	{
	  tramp = fix_lexical_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0),
				    function);
	  return adjust_trampoline_addr (tramp);
	}

  /* None exists; we must make one.  */

  /* Find the `struct function' for the function containing FUNCTION.  */
  fp = 0;
  fn_context = decl_function_context (function);
  if (fn_context != current_function_decl
      && fn_context != inline_function_decl)
    fp = find_function_data (fn_context);

  /* Allocate run-time space for this trampoline
     (usually in the defining function's stack frame).  */
#ifdef ALLOCATE_TRAMPOLINE
  tramp = ALLOCATE_TRAMPOLINE (fp);
#else
  /* If rounding needed, allocate extra space
     to ensure we have TRAMPOLINE_SIZE bytes left after rounding up.  */
#define TRAMPOLINE_REAL_SIZE \
  (TRAMPOLINE_SIZE + (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT) - 1)
  tramp = assign_stack_local_1 (BLKmode, TRAMPOLINE_REAL_SIZE, 0,
				fp ? fp : cfun);
#endif

  /* Record the trampoline for reuse and note it for later initialization
     by expand_function_end.  */
  if (fp != 0)
    {
      rtlexp = make_node (RTL_EXPR);
      RTL_EXPR_RTL (rtlexp) = tramp;
      fp->x_trampoline_list = tree_cons (function, rtlexp,
					 fp->x_trampoline_list);
    }
  else
    {
      /* Make the RTL_EXPR node temporary, not momentary, so that the
	 trampoline_list doesn't become garbage.  */
      rtlexp = make_node (RTL_EXPR);

      RTL_EXPR_RTL (rtlexp) = tramp;
      trampoline_list = tree_cons (function, rtlexp, trampoline_list);
    }

  tramp = fix_lexical_addr (XEXP (tramp, 0), function);
  return adjust_trampoline_addr (tramp);
}

/* Given a trampoline address,
   round it to multiple of TRAMPOLINE_ALIGNMENT.  */

static rtx
round_trampoline_addr (tramp)
     rtx tramp;
{
  /* Round address up to desired boundary.  */
  rtx temp = gen_reg_rtx (Pmode);
  rtx addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
  rtx mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);

  temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
			       temp, 0, OPTAB_LIB_WIDEN);
  tramp = expand_simple_binop (Pmode, AND, temp, mask,
			       temp, 0, OPTAB_LIB_WIDEN);

  return tramp;
}

/* Given a trampoline address, round it then apply any
   platform-specific adjustments so that the result can be used for a
   function call .  */

static rtx
adjust_trampoline_addr (tramp)
     rtx tramp;
{
  tramp = round_trampoline_addr (tramp);
#ifdef TRAMPOLINE_ADJUST_ADDRESS
  TRAMPOLINE_ADJUST_ADDRESS (tramp);
#endif
  return tramp;
}

/* Put all this function's BLOCK nodes including those that are chained
   onto the first block into a vector, and return it.
   Also store in each NOTE for the beginning or end of a block
   the index of that block in the vector.
   The arguments are BLOCK, the chain of top-level blocks of the function,
   and INSNS, the insn chain of the function.  */

void
identify_blocks ()
{
  int n_blocks;
  tree *block_vector, *last_block_vector;
  tree *block_stack;
  tree block = DECL_INITIAL (current_function_decl);

  if (block == 0)
    return;

  /* Fill the BLOCK_VECTOR with all of the BLOCKs in this function, in
     depth-first order.  */
  block_vector = get_block_vector (block, &n_blocks);
  block_stack = (tree *) xmalloc (n_blocks * sizeof (tree));

  last_block_vector = identify_blocks_1 (get_insns (),
					 block_vector + 1,
					 block_vector + n_blocks,
					 block_stack);

  /* If we didn't use all of the subblocks, we've misplaced block notes.  */
  /* ??? This appears to happen all the time.  Latent bugs elsewhere?  */
  if (0 && last_block_vector != block_vector + n_blocks)
    abort ();

  free (block_vector);
  free (block_stack);
}

/* Subroutine of identify_blocks.  Do the block substitution on the
   insn chain beginning with INSNS.  Recurse for CALL_PLACEHOLDER chains.

   BLOCK_STACK is pushed and popped for each BLOCK_BEGIN/BLOCK_END pair.
   BLOCK_VECTOR is incremented for each block seen.  */

static tree *
identify_blocks_1 (insns, block_vector, end_block_vector, orig_block_stack)
     rtx insns;
     tree *block_vector;
     tree *end_block_vector;
     tree *orig_block_stack;
{
  rtx insn;
  tree *block_stack = orig_block_stack;

  for (insn = insns; insn; insn = NEXT_INSN (insn))
    {
      if (GET_CODE (insn) == NOTE)
	{
	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
	    {
	      tree b;

	      /* If there are more block notes than BLOCKs, something
		 is badly wrong.  */
	      if (block_vector == end_block_vector)
		abort ();

	      b = *block_vector++;
	      NOTE_BLOCK (insn) = b;
	      *block_stack++ = b;
	    }
	  else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
	    {
	      /* If there are more NOTE_INSN_BLOCK_ENDs than
		 NOTE_INSN_BLOCK_BEGs, something is badly wrong.  */
	      if (block_stack == orig_block_stack)
		abort ();

	      NOTE_BLOCK (insn) = *--block_stack;
	    }
	}
      else if (GET_CODE (insn) == CALL_INSN
	       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
	{
	  rtx cp = PATTERN (insn);

	  block_vector = identify_blocks_1 (XEXP (cp, 0), block_vector,
					    end_block_vector, block_stack);
	  if (XEXP (cp, 1))
	    block_vector = identify_blocks_1 (XEXP (cp, 1), block_vector,
					      end_block_vector, block_stack);
	  if (XEXP (cp, 2))
	    block_vector = identify_blocks_1 (XEXP (cp, 2), block_vector,
					      end_block_vector, block_stack);
	}
    }

  /* If there are more NOTE_INSN_BLOCK_BEGINs than NOTE_INSN_BLOCK_ENDs,
     something is badly wrong.  */
  if (block_stack != orig_block_stack)
    abort ();

  return block_vector;
}

/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
   and create duplicate blocks.  */
/* ??? Need an option to either create block fragments or to create
   abstract origin duplicates of a source block.  It really depends
   on what optimization has been performed.  */

void
reorder_blocks ()
{
  tree block = DECL_INITIAL (current_function_decl);
  varray_type block_stack;

  if (block == NULL_TREE)
    return;

  VARRAY_TREE_INIT (block_stack, 10, "block_stack");

  /* Reset the TREE_ASM_WRITTEN bit for all blocks.  */
  reorder_blocks_0 (block);

  /* Prune the old trees away, so that they don't get in the way.  */
  BLOCK_SUBBLOCKS (block) = NULL_TREE;
  BLOCK_CHAIN (block) = NULL_TREE;

  /* Recreate the block tree from the note nesting.  */
  reorder_blocks_1 (get_insns (), block, &block_stack);
  BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block));

  /* Remove deleted blocks from the block fragment chains.  */
  reorder_fix_fragments (block);
}

/* Helper function for reorder_blocks.  Reset TREE_ASM_WRITTEN.  */

static void
reorder_blocks_0 (block)
     tree block;
{
  while (block)
    {
      TREE_ASM_WRITTEN (block) = 0;
      reorder_blocks_0 (BLOCK_SUBBLOCKS (block));
      block = BLOCK_CHAIN (block);
    }
}

static void
reorder_blocks_1 (insns, current_block, p_block_stack)
     rtx insns;
     tree current_block;
     varray_type *p_block_stack;
{
  rtx insn;

  for (insn = insns; insn; insn = NEXT_INSN (insn))
    {
      if (GET_CODE (insn) == NOTE)
	{
	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
	    {
	      tree block = NOTE_BLOCK (insn);

	      /* If we have seen this block before, that means it now
		 spans multiple address regions.  Create a new fragment.  */
	      if (TREE_ASM_WRITTEN (block))
		{
		  tree new_block = copy_node (block);
		  tree origin;

		  origin = (BLOCK_FRAGMENT_ORIGIN (block)
			    ? BLOCK_FRAGMENT_ORIGIN (block)
			    : block);
		  BLOCK_FRAGMENT_ORIGIN (new_block) = origin;
		  BLOCK_FRAGMENT_CHAIN (new_block)
		    = BLOCK_FRAGMENT_CHAIN (origin);
		  BLOCK_FRAGMENT_CHAIN (origin) = new_block;

		  NOTE_BLOCK (insn) = new_block;
		  block = new_block;
		}

	      BLOCK_SUBBLOCKS (block) = 0;
	      TREE_ASM_WRITTEN (block) = 1;
	      BLOCK_SUPERCONTEXT (block) = current_block;
	      BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
	      BLOCK_SUBBLOCKS (current_block) = block;
	      current_block = block;
	      VARRAY_PUSH_TREE (*p_block_stack, block);
	    }
	  else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
	    {
	      NOTE_BLOCK (insn) = VARRAY_TOP_TREE (*p_block_stack);
	      VARRAY_POP (*p_block_stack);
	      BLOCK_SUBBLOCKS (current_block)
		= blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
	      current_block = BLOCK_SUPERCONTEXT (current_block);
	    }
	}
      else if (GET_CODE (insn) == CALL_INSN
	       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
	{
	  rtx cp = PATTERN (insn);
	  reorder_blocks_1 (XEXP (cp, 0), current_block, p_block_stack);
	  if (XEXP (cp, 1))
	    reorder_blocks_1 (XEXP (cp, 1), current_block, p_block_stack);
	  if (XEXP (cp, 2))
	    reorder_blocks_1 (XEXP (cp, 2), current_block, p_block_stack);
	}
    }
}

/* Rationalize BLOCK_FRAGMENT_ORIGIN.  If an origin block no longer
   appears in the block tree, select one of the fragments to become
   the new origin block.  */

static void
reorder_fix_fragments (block)
     tree block;
{
  while (block)
    {
      tree dup_origin = BLOCK_FRAGMENT_ORIGIN (block);
      tree new_origin = NULL_TREE;

      if (dup_origin)
	{
	  if (! TREE_ASM_WRITTEN (dup_origin))
	    {
	      new_origin = BLOCK_FRAGMENT_CHAIN (dup_origin);

	      /* Find the first of the remaining fragments.  There must
		 be at least one -- the current block.  */
	      while (! TREE_ASM_WRITTEN (new_origin))
		new_origin = BLOCK_FRAGMENT_CHAIN (new_origin);
	      BLOCK_FRAGMENT_ORIGIN (new_origin) = NULL_TREE;
	    }
	}
      else if (! dup_origin)
	new_origin = block;

      /* Re-root the rest of the fragments to the new origin.  In the
	 case that DUP_ORIGIN was null, that means BLOCK was the origin
	 of a chain of fragments and we want to remove those fragments
	 that didn't make it to the output.  */
      if (new_origin)
	{
	  tree *pp = &BLOCK_FRAGMENT_CHAIN (new_origin);
	  tree chain = *pp;

	  while (chain)
	    {
	      if (TREE_ASM_WRITTEN (chain))
		{
		  BLOCK_FRAGMENT_ORIGIN (chain) = new_origin;
		  *pp = chain;
		  pp = &BLOCK_FRAGMENT_CHAIN (chain);
		}
	      chain = BLOCK_FRAGMENT_CHAIN (chain);
	    }
	  *pp = NULL_TREE;
	}

      reorder_fix_fragments (BLOCK_SUBBLOCKS (block));
      block = BLOCK_CHAIN (block);
    }
}

/* Reverse the order of elements in the chain T of blocks,
   and return the new head of the chain (old last element).  */

static tree
blocks_nreverse (t)
     tree t;
{
  tree prev = 0, decl, next;
  for (decl = t; decl; decl = next)
    {
      next = BLOCK_CHAIN (decl);
      BLOCK_CHAIN (decl) = prev;
      prev = decl;
    }
  return prev;
}

/* Count the subblocks of the list starting with BLOCK.  If VECTOR is
   non-NULL, list them all into VECTOR, in a depth-first preorder
   traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
   blocks.  */

static int
all_blocks (block, vector)
     tree block;
     tree *vector;
{
  int n_blocks = 0;

  while (block)
    {
      TREE_ASM_WRITTEN (block) = 0;

      /* Record this block.  */
      if (vector)
	vector[n_blocks] = block;

      ++n_blocks;

      /* Record the subblocks, and their subblocks...  */
      n_blocks += all_blocks (BLOCK_SUBBLOCKS (block),
			      vector ? vector + n_blocks : 0);
      block = BLOCK_CHAIN (block);
    }

  return n_blocks;
}

/* Return a vector containing all the blocks rooted at BLOCK.  The
   number of elements in the vector is stored in N_BLOCKS_P.  The
   vector is dynamically allocated; it is the caller's responsibility
   to call `free' on the pointer returned.  */

static tree *
get_block_vector (block, n_blocks_p)
     tree block;
     int *n_blocks_p;
{
  tree *block_vector;

  *n_blocks_p = all_blocks (block, NULL);
  block_vector = (tree *) xmalloc (*n_blocks_p * sizeof (tree));
  all_blocks (block, block_vector);

  return block_vector;
}

static int next_block_index = 2;

/* Set BLOCK_NUMBER for all the blocks in FN.  */

void
number_blocks (fn)
     tree fn;
{
  int i;
  int n_blocks;
  tree *block_vector;

  /* For SDB and XCOFF debugging output, we start numbering the blocks
     from 1 within each function, rather than keeping a running
     count.  */
#if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG)
    next_block_index = 1;
#endif

  block_vector = get_block_vector (DECL_INITIAL (fn), &n_blocks);

  /* The top-level BLOCK isn't numbered at all.  */
  for (i = 1; i < n_blocks; ++i)
    /* We number the blocks from two.  */
    BLOCK_NUMBER (block_vector[i]) = next_block_index++;

  free (block_vector);

  return;
}

/* If VAR is present in a subblock of BLOCK, return the subblock.  */

tree
debug_find_var_in_block_tree (var, block)
     tree var;
     tree block;
{
  tree t;

  for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
    if (t == var)
      return block;

  for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
    {
      tree ret = debug_find_var_in_block_tree (var, t);
      if (ret)
	return ret;
    }

  return NULL_TREE;
}

/* Allocate a function structure and reset its contents to the defaults.  */

static void
prepare_function_start ()
{
  cfun = (struct function *) ggc_alloc_cleared (sizeof (struct function));

  init_stmt_for_function ();
  init_eh_for_function ();

  cse_not_expected = ! optimize;

  /* Caller save not needed yet.  */
  caller_save_needed = 0;

  /* No stack slots have been made yet.  */
  stack_slot_list = 0;

  current_function_has_nonlocal_label = 0;
  current_function_has_nonlocal_goto = 0;

  /* There is no stack slot for handling nonlocal gotos.  */
  nonlocal_goto_handler_slots = 0;
  nonlocal_goto_stack_level = 0;

  /* No labels have been declared for nonlocal use.  */
  nonlocal_labels = 0;
  nonlocal_goto_handler_labels = 0;

  /* No function calls so far in this function.  */
  function_call_count = 0;

  /* No parm regs have been allocated.
     (This is important for output_inline_function.)  */
  max_parm_reg = LAST_VIRTUAL_REGISTER + 1;

  /* Initialize the RTL mechanism.  */
  init_emit ();

  /* Initialize the queue of pending postincrement and postdecrements,
     and some other info in expr.c.  */
  init_expr ();

  /* We haven't done register allocation yet.  */
  reg_renumber = 0;

  init_varasm_status (cfun);

  /* Clear out data used for inlining.  */
  cfun->inlinable = 0;
  cfun->original_decl_initial = 0;
  cfun->original_arg_vector = 0;

  cfun->stack_alignment_needed = STACK_BOUNDARY;
  cfun->preferred_stack_boundary = STACK_BOUNDARY;

  /* Set if a call to setjmp is seen.  */
  current_function_calls_setjmp = 0;

  /* Set if a call to longjmp is seen.  */
  current_function_calls_longjmp = 0;

  current_function_calls_alloca = 0;
  current_function_contains_functions = 0;
  current_function_is_leaf = 0;
  current_function_nothrow = 0;
  current_function_sp_is_unchanging = 0;
  current_function_uses_only_leaf_regs = 0;
  current_function_has_computed_jump = 0;
  current_function_is_thunk = 0;

  current_function_returns_pcc_struct = 0;
  current_function_returns_struct = 0;
  current_function_epilogue_delay_list = 0;
  current_function_uses_const_pool = 0;
  current_function_uses_pic_offset_table = 0;
  current_function_cannot_inline = 0;

  /* We have not yet needed to make a label to jump to for tail-recursion.  */
  tail_recursion_label = 0;

  /* We haven't had a need to make a save area for ap yet.  */
  arg_pointer_save_area = 0;

  /* No stack slots allocated yet.  */
  frame_offset = 0;

  /* No SAVE_EXPRs in this function yet.  */
  save_expr_regs = 0;

  /* No RTL_EXPRs in this function yet.  */
  rtl_expr_chain = 0;

  /* Set up to allocate temporaries.  */
  init_temp_slots ();

  /* Indicate that we need to distinguish between the return value of the
     present function and the return value of a function being called.  */
  rtx_equal_function_value_matters = 1;

  /* Indicate that we have not instantiated virtual registers yet.  */
  virtuals_instantiated = 0;

  /* Indicate that we want CONCATs now.  */
  generating_concat_p = 1;

  /* Indicate we have no need of a frame pointer yet.  */
  frame_pointer_needed = 0;

  /* By default assume not stdarg.  */
  current_function_stdarg = 0;

  /* We haven't made any trampolines for this function yet.  */
  trampoline_list = 0;

  init_pending_stack_adjust ();
  inhibit_defer_pop = 0;

  current_function_outgoing_args_size = 0;

  current_function_funcdef_no = funcdef_no++;

  cfun->arc_profile = profile_arc_flag || flag_test_coverage;

  cfun->arc_profile = profile_arc_flag || flag_test_coverage;

  cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;

  cfun->max_jumptable_ents = 0;

  (*lang_hooks.function.init) (cfun);
  if (init_machine_status)
    cfun->machine = (*init_machine_status) ();
}

/* Initialize the rtl expansion mechanism so that we can do simple things
   like generate sequences.  This is used to provide a context during global
   initialization of some passes.  */
void
init_dummy_function_start ()
{
  prepare_function_start ();
}

/* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
   and initialize static variables for generating RTL for the statements
   of the function.  */

void
init_function_start (subr, filename, line)
     tree subr;
     const char *filename;
     int line;
{
  prepare_function_start ();

  current_function_name = (*lang_hooks.decl_printable_name) (subr, 2);
  cfun->decl = subr;

  /* Nonzero if this is a nested function that uses a static chain.  */

  current_function_needs_context
    = (decl_function_context (current_function_decl) != 0
       && ! DECL_NO_STATIC_CHAIN (current_function_decl));

  /* Within function body, compute a type's size as soon it is laid out.  */
  immediate_size_expand++;

  /* Prevent ever trying to delete the first instruction of a function.
     Also tell final how to output a linenum before the function prologue.
     Note linenums could be missing, e.g. when compiling a Java .class file.  */
  if (line > 0)
    emit_line_note (filename, line);

  /* Make sure first insn is a note even if we don't want linenums.
     This makes sure the first insn will never be deleted.
     Also, final expects a note to appear there.  */
  emit_note (NULL, NOTE_INSN_DELETED);

  /* Set flags used by final.c.  */
  if (aggregate_value_p (DECL_RESULT (subr)))
    {
#ifdef PCC_STATIC_STRUCT_RETURN
      current_function_returns_pcc_struct = 1;
#endif
      current_function_returns_struct = 1;
    }

  /* Warn if this value is an aggregate type,
     regardless of which calling convention we are using for it.  */
  if (warn_aggregate_return
      && AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
    warning ("function returns an aggregate");

  current_function_returns_pointer
    = POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
}

/* Make sure all values used by the optimization passes have sane
   defaults.  */
void
init_function_for_compilation ()
{
  reg_renumber = 0;

  /* No prologue/epilogue insns yet.  */
  VARRAY_GROW (prologue, 0);
  VARRAY_GROW (epilogue, 0);
  VARRAY_GROW (sibcall_epilogue, 0);
}

/* Expand a call to __main at the beginning of a possible main function.  */

#if defined(INIT_SECTION_ASM_OP) && !defined(INVOKE__main)
#undef HAS_INIT_SECTION
#define HAS_INIT_SECTION
#endif

void
expand_main_function ()
{
#ifdef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
  if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN)
    {
      int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
      rtx tmp, seq;

      start_sequence ();
      /* Forcibly align the stack.  */
#ifdef STACK_GROWS_DOWNWARD
      tmp = expand_simple_binop (Pmode, AND, stack_pointer_rtx, GEN_INT(-align),
				 stack_pointer_rtx, 1, OPTAB_WIDEN);
#else
      tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
				 GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN);
      tmp = expand_simple_binop (Pmode, AND, tmp, GEN_INT (-align),
				 stack_pointer_rtx, 1, OPTAB_WIDEN);
#endif
      if (tmp != stack_pointer_rtx)
	emit_move_insn (stack_pointer_rtx, tmp);

      /* Enlist allocate_dynamic_stack_space to pick up the pieces.  */
      tmp = force_reg (Pmode, const0_rtx);
      allocate_dynamic_stack_space (tmp, NULL_RTX, BIGGEST_ALIGNMENT);
      seq = get_insns ();
      end_sequence ();

      for (tmp = get_last_insn (); tmp; tmp = PREV_INSN (tmp))
	if (NOTE_P (tmp) && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_FUNCTION_BEG)
	  break;
      if (tmp)
	emit_insn_before (seq, tmp);
      else
	emit_insn (seq);
    }
#endif

#ifndef HAS_INIT_SECTION
  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, NAME__MAIN), LCT_NORMAL,
		     VOIDmode, 0);
#endif
}

/* The PENDING_SIZES represent the sizes of variable-sized types.
   Create RTL for the various sizes now (using temporary variables),
   so that we can refer to the sizes from the RTL we are generating
   for the current function.  The PENDING_SIZES are a TREE_LIST.  The
   TREE_VALUE of each node is a SAVE_EXPR.  */

void
expand_pending_sizes (pending_sizes)
     tree pending_sizes;
{
  tree tem;

  /* Evaluate now the sizes of any types declared among the arguments.  */
  for (tem = pending_sizes; tem; tem = TREE_CHAIN (tem))
    {
      expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode, 0);
      /* Flush the queue in case this parameter declaration has
	 side-effects.  */
      emit_queue ();
    }
}

/* Start the RTL for a new function, and set variables used for
   emitting RTL.
   SUBR is the FUNCTION_DECL node.
   PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
   the function's parameters, which must be run at any return statement.  */

void
expand_function_start (subr, parms_have_cleanups)
     tree subr;
     int parms_have_cleanups;
{
  tree tem;
  rtx last_ptr = NULL_RTX;

  /* Make sure volatile mem refs aren't considered
     valid operands of arithmetic insns.  */
  init_recog_no_volatile ();

  current_function_instrument_entry_exit
    = (flag_instrument_function_entry_exit
       && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));

  current_function_profile
    = (profile_flag
       && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));

  current_function_limit_stack
    = (stack_limit_rtx != NULL_RTX && ! DECL_NO_LIMIT_STACK (subr));

  /* If function gets a static chain arg, store it in the stack frame.
     Do this first, so it gets the first stack slot offset.  */
  if (current_function_needs_context)
    {
      last_ptr = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);

      /* Delay copying static chain if it is not a register to avoid
	 conflicts with regs used for parameters.  */
      if (! SMALL_REGISTER_CLASSES
	  || GET_CODE (static_chain_incoming_rtx) == REG)
	emit_move_insn (last_ptr, static_chain_incoming_rtx);
    }

  /* If the parameters of this function need cleaning up, get a label
     for the beginning of the code which executes those cleanups.  This must
     be done before doing anything with return_label.  */
  if (parms_have_cleanups)
    cleanup_label = gen_label_rtx ();
  else
    cleanup_label = 0;

  /* Make the label for return statements to jump to.  Do not special
     case machines with special return instructions -- they will be
     handled later during jump, ifcvt, or epilogue creation.  */
  return_label = gen_label_rtx ();

  /* Initialize rtx used to return the value.  */
  /* Do this before assign_parms so that we copy the struct value address
     before any library calls that assign parms might generate.  */

  /* Decide whether to return the value in memory or in a register.  */
  if (aggregate_value_p (DECL_RESULT (subr)))
    {
      /* Returning something that won't go in a register.  */
      rtx value_address = 0;

#ifdef PCC_STATIC_STRUCT_RETURN
      if (current_function_returns_pcc_struct)
	{
	  int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
	  value_address = assemble_static_space (size);
	}
      else
#endif
	{
	  /* Expect to be passed the address of a place to store the value.
	     If it is passed as an argument, assign_parms will take care of
	     it.  */
	  if (struct_value_incoming_rtx)
	    {
	      value_address = gen_reg_rtx (Pmode);
	      emit_move_insn (value_address, struct_value_incoming_rtx);
	    }
	}
      if (value_address)
	{
	  rtx x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
	  set_mem_attributes (x, DECL_RESULT (subr), 1);
	  SET_DECL_RTL (DECL_RESULT (subr), x);
	}
    }
  else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
    /* If return mode is void, this decl rtl should not be used.  */
    SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX);
  else
    {
      /* Compute the return values into a pseudo reg, which we will copy
	 into the true return register after the cleanups are done.  */

      /* In order to figure out what mode to use for the pseudo, we
	 figure out what the mode of the eventual return register will
	 actually be, and use that.  */
      rtx hard_reg
	= hard_function_value (TREE_TYPE (DECL_RESULT (subr)),
			       subr, 1);

      /* Structures that are returned in registers are not aggregate_value_p,
	 so we may see a PARALLEL or a REG.  */
      if (REG_P (hard_reg))
	SET_DECL_RTL (DECL_RESULT (subr), gen_reg_rtx (GET_MODE (hard_reg)));
      else if (GET_CODE (hard_reg) == PARALLEL)
	SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg));
      else
	abort ();

      /* Set DECL_REGISTER flag so that expand_function_end will copy the
	 result to the real return register(s).  */
      DECL_REGISTER (DECL_RESULT (subr)) = 1;
    }

  /* Initialize rtx for parameters and local variables.
     In some cases this requires emitting insns.  */

  assign_parms (subr);

  /* Copy the static chain now if it wasn't a register.  The delay is to
     avoid conflicts with the parameter passing registers.  */

  if (SMALL_REGISTER_CLASSES && current_function_needs_context)
    if (GET_CODE (static_chain_incoming_rtx) != REG)
      emit_move_insn (last_ptr, static_chain_incoming_rtx);

  /* The following was moved from init_function_start.
     The move is supposed to make sdb output more accurate.  */
  /* Indicate the beginning of the function body,
     as opposed to parm setup.  */
  emit_note (NULL, NOTE_INSN_FUNCTION_BEG);

  if (GET_CODE (get_last_insn ()) != NOTE)
    emit_note (NULL, NOTE_INSN_DELETED);
  parm_birth_insn = get_last_insn ();

  context_display = 0;
  if (current_function_needs_context)
    {
      /* Fetch static chain values for containing functions.  */
      tem = decl_function_context (current_function_decl);
      /* Copy the static chain pointer into a pseudo.  If we have
	 small register classes, copy the value from memory if
	 static_chain_incoming_rtx is a REG.  */
      if (tem)
	{
	  /* If the static chain originally came in a register, put it back
	     there, then move it out in the next insn.  The reason for
	     this peculiar code is to satisfy function integration.  */
	  if (SMALL_REGISTER_CLASSES
	      && GET_CODE (static_chain_incoming_rtx) == REG)
	    emit_move_insn (static_chain_incoming_rtx, last_ptr);
	  last_ptr = copy_to_reg (static_chain_incoming_rtx);
	}

      while (tem)
	{
	  tree rtlexp = make_node (RTL_EXPR);

	  RTL_EXPR_RTL (rtlexp) = last_ptr;
	  context_display = tree_cons (tem, rtlexp, context_display);
	  tem = decl_function_context (tem);
	  if (tem == 0)
	    break;
	  /* Chain thru stack frames, assuming pointer to next lexical frame
	     is found at the place we always store it.  */
#ifdef FRAME_GROWS_DOWNWARD
	  last_ptr = plus_constant (last_ptr,
				    -(HOST_WIDE_INT) GET_MODE_SIZE (Pmode));
#endif
	  last_ptr = gen_rtx_MEM (Pmode, memory_address (Pmode, last_ptr));
	  set_mem_alias_set (last_ptr, get_frame_alias_set ());
	  last_ptr = copy_to_reg (last_ptr);

	  /* If we are not optimizing, ensure that we know that this
	     piece of context is live over the entire function.  */
	  if (! optimize)
	    save_expr_regs = gen_rtx_EXPR_LIST (VOIDmode, last_ptr,
						save_expr_regs);
	}
    }

  if (current_function_instrument_entry_exit)
    {
      rtx fun = DECL_RTL (current_function_decl);
      if (GET_CODE (fun) == MEM)
	fun = XEXP (fun, 0);
      else
	abort ();
      emit_library_call (profile_function_entry_libfunc, LCT_NORMAL, VOIDmode,
			 2, fun, Pmode,
			 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
						     0,
						     hard_frame_pointer_rtx),
			 Pmode);
    }

  if (current_function_profile)
    {
#ifdef PROFILE_HOOK
      PROFILE_HOOK (current_function_funcdef_no);
#endif
    }

  /* After the display initializations is where the tail-recursion label
     should go, if we end up needing one.   Ensure we have a NOTE here
     since some things (like trampolines) get placed before this.  */
  tail_recursion_reentry = emit_note (NULL, NOTE_INSN_DELETED);

  /* Evaluate now the sizes of any types declared among the arguments.  */
  expand_pending_sizes (nreverse (get_pending_sizes ()));

  /* Make sure there is a line number after the function entry setup code.  */
  force_next_line_note ();
}

/* Undo the effects of init_dummy_function_start.  */
void
expand_dummy_function_end ()
{
  /* End any sequences that failed to be closed due to syntax errors.  */
  while (in_sequence_p ())
    end_sequence ();

  /* Outside function body, can't compute type's actual size
     until next function's body starts.  */

  free_after_parsing (cfun);
  free_after_compilation (cfun);
  cfun = 0;
}

/* Call DOIT for each hard register used as a return value from
   the current function.  */

void
diddle_return_value (doit, arg)
     void (*doit) PARAMS ((rtx, void *));
     void *arg;
{
  rtx outgoing = current_function_return_rtx;

  if (! outgoing)
    return;

  if (GET_CODE (outgoing) == REG)
    (*doit) (outgoing, arg);
  else if (GET_CODE (outgoing) == PARALLEL)
    {
      int i;

      for (i = 0; i < XVECLEN (outgoing, 0); i++)
	{
	  rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);

	  if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
	    (*doit) (x, arg);
	}
    }
}

static void
do_clobber_return_reg (reg, arg)
     rtx reg;
     void *arg ATTRIBUTE_UNUSED;
{
  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg));
}

void
clobber_return_register ()
{
  diddle_return_value (do_clobber_return_reg, NULL);

  /* In case we do use pseudo to return value, clobber it too.  */
  if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
    {
      tree decl_result = DECL_RESULT (current_function_decl);
      rtx decl_rtl = DECL_RTL (decl_result);
      if (REG_P (decl_rtl) && REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER)
	{
	  do_clobber_return_reg (decl_rtl, NULL);
	}
    }
}

static void
do_use_return_reg (reg, arg)
     rtx reg;
     void *arg ATTRIBUTE_UNUSED;
{
  emit_insn (gen_rtx_USE (VOIDmode, reg));
}

void
use_return_register ()
{
  diddle_return_value (do_use_return_reg, NULL);
}

static GTY(()) rtx initial_trampoline;

/* Generate RTL for the end of the current function.
   FILENAME and LINE are the current position in the source file.

   It is up to language-specific callers to do cleanups for parameters--
   or else, supply 1 for END_BINDINGS and we will call expand_end_bindings.  */

void
expand_function_end (filename, line, end_bindings)
     const char *filename;
     int line;
     int end_bindings;
{
  tree link;
  rtx clobber_after;

  finish_expr_for_function ();

  /* If arg_pointer_save_area was referenced only from a nested
     function, we will not have initialized it yet.  Do that now.  */
  if (arg_pointer_save_area && ! cfun->arg_pointer_save_area_init)
    get_arg_pointer_save_area (cfun);

#ifdef NON_SAVING_SETJMP
  /* Don't put any variables in registers if we call setjmp
     on a machine that fails to restore the registers.  */
  if (NON_SAVING_SETJMP && current_function_calls_setjmp)
    {
      if (DECL_INITIAL (current_function_decl) != error_mark_node)
	setjmp_protect (DECL_INITIAL (current_function_decl));

      setjmp_protect_args ();
    }
#endif

  /* Initialize any trampolines required by this function.  */
  for (link = trampoline_list; link; link = TREE_CHAIN (link))
    {
      tree function = TREE_PURPOSE (link);
      rtx context ATTRIBUTE_UNUSED = lookup_static_chain (function);
      rtx tramp = RTL_EXPR_RTL (TREE_VALUE (link));
#ifdef TRAMPOLINE_TEMPLATE
      rtx blktramp;
#endif
      rtx seq;

#ifdef TRAMPOLINE_TEMPLATE
      /* First make sure this compilation has a template for
	 initializing trampolines.  */
      if (initial_trampoline == 0)
	{
	  initial_trampoline
	    = gen_rtx_MEM (BLKmode, assemble_trampoline_template ());
	  set_mem_align (initial_trampoline, TRAMPOLINE_ALIGNMENT);
	}
#endif

      /* Generate insns to initialize the trampoline.  */
      start_sequence ();
      tramp = round_trampoline_addr (XEXP (tramp, 0));
#ifdef TRAMPOLINE_TEMPLATE
      blktramp = replace_equiv_address (initial_trampoline, tramp);
      emit_block_move (blktramp, initial_trampoline,
		       GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
#endif
      trampolines_created = 1;
      INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
      seq = get_insns ();
      end_sequence ();

      /* Put those insns at entry to the containing function (this one).  */
      emit_insn_before (seq, tail_recursion_reentry);
    }

  /* If we are doing stack checking and this function makes calls,
     do a stack probe at the start of the function to ensure we have enough
     space for another stack frame.  */
  if (flag_stack_check && ! STACK_CHECK_BUILTIN)
    {
      rtx insn, seq;

      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
	if (GET_CODE (insn) == CALL_INSN)
	  {
	    start_sequence ();
	    probe_stack_range (STACK_CHECK_PROTECT,
			       GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
	    seq = get_insns ();
	    end_sequence ();
	    emit_insn_before (seq, tail_recursion_reentry);
	    break;
	  }
    }

  /* Warn about unused parms if extra warnings were specified.  */
  /* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this
     warning.  WARN_UNUSED_PARAMETER is negative when set by
     -Wunused.  */
  if (warn_unused_parameter > 0
      || (warn_unused_parameter < 0 && extra_warnings))
    {
      tree decl;

      for (decl = DECL_ARGUMENTS (current_function_decl);
	   decl; decl = TREE_CHAIN (decl))
	if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
	    && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
	  warning_with_decl (decl, "unused parameter `%s'");
    }

  /* Delete handlers for nonlocal gotos if nothing uses them.  */
  if (nonlocal_goto_handler_slots != 0
      && ! current_function_has_nonlocal_label)
    delete_handlers ();

  /* End any sequences that failed to be closed due to syntax errors.  */
  while (in_sequence_p ())
    end_sequence ();

  /* Outside function body, can't compute type's actual size
     until next function's body starts.  */
  immediate_size_expand--;

  clear_pending_stack_adjust ();
  do_pending_stack_adjust ();

  /* ???  This is a kludge.  We want to ensure that instructions that
     may trap are not moved into the epilogue by scheduling, because
     we don't always emit unwind information for the epilogue.
     However, not all machine descriptions define a blockage insn, so
     emit an ASM_INPUT to act as one.  */
  if (flag_non_call_exceptions)
    emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));

  /* Mark the end of the function body.
     If control reaches this insn, the function can drop through
     without returning a value.  */
  emit_note (NULL, NOTE_INSN_FUNCTION_END);

  /* Must mark the last line number note in the function, so that the test
     coverage code can avoid counting the last line twice.  This just tells
     the code to ignore the immediately following line note, since there
     already exists a copy of this note somewhere above.  This line number
     note is still needed for debugging though, so we can't delete it.  */
  if (flag_test_coverage)
    emit_note (NULL, NOTE_INSN_REPEATED_LINE_NUMBER);

  /* Output a linenumber for the end of the function.
     SDB depends on this.  */
  emit_line_note_force (filename, line);

  /* Before the return label (if any), clobber the return
     registers so that they are not propagated live to the rest of
     the function.  This can only happen with functions that drop
     through; if there had been a return statement, there would
     have either been a return rtx, or a jump to the return label.

     We delay actual code generation after the current_function_value_rtx
     is computed.  */
  clobber_after = get_last_insn ();

  /* Output the label for the actual return from the function,
     if one is expected.  This happens either because a function epilogue
     is used instead of a return instruction, or because a return was done
     with a goto in order to run local cleanups, or because of pcc-style
     structure returning.  */
  if (return_label)
    emit_label (return_label);

  /* C++ uses this.  */
  if (end_bindings)
    expand_end_bindings (0, 0, 0);

  if (current_function_instrument_entry_exit)
    {
      rtx fun = DECL_RTL (current_function_decl);
      if (GET_CODE (fun) == MEM)
	fun = XEXP (fun, 0);
      else
	abort ();
      emit_library_call (profile_function_exit_libfunc, LCT_NORMAL, VOIDmode,
			 2, fun, Pmode,
			 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
						     0,
						     hard_frame_pointer_rtx),
			 Pmode);
    }

  /* Let except.c know where it should emit the call to unregister
     the function context for sjlj exceptions.  */
  if (flag_exceptions && USING_SJLJ_EXCEPTIONS)
    sjlj_emit_function_exit_after (get_last_insn ());

  /* If we had calls to alloca, and this machine needs
     an accurate stack pointer to exit the function,
     insert some code to save and restore the stack pointer.  */
#ifdef EXIT_IGNORE_STACK
  if (! EXIT_IGNORE_STACK)
#endif
    if (current_function_calls_alloca)
      {
	rtx tem = 0;

	emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
	emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
      }

  /* If scalar return value was computed in a pseudo-reg, or was a named
     return value that got dumped to the stack, copy that to the hard
     return register.  */
  if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
    {
      tree decl_result = DECL_RESULT (current_function_decl);
      rtx decl_rtl = DECL_RTL (decl_result);

      if (REG_P (decl_rtl)
	  ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
	  : DECL_REGISTER (decl_result))
	{
	  rtx real_decl_rtl = current_function_return_rtx;

	  /* This should be set in assign_parms.  */
	  if (! REG_FUNCTION_VALUE_P (real_decl_rtl))
	    abort ();

	  /* If this is a BLKmode structure being returned in registers,
	     then use the mode computed in expand_return.  Note that if
	     decl_rtl is memory, then its mode may have been changed,
	     but that current_function_return_rtx has not.  */
	  if (GET_MODE (real_decl_rtl) == BLKmode)
	    PUT_MODE (real_decl_rtl, GET_MODE (decl_rtl));

	  /* If a named return value dumped decl_return to memory, then
	     we may need to re-do the PROMOTE_MODE signed/unsigned
	     extension.  */
	  if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
	    {
	      int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));

#ifdef PROMOTE_FUNCTION_RETURN
	      promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
			    &unsignedp, 1);
#endif

	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
	    }
	  else if (GET_CODE (real_decl_rtl) == PARALLEL)
	    {
	      /* If expand_function_start has created a PARALLEL for decl_rtl,
		 move the result to the real return registers.  Otherwise, do
		 a group load from decl_rtl for a named return.  */
	      if (GET_CODE (decl_rtl) == PARALLEL)
		emit_group_move (real_decl_rtl, decl_rtl);
	      else
		emit_group_load (real_decl_rtl, decl_rtl,
				 int_size_in_bytes (TREE_TYPE (decl_result)));
	    }
	  else
	    emit_move_insn (real_decl_rtl, decl_rtl);
	}
    }

  /* If returning a structure, arrange to return the address of the value
     in a place where debuggers expect to find it.

     If returning a structure PCC style,
     the caller also depends on this value.
     And current_function_returns_pcc_struct is not necessarily set.  */
  if (current_function_returns_struct
      || current_function_returns_pcc_struct)
    {
      rtx value_address
	= XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
      tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
#ifdef FUNCTION_OUTGOING_VALUE
      rtx outgoing
	= FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
				   current_function_decl);
#else
      rtx outgoing
	= FUNCTION_VALUE (build_pointer_type (type), current_function_decl);
#endif

      /* Mark this as a function return value so integrate will delete the
	 assignment and USE below when inlining this function.  */
      REG_FUNCTION_VALUE_P (outgoing) = 1;

#ifdef POINTERS_EXTEND_UNSIGNED
      /* The address may be ptr_mode and OUTGOING may be Pmode.  */
      if (GET_MODE (outgoing) != GET_MODE (value_address))
	value_address = convert_memory_address (GET_MODE (outgoing),
						value_address);
#endif

      emit_move_insn (outgoing, value_address);

      /* Show return register used to hold result (in this case the address
	 of the result.  */
      current_function_return_rtx = outgoing;
    }

  /* If this is an implementation of throw, do what's necessary to
     communicate between __builtin_eh_return and the epilogue.  */
  expand_eh_return ();

  /* Emit the actual code to clobber return register.  */
  {
    rtx seq, after;

    start_sequence ();
    clobber_return_register ();
    seq = get_insns ();
    end_sequence ();

    after = emit_insn_after (seq, clobber_after);

    if (clobber_after != after)
      cfun->x_clobber_return_insn = after;
  }

  /* ??? This should no longer be necessary since stupid is no longer with
     us, but there are some parts of the compiler (eg reload_combine, and
     sh mach_dep_reorg) that still try and compute their own lifetime info
     instead of using the general framework.  */
  use_return_register ();

  /* Fix up any gotos that jumped out to the outermost
     binding level of the function.
     Must follow emitting RETURN_LABEL.  */

  /* If you have any cleanups to do at this point,
     and they need to create temporary variables,
     then you will lose.  */
  expand_fixups (get_insns ());
}

rtx
get_arg_pointer_save_area (f)
     struct function *f;
{
  rtx ret = f->x_arg_pointer_save_area;

  if (! ret)
    {
      ret = assign_stack_local_1 (Pmode, GET_MODE_SIZE (Pmode), 0, f);
      f->x_arg_pointer_save_area = ret;
    }

  if (f == cfun && ! f->arg_pointer_save_area_init)
    {
      rtx seq;

      /* Save the arg pointer at the beginning of the function.  The
	 generated stack slot may not be a valid memory address, so we
	 have to check it and fix it if necessary.  */
      start_sequence ();
      emit_move_insn (validize_mem (ret), virtual_incoming_args_rtx);
      seq = get_insns ();
      end_sequence ();

      push_topmost_sequence ();
      emit_insn_after (seq, get_insns ());
      pop_topmost_sequence ();
    }

  return ret;
}

/* Extend a vector that records the INSN_UIDs of INSNS
   (a list of one or more insns).  */

static void
record_insns (insns, vecp)
     rtx insns;
     varray_type *vecp;
{
  int i, len;
  rtx tmp;

  tmp = insns;
  len = 0;
  while (tmp != NULL_RTX)
    {
      len++;
      tmp = NEXT_INSN (tmp);
    }

  i = VARRAY_SIZE (*vecp);
  VARRAY_GROW (*vecp, i + len);
  tmp = insns;
  while (tmp != NULL_RTX)
    {
      VARRAY_INT (*vecp, i) = INSN_UID (tmp);
      i++;
      tmp = NEXT_INSN (tmp);
    }
}

/* Determine how many INSN_UIDs in VEC are part of INSN.  Because we can
   be running after reorg, SEQUENCE rtl is possible.  */

static int
contains (insn, vec)
     rtx insn;
     varray_type vec;
{
  int i, j;

  if (GET_CODE (insn) == INSN
      && GET_CODE (PATTERN (insn)) == SEQUENCE)
    {
      int count = 0;
      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
	for (j = VARRAY_SIZE (vec) - 1; j >= 0; --j)
	  if (INSN_UID (XVECEXP (PATTERN (insn), 0, i)) == VARRAY_INT (vec, j))
	    count++;
      return count;
    }
  else
    {
      for (j = VARRAY_SIZE (vec) - 1; j >= 0; --j)
	if (INSN_UID (insn) == VARRAY_INT (vec, j))
	  return 1;
    }
  return 0;
}

int
prologue_epilogue_contains (insn)
     rtx insn;
{
  if (contains (insn, prologue))
    return 1;
  if (contains (insn, epilogue))
    return 1;
  return 0;
}

int
sibcall_epilogue_contains (insn)
     rtx insn;
{
  if (sibcall_epilogue)
    return contains (insn, sibcall_epilogue);
  return 0;
}

#ifdef HAVE_return
/* Insert gen_return at the end of block BB.  This also means updating
   block_for_insn appropriately.  */

static void
emit_return_into_block (bb, line_note)
     basic_block bb;
     rtx line_note;
{
  rtx p, end;

  p = NEXT_INSN (bb->end);
  end = emit_jump_insn_after (gen_return (), bb->end);
  if (line_note)
    emit_line_note_after (NOTE_SOURCE_FILE (line_note),
			  NOTE_LINE_NUMBER (line_note), PREV_INSN (bb->end));
}
#endif /* HAVE_return */

#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)

/* These functions convert the epilogue into a variant that does not modify the
   stack pointer.  This is used in cases where a function returns an object
   whose size is not known until it is computed.  The called function leaves the
   object on the stack, leaves the stack depressed, and returns a pointer to
   the object.

   What we need to do is track all modifications and references to the stack
   pointer, deleting the modifications and changing the references to point to
   the location the stack pointer would have pointed to had the modifications
   taken place.

   These functions need to be portable so we need to make as few assumptions
   about the epilogue as we can.  However, the epilogue basically contains
   three things: instructions to reset the stack pointer, instructions to
   reload registers, possibly including the frame pointer, and an
   instruction to return to the caller.

   If we can't be sure of what a relevant epilogue insn is doing, we abort.
   We also make no attempt to validate the insns we make since if they are
   invalid, we probably can't do anything valid.  The intent is that these
   routines get "smarter" as more and more machines start to use them and
   they try operating on different epilogues.

   We use the following structure to track what the part of the epilogue that
   we've already processed has done.  We keep two copies of the SP equivalence,
   one for use during the insn we are processing and one for use in the next
   insn.  The difference is because one part of a PARALLEL may adjust SP
   and the other may use it.  */

struct epi_info
{
  rtx sp_equiv_reg;		/* REG that SP is set from, perhaps SP.  */
  HOST_WIDE_INT sp_offset;	/* Offset from SP_EQUIV_REG of present SP.  */
  rtx new_sp_equiv_reg;		/* REG to be used at end of insn.  */
  HOST_WIDE_INT new_sp_offset;	/* Offset to be used at end of insn.  */
  rtx equiv_reg_src;		/* If nonzero, the value that SP_EQUIV_REG
				   should be set to once we no longer need
				   its value.  */
};

static void handle_epilogue_set PARAMS ((rtx, struct epi_info *));
static void emit_equiv_load PARAMS ((struct epi_info *));

/* Modify INSN, a list of one or more insns that is part of the epilogue, to
   no modifications to the stack pointer.  Return the new list of insns.  */

static rtx
keep_stack_depressed (insns)
     rtx insns;
{
  int j;
  struct epi_info info;
  rtx insn, next;

  /* If the epilogue is just a single instruction, it ust be OK as is.  */

  if (NEXT_INSN (insns) == NULL_RTX)
    return insns;

  /* Otherwise, start a sequence, initialize the information we have, and
     process all the insns we were given.  */
  start_sequence ();

  info.sp_equiv_reg = stack_pointer_rtx;
  info.sp_offset = 0;
  info.equiv_reg_src = 0;

  insn = insns;
  next = NULL_RTX;
  while (insn != NULL_RTX)
    {
      next = NEXT_INSN (insn);

      if (!INSN_P (insn))
	{
	  add_insn (insn);
	  insn = next;
	  continue;
	}

      /* If this insn references the register that SP is equivalent to and
	 we have a pending load to that register, we must force out the load
	 first and then indicate we no longer know what SP's equivalent is.  */
      if (info.equiv_reg_src != 0
	  && reg_referenced_p (info.sp_equiv_reg, PATTERN (insn)))
	{
	  emit_equiv_load (&info);
	  info.sp_equiv_reg = 0;
	}

      info.new_sp_equiv_reg = info.sp_equiv_reg;
      info.new_sp_offset = info.sp_offset;

      /* If this is a (RETURN) and the return address is on the stack,
	 update the address and change to an indirect jump.  */
      if (GET_CODE (PATTERN (insn)) == RETURN
	  || (GET_CODE (PATTERN (insn)) == PARALLEL
	      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == RETURN))
	{
	  rtx retaddr = INCOMING_RETURN_ADDR_RTX;
	  rtx base = 0;
	  HOST_WIDE_INT offset = 0;
	  rtx jump_insn, jump_set;

	  /* If the return address is in a register, we can emit the insn
	     unchanged.  Otherwise, it must be a MEM and we see what the
	     base register and offset are.  In any case, we have to emit any
	     pending load to the equivalent reg of SP, if any.  */
	  if (GET_CODE (retaddr) == REG)
	    {
	      emit_equiv_load (&info);
	      add_insn (insn);
	      insn = next;
	      continue;
	    }
	  else if (GET_CODE (retaddr) == MEM
		   && GET_CODE (XEXP (retaddr, 0)) == REG)
	    base = gen_rtx_REG (Pmode, REGNO (XEXP (retaddr, 0))), offset = 0;
	  else if (GET_CODE (retaddr) == MEM
		   && GET_CODE (XEXP (retaddr, 0)) == PLUS
		   && GET_CODE (XEXP (XEXP (retaddr, 0), 0)) == REG
		   && GET_CODE (XEXP (XEXP (retaddr, 0), 1)) == CONST_INT)
	    {
	      base = gen_rtx_REG (Pmode, REGNO (XEXP (XEXP (retaddr, 0), 0)));
	      offset = INTVAL (XEXP (XEXP (retaddr, 0), 1));
	    }
	  else
	    abort ();

	  /* If the base of the location containing the return pointer
	     is SP, we must update it with the replacement address.  Otherwise,
	     just build the necessary MEM.  */
	  retaddr = plus_constant (base, offset);
	  if (base == stack_pointer_rtx)
	    retaddr = simplify_replace_rtx (retaddr, stack_pointer_rtx,
					    plus_constant (info.sp_equiv_reg,
							   info.sp_offset));

	  retaddr = gen_rtx_MEM (Pmode, retaddr);

	  /* If there is a pending load to the equivalent register for SP
	     and we reference that register, we must load our address into
	     a scratch register and then do that load.  */
	  if (info.equiv_reg_src
	      && reg_overlap_mentioned_p (info.equiv_reg_src, retaddr))
	    {
	      unsigned int regno;
	      rtx reg;

	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
		if (HARD_REGNO_MODE_OK (regno, Pmode)
		    && !fixed_regs[regno]
		    && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)
		    && !REGNO_REG_SET_P (EXIT_BLOCK_PTR->global_live_at_start,
					 regno)
		    && !refers_to_regno_p (regno,
					   regno + HARD_REGNO_NREGS (regno,
								     Pmode),
					   info.equiv_reg_src, NULL))
		  break;

	      if (regno == FIRST_PSEUDO_REGISTER)
		abort ();

	      reg = gen_rtx_REG (Pmode, regno);
	      emit_move_insn (reg, retaddr);
	      retaddr = reg;
	    }

	  emit_equiv_load (&info);
	  jump_insn = emit_jump_insn (gen_indirect_jump (retaddr));

	  /* Show the SET in the above insn is a RETURN.  */
	  jump_set = single_set (jump_insn);
	  if (jump_set == 0)
	    abort ();
	  else
	    SET_IS_RETURN_P (jump_set) = 1;
	}

      /* If SP is not mentioned in the pattern and its equivalent register, if
	 any, is not modified, just emit it.  Otherwise, if neither is set,
	 replace the reference to SP and emit the insn.  If none of those are
	 true, handle each SET individually.  */
      else if (!reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))
	       && (info.sp_equiv_reg == stack_pointer_rtx
		   || !reg_set_p (info.sp_equiv_reg, insn)))
	add_insn (insn);
      else if (! reg_set_p (stack_pointer_rtx, insn)
	       && (info.sp_equiv_reg == stack_pointer_rtx
		   || !reg_set_p (info.sp_equiv_reg, insn)))
	{
	  if (! validate_replace_rtx (stack_pointer_rtx,
				      plus_constant (info.sp_equiv_reg,
						     info.sp_offset),
				      insn))
	    abort ();

	  add_insn (insn);
	}
      else if (GET_CODE (PATTERN (insn)) == SET)
	handle_epilogue_set (PATTERN (insn), &info);
      else if (GET_CODE (PATTERN (insn)) == PARALLEL)
	{
	  for (j = 0; j < XVECLEN (PATTERN (insn), 0); j++)
	    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET)
	      handle_epilogue_set (XVECEXP (PATTERN (insn), 0, j), &info);
	}
      else
	add_insn (insn);

      info.sp_equiv_reg = info.new_sp_equiv_reg;
      info.sp_offset = info.new_sp_offset;

      insn = next;
    }

  insns = get_insns ();
  end_sequence ();
  return insns;
}

/* SET is a SET from an insn in the epilogue.  P is a pointer to the epi_info
   structure that contains information about what we've seen so far.  We
   process this SET by either updating that data or by emitting one or
   more insns.  */

static void
handle_epilogue_set (set, p)
     rtx set;
     struct epi_info *p;
{
  /* First handle the case where we are setting SP.  Record what it is being
     set from.  If unknown, abort.  */
  if (reg_set_p (stack_pointer_rtx, set))
    {
      if (SET_DEST (set) != stack_pointer_rtx)
	abort ();

      if (GET_CODE (SET_SRC (set)) == PLUS
	  && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
	{
	  p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
	  p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
	}
      else
	p->new_sp_equiv_reg = SET_SRC (set), p->new_sp_offset = 0;

      /* If we are adjusting SP, we adjust from the old data.  */
      if (p->new_sp_equiv_reg == stack_pointer_rtx)
	{
	  p->new_sp_equiv_reg = p->sp_equiv_reg;
	  p->new_sp_offset += p->sp_offset;
	}

      if (p->new_sp_equiv_reg == 0 || GET_CODE (p->new_sp_equiv_reg) != REG)
	abort ();

      return;
    }

  /* Next handle the case where we are setting SP's equivalent register.
     If we already have a value to set it to, abort.  We could update, but
     there seems little point in handling that case.  Note that we have
     to allow for the case where we are setting the register set in
     the previous part of a PARALLEL inside a single insn.  But use the
     old offset for any updates within this insn.  */
  else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
    {
      if (!rtx_equal_p (p->new_sp_equiv_reg, SET_DEST (set))
	  || p->equiv_reg_src != 0)
	abort ();
      else
	p->equiv_reg_src
	  = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
				  plus_constant (p->sp_equiv_reg,
						 p->sp_offset));
    }

  /* Otherwise, replace any references to SP in the insn to its new value
     and emit the insn.  */
  else
    {
      SET_SRC (set) = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
					    plus_constant (p->sp_equiv_reg,
							   p->sp_offset));
      SET_DEST (set) = simplify_replace_rtx (SET_DEST (set), stack_pointer_rtx,
					     plus_constant (p->sp_equiv_reg,
							    p->sp_offset));
      emit_insn (set);
    }
}

/* Emit an insn to do the load shown in p->equiv_reg_src, if needed.  */

static void
emit_equiv_load (p)
     struct epi_info *p;
{
  if (p->equiv_reg_src != 0)
    emit_move_insn (p->sp_equiv_reg, p->equiv_reg_src);

  p->equiv_reg_src = 0;
}
#endif

/* Generate the prologue and epilogue RTL if the machine supports it.  Thread
   this into place with notes indicating where the prologue ends and where
   the epilogue begins.  Update the basic block information when possible.  */

void
thread_prologue_and_epilogue_insns (f)
     rtx f ATTRIBUTE_UNUSED;
{
  int inserted = 0;
  edge e;
#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)
  rtx seq;
#endif
#ifdef HAVE_prologue
  rtx prologue_end = NULL_RTX;
#endif
#if defined (HAVE_epilogue) || defined(HAVE_return)
  rtx epilogue_end = NULL_RTX;
#endif

#ifdef HAVE_prologue
  if (HAVE_prologue)
    {
      start_sequence ();
      seq = gen_prologue ();
      emit_insn (seq);

      /* Retain a map of the prologue insns.  */
      record_insns (seq, &prologue);
      prologue_end = emit_note (NULL, NOTE_INSN_PROLOGUE_END);

      seq = get_insns ();
      end_sequence ();

      /* Can't deal with multiple successors of the entry block
         at the moment.  Function should always have at least one
         entry point.  */
      if (!ENTRY_BLOCK_PTR->succ || ENTRY_BLOCK_PTR->succ->succ_next)
	abort ();

      insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
      inserted = 1;
    }
#endif

  /* If the exit block has no non-fake predecessors, we don't need
     an epilogue.  */
  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
    if ((e->flags & EDGE_FAKE) == 0)
      break;
  if (e == NULL)
    goto epilogue_done;

#ifdef HAVE_return
  if (optimize && HAVE_return)
    {
      /* If we're allowed to generate a simple return instruction,
	 then by definition we don't need a full epilogue.  Examine
	 the block that falls through to EXIT.   If it does not
	 contain any code, examine its predecessors and try to
	 emit (conditional) return instructions.  */

      basic_block last;
      edge e_next;
      rtx label;

      for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
	if (e->flags & EDGE_FALLTHRU)
	  break;
      if (e == NULL)
	goto epilogue_done;
      last = e->src;

      /* Verify that there are no active instructions in the last block.  */
      label = last->end;
      while (label && GET_CODE (label) != CODE_LABEL)
	{
	  if (active_insn_p (label))
	    break;
	  label = PREV_INSN (label);
	}

      if (last->head == label && GET_CODE (label) == CODE_LABEL)
	{
	  rtx epilogue_line_note = NULL_RTX;

	  /* Locate the line number associated with the closing brace,
	     if we can find one.  */
	  for (seq = get_last_insn ();
	       seq && ! active_insn_p (seq);
	       seq = PREV_INSN (seq))
	    if (GET_CODE (seq) == NOTE && NOTE_LINE_NUMBER (seq) > 0)
	      {
		epilogue_line_note = seq;
		break;
	      }

	  for (e = last->pred; e; e = e_next)
	    {
	      basic_block bb = e->src;
	      rtx jump;

	      e_next = e->pred_next;
	      if (bb == ENTRY_BLOCK_PTR)
		continue;

	      jump = bb->end;
	      if ((GET_CODE (jump) != JUMP_INSN) || JUMP_LABEL (jump) != label)
		continue;

	      /* If we have an unconditional jump, we can replace that
		 with a simple return instruction.  */
	      if (simplejump_p (jump))
		{
		  emit_return_into_block (bb, epilogue_line_note);
		  delete_insn (jump);
		}

	      /* If we have a conditional jump, we can try to replace
		 that with a conditional return instruction.  */
	      else if (condjump_p (jump))
		{
		  if (! redirect_jump (jump, 0, 0))
		    continue;

		  /* If this block has only one successor, it both jumps
		     and falls through to the fallthru block, so we can't
		     delete the edge.  */
		  if (bb->succ->succ_next == NULL)
		    continue;
		}
	      else
		continue;

	      /* Fix up the CFG for the successful change we just made.  */
	      redirect_edge_succ (e, EXIT_BLOCK_PTR);
	    }

	  /* Emit a return insn for the exit fallthru block.  Whether
	     this is still reachable will be determined later.  */

	  emit_barrier_after (last->end);
	  emit_return_into_block (last, epilogue_line_note);
	  epilogue_end = last->end;
	  last->succ->flags &= ~EDGE_FALLTHRU;
	  goto epilogue_done;
	}
    }
#endif
#ifdef HAVE_epilogue
  if (HAVE_epilogue)
    {
      /* Find the edge that falls through to EXIT.  Other edges may exist
	 due to RETURN instructions, but those don't need epilogues.
	 There really shouldn't be a mixture -- either all should have
	 been converted or none, however...  */

      for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
	if (e->flags & EDGE_FALLTHRU)
	  break;
      if (e == NULL)
	goto epilogue_done;

      start_sequence ();
      epilogue_end = emit_note (NULL, NOTE_INSN_EPILOGUE_BEG);

      seq = gen_epilogue ();

#ifdef INCOMING_RETURN_ADDR_RTX
      /* If this function returns with the stack depressed and we can support
	 it, massage the epilogue to actually do that.  */
      if (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
	  && TYPE_RETURNS_STACK_DEPRESSED (TREE_TYPE (current_function_decl)))
	seq = keep_stack_depressed (seq);
#endif

      emit_jump_insn (seq);

      /* Retain a map of the epilogue insns.  */
      record_insns (seq, &epilogue);

      seq = get_insns ();
      end_sequence ();

      insert_insn_on_edge (seq, e);
      inserted = 1;
    }
#endif
epilogue_done:

  if (inserted)
    commit_edge_insertions ();

#ifdef HAVE_sibcall_epilogue
  /* Emit sibling epilogues before any sibling call sites.  */
  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
    {
      basic_block bb = e->src;
      rtx insn = bb->end;
      rtx i;
      rtx newinsn;

      if (GET_CODE (insn) != CALL_INSN
	  || ! SIBLING_CALL_P (insn))
	continue;

      start_sequence ();
      emit_insn (gen_sibcall_epilogue ());
      seq = get_insns ();
      end_sequence ();

      /* Retain a map of the epilogue insns.  Used in life analysis to
	 avoid getting rid of sibcall epilogue insns.  Do this before we
	 actually emit the sequence.  */
      record_insns (seq, &sibcall_epilogue);

      i = PREV_INSN (insn);
      newinsn = emit_insn_before (seq, insn);
    }
#endif

#ifdef HAVE_prologue
  if (prologue_end)
    {
      rtx insn, prev;

      /* GDB handles `break f' by setting a breakpoint on the first
	 line note after the prologue.  Which means (1) that if
	 there are line number notes before where we inserted the
	 prologue we should move them, and (2) we should generate a
	 note before the end of the first basic block, if there isn't
	 one already there.

	 ??? This behavior is completely broken when dealing with
	 multiple entry functions.  We simply place the note always
	 into first basic block and let alternate entry points
	 to be missed.
       */

      for (insn = prologue_end; insn; insn = prev)
	{
	  prev = PREV_INSN (insn);
	  if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
	    {
	      /* Note that we cannot reorder the first insn in the
		 chain, since rest_of_compilation relies on that
		 remaining constant.  */
	      if (prev == NULL)
		break;
	      reorder_insns (insn, insn, prologue_end);
	    }
	}

      /* Find the last line number note in the first block.  */
      for (insn = ENTRY_BLOCK_PTR->next_bb->end;
	   insn != prologue_end && insn;
	   insn = PREV_INSN (insn))
	if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
	  break;

      /* If we didn't find one, make a copy of the first line number
	 we run across.  */
      if (! insn)
	{
	  for (insn = next_active_insn (prologue_end);
	       insn;
	       insn = PREV_INSN (insn))
	    if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
	      {
		emit_line_note_after (NOTE_SOURCE_FILE (insn),
				      NOTE_LINE_NUMBER (insn),
				      prologue_end);
		break;
	      }
	}
    }
#endif
#ifdef HAVE_epilogue
  if (epilogue_end)
    {
      rtx insn, next;

      /* Similarly, move any line notes that appear after the epilogue.
         There is no need, however, to be quite so anal about the existence
	 of such a note.  */
      for (insn = epilogue_end; insn; insn = next)
	{
	  next = NEXT_INSN (insn);
	  if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
	    reorder_insns (insn, insn, PREV_INSN (epilogue_end));
	}
    }
#endif
}

/* Reposition the prologue-end and epilogue-begin notes after instruction
   scheduling and delayed branch scheduling.  */

void
reposition_prologue_and_epilogue_notes (f)
     rtx f ATTRIBUTE_UNUSED;
{
#if defined (HAVE_prologue) || defined (HAVE_epilogue)
  rtx insn, last, note;
  int len;

  if ((len = VARRAY_SIZE (prologue)) > 0)
    {
      last = 0, note = 0;

      /* Scan from the beginning until we reach the last prologue insn.
	 We apparently can't depend on basic_block_{head,end} after
	 reorg has run.  */
      for (insn = f; insn; insn = NEXT_INSN (insn))
	{
	  if (GET_CODE (insn) == NOTE)
	    {
	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
		note = insn;
	    }
	  else if (contains (insn, prologue))
	    {
	      last = insn;
	      if (--len == 0)
		break;
	    }
	}

      if (last)
	{
	  rtx next;

	  /* Find the prologue-end note if we haven't already, and
	     move it to just after the last prologue insn.  */
	  if (note == 0)
	    {
	      for (note = last; (note = NEXT_INSN (note));)
		if (GET_CODE (note) == NOTE
		    && NOTE_LINE_NUMBER (note) == NOTE_INSN_PROLOGUE_END)
		  break;
	    }

	  next = NEXT_INSN (note);

	  /* Avoid placing note between CODE_LABEL and BASIC_BLOCK note.  */
	  if (GET_CODE (last) == CODE_LABEL)
	    last = NEXT_INSN (last);
	  reorder_insns (note, note, last);
	}
    }

  if ((len = VARRAY_SIZE (epilogue)) > 0)
    {
      last = 0, note = 0;

      /* Scan from the end until we reach the first epilogue insn.
	 We apparently can't depend on basic_block_{head,end} after
	 reorg has run.  */
      for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
	{
	  if (GET_CODE (insn) == NOTE)
	    {
	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
		note = insn;
	    }
	  else if (contains (insn, epilogue))
	    {
	      last = insn;
	      if (--len == 0)
		break;
	    }
	}

      if (last)
	{
	  /* Find the epilogue-begin note if we haven't already, and
	     move it to just before the first epilogue insn.  */
	  if (note == 0)
	    {
	      for (note = insn; (note = PREV_INSN (note));)
		if (GET_CODE (note) == NOTE
		    && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG)
		  break;
	    }

	  if (PREV_INSN (last) != note)
	    reorder_insns (note, note, PREV_INSN (last));
	}
    }
#endif /* HAVE_prologue or HAVE_epilogue */
}

/* Called once, at initialization, to initialize function.c.  */

void
init_function_once ()
{
  VARRAY_INT_INIT (prologue, 0, "prologue");
  VARRAY_INT_INIT (epilogue, 0, "epilogue");
  VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
}

#include "gt-function.h"
