OSDN Git Service

* de.po: Update.
[pf3gnuchains/gcc-fork.git] / gcc / integrate.c
index 0552267..fed0a27 100644 (file)
@@ -1,6 +1,6 @@
 /* Procedure integration for GCC.
-   Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
 #include "rtl.h"
 #include "tree.h"
@@ -39,73 +41,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "function.h"
 #include "toplev.h"
 #include "intl.h"
-#include "loop.h"
 #include "params.h"
 #include "ggc.h"
 #include "target.h"
+#include "langhooks.h"
 
-#include "obstack.h"
-#define        obstack_chunk_alloc     xmalloc
-#define        obstack_chunk_free      free
-
-extern struct obstack *function_maybepermanent_obstack;
-
-/* Similar, but round to the next highest integer that meets the
-   alignment.  */
+/* Round to the next highest integer that meets the alignment.  */
 #define CEIL_ROUND(VALUE,ALIGN)        (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
-
-/* Default max number of insns a function can have and still be inline.
-   This is overridden on RISC machines.  */
-#ifndef INTEGRATE_THRESHOLD
-/* Inlining small functions might save more space then not inlining at
-   all.  Assume 1 instruction for the call and 1.5 insns per argument.  */
-#define INTEGRATE_THRESHOLD(DECL) \
-  (optimize_size \
-   ? (1 + (3 * list_length (DECL_ARGUMENTS (DECL))) / 2) \
-   : (8 * (8 + list_length (DECL_ARGUMENTS (DECL)))))
-#endif
 \f
 
 /* Private type used by {get/has}_func_hard_reg_initial_val.  */
-typedef struct initial_value_pair {
+typedef struct initial_value_pair GTY(()) {
   rtx hard_reg;
   rtx pseudo;
 } initial_value_pair;
-typedef struct initial_value_struct {
+typedef struct initial_value_struct GTY(()) {
   int num_entries;
   int max_entries;
-  initial_value_pair *entries;
+  initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
 } initial_value_struct;
 
-static void setup_initial_hard_reg_value_integration PARAMS ((struct function *, struct inline_remap *));
-
-static rtvec initialize_for_inline     PARAMS ((tree));
-static void note_modified_parmregs     PARAMS ((rtx, rtx, void *));
-static void integrate_parm_decls       PARAMS ((tree, struct inline_remap *,
-                                                rtvec));
-static tree integrate_decl_tree                PARAMS ((tree,
-                                                struct inline_remap *));
-static void subst_constants            PARAMS ((rtx *, rtx,
-                                                struct inline_remap *, int));
-static void set_block_origin_self      PARAMS ((tree));
-static void set_block_abstract_flags   PARAMS ((tree, int));
-static void process_reg_param          PARAMS ((struct inline_remap *, rtx,
-                                                rtx));
-void set_decl_abstract_flags           PARAMS ((tree, int));
-static void mark_stores                 PARAMS ((rtx, rtx, void *));
-static void save_parm_insns            PARAMS ((rtx, rtx));
-static void copy_insn_list              PARAMS ((rtx, struct inline_remap *,
-                                                rtx));
-static void copy_insn_notes            PARAMS ((rtx, struct inline_remap *,
-                                                int));
-static int compare_blocks               PARAMS ((const PTR, const PTR));
-static int find_block                   PARAMS ((const PTR, const PTR));
-
-/* Used by copy_rtx_and_substitute; this indicates whether the function is
-   called for the purpose of inlining or some other purpose (i.e. loop
-   unrolling).  This affects how constant pool references are handled.
-   This variable contains the FUNCTION_DECL for the inlined function.  */
-static struct function *inlining = 0;
+static void subst_constants (rtx *, rtx, struct inline_remap *, int);
+static void set_block_origin_self (tree);
+static void set_block_abstract_flags (tree, int);
+static void mark_stores (rtx, rtx, void *);
 \f
 /* Returns the Ith entry in the label_map contained in MAP.  If the
    Ith entry has not yet been set, return a fresh label.  This function
@@ -113,9 +72,7 @@ static struct function *inlining = 0;
    explosions when the label_map gets very large.  */
 
 rtx
-get_label_from_map (map, i)
-     struct inline_remap *map;
-     int i;
+get_label_from_map (struct inline_remap *map, int i)
 {
   rtx x = map->label_map[i];
 
@@ -128,239 +85,42 @@ get_label_from_map (map, i)
 /* Return false if the function FNDECL cannot be inlined on account of its
    attributes, true otherwise.  */
 bool
-function_attribute_inlinable_p (fndecl)
-     tree fndecl;
+function_attribute_inlinable_p (tree fndecl)
 {
-  bool has_machine_attr = false;
-  tree a;
-
-  for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a))
+  if (targetm.attribute_table)
     {
-      tree name = TREE_PURPOSE (a);
-      int i;
+      tree a;
 
-      for (i = 0; targetm.attribute_table[i].name != NULL; i++)
+      for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a))
        {
-         if (is_attribute_p (targetm.attribute_table[i].name, name))
-           {
-             has_machine_attr = true;
-             break;
-           }
-       }
-      if (has_machine_attr)
-       break;
-    }
-
-  if (has_machine_attr)
-    return (*targetm.function_attribute_inlinable_p) (fndecl);
-  else
-    return true;
-}
-
-/* Zero if the current function (whose FUNCTION_DECL is FNDECL)
-   is safe and reasonable to integrate into other functions.
-   Nonzero means value is a warning msgid with a single %s
-   for the function's name.  */
-
-const char *
-function_cannot_inline_p (fndecl)
-     tree fndecl;
-{
-  rtx insn;
-  tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
-
-  /* For functions marked as inline increase the maximum size to
-     MAX_INLINE_INSNS (-finline-limit-<n>).  For regular functions
-     use the limit given by INTEGRATE_THRESHOLD.  */
-
-  int max_insns = (DECL_INLINE (fndecl))
-                  ? (MAX_INLINE_INSNS
-                     + 8 * list_length (DECL_ARGUMENTS (fndecl)))
-                  : INTEGRATE_THRESHOLD (fndecl);
-
-  int ninsns = 0;
-  tree parms;
-
-  if (DECL_UNINLINABLE (fndecl))
-    return N_("function cannot be inline");
-
-  /* No inlines with varargs.  */
-  if ((last && TREE_VALUE (last) != void_type_node)
-      || current_function_varargs)
-    return N_("varargs function cannot be inline");
-
-  if (current_function_calls_alloca)
-    return N_("function using alloca cannot be inline");
-
-  if (current_function_calls_setjmp)
-    return N_("function using setjmp cannot be inline");
-
-  if (current_function_calls_eh_return)
-    return N_("function uses __builtin_eh_return");
-
-  if (current_function_contains_functions)
-    return N_("function with nested functions cannot be inline");
-
-  if (forced_labels)
-    return
-      N_("function with label addresses used in initializers cannot inline");
-
-  if (current_function_cannot_inline)
-    return current_function_cannot_inline;
-
-  /* If its not even close, don't even look.  */
-  if (get_max_uid () > 3 * max_insns)
-    return N_("function too large to be inline");
-
-#if 0
-  /* Don't inline functions which do not specify a function prototype and
-     have BLKmode argument or take the address of a parameter.  */
-  for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
-    {
-      if (TYPE_MODE (TREE_TYPE (parms)) == BLKmode)
-       TREE_ADDRESSABLE (parms) = 1;
-      if (last == NULL_TREE && TREE_ADDRESSABLE (parms))
-       return N_("no prototype, and parameter address used; cannot be inline");
-    }
-#endif
-
-  /* We can't inline functions that return structures
-     the old-fashioned PCC way, copying into a static block.  */
-  if (current_function_returns_pcc_struct)
-    return N_("inline functions not supported for this return value type");
-
-  /* We can't inline functions that return structures of varying size.  */
-  if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
-      && int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
-    return N_("function with varying-size return value cannot be inline");
-
-  /* Cannot inline a function with a varying size argument or one that
-     receives a transparent union.  */
-  for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
-    {
-      if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
-       return N_("function with varying-size parameter cannot be inline");
-      else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
-              && TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
-       return N_("function with transparent unit parameter cannot be inline");
-    }
-
-  if (get_max_uid () > max_insns)
-    {
-      for (ninsns = 0, insn = get_first_nonparm_insn ();
-          insn && ninsns < max_insns;
-          insn = NEXT_INSN (insn))
-       if (INSN_P (insn))
-         ninsns++;
-
-      if (ninsns >= max_insns)
-       return N_("function too large to be inline");
-    }
-
-  /* We will not inline a function which uses computed goto.  The addresses of
-     its local labels, which may be tucked into global storage, are of course
-     not constant across instantiations, which causes unexpected behaviour.  */
-  if (current_function_has_computed_jump)
-    return N_("function with computed jump cannot inline");
-
-  /* We cannot inline a nested function that jumps to a nonlocal label.  */
-  if (current_function_has_nonlocal_goto)
-    return N_("function with nonlocal goto cannot be inline");
-
-  /* We can't inline functions that return a PARALLEL rtx.  */
-  if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
-    {
-      rtx result = DECL_RTL (DECL_RESULT (fndecl));
-      if (GET_CODE (result) == PARALLEL)
-       return N_("inline functions not supported for this return value type");
-    }
-
-  /* If the function has a target specific attribute attached to it,
-     then we assume that we should not inline it.  This can be overriden
-     by the target if it defines TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P.  */
-  if (!function_attribute_inlinable_p (fndecl))
-    return N_("function with target specific attribute(s) cannot be inlined");
-
-  return NULL;
-}
-\f
-/* Map pseudo reg number into the PARM_DECL for the parm living in the reg.
-   Zero for a reg that isn't a parm's home.
-   Only reg numbers less than max_parm_reg are mapped here.  */
-static tree *parmdecl_map;
-
-/* In save_for_inline, nonzero if past the parm-initialization insns.  */
-static int in_nonparm_insns;
-\f
-/* Subroutine for `save_for_inline'.  Performs initialization
-   needed to save FNDECL's insns and info for future inline expansion.  */
-
-static rtvec
-initialize_for_inline (fndecl)
-     tree fndecl;
-{
-  int i;
-  rtvec arg_vector;
-  tree parms;
-
-  /* Clear out PARMDECL_MAP.  It was allocated in the caller's frame.  */
-  memset ((char *) parmdecl_map, 0, max_parm_reg * sizeof (tree));
-  arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
-
-  for (parms = DECL_ARGUMENTS (fndecl), i = 0;
-       parms;
-       parms = TREE_CHAIN (parms), i++)
-    {
-      rtx p = DECL_RTL (parms);
-
-      /* If we have (mem (addressof (mem ...))), use the inner MEM since
-        otherwise the copy_rtx call below will not unshare the MEM since
-        it shares ADDRESSOF.  */
-      if (GET_CODE (p) == MEM && GET_CODE (XEXP (p, 0)) == ADDRESSOF
-         && GET_CODE (XEXP (XEXP (p, 0), 0)) == MEM)
-       p = XEXP (XEXP (p, 0), 0);
-
-      RTVEC_ELT (arg_vector, i) = p;
-
-      if (GET_CODE (p) == REG)
-       parmdecl_map[REGNO (p)] = parms;
-      else if (GET_CODE (p) == CONCAT)
-       {
-         rtx preal = gen_realpart (GET_MODE (XEXP (p, 0)), p);
-         rtx pimag = gen_imagpart (GET_MODE (preal), p);
+         tree name = TREE_PURPOSE (a);
+         int i;
 
-         if (GET_CODE (preal) == REG)
-           parmdecl_map[REGNO (preal)] = parms;
-         if (GET_CODE (pimag) == REG)
-           parmdecl_map[REGNO (pimag)] = parms;
+         for (i = 0; targetm.attribute_table[i].name != NULL; i++)
+           if (is_attribute_p (targetm.attribute_table[i].name, name))
+             return targetm.function_attribute_inlinable_p (fndecl);
        }
-
-      /* This flag is cleared later
-        if the function ever modifies the value of the parm.  */
-      TREE_READONLY (parms) = 1;
     }
 
-  return arg_vector;
+  return true;
 }
-
-/* Copy NODE (which must be a DECL, but not a PARM_DECL).  The DECL
-   originally was in the FROM_FN, but now it will be in the
-   TO_FN.  */
+\f
+/* Copy NODE (which must be a DECL).  The DECL originally was in the FROM_FN,
+   but now it will be in the TO_FN.  */
 
 tree
-copy_decl_for_inlining (decl, from_fn, to_fn)
-     tree decl;
-     tree from_fn;
-     tree to_fn;
+copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
 {
   tree copy;
 
   /* Copy the declaration.  */
   if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
     {
-      /* For a parameter, we must make an equivalent VAR_DECL, not a
+      tree type = TREE_TYPE (decl);
+
+      /* For a parameter or result, we must make an equivalent VAR_DECL, not a
         new PARM_DECL.  */
-      copy = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
+      copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
       TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
       TREE_READONLY (copy) = TREE_READONLY (decl);
       TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
@@ -368,22 +128,31 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
   else
     {
       copy = copy_node (decl);
-      if (DECL_LANG_SPECIFIC (copy))
-       copy_lang_decl (copy);
+      /* The COPY is not abstract; it will be generated in TO_FN.  */
+      DECL_ABSTRACT (copy) = 0;
+      lang_hooks.dup_lang_specific_decl (copy);
 
       /* TREE_ADDRESSABLE isn't used to indicate that a label's
         address has been taken; it's for internal bookkeeping in
         expand_goto_internal.  */
       if (TREE_CODE (copy) == LABEL_DECL)
-       TREE_ADDRESSABLE (copy) = 0;
+       {
+         TREE_ADDRESSABLE (copy) = 0;
+       }
     }
 
+  /* Don't generate debug information for the copy if we wouldn't have
+     generated it for the copy either.  */
+  DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
+  DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
+
   /* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what
      declaration inspired this copy.  */
   DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
 
   /* The new variable/label has no RTL, yet.  */
-  SET_DECL_RTL (copy, NULL_RTX);
+  if (!TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
+    SET_DECL_RTL (copy, NULL_RTX);
 
   /* These args would always appear unused, if not for this.  */
   TREE_USED (copy) = 1;
@@ -394,10 +163,10 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
     ;
   else if (DECL_CONTEXT (decl) != from_fn)
     /* Things that weren't in the scope of the function we're inlining
-       from aren't in the scope we're inlining too, either.  */
+       from aren't in the scope we're inlining to, either.  */
     ;
   else if (TREE_STATIC (decl))
-    /* Function-scoped static variables should say in the original
+    /* Function-scoped static variables should stay in the original
        function.  */
     ;
   else
@@ -407,1407 +176,13 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
 
   return copy;
 }
-
-/* Make the insns and PARM_DECLs of the current function permanent
-   and record other information in DECL_SAVED_INSNS to allow inlining
-   of this function in subsequent calls.
-
-   This routine need not copy any insns because we are not going
-   to immediately compile the insns in the insn chain.  There
-   are two cases when we would compile the insns for FNDECL:
-   (1) when FNDECL is expanded inline, and (2) when FNDECL needs to
-   be output at the end of other compilation, because somebody took
-   its address.  In the first case, the insns of FNDECL are copied
-   as it is expanded inline, so FNDECL's saved insns are not
-   modified.  In the second case, FNDECL is used for the last time,
-   so modifying the rtl is not a problem.
-
-   We don't have to worry about FNDECL being inline expanded by
-   other functions which are written at the end of compilation
-   because flag_no_inline is turned on when we begin writing
-   functions at the end of compilation.  */
-
-void
-save_for_inline (fndecl)
-     tree fndecl;
-{
-  rtx insn;
-  rtvec argvec;
-  rtx first_nonparm_insn;
-
-  /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
-     Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
-     Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
-     for the parms, prior to elimination of virtual registers.
-     These values are needed for substituting parms properly.  */
-  if (! flag_no_inline)
-    parmdecl_map = (tree *) xmalloc (max_parm_reg * sizeof (tree));
-
-  /* Make and emit a return-label if we have not already done so.  */
-
-  if (return_label == 0)
-    {
-      return_label = gen_label_rtx ();
-      emit_label (return_label);
-    }
-
-  if (! flag_no_inline)
-    argvec = initialize_for_inline (fndecl);
-  else
-    argvec = NULL;
-
-  /* Delete basic block notes created by early run of find_basic_block.
-     The notes would be later used by find_basic_blocks to reuse the memory
-     for basic_block structures on already freed obstack.  */
-  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
-      delete_related_insns (insn);
-
-  /* If there are insns that copy parms from the stack into pseudo registers,
-     those insns are not copied.  `expand_inline_function' must
-     emit the correct code to handle such things.  */
-
-  insn = get_insns ();
-  if (GET_CODE (insn) != NOTE)
-    abort ();
-
-  if (! flag_no_inline)
-    {
-      /* Get the insn which signals the end of parameter setup code.  */
-      first_nonparm_insn = get_first_nonparm_insn ();
-
-      /* Now just scan the chain of insns to see what happens to our
-        PARM_DECLs.  If a PARM_DECL is used but never modified, we
-        can substitute its rtl directly when expanding inline (and
-        perform constant folding when its incoming value is
-        constant).  Otherwise, we have to copy its value into a new
-        register and track the new register's life.  */
-      in_nonparm_insns = 0;
-      save_parm_insns (insn, first_nonparm_insn);
-
-      cfun->inl_max_label_num = max_label_num ();
-      cfun->inl_last_parm_insn = cfun->x_last_parm_insn;
-      cfun->original_arg_vector = argvec;
-    }
-  cfun->original_decl_initial = DECL_INITIAL (fndecl);
-  cfun->no_debugging_symbols = (write_symbols == NO_DEBUG);
-  DECL_SAVED_INSNS (fndecl) = cfun;
-
-  /* Clean up.  */
-  if (! flag_no_inline)
-    free (parmdecl_map);
-}
-
-/* Scan the chain of insns to see what happens to our PARM_DECLs.  If a
-   PARM_DECL is used but never modified, we can substitute its rtl directly
-   when expanding inline (and perform constant folding when its incoming
-   value is constant). Otherwise, we have to copy its value into a new
-   register and track the new register's life.  */
-
-static void
-save_parm_insns (insn, first_nonparm_insn)
-     rtx insn;
-     rtx first_nonparm_insn;
-{
-  if (insn == NULL_RTX)
-    return;
-
-  for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
-    {
-      if (insn == first_nonparm_insn)
-       in_nonparm_insns = 1;
-
-      if (INSN_P (insn))
-       {
-         /* Record what interesting things happen to our parameters.  */
-         note_stores (PATTERN (insn), note_modified_parmregs, NULL);
-
-         /* If this is a CALL_PLACEHOLDER insn then we need to look into the
-            three attached sequences: normal call, sibling call and tail
-            recursion.  */
-         if (GET_CODE (insn) == CALL_INSN
-             && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-           {
-             int i;
-
-             for (i = 0; i < 3; i++)
-               save_parm_insns (XEXP (PATTERN (insn), i),
-                                first_nonparm_insn);
-           }
-       }
-    }
-}
 \f
-/* Note whether a parameter is modified or not.  */
-
-static void
-note_modified_parmregs (reg, x, data)
-     rtx reg;
-     rtx x ATTRIBUTE_UNUSED;
-     void *data ATTRIBUTE_UNUSED;
-{
-  if (GET_CODE (reg) == REG && in_nonparm_insns
-      && REGNO (reg) < max_parm_reg
-      && REGNO (reg) >= FIRST_PSEUDO_REGISTER
-      && parmdecl_map[REGNO (reg)] != 0)
-    TREE_READONLY (parmdecl_map[REGNO (reg)]) = 0;
-}
-
 /* Unfortunately, we need a global copy of const_equiv map for communication
    with a function called from note_stores.  Be *very* careful that this
    is used properly in the presence of recursion.  */
 
 varray_type global_const_equiv_varray;
-\f
-#define FIXED_BASE_PLUS_P(X) \
-  (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
-   && GET_CODE (XEXP (X, 0)) == REG                            \
-   && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER            \
-   && REGNO (XEXP (X, 0)) <= LAST_VIRTUAL_REGISTER)
-
-/* Called to set up a mapping for the case where a parameter is in a
-   register.  If it is read-only and our argument is a constant, set up the
-   constant equivalence.
-
-   If LOC is REG_USERVAR_P, the usual case, COPY must also have that flag set
-   if it is a register.
-
-   Also, don't allow hard registers here; they might not be valid when
-   substituted into insns.  */
-static void
-process_reg_param (map, loc, copy)
-     struct inline_remap *map;
-     rtx loc, copy;
-{
-  if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
-      || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
-         && ! REG_USERVAR_P (copy))
-      || (GET_CODE (copy) == REG
-         && REGNO (copy) < FIRST_PSEUDO_REGISTER))
-    {
-      rtx temp = copy_to_mode_reg (GET_MODE (loc), copy);
-      REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
-      if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
-       SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
-      copy = temp;
-    }
-  map->reg_map[REGNO (loc)] = copy;
-}
-
-/* Compare two BLOCKs for qsort.  The key we sort on is the
-   BLOCK_ABSTRACT_ORIGIN of the blocks.  */
-
-static int
-compare_blocks (v1, v2)
-     const PTR v1;
-     const PTR v2;
-{
-  tree b1 = *((const tree *) v1);
-  tree b2 = *((const tree *) v2);
-
-  return ((char *) BLOCK_ABSTRACT_ORIGIN (b1)
-         - (char *) BLOCK_ABSTRACT_ORIGIN (b2));
-}
-
-/* Compare two BLOCKs for bsearch.  The first pointer corresponds to
-   an original block; the second to a remapped equivalent.  */
-
-static int
-find_block (v1, v2)
-     const PTR v1;
-     const PTR v2;
-{
-  const union tree_node *b1 = (const union tree_node *) v1;
-  tree b2 = *((const tree *) v2);
-
-  return ((const char *) b1 - (char *) BLOCK_ABSTRACT_ORIGIN (b2));
-}
-
-/* Integrate the procedure defined by FNDECL.  Note that this function
-   may wind up calling itself.  Since the static variables are not
-   reentrant, we do not assign them until after the possibility
-   of recursion is eliminated.
-
-   If IGNORE is nonzero, do not produce a value.
-   Otherwise store the value in TARGET if it is nonzero and that is convenient.
-
-   Value is:
-   (rtx)-1 if we could not substitute the function
-   0 if we substituted it and it does not produce a value
-   else an rtx for where the value is stored.  */
-
-rtx
-expand_inline_function (fndecl, parms, target, ignore, type,
-                       structure_value_addr)
-     tree fndecl, parms;
-     rtx target;
-     int ignore;
-     tree type;
-     rtx structure_value_addr;
-{
-  struct function *inlining_previous;
-  struct function *inl_f = DECL_SAVED_INSNS (fndecl);
-  tree formal, actual, block;
-  rtx parm_insns = inl_f->emit->x_first_insn;
-  rtx insns = (inl_f->inl_last_parm_insn
-              ? NEXT_INSN (inl_f->inl_last_parm_insn)
-              : parm_insns);
-  tree *arg_trees;
-  rtx *arg_vals;
-  int max_regno;
-  int i;
-  int min_labelno = inl_f->emit->x_first_label_num;
-  int max_labelno = inl_f->inl_max_label_num;
-  int nargs;
-  rtx loc;
-  rtx stack_save = 0;
-  rtx temp;
-  struct inline_remap *map = 0;
-  rtvec arg_vector = (rtvec) inl_f->original_arg_vector;
-  rtx static_chain_value = 0;
-  int inl_max_uid;
-  int eh_region_offset;
-
-  /* The pointer used to track the true location of the memory used
-     for MAP->LABEL_MAP.  */
-  rtx *real_label_map = 0;
-
-  /* Allow for equivalences of the pseudos we make for virtual fp and ap.  */
-  max_regno = inl_f->emit->x_reg_rtx_no + 3;
-  if (max_regno < FIRST_PSEUDO_REGISTER)
-    abort ();
-
-  /* Pull out the decl for the function definition; fndecl may be a
-     local declaration, which would break DECL_ABSTRACT_ORIGIN.  */
-  fndecl = inl_f->decl;
-
-  nargs = list_length (DECL_ARGUMENTS (fndecl));
-
-  if (cfun->preferred_stack_boundary < inl_f->preferred_stack_boundary)
-    cfun->preferred_stack_boundary = inl_f->preferred_stack_boundary;
-
-  /* Check that the parms type match and that sufficient arguments were
-     passed.  Since the appropriate conversions or default promotions have
-     already been applied, the machine modes should match exactly.  */
-
-  for (formal = DECL_ARGUMENTS (fndecl), actual = parms;
-       formal;
-       formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual))
-    {
-      tree arg;
-      enum machine_mode mode;
-
-      if (actual == 0)
-       return (rtx) (HOST_WIDE_INT) -1;
-
-      arg = TREE_VALUE (actual);
-      mode = TYPE_MODE (DECL_ARG_TYPE (formal));
-
-      if (arg == error_mark_node
-         || mode != TYPE_MODE (TREE_TYPE (arg))
-         /* If they are block mode, the types should match exactly.
-            They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
-            which could happen if the parameter has incomplete type.  */
-         || (mode == BLKmode
-             && (TYPE_MAIN_VARIANT (TREE_TYPE (arg))
-                 != TYPE_MAIN_VARIANT (TREE_TYPE (formal)))))
-       return (rtx) (HOST_WIDE_INT) -1;
-    }
-
-  /* Extra arguments are valid, but will be ignored below, so we must
-     evaluate them here for side-effects.  */
-  for (; actual; actual = TREE_CHAIN (actual))
-    expand_expr (TREE_VALUE (actual), const0_rtx,
-                TYPE_MODE (TREE_TYPE (TREE_VALUE (actual))), 0);
-
-  /* Expand the function arguments.  Do this first so that any
-     new registers get created before we allocate the maps.  */
-
-  arg_vals = (rtx *) xmalloc (nargs * sizeof (rtx));
-  arg_trees = (tree *) xmalloc (nargs * sizeof (tree));
-
-  for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0;
-       formal;
-       formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual), i++)
-    {
-      /* Actual parameter, converted to the type of the argument within the
-        function.  */
-      tree arg = convert (TREE_TYPE (formal), TREE_VALUE (actual));
-      /* Mode of the variable used within the function.  */
-      enum machine_mode mode = TYPE_MODE (TREE_TYPE (formal));
-      int invisiref = 0;
-
-      arg_trees[i] = arg;
-      loc = RTVEC_ELT (arg_vector, i);
-
-      /* If this is an object passed by invisible reference, we copy the
-        object into a stack slot and save its address.  If this will go
-        into memory, we do nothing now.  Otherwise, we just expand the
-        argument.  */
-      if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
-         && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
-       {
-         rtx stack_slot = assign_temp (TREE_TYPE (arg), 1, 1, 1);
-
-         store_expr (arg, stack_slot, 0);
-         arg_vals[i] = XEXP (stack_slot, 0);
-         invisiref = 1;
-       }
-      else if (GET_CODE (loc) != MEM)
-       {
-         if (GET_MODE (loc) != TYPE_MODE (TREE_TYPE (arg)))
-           {
-             int unsignedp = TREE_UNSIGNED (TREE_TYPE (formal));
-             enum machine_mode pmode = TYPE_MODE (TREE_TYPE (formal));
-
-             pmode = promote_mode (TREE_TYPE (formal), pmode,
-                                   &unsignedp, 0);
-
-             if (GET_MODE (loc) != pmode)
-               abort ();
-
-             /* The mode if LOC and ARG can differ if LOC was a variable
-                that had its mode promoted via PROMOTED_MODE.  */
-             arg_vals[i] = convert_modes (pmode,
-                                          TYPE_MODE (TREE_TYPE (arg)),
-                                          expand_expr (arg, NULL_RTX, mode,
-                                                       EXPAND_SUM),
-                                          unsignedp);
-           }
-         else
-           arg_vals[i] = expand_expr (arg, NULL_RTX, mode, EXPAND_SUM);
-       }
-      else
-       arg_vals[i] = 0;
-
-      if (arg_vals[i] != 0
-         && (! TREE_READONLY (formal)
-             /* If the parameter is not read-only, copy our argument through
-                a register.  Also, we cannot use ARG_VALS[I] if it overlaps
-                TARGET in any way.  In the inline function, they will likely
-                be two different pseudos, and `safe_from_p' will make all
-                sorts of smart assumptions about their not conflicting.
-                But if ARG_VALS[I] overlaps TARGET, these assumptions are
-                wrong, so put ARG_VALS[I] into a fresh register.
-                Don't worry about invisible references, since their stack
-                temps will never overlap the target.  */
-             || (target != 0
-                 && ! invisiref
-                 && (GET_CODE (arg_vals[i]) == REG
-                     || GET_CODE (arg_vals[i]) == SUBREG
-                     || GET_CODE (arg_vals[i]) == MEM)
-                 && reg_overlap_mentioned_p (arg_vals[i], target))
-             /* ??? We must always copy a SUBREG into a REG, because it might
-                get substituted into an address, and not all ports correctly
-                handle SUBREGs in addresses.  */
-             || (GET_CODE (arg_vals[i]) == SUBREG)))
-       arg_vals[i] = copy_to_mode_reg (GET_MODE (loc), arg_vals[i]);
-
-      if (arg_vals[i] != 0 && GET_CODE (arg_vals[i]) == REG
-         && POINTER_TYPE_P (TREE_TYPE (formal)))
-       mark_reg_pointer (arg_vals[i],
-                         TYPE_ALIGN (TREE_TYPE (TREE_TYPE (formal))));
-    }
-
-  /* Allocate the structures we use to remap things.  */
-
-  map = (struct inline_remap *) xcalloc (1, sizeof (struct inline_remap));
-  map->fndecl = fndecl;
-
-  VARRAY_TREE_INIT (map->block_map, 10, "block_map");
-  map->reg_map = (rtx *) xcalloc (max_regno, sizeof (rtx));
-
-  /* We used to use alloca here, but the size of what it would try to
-     allocate would occasionally cause it to exceed the stack limit and
-     cause unpredictable core dumps.  */
-  real_label_map
-    = (rtx *) xmalloc ((max_labelno) * sizeof (rtx));
-  map->label_map = real_label_map;
-  map->local_return_label = NULL_RTX;
-
-  inl_max_uid = (inl_f->emit->x_cur_insn_uid + 1);
-  map->insn_map = (rtx *) xcalloc (inl_max_uid, sizeof (rtx));
-  map->min_insnno = 0;
-  map->max_insnno = inl_max_uid;
-
-  map->integrating = 1;
-  map->compare_src = NULL_RTX;
-  map->compare_mode = VOIDmode;
-
-  /* const_equiv_varray maps pseudos in our routine to constants, so
-     it needs to be large enough for all our pseudos.  This is the
-     number we are currently using plus the number in the called
-     routine, plus 15 for each arg, five to compute the virtual frame
-     pointer, and five for the return value.  This should be enough
-     for most cases.  We do not reference entries outside the range of
-     the map.
-
-     ??? These numbers are quite arbitrary and were obtained by
-     experimentation.  At some point, we should try to allocate the
-     table after all the parameters are set up so we an more accurately
-     estimate the number of pseudos we will need.  */
-
-  VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
-                          (max_reg_num ()
-                           + (max_regno - FIRST_PSEUDO_REGISTER)
-                           + 15 * nargs
-                           + 10),
-                          "expand_inline_function");
-  map->const_age = 0;
-
-  /* Record the current insn in case we have to set up pointers to frame
-     and argument memory blocks.  If there are no insns yet, add a dummy
-     insn that can be used as an insertion point.  */
-  map->insns_at_start = get_last_insn ();
-  if (map->insns_at_start == 0)
-    map->insns_at_start = emit_note (NULL, NOTE_INSN_DELETED);
-
-  map->regno_pointer_align = inl_f->emit->regno_pointer_align;
-  map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx;
-
-  /* Update the outgoing argument size to allow for those in the inlined
-     function.  */
-  if (inl_f->outgoing_args_size > current_function_outgoing_args_size)
-    current_function_outgoing_args_size = inl_f->outgoing_args_size;
-
-  /* If the inline function needs to make PIC references, that means
-     that this function's PIC offset table must be used.  */
-  if (inl_f->uses_pic_offset_table)
-    current_function_uses_pic_offset_table = 1;
-
-  /* If this function needs a context, set it up.  */
-  if (inl_f->needs_context)
-    static_chain_value = lookup_static_chain (fndecl);
-
-  if (GET_CODE (parm_insns) == NOTE
-      && NOTE_LINE_NUMBER (parm_insns) > 0)
-    {
-      rtx note = emit_note (NOTE_SOURCE_FILE (parm_insns),
-                           NOTE_LINE_NUMBER (parm_insns));
-      if (note)
-       RTX_INTEGRATED_P (note) = 1;
-    }
-
-  /* Process each argument.  For each, set up things so that the function's
-     reference to the argument will refer to the argument being passed.
-     We only replace REG with REG here.  Any simplifications are done
-     via const_equiv_map.
-
-     We make two passes:  In the first, we deal with parameters that will
-     be placed into registers, since we need to ensure that the allocated
-     register number fits in const_equiv_map.  Then we store all non-register
-     parameters into their memory location.  */
-
-  /* Don't try to free temp stack slots here, because we may put one of the
-     parameters into a temp stack slot.  */
-
-  for (i = 0; i < nargs; i++)
-    {
-      rtx copy = arg_vals[i];
-
-      loc = RTVEC_ELT (arg_vector, i);
-
-      /* There are three cases, each handled separately.  */
-      if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
-         && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
-       {
-         /* This must be an object passed by invisible reference (it could
-            also be a variable-sized object, but we forbid inlining functions
-            with variable-sized arguments).  COPY is the address of the
-            actual value (this computation will cause it to be copied).  We
-            map that address for the register, noting the actual address as
-            an equivalent in case it can be substituted into the insns.  */
-
-         if (GET_CODE (copy) != REG)
-           {
-             temp = copy_addr_to_reg (copy);
-             if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
-               SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
-             copy = temp;
-           }
-         map->reg_map[REGNO (XEXP (loc, 0))] = copy;
-       }
-      else if (GET_CODE (loc) == MEM)
-       {
-         /* This is the case of a parameter that lives in memory.  It
-            will live in the block we allocate in the called routine's
-            frame that simulates the incoming argument area.  Do nothing
-            with the parameter now; we will call store_expr later.  In
-            this case, however, we must ensure that the virtual stack and
-            incoming arg rtx values are expanded now so that we can be
-            sure we have enough slots in the const equiv map since the
-            store_expr call can easily blow the size estimate.  */
-         if (DECL_SAVED_INSNS (fndecl)->args_size != 0)
-           copy_rtx_and_substitute (virtual_incoming_args_rtx, map, 0);
-       }
-      else if (GET_CODE (loc) == REG)
-       process_reg_param (map, loc, copy);
-      else if (GET_CODE (loc) == CONCAT)
-       {
-         rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
-         rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
-         rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
-         rtx copyimag = gen_imagpart (GET_MODE (locimag), copy);
-
-         process_reg_param (map, locreal, copyreal);
-         process_reg_param (map, locimag, copyimag);
-       }
-      else
-       abort ();
-    }
-
-  /* Tell copy_rtx_and_substitute to handle constant pool SYMBOL_REFs
-     specially.  This function can be called recursively, so we need to
-     save the previous value.  */
-  inlining_previous = inlining;
-  inlining = inl_f;
-
-  /* Now do the parameters that will be placed in memory.  */
-
-  for (formal = DECL_ARGUMENTS (fndecl), i = 0;
-       formal; formal = TREE_CHAIN (formal), i++)
-    {
-      loc = RTVEC_ELT (arg_vector, i);
-
-      if (GET_CODE (loc) == MEM
-         /* Exclude case handled above.  */
-         && ! (GET_CODE (XEXP (loc, 0)) == REG
-               && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
-       {
-         rtx note = emit_note (DECL_SOURCE_FILE (formal),
-                               DECL_SOURCE_LINE (formal));
-         if (note)
-           RTX_INTEGRATED_P (note) = 1;
-
-         /* Compute the address in the area we reserved and store the
-            value there.  */
-         temp = copy_rtx_and_substitute (loc, map, 1);
-         subst_constants (&temp, NULL_RTX, map, 1);
-         apply_change_group ();
-         if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
-           temp = change_address (temp, VOIDmode, XEXP (temp, 0));
-         store_expr (arg_trees[i], temp, 0);
-       }
-    }
-
-  /* Deal with the places that the function puts its result.
-     We are driven by what is placed into DECL_RESULT.
-
-     Initially, we assume that we don't have anything special handling for
-     REG_FUNCTION_RETURN_VALUE_P.  */
-
-  map->inline_target = 0;
-  loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl)) 
-        ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
-
-  if (TYPE_MODE (type) == VOIDmode)
-    /* There is no return value to worry about.  */
-    ;
-  else if (GET_CODE (loc) == MEM)
-    {
-      if (GET_CODE (XEXP (loc, 0)) == ADDRESSOF)
-       {
-         temp = copy_rtx_and_substitute (loc, map, 1);
-         subst_constants (&temp, NULL_RTX, map, 1);
-         apply_change_group ();
-         target = temp;
-       }
-      else
-       {
-         if (! structure_value_addr
-             || ! aggregate_value_p (DECL_RESULT (fndecl)))
-           abort ();
-
-         /* Pass the function the address in which to return a structure
-            value.  Note that a constructor can cause someone to call us
-            with STRUCTURE_VALUE_ADDR, but the initialization takes place
-            via the first parameter, rather than the struct return address.
-
-            We have two cases: If the address is a simple register
-            indirect, use the mapping mechanism to point that register to
-            our structure return address.  Otherwise, store the structure
-            return value into the place that it will be referenced from.  */
-
-         if (GET_CODE (XEXP (loc, 0)) == REG)
-           {
-             temp = force_operand (structure_value_addr, NULL_RTX);
-             temp = force_reg (Pmode, temp);
-             /* A virtual register might be invalid in an insn, because
-                it can cause trouble in reload.  Since we don't have access
-                to the expanders at map translation time, make sure we have
-                a proper register now.
-                If a virtual register is actually valid, cse or combine
-                can put it into the mapped insns.  */
-             if (REGNO (temp) >= FIRST_VIRTUAL_REGISTER
-                 && REGNO (temp) <= LAST_VIRTUAL_REGISTER)
-             temp = copy_to_mode_reg (Pmode, temp);
-             map->reg_map[REGNO (XEXP (loc, 0))] = temp;
-
-             if (CONSTANT_P (structure_value_addr)
-                 || GET_CODE (structure_value_addr) == ADDRESSOF
-                 || (GET_CODE (structure_value_addr) == PLUS
-                     && (XEXP (structure_value_addr, 0)
-                         == virtual_stack_vars_rtx)
-                     && (GET_CODE (XEXP (structure_value_addr, 1))
-                         == CONST_INT)))
-               {
-                 SET_CONST_EQUIV_DATA (map, temp, structure_value_addr,
-                                       CONST_AGE_PARM);
-               }
-           }
-         else
-           {
-             temp = copy_rtx_and_substitute (loc, map, 1);
-             subst_constants (&temp, NULL_RTX, map, 0);
-             apply_change_group ();
-             emit_move_insn (temp, structure_value_addr);
-           }
-       }
-    }
-  else if (ignore)
-    /* We will ignore the result value, so don't look at its structure.
-       Note that preparations for an aggregate return value
-       do need to be made (above) even if it will be ignored.  */
-    ;
-  else if (GET_CODE (loc) == REG)
-    {
-      /* The function returns an object in a register and we use the return
-        value.  Set up our target for remapping.  */
-
-      /* Machine mode function was declared to return.  */
-      enum machine_mode departing_mode = TYPE_MODE (type);
-      /* (Possibly wider) machine mode it actually computes
-        (for the sake of callers that fail to declare it right).
-        We have to use the mode of the result's RTL, rather than
-        its type, since expand_function_start may have promoted it.  */
-      enum machine_mode arriving_mode
-       = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-      rtx reg_to_map;
-
-      /* Don't use MEMs as direct targets because on some machines
-        substituting a MEM for a REG makes invalid insns.
-        Let the combiner substitute the MEM if that is valid.  */
-      if (target == 0 || GET_CODE (target) != REG
-         || GET_MODE (target) != departing_mode)
-       {
-         /* Don't make BLKmode registers.  If this looks like
-            a BLKmode object being returned in a register, get
-            the mode from that, otherwise abort.  */
-         if (departing_mode == BLKmode)
-           {
-             if (REG == GET_CODE (DECL_RTL (DECL_RESULT (fndecl))))
-               {
-                 departing_mode = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-                 arriving_mode = departing_mode;
-               }
-             else
-               abort ();
-           }
-
-         target = gen_reg_rtx (departing_mode);
-       }
-
-      /* If function's value was promoted before return,
-        avoid machine mode mismatch when we substitute INLINE_TARGET.
-        But TARGET is what we will return to the caller.  */
-      if (arriving_mode != departing_mode)
-       {
-         /* Avoid creating a paradoxical subreg wider than
-            BITS_PER_WORD, since that is illegal.  */
-         if (GET_MODE_BITSIZE (arriving_mode) > BITS_PER_WORD)
-           {
-             if (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (departing_mode),
-                                         GET_MODE_BITSIZE (arriving_mode)))
-               /* Maybe could be handled by using convert_move () ?  */
-               abort ();
-             reg_to_map = gen_reg_rtx (arriving_mode);
-             target = gen_lowpart (departing_mode, reg_to_map);
-           }
-         else
-           reg_to_map = gen_rtx_SUBREG (arriving_mode, target, 0);
-       }
-      else
-       reg_to_map = target;
-
-      /* Usually, the result value is the machine's return register.
-        Sometimes it may be a pseudo. Handle both cases.  */
-      if (REG_FUNCTION_VALUE_P (loc))
-       map->inline_target = reg_to_map;
-      else
-       map->reg_map[REGNO (loc)] = reg_to_map;
-    }
-  else if (GET_CODE (loc) == CONCAT)
-    {
-      enum machine_mode departing_mode = TYPE_MODE (type);
-      enum machine_mode arriving_mode
-       = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-
-      if (departing_mode != arriving_mode)
-       abort ();
-      if (GET_CODE (XEXP (loc, 0)) != REG
-         || GET_CODE (XEXP (loc, 1)) != REG)
-       abort ();
-
-      /* Don't use MEMs as direct targets because on some machines
-        substituting a MEM for a REG makes invalid insns.
-        Let the combiner substitute the MEM if that is valid.  */
-      if (target == 0 || GET_CODE (target) != REG
-         || GET_MODE (target) != departing_mode)
-       target = gen_reg_rtx (departing_mode);
-
-      if (GET_CODE (target) != CONCAT)
-       abort ();
-
-      map->reg_map[REGNO (XEXP (loc, 0))] = XEXP (target, 0);
-      map->reg_map[REGNO (XEXP (loc, 1))] = XEXP (target, 1);
-    }
-  else
-    abort ();
-
-  /* Remap the exception handler data pointer from one to the other.  */
-  temp = get_exception_pointer (inl_f);
-  if (temp)
-    map->reg_map[REGNO (temp)] = get_exception_pointer (cfun);
-
-  /* Initialize label_map.  get_label_from_map will actually make
-     the labels.  */
-  memset ((char *) &map->label_map[min_labelno], 0,
-        (max_labelno - min_labelno) * sizeof (rtx));
-
-  /* Make copies of the decls of the symbols in the inline function, so that
-     the copies of the variables get declared in the current function.  Set
-     up things so that lookup_static_chain knows that to interpret registers
-     in SAVE_EXPRs for TYPE_SIZEs as local.  */
-  inline_function_decl = fndecl;
-  integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
-  block = integrate_decl_tree (inl_f->original_decl_initial, map);
-  BLOCK_ABSTRACT_ORIGIN (block) = DECL_ORIGIN (fndecl);
-  inline_function_decl = 0;
-
-  /* Make a fresh binding contour that we can easily remove.  Do this after
-     expanding our arguments so cleanups are properly scoped.  */
-  expand_start_bindings_and_block (0, block);
-
-  /* Sort the block-map so that it will be easy to find remapped
-     blocks later.  */
-  qsort (&VARRAY_TREE (map->block_map, 0),
-        map->block_map->elements_used,
-        sizeof (tree),
-        compare_blocks);
-
-  /* Perform postincrements before actually calling the function.  */
-  emit_queue ();
-
-  /* Clean up stack so that variables might have smaller offsets.  */
-  do_pending_stack_adjust ();
-
-  /* Save a copy of the location of const_equiv_varray for
-     mark_stores, called via note_stores.  */
-  global_const_equiv_varray = map->const_equiv_varray;
-
-  /* If the called function does an alloca, save and restore the
-     stack pointer around the call.  This saves stack space, but
-     also is required if this inline is being done between two
-     pushes.  */
-  if (inl_f->calls_alloca)
-    emit_stack_save (SAVE_BLOCK, &stack_save, NULL_RTX);
-
-  /* Map pseudos used for initial hard reg values.  */
-  setup_initial_hard_reg_value_integration (inl_f, map);
-
-  /* Now copy the insns one by one.  */
-  copy_insn_list (insns, map, static_chain_value);
-
-  /* Duplicate the EH regions.  This will create an offset from the
-     region numbers in the function we're inlining to the region
-     numbers in the calling function.  This must wait until after
-     copy_insn_list, as we need the insn map to be complete.  */
-  eh_region_offset = duplicate_eh_regions (inl_f, map);
-
-  /* Now copy the REG_NOTES for those insns.  */
-  copy_insn_notes (insns, map, eh_region_offset);
-
-  /* If the insn sequence required one, emit the return label.  */
-  if (map->local_return_label)
-    emit_label (map->local_return_label);
-
-  /* Restore the stack pointer if we saved it above.  */
-  if (inl_f->calls_alloca)
-    emit_stack_restore (SAVE_BLOCK, stack_save, NULL_RTX);
-
-  if (! cfun->x_whole_function_mode_p)
-    /* In statement-at-a-time mode, we just tell the front-end to add
-       this block to the list of blocks at this binding level.  We
-       can't do it the way it's done for function-at-a-time mode the
-       superblocks have not been created yet.  */
-    insert_block (block);
-  else
-    {
-      BLOCK_CHAIN (block)
-       = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
-      BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) = block;
-    }
-
-  /* End the scope containing the copied formal parameter variables
-     and copied LABEL_DECLs.  We pass NULL_TREE for the variables list
-     here so that expand_end_bindings will not check for unused
-     variables.  That's already been checked for when the inlined
-     function was defined.  */
-  expand_end_bindings (NULL_TREE, 1, 1);
-
-  /* Must mark the line number note after inlined functions as a repeat, so
-     that the test coverage code can avoid counting the call twice.  This
-     just tells the code to ignore the immediately following line note, since
-     there already exists a copy of this note before the expanded inline call.
-     This line number note is still needed for debugging though, so we can't
-     delete it.  */
-  if (flag_test_coverage)
-    emit_note (0, NOTE_INSN_REPEATED_LINE_NUMBER);
-
-  emit_line_note (input_filename, lineno);
-
-  /* If the function returns a BLKmode object in a register, copy it
-     out of the temp register into a BLKmode memory object.  */
-  if (target
-      && TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
-      && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
-    target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
-
-  if (structure_value_addr)
-    {
-      target = gen_rtx_MEM (TYPE_MODE (type),
-                           memory_address (TYPE_MODE (type),
-                                           structure_value_addr));
-      set_mem_attributes (target, type, 1);
-    }
-
-  /* Make sure we free the things we explicitly allocated with xmalloc.  */
-  if (real_label_map)
-    free (real_label_map);
-  VARRAY_FREE (map->const_equiv_varray);
-  free (map->reg_map);
-  VARRAY_FREE (map->block_map);
-  free (map->insn_map);
-  free (map);
-  free (arg_vals);
-  free (arg_trees);
-
-  inlining = inlining_previous;
 
-  return target;
-}
-
-/* Make copies of each insn in the given list using the mapping
-   computed in expand_inline_function. This function may call itself for
-   insns containing sequences.
-
-   Copying is done in two passes, first the insns and then their REG_NOTES.
-
-   If static_chain_value is non-zero, it represents the context-pointer
-   register for the function.  */
-
-static void
-copy_insn_list (insns, map, static_chain_value)
-     rtx insns;
-     struct inline_remap *map;
-     rtx static_chain_value;
-{
-  int i;
-  rtx insn;
-  rtx temp;
-#ifdef HAVE_cc0
-  rtx cc0_insn = 0;
-#endif
-
-  /* Copy the insns one by one.  Do this in two passes, first the insns and
-     then their REG_NOTES.  */
-
-  /* This loop is very similar to the loop in copy_loop_body in unroll.c.  */
-
-  for (insn = insns; insn; insn = NEXT_INSN (insn))
-    {
-      rtx copy, pattern, set;
-
-      map->orig_asm_operands_vector = 0;
-
-      switch (GET_CODE (insn))
-       {
-       case INSN:
-         pattern = PATTERN (insn);
-         set = single_set (insn);
-         copy = 0;
-         if (GET_CODE (pattern) == USE
-             && GET_CODE (XEXP (pattern, 0)) == REG
-             && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
-           /* The (USE (REG n)) at return from the function should
-              be ignored since we are changing (REG n) into
-              inline_target.  */
-           break;
-
-         /* Ignore setting a function value that we don't want to use.  */
-         if (map->inline_target == 0
-             && set != 0
-             && GET_CODE (SET_DEST (set)) == REG
-             && REG_FUNCTION_VALUE_P (SET_DEST (set)))
-           {
-             if (volatile_refs_p (SET_SRC (set)))
-               {
-                 rtx new_set;
-
-                 /* If we must not delete the source,
-                    load it into a new temporary.  */
-                 copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-
-                 new_set = single_set (copy);
-                 if (new_set == 0)
-                   abort ();
-
-                 SET_DEST (new_set)
-                   = gen_reg_rtx (GET_MODE (SET_DEST (new_set)));
-               }
-             /* If the source and destination are the same and it
-                has a note on it, keep the insn.  */
-             else if (rtx_equal_p (SET_DEST (set), SET_SRC (set))
-                      && REG_NOTES (insn) != 0)
-               copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-             else
-               break;
-           }
-
-         /* Similarly if an ignored return value is clobbered.  */
-         else if (map->inline_target == 0
-                  && GET_CODE (pattern) == CLOBBER
-                  && GET_CODE (XEXP (pattern, 0)) == REG
-                  && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
-           break;
-
-         /* If this is setting the static chain rtx, omit it.  */
-         else if (static_chain_value != 0
-                  && set != 0
-                  && GET_CODE (SET_DEST (set)) == REG
-                  && rtx_equal_p (SET_DEST (set),
-                                  static_chain_incoming_rtx))
-           break;
-
-         /* If this is setting the static chain pseudo, set it from
-            the value we want to give it instead.  */
-         else if (static_chain_value != 0
-                  && set != 0
-                  && rtx_equal_p (SET_SRC (set),
-                                  static_chain_incoming_rtx))
-           {
-             rtx newdest = copy_rtx_and_substitute (SET_DEST (set), map, 1);
-
-             copy = emit_move_insn (newdest, static_chain_value);
-             static_chain_value = 0;
-           }
-
-         /* If this is setting the virtual stack vars register, this must
-            be the code at the handler for a builtin longjmp.  The value
-            saved in the setjmp buffer will be the address of the frame
-            we've made for this inlined instance within our frame.  But we
-            know the offset of that value so we can use it to reconstruct
-            our virtual stack vars register from that value.  If we are
-            copying it from the stack pointer, leave it unchanged.  */
-         else if (set != 0
-                  && rtx_equal_p (SET_DEST (set), virtual_stack_vars_rtx))
-           {
-             HOST_WIDE_INT offset;
-             temp = map->reg_map[REGNO (SET_DEST (set))];
-             temp = VARRAY_CONST_EQUIV (map->const_equiv_varray,
-                                        REGNO (temp)).rtx;
-
-             if (rtx_equal_p (temp, virtual_stack_vars_rtx))
-               offset = 0;
-             else if (GET_CODE (temp) == PLUS
-                      && rtx_equal_p (XEXP (temp, 0), virtual_stack_vars_rtx)
-                      && GET_CODE (XEXP (temp, 1)) == CONST_INT)
-               offset = INTVAL (XEXP (temp, 1));
-             else
-               abort ();
-
-             if (rtx_equal_p (SET_SRC (set), stack_pointer_rtx))
-               temp = SET_SRC (set);
-             else
-               temp = force_operand (plus_constant (SET_SRC (set),
-                                                    - offset),
-                                     NULL_RTX);
-
-             copy = emit_move_insn (virtual_stack_vars_rtx, temp);
-           }
-
-         else
-           copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-         /* REG_NOTES will be copied later.  */
-
-#ifdef HAVE_cc0
-         /* If this insn is setting CC0, it may need to look at
-            the insn that uses CC0 to see what type of insn it is.
-            In that case, the call to recog via validate_change will
-            fail.  So don't substitute constants here.  Instead,
-            do it when we emit the following insn.
-
-            For example, see the pyr.md file.  That machine has signed and
-            unsigned compares.  The compare patterns must check the
-            following branch insn to see which what kind of compare to
-            emit.
-
-            If the previous insn set CC0, substitute constants on it as
-            well.  */
-         if (sets_cc0_p (PATTERN (copy)) != 0)
-           cc0_insn = copy;
-         else
-           {
-             if (cc0_insn)
-               try_constants (cc0_insn, map);
-             cc0_insn = 0;
-             try_constants (copy, map);
-           }
-#else
-         try_constants (copy, map);
-#endif
-         break;
-
-       case JUMP_INSN:
-         if (map->integrating && returnjump_p (insn))
-           {
-             if (map->local_return_label == 0)
-               map->local_return_label = gen_label_rtx ();
-             pattern = gen_jump (map->local_return_label);
-           }
-         else
-           pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
-
-         copy = emit_jump_insn (pattern);
-
-#ifdef HAVE_cc0
-         if (cc0_insn)
-           try_constants (cc0_insn, map);
-         cc0_insn = 0;
-#endif
-         try_constants (copy, map);
-
-         /* If this used to be a conditional jump insn but whose branch
-            direction is now know, we must do something special.  */
-         if (any_condjump_p (insn) && onlyjump_p (insn) && map->last_pc_value)
-           {
-#ifdef HAVE_cc0
-             /* If the previous insn set cc0 for us, delete it.  */
-             if (only_sets_cc0_p (PREV_INSN (copy)))
-               delete_related_insns (PREV_INSN (copy));
-#endif
-
-             /* If this is now a no-op, delete it.  */
-             if (map->last_pc_value == pc_rtx)
-               {
-                 delete_related_insns (copy);
-                 copy = 0;
-               }
-             else
-               /* Otherwise, this is unconditional jump so we must put a
-                  BARRIER after it.  We could do some dead code elimination
-                  here, but jump.c will do it just as well.  */
-               emit_barrier ();
-           }
-         break;
-
-       case CALL_INSN:
-         /* If this is a CALL_PLACEHOLDER insn then we need to copy the
-            three attached sequences: normal call, sibling call and tail
-            recursion.  */
-         if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-           {
-             rtx sequence[3];
-             rtx tail_label;
-
-             for (i = 0; i < 3; i++)
-               {
-                 rtx seq;
-
-                 sequence[i] = NULL_RTX;
-                 seq = XEXP (PATTERN (insn), i);
-                 if (seq)
-                   {
-                     start_sequence ();
-                     copy_insn_list (seq, map, static_chain_value);
-                     sequence[i] = get_insns ();
-                     end_sequence ();
-                   }
-               }
-
-             /* Find the new tail recursion label.
-                It will already be substituted into sequence[2].  */
-             tail_label = copy_rtx_and_substitute (XEXP (PATTERN (insn), 3),
-                                                   map, 0);
-
-             copy = emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode,
-                                                              sequence[0],
-                                                              sequence[1],
-                                                              sequence[2],
-                                                              tail_label));
-             break;
-           }
-
-         pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
-         copy = emit_call_insn (pattern);
-
-         SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
-         CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn);
-
-         /* Because the USAGE information potentially contains objects other
-            than hard registers, we need to copy it.  */
-
-         CALL_INSN_FUNCTION_USAGE (copy)
-           = copy_rtx_and_substitute (CALL_INSN_FUNCTION_USAGE (insn),
-                                      map, 0);
-
-#ifdef HAVE_cc0
-         if (cc0_insn)
-           try_constants (cc0_insn, map);
-         cc0_insn = 0;
-#endif
-         try_constants (copy, map);
-
-         /* Be lazy and assume CALL_INSNs clobber all hard registers.  */
-         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-           VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
-         break;
-
-       case CODE_LABEL:
-         copy = emit_label (get_label_from_map (map,
-                                                CODE_LABEL_NUMBER (insn)));
-         LABEL_NAME (copy) = LABEL_NAME (insn);
-         map->const_age++;
-         break;
-
-       case BARRIER:
-         copy = emit_barrier ();
-         break;
-
-       case NOTE:
-         if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)
-           {
-             copy = emit_label (get_label_from_map (map,
-                                                   CODE_LABEL_NUMBER (insn)));
-             LABEL_NAME (copy) = NOTE_SOURCE_FILE (insn);
-             map->const_age++;
-             break;
-           }
-
-         /* NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG are
-            discarded because it is important to have only one of
-            each in the current function.
-
-            NOTE_INSN_DELETED notes aren't useful.  */
-
-         if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
-             && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
-             && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
-           {
-             copy = emit_note (NOTE_SOURCE_FILE (insn),
-                               NOTE_LINE_NUMBER (insn));
-             if (copy
-                 && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
-                     || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
-                 && NOTE_BLOCK (insn))
-               {
-                 tree *mapped_block_p;
-
-                 mapped_block_p
-                   = (tree *) bsearch (NOTE_BLOCK (insn),
-                                       &VARRAY_TREE (map->block_map, 0),
-                                       map->block_map->elements_used,
-                                       sizeof (tree),
-                                       find_block);
-
-                 if (!mapped_block_p)
-                   abort ();
-                 else
-                   NOTE_BLOCK (copy) = *mapped_block_p;
-               }
-             else if (copy
-                      && NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
-               NOTE_EXPECTED_VALUE (copy)
-                 = copy_rtx_and_substitute (NOTE_EXPECTED_VALUE (insn),
-                                            map, 0);
-           }
-         else
-           copy = 0;
-         break;
-
-       default:
-         abort ();
-       }
-
-      if (copy)
-       RTX_INTEGRATED_P (copy) = 1;
-
-      map->insn_map[INSN_UID (insn)] = copy;
-    }
-}
-
-/* Copy the REG_NOTES.  Increment const_age, so that only constants
-   from parameters can be substituted in.  These are the only ones
-   that are valid across the entire function.  */
-
-static void
-copy_insn_notes (insns, map, eh_region_offset)
-     rtx insns;
-     struct inline_remap *map;
-     int eh_region_offset;
-{
-  rtx insn, new_insn;
-
-  map->const_age++;
-  for (insn = insns; insn; insn = NEXT_INSN (insn))
-    {
-      if (! INSN_P (insn))
-       continue;
-
-      new_insn = map->insn_map[INSN_UID (insn)];
-      if (! new_insn)
-       continue;
-
-      if (REG_NOTES (insn))
-        {
-         rtx next, note = copy_rtx_and_substitute (REG_NOTES (insn), map, 0);
-
-         /* We must also do subst_constants, in case one of our parameters
-            has const type and constant value.  */
-         subst_constants (&note, NULL_RTX, map, 0);
-         apply_change_group ();
-         REG_NOTES (new_insn) = note;
-
-         /* Delete any REG_LABEL notes from the chain.  Remap any
-             REG_EH_REGION notes.  */
-         for (; note; note = next)
-           {
-             next = XEXP (note, 1);
-             if (REG_NOTE_KIND (note) == REG_LABEL)
-               remove_note (new_insn, note);
-             else if (REG_NOTE_KIND (note) == REG_EH_REGION)
-               XEXP (note, 0) = GEN_INT (INTVAL (XEXP (note, 0))
-                                         + eh_region_offset);
-           }
-        }
-
-      if (GET_CODE (insn) == CALL_INSN
-         && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-       {
-         int i;
-         for (i = 0; i < 3; i++)
-           copy_insn_notes (XEXP (PATTERN (insn), i), map, eh_region_offset);
-       }
-
-      if (GET_CODE (insn) == JUMP_INSN
-         && GET_CODE (PATTERN (insn)) == RESX)
-       XINT (PATTERN (new_insn), 0) += eh_region_offset;
-    }
-}
-\f
-/* Given a chain of PARM_DECLs, ARGS, copy each decl into a VAR_DECL,
-   push all of those decls and give each one the corresponding home.  */
-
-static void
-integrate_parm_decls (args, map, arg_vector)
-     tree args;
-     struct inline_remap *map;
-     rtvec arg_vector;
-{
-  tree tail;
-  int i;
-
-  for (tail = args, i = 0; tail; tail = TREE_CHAIN (tail), i++)
-    {
-      tree decl = copy_decl_for_inlining (tail, map->fndecl,
-                                         current_function_decl);
-      rtx new_decl_rtl
-       = copy_rtx_and_substitute (RTVEC_ELT (arg_vector, i), map, 1);
-
-      /* We really should be setting DECL_INCOMING_RTL to something reasonable
-        here, but that's going to require some more work.  */
-      /* DECL_INCOMING_RTL (decl) = ?; */
-      /* Fully instantiate the address with the equivalent form so that the
-        debugging information contains the actual register, instead of the
-        virtual register.   Do this by not passing an insn to
-        subst_constants.  */
-      subst_constants (&new_decl_rtl, NULL_RTX, map, 1);
-      apply_change_group ();
-      SET_DECL_RTL (decl, new_decl_rtl);
-    }
-}
-
-/* Given a BLOCK node LET, push decls and levels so as to construct in the
-   current function a tree of contexts isomorphic to the one that is given.
-
-   MAP, if nonzero, is a pointer to an inline_remap map which indicates how
-   registers used in the DECL_RTL field should be remapped.  If it is zero,
-   no mapping is necessary.  */
-
-static tree
-integrate_decl_tree (let, map)
-     tree let;
-     struct inline_remap *map;
-{
-  tree t;
-  tree new_block;
-  tree *next;
-
-  new_block = make_node (BLOCK);
-  VARRAY_PUSH_TREE (map->block_map, new_block);
-  next = &BLOCK_VARS (new_block);
-
-  for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
-    {
-      tree d;
-
-      d = copy_decl_for_inlining (t, map->fndecl, current_function_decl);
-
-      if (DECL_RTL_SET_P (t))
-       {
-         rtx r;
-
-         SET_DECL_RTL (d, copy_rtx_and_substitute (DECL_RTL (t), map, 1));
-
-         /* Fully instantiate the address with the equivalent form so that the
-            debugging information contains the actual register, instead of the
-            virtual register.   Do this by not passing an insn to
-            subst_constants.  */
-         r = DECL_RTL (d);
-         subst_constants (&r, NULL_RTX, map, 1);
-         SET_DECL_RTL (d, r);
-
-         if (GET_CODE (r) == REG)
-           REGNO_DECL (REGNO (r)) = d;
-         else if (GET_CODE (r) == CONCAT)
-           {
-             REGNO_DECL (REGNO (XEXP (r, 0))) = d;
-             REGNO_DECL (REGNO (XEXP (r, 1))) = d;
-           }
-
-         apply_change_group ();
-       }
-
-      /* Add this declaration to the list of variables in the new
-        block.  */
-      *next = d;
-      next = &TREE_CHAIN (d);
-    }
-
-  next = &BLOCK_SUBBLOCKS (new_block);
-  for (t = BLOCK_SUBBLOCKS (let); t; t = BLOCK_CHAIN (t))
-    {
-      *next = integrate_decl_tree (t, map);
-      BLOCK_SUPERCONTEXT (*next) = new_block;
-      next = &BLOCK_CHAIN (*next);
-    }
-
-  TREE_USED (new_block) = TREE_USED (let);
-  BLOCK_ABSTRACT_ORIGIN (new_block) = let;
-
-  return new_block;
-}
-\f
 /* Create a new copy of an rtx. Recursively copies the operands of the rtx,
    except for those few rtx codes that are sharable.
 
@@ -1816,18 +191,13 @@ integrate_decl_tree (let, map)
    rtl is ever emitted.
 
    If FOR_LHS is nonzero, if means we are processing something that will
-   be the LHS of a SET.  In that case, we copy RTX_UNCHANGING_P even if
-   inlining since we need to be conservative in how it is set for
-   such cases.
+   be the LHS of a SET.
 
    Handle constants that need to be placed in the constant pool by
    calling `force_const_mem'.  */
 
 rtx
-copy_rtx_and_substitute (orig, map, for_lhs)
-     rtx orig;
-     struct inline_remap *map;
-     int for_lhs;
+copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
 {
   rtx copy, temp;
   int i, j;
@@ -1850,9 +220,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
         Small hard registers are returned as-is.  Pseudo-registers
         go through their `reg_map'.  */
       regno = REGNO (orig);
-      if (regno <= LAST_VIRTUAL_REGISTER
-         || (map->integrating
-             && DECL_SAVED_INSNS (map->fndecl)->internal_arg_pointer == orig))
+      if (regno <= LAST_VIRTUAL_REGISTER)
        {
          /* Some hard registers are also mapped,
             but others are not translated.  */
@@ -1870,10 +238,11 @@ copy_rtx_and_substitute (orig, map, for_lhs)
          else if (regno == VIRTUAL_STACK_VARS_REGNUM)
            {
              rtx loc, seq;
-             int size = get_func_frame_size (DECL_SAVED_INSNS (map->fndecl));
+             int size
+               = get_func_frame_size (DECL_STRUCT_FUNCTION (map->fndecl));
 #ifdef FRAME_GROWS_DOWNWARD
              int alignment
-               = (DECL_SAVED_INSNS (map->fndecl)->stack_alignment_needed
+               = (DECL_STRUCT_FUNCTION (map->fndecl)->stack_alignment_needed
                   / BITS_PER_UNIT);
 
              /* In this case, virtual_stack_vars_rtx points to one byte
@@ -1901,20 +270,17 @@ copy_rtx_and_substitute (orig, map, for_lhs)
 
              SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
 
-             seq = gen_sequence ();
+             seq = get_insns ();
              end_sequence ();
              emit_insn_after (seq, map->insns_at_start);
              return temp;
            }
-         else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM
-                  || (map->integrating
-                      && (DECL_SAVED_INSNS (map->fndecl)->internal_arg_pointer
-                          == orig)))
+         else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
            {
              /* Do the same for a block to contain any arguments referenced
                 in memory.  */
              rtx loc, seq;
-             int size = DECL_SAVED_INSNS (map->fndecl)->args_size;
+             int size = DECL_STRUCT_FUNCTION (map->fndecl)->args_size;
 
              start_sequence ();
              loc = assign_stack_temp (BLKmode, size, 1);
@@ -1934,51 +300,11 @@ copy_rtx_and_substitute (orig, map, for_lhs)
 
              SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
 
-             seq = gen_sequence ();
+             seq = get_insns ();
              end_sequence ();
              emit_insn_after (seq, map->insns_at_start);
              return temp;
            }
-         else if (REG_FUNCTION_VALUE_P (orig))
-           {
-             /* This is a reference to the function return value.  If
-                the function doesn't have a return value, error.  If the
-                mode doesn't agree, and it ain't BLKmode, make a SUBREG.  */
-             if (map->inline_target == 0)
-               {
-                 if (rtx_equal_function_value_matters)
-                   /* This is an ignored return value.  We must not
-                      leave it in with REG_FUNCTION_VALUE_P set, since
-                      that would confuse subsequent inlining of the
-                      current function into a later function.  */
-                   return gen_rtx_REG (GET_MODE (orig), regno);
-                 else
-                   /* Must be unrolling loops or replicating code if we
-                      reach here, so return the register unchanged.  */
-                   return orig;
-               }
-             else if (GET_MODE (map->inline_target) != BLKmode
-                      && mode != GET_MODE (map->inline_target))
-               return gen_lowpart (mode, map->inline_target);
-             else
-               return map->inline_target;
-           }
-#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
-         /* If leaf_renumber_regs_insn() might remap this register to
-            some other number, make sure we don't share it with the
-            inlined function, otherwise delayed optimization of the
-            inlined function may change it in place, breaking our
-            reference to it.  We may still shared it within the
-            function, so create an entry for this register in the
-            reg_map.  */
-         if (map->integrating && regno < FIRST_PSEUDO_REGISTER
-             && LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
-           {
-             if (!map->leaf_reg_map[regno][mode])
-               map->leaf_reg_map[regno][mode] = gen_rtx_REG (mode, regno);
-             return map->leaf_reg_map[regno][mode]; 
-           }
-#endif
          else
            return orig;
 
@@ -1989,7 +315,6 @@ copy_rtx_and_substitute (orig, map, for_lhs)
          map->reg_map[regno] = gen_reg_rtx (mode);
          REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (orig);
          REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (orig);
-         RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (orig);
          /* A reg with REG_FUNCTION_VALUE_P true will never reach here.  */
 
          if (REG_POINTER (map->x_regno_reg_rtx[regno]))
@@ -2004,36 +329,11 @@ copy_rtx_and_substitute (orig, map, for_lhs)
                                  GET_MODE (SUBREG_REG (orig)),
                                  SUBREG_BYTE (orig));
 
-    case ADDRESSOF:
-      copy = gen_rtx_ADDRESSOF (mode,
-                               copy_rtx_and_substitute (XEXP (orig, 0),
-                                                        map, for_lhs),
-                               0, ADDRESSOF_DECL (orig));
-      regno = ADDRESSOF_REGNO (orig);
-      if (map->reg_map[regno])
-       regno = REGNO (map->reg_map[regno]);
-      else if (regno > LAST_VIRTUAL_REGISTER)
-       {
-         temp = XEXP (orig, 0);
-         map->reg_map[regno] = gen_reg_rtx (GET_MODE (temp));
-         REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (temp);
-         REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (temp);
-         RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (temp);
-         /* A reg with REG_FUNCTION_VALUE_P true will never reach here.  */
-
-         if (REG_POINTER (map->x_regno_reg_rtx[regno]))
-           mark_reg_pointer (map->reg_map[regno],
-                             map->regno_pointer_align[regno]);
-         regno = REGNO (map->reg_map[regno]);
-       }
-      ADDRESSOF_REGNO (copy) = regno;
-      return copy;
-
     case USE:
     case CLOBBER:
       /* USE and CLOBBER are ordinary, but we convert (use (subreg foo))
         to (use foo) if the original insn didn't have a subreg.
-        Removing the subreg distorts the VAX movstrhi pattern
+        Removing the subreg distorts the VAX movmemhi pattern
         by changing the mode of an operand.  */
       copy = copy_rtx_and_substitute (XEXP (orig, 0), map, code == CLOBBER);
       if (GET_CODE (copy) == SUBREG && GET_CODE (XEXP (orig, 0)) != SUBREG)
@@ -2046,7 +346,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
       if (NOTE_LINE_NUMBER (orig) != NOTE_INSN_DELETED_LABEL)
        break;
 
-      /* ... FALLTHRU ...  */
+      /* Fall through.  */
     case CODE_LABEL:
       LABEL_PRESERVE_P (get_label_from_map (map, CODE_LABEL_NUMBER (orig)))
        = LABEL_PRESERVE_P (orig);
@@ -2069,18 +369,12 @@ copy_rtx_and_substitute (orig, map, for_lhs)
           && ! (CODE_LABEL_NUMBER (XEXP (copy, 0)) >= get_first_label_num ()
                 && CODE_LABEL_NUMBER (XEXP (copy, 0)) < max_label_num ()));
 
-      /* If we have made a nonlocal label local, it means that this
-        inlined call will be referring to our nonlocal goto handler.
-        So make sure we create one for this block; we normally would
-        not since this is not otherwise considered a "call".  */
-      if (LABEL_REF_NONLOCAL_P (orig) && ! LABEL_REF_NONLOCAL_P (copy))
-       function_call_count++;
-
       return copy;
 
     case PC:
     case CC0:
     case CONST_INT:
+    case CONST_VECTOR:
       return orig;
 
     case SYMBOL_REF:
@@ -2089,46 +383,14 @@ copy_rtx_and_substitute (orig, map, for_lhs)
         remapped label.  Otherwise, symbols are returned unchanged.  */
       if (CONSTANT_POOL_ADDRESS_P (orig))
        {
-         struct function *f = inlining ? inlining : cfun;
+         struct function *f = cfun;
          rtx constant = get_pool_constant_for_function (f, orig);
-         enum machine_mode const_mode = get_pool_mode_for_function (f, orig);
-         if (inlining)
-           {
-             rtx temp = force_const_mem (const_mode,
-                                         copy_rtx_and_substitute (constant,
-                                                                  map, 0));
-
-#if 0
-             /* Legitimizing the address here is incorrect.
-
-                Since we had a SYMBOL_REF before, we can assume it is valid
-                to have one in this position in the insn.
-
-                Also, change_address may create new registers.  These
-                registers will not have valid reg_map entries.  This can
-                cause try_constants() to fail because assumes that all
-                registers in the rtx have valid reg_map entries, and it may
-                end up replacing one of these new registers with junk.  */
-
-             if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
-               temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));
-#endif
-
-             temp = XEXP (temp, 0);
-
-#ifdef POINTERS_EXTEND_UNSIGNED
-             if (GET_MODE (temp) != GET_MODE (orig))
-               temp = convert_memory_address (GET_MODE (orig), temp);
-#endif
-             return temp;
-           }
-         else if (GET_CODE (constant) == LABEL_REF)
+         if (GET_CODE (constant) == LABEL_REF)
            return XEXP (force_const_mem
                         (GET_MODE (orig),
                          copy_rtx_and_substitute (constant, map, for_lhs)),
                         0);
        }
-
       return orig;
 
     case CONST_DOUBLE:
@@ -2147,10 +409,6 @@ copy_rtx_and_substitute (orig, map, for_lhs)
                                   CONST_DOUBLE_HIGH (orig), VOIDmode);
 
     case CONST:
-      /* Make new constant pool entry for a constant
-        that was in the pool of the inline function.  */
-      if (RTX_INTEGRATED_P (orig))
-       abort ();
       break;
 
     case ASM_OPERANDS:
@@ -2161,7 +419,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
       if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))
        {
          copy = rtx_alloc (ASM_OPERANDS);
-         copy->volatil = orig->volatil;
+         RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
          PUT_MODE (copy, GET_MODE (orig));
          ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig);
          ASM_OPERANDS_OUTPUT_CONSTRAINT (copy)
@@ -2170,8 +428,13 @@ copy_rtx_and_substitute (orig, map, for_lhs)
          ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector;
          ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy)
            = map->copy_asm_constraints_vector;
+#ifdef USE_MAPPED_LOCATION
+         ASM_OPERANDS_SOURCE_LOCATION (copy)
+           = ASM_OPERANDS_SOURCE_LOCATION (orig);
+#else
          ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig);
          ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);
+#endif
          return copy;
        }
       break;
@@ -2190,16 +453,17 @@ copy_rtx_and_substitute (orig, map, for_lhs)
                           copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0),
                                                    map, 0));
 
-         MEM_COPY_ATTRIBUTES (copy, orig);
+         MEM_COPY_ATTRIBUTES (copy, XEXP (orig, 0));
 
          return
-           gen_rtx_CALL (GET_MODE (orig), copy, 
+           gen_rtx_CALL (GET_MODE (orig), copy,
                          copy_rtx_and_substitute (XEXP (orig, 1), map, 0));
        }
       break;
 
 #if 0
-      /* Must be ifdefed out for loop unrolling to work.  */
+    /* Must be ifdefed out for loop unrolling to work.  */
+    /* ??? Is this for the old or the new unroller?  */
     case RETURN:
       abort ();
 #endif
@@ -2222,7 +486,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
          equiv_loc = VARRAY_CONST_EQUIV (map->const_equiv_varray,
                                          REGNO (equiv_reg)).rtx;
          loc_offset
-           = GET_CODE (equiv_loc) == REG ? 0 : INTVAL (XEXP (equiv_loc, 1));
+           = REG_P (equiv_loc) ? 0 : INTVAL (XEXP (equiv_loc, 1));
 
          return gen_rtx_SET (VOIDmode, SET_DEST (orig),
                              force_operand
@@ -2239,32 +503,8 @@ copy_rtx_and_substitute (orig, map, for_lhs)
       break;
 
     case MEM:
-      if (inlining
-         && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
-         && CONSTANT_POOL_ADDRESS_P (XEXP (orig, 0)))
-       {
-         enum machine_mode const_mode
-           = get_pool_mode_for_function (inlining, XEXP (orig, 0));
-         rtx constant
-           = get_pool_constant_for_function (inlining, XEXP (orig, 0));
-
-         constant = copy_rtx_and_substitute (constant, map, 0);
-
-         /* If this was an address of a constant pool entry that itself
-            had to be placed in the constant pool, it might not be a
-            valid address.  So the recursive call might have turned it
-            into a register.  In that case, it isn't a constant any
-            more, so return it.  This has the potential of changing a
-            MEM into a REG, but we'll assume that it safe.  */
-         if (! CONSTANT_P (constant))
-           return constant;
-
-         return validize_mem (force_const_mem (const_mode, constant));
-       }
-
-      copy = rtx_alloc (MEM);
-      PUT_MODE (copy, mode);
-      XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (orig, 0), map, 0);
+      copy = gen_rtx_MEM (mode, copy_rtx_and_substitute (XEXP (orig, 0),
+                                                        map, 0));
       MEM_COPY_ATTRIBUTES (copy, orig);
       return copy;
 
@@ -2274,9 +514,9 @@ copy_rtx_and_substitute (orig, map, for_lhs)
 
   copy = rtx_alloc (code);
   PUT_MODE (copy, mode);
-  copy->in_struct = orig->in_struct;
-  copy->volatil = orig->volatil;
-  copy->unchanging = orig->unchanging;
+  RTX_FLAG (copy, in_struct) = RTX_FLAG (orig, in_struct);
+  RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
+  RTX_FLAG (copy, unchanging) = RTX_FLAG (orig, unchanging);
 
   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
 
@@ -2285,8 +525,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
       switch (*format_ptr++)
        {
        case '0':
-         /* Copy this through the wide int field; that's safest.  */
-         X0WINT (copy, i) = X0WINT (orig, i);
+         X0ANY (copy, i) = X0ANY (orig, i);
          break;
 
        case 'e':
@@ -2347,9 +586,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
 /* Substitute known constant values into INSN, if that is valid.  */
 
 void
-try_constants (insn, map)
-     rtx insn;
-     struct inline_remap *map;
+try_constants (rtx insn, struct inline_remap *map)
 {
   int i;
 
@@ -2364,6 +601,14 @@ try_constants (insn, map)
   subst_constants (&PATTERN (insn), insn, map, 0);
   apply_change_group ();
 
+  /* Enforce consistency between the addresses in the regular insn flow
+     and the ones in CALL_INSN_FUNCTION_USAGE lists, if any.  */
+  if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
+    {
+      subst_constants (&CALL_INSN_FUNCTION_USAGE (insn), insn, map, 1);
+      apply_change_group ();
+    }
+
   /* Show we don't know the value of anything stored or clobbered.  */
   note_stores (PATTERN (insn), mark_stores, NULL);
   map->last_pc_value = 0;
@@ -2374,7 +619,7 @@ try_constants (insn, map)
   /* Set up any constant equivalences made in this insn.  */
   for (i = 0; i < map->num_sets; i++)
     {
-      if (GET_CODE (map->equiv_sets[i].dest) == REG)
+      if (REG_P (map->equiv_sets[i].dest))
        {
          int regno = REGNO (map->equiv_sets[i].dest);
 
@@ -2413,11 +658,7 @@ try_constants (insn, map)
    If MEMONLY is nonzero, only make changes inside a MEM.  */
 
 static void
-subst_constants (loc, insn, map, memonly)
-     rtx *loc;
-     rtx insn;
-     struct inline_remap *map;
-     int memonly;
+subst_constants (rtx *loc, rtx insn, struct inline_remap *map, int memonly)
 {
   rtx x = *loc;
   int i, j;
@@ -2434,6 +675,7 @@ subst_constants (loc, insn, map, memonly)
     case PC:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CONST:
     case LABEL_REF:
@@ -2451,7 +693,7 @@ subst_constants (loc, insn, map, memonly)
     case CLOBBER:
       /* The only thing we can do with a USE or CLOBBER is possibly do
         some substitutions in a MEM within it.  */
-      if (GET_CODE (XEXP (x, 0)) == MEM)
+      if (MEM_P (XEXP (x, 0)))
        subst_constants (&XEXP (XEXP (x, 0), 0), insn, map, 0);
       return;
 
@@ -2478,7 +720,7 @@ subst_constants (loc, insn, map, memonly)
         be a special hack and we don't know how to treat it specially.
         Consider for example mulsidi3 in m68k.md.
         Ordinary SUBREG of a REG needs this special treatment.  */
-      if (! memonly && GET_CODE (SUBREG_REG (x)) == REG)
+      if (! memonly && REG_P (SUBREG_REG (x)))
        {
          rtx inner = SUBREG_REG (x);
          rtx new = 0;
@@ -2490,7 +732,7 @@ subst_constants (loc, insn, map, memonly)
             integral mode and extracting the low part.  */
          subst_constants (&inner, NULL_RTX, map, 0);
          new = simplify_gen_subreg (GET_MODE (x), inner,
-                                    GET_MODE (SUBREG_REG (x)),
+                                    GET_MODE (SUBREG_REG (x)),
                                     SUBREG_BYTE (x));
 
          if (new)
@@ -2528,10 +770,7 @@ subst_constants (loc, insn, map, memonly)
          {
            src = SET_SRC (x);
            if (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
-#ifdef HAVE_cc0
-               || dest == cc0_rtx
-#endif
-               )
+               || CC0_P (dest))
              {
                compare_mode = GET_MODE (XEXP (src, 0));
                if (compare_mode == VOIDmode)
@@ -2555,7 +794,7 @@ subst_constants (loc, insn, map, memonly)
          }
 
        /* Do substitute in the address of a destination in memory.  */
-       if (GET_CODE (*dest_loc) == MEM)
+       if (MEM_P (*dest_loc))
          subst_constants (&XEXP (*dest_loc, 0), insn, map, 0);
 
        /* Check for the case of DEST a SUBREG, both it and the underlying
@@ -2574,18 +813,16 @@ subst_constants (loc, insn, map, memonly)
        /* If storing a recognizable value save it for later recording.  */
        if ((map->num_sets < MAX_RECOG_OPERANDS)
            && (CONSTANT_P (src)
-               || (GET_CODE (src) == REG
+               || (REG_P (src)
                    && (REGNO (src) == VIRTUAL_INCOMING_ARGS_REGNUM
                        || REGNO (src) == VIRTUAL_STACK_VARS_REGNUM))
                || (GET_CODE (src) == PLUS
-                   && GET_CODE (XEXP (src, 0)) == REG
+                   && REG_P (XEXP (src, 0))
                    && (REGNO (XEXP (src, 0)) == VIRTUAL_INCOMING_ARGS_REGNUM
                        || REGNO (XEXP (src, 0)) == VIRTUAL_STACK_VARS_REGNUM)
                    && CONSTANT_P (XEXP (src, 1)))
                || GET_CODE (src) == COMPARE
-#ifdef HAVE_cc0
-               || dest == cc0_rtx
-#endif
+               || CC0_P (dest)
                || (dest == pc_rtx
                    && (src == pc_rtx || GET_CODE (src) == RETURN
                        || GET_CODE (src) == LABEL_REF))))
@@ -2599,10 +836,7 @@ subst_constants (loc, insn, map, memonly)
            if (compare_mode != VOIDmode
                && GET_CODE (src) == COMPARE
                && (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
-#ifdef HAVE_cc0
-                   || dest == cc0_rtx
-#endif
-                   )
+                   || CC0_P (dest))
                && GET_MODE (XEXP (src, 0)) == VOIDmode
                && GET_MODE (XEXP (src, 1)) == VOIDmode)
              {
@@ -2641,6 +875,7 @@ subst_constants (loc, insn, map, memonly)
        case 'w':
        case 'n':
        case 't':
+       case 'B':
          break;
 
        case 'E':
@@ -2658,7 +893,8 @@ subst_constants (loc, insn, map, memonly)
   /* If this is a commutative operation, move a constant to the second
      operand unless the second operand is already a CONST_INT.  */
   if (! memonly
-      && (GET_RTX_CLASS (code) == 'c' || code == NE || code == EQ)
+      && (GET_RTX_CLASS (code) == RTX_COMM_ARITH
+         || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
       && CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
     {
       rtx tem = XEXP (x, 0);
@@ -2670,45 +906,34 @@ subst_constants (loc, insn, map, memonly)
   if (! memonly)
     switch (GET_RTX_CLASS (code))
       {
-      case '1':
+      case RTX_UNARY:
        if (op0_mode == MAX_MACHINE_MODE)
          abort ();
        new = simplify_unary_operation (code, GET_MODE (x),
                                        XEXP (x, 0), op0_mode);
        break;
 
-      case '<':
+      case RTX_COMPARE:
+      case RTX_COMM_COMPARE:
        {
          enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
 
          if (op_mode == VOIDmode)
            op_mode = GET_MODE (XEXP (x, 1));
-         new = simplify_relational_operation (code, op_mode,
+
+         new = simplify_relational_operation (code, GET_MODE (x), op_mode,
                                               XEXP (x, 0), XEXP (x, 1));
-#ifdef FLOAT_STORE_FLAG_VALUE
-         if (new != 0 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
-           {
-             enum machine_mode mode = GET_MODE (x);
-             if (new == const0_rtx)
-               new = CONST0_RTX (mode);
-             else
-               {
-                 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
-                 new = CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
-               }
-           }
-#endif
          break;
        }
 
-      case '2':
-      case 'c':
+      case RTX_BIN_ARITH:
+      case RTX_COMM_ARITH:
        new = simplify_binary_operation (code, GET_MODE (x),
                                         XEXP (x, 0), XEXP (x, 1));
        break;
 
-      case 'b':
-      case '3':
+      case RTX_BITFIELD_OPS:
+      case RTX_TERNARY:
        if (op0_mode == MAX_MACHINE_MODE)
          abort ();
 
@@ -2716,7 +941,7 @@ subst_constants (loc, insn, map, memonly)
          {
            rtx op0 = XEXP (x, 0);
 
-           if (GET_RTX_CLASS (GET_CODE (op0)) == '<'
+           if (COMPARISON_P (op0)
                && GET_MODE (op0) == VOIDmode
                && ! side_effects_p (op0)
                && XEXP (op0, 0) == map->compare_src
@@ -2724,15 +949,18 @@ subst_constants (loc, insn, map, memonly)
              {
                /* We have compare of two VOIDmode constants for which
                   we recorded the comparison mode.  */
-               rtx temp =
-                 simplify_relational_operation (GET_CODE (op0),
-                                                map->compare_mode,
-                                                XEXP (op0, 0),
-                                                XEXP (op0, 1));
-
-               if (temp == const0_rtx)
+               rtx tem =
+                 simplify_gen_relational (GET_CODE (op0), GET_MODE (op0),
+                                          map->compare_mode, XEXP (op0, 0),
+                                          XEXP (op0, 1));
+
+               if (GET_CODE (tem) != CONST_INT)
+                 new = simplify_ternary_operation (code, GET_MODE (x),
+                                                   op0_mode, tem, XEXP (x, 1),
+                                                   XEXP (x, 2));
+               else if (tem == const0_rtx)
                  new = XEXP (x, 2);
-               else if (temp == const1_rtx)
+               else
                  new = XEXP (x, 1);
              }
          }
@@ -2741,6 +969,9 @@ subst_constants (loc, insn, map, memonly)
                                            XEXP (x, 0), XEXP (x, 1),
                                            XEXP (x, 2));
        break;
+
+      default:
+       break;
       }
 
   if (new)
@@ -2751,10 +982,7 @@ subst_constants (loc, insn, map, memonly)
    called from note_stores with parts of the new insn.  */
 
 static void
-mark_stores (dest, x, data)
-     rtx dest;
-     rtx x ATTRIBUTE_UNUSED;
-     void *data ATTRIBUTE_UNUSED;
+mark_stores (rtx dest, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
 {
   int regno = -1;
   enum machine_mode mode = VOIDmode;
@@ -2762,9 +990,9 @@ mark_stores (dest, x, data)
   /* DEST is always the innermost thing set, except in the case of
      SUBREGs of hard registers.  */
 
-  if (GET_CODE (dest) == REG)
+  if (REG_P (dest))
     regno = REGNO (dest), mode = GET_MODE (dest);
-  else if (GET_CODE (dest) == SUBREG && GET_CODE (SUBREG_REG (dest)) == REG)
+  else if (GET_CODE (dest) == SUBREG && REG_P (SUBREG_REG (dest)))
     {
       regno = REGNO (SUBREG_REG (dest));
       if (regno < FIRST_PSEUDO_REGISTER)
@@ -2779,7 +1007,7 @@ mark_stores (dest, x, data)
     {
       unsigned int uregno = regno;
       unsigned int last_reg = (uregno >= FIRST_PSEUDO_REGISTER ? uregno
-                              : uregno + HARD_REGNO_NREGS (uregno, mode) - 1);
+                              : uregno + hard_regno_nregs[uregno][mode] - 1);
       unsigned int i;
 
       /* Ignore virtual stack var or virtual arg register since those
@@ -2803,8 +1031,7 @@ mark_stores (dest, x, data)
    values to point to themselves.  */
 
 static void
-set_block_origin_self (stmt)
-     tree stmt;
+set_block_origin_self (tree stmt)
 {
   if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE)
     {
@@ -2842,8 +1069,7 @@ set_block_origin_self (stmt)
    point to themselves.  */
 
 void
-set_decl_origin_self (decl)
-     tree decl;
+set_decl_origin_self (tree decl)
 {
   if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE)
     {
@@ -2867,9 +1093,7 @@ set_decl_origin_self (decl)
    (recursively) which are contained therein.  */
 
 static void
-set_block_abstract_flags (stmt, setting)
-     tree stmt;
-     int setting;
+set_block_abstract_flags (tree stmt, int setting)
 {
   tree local_decl;
   tree subblock;
@@ -2894,9 +1118,7 @@ set_block_abstract_flags (stmt, setting)
    blocks and sub-blocks (recursively) to the same setting.  */
 
 void
-set_decl_abstract_flags (decl, setting)
-     tree decl;
-     int setting;
+set_decl_abstract_flags (tree decl, int setting)
 {
   DECL_ABSTRACT (decl) = setting;
   if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -2911,59 +1133,27 @@ set_decl_abstract_flags (decl, setting)
     }
 }
 \f
-/* Output the assembly language code for the function FNDECL
-   from its DECL_SAVED_INSNS.  Used for inline functions that are output
-   at end of compilation instead of where they came in the source.  */
+/* Functions to keep track of the values hard regs had at the start of
+   the function.  */
 
-void
-output_inline_function (fndecl)
-     tree fndecl;
+rtx
+get_hard_reg_initial_reg (struct function *fun, rtx reg)
 {
-  struct function *old_cfun = cfun;
-  enum debug_info_type old_write_symbols = write_symbols;
-  struct gcc_debug_hooks *old_debug_hooks = debug_hooks;
-  struct function *f = DECL_SAVED_INSNS (fndecl);
-
-  cfun = f;
-  current_function_decl = fndecl;
-  clear_emit_caches ();
-
-  set_new_last_label_num (f->inl_max_label_num);
-
-  /* We're not deferring this any longer.  */
-  DECL_DEFER_OUTPUT (fndecl) = 0;
-
-  /* If requested, suppress debugging information.  */
-  if (f->no_debugging_symbols)
-    {
-      write_symbols = NO_DEBUG;
-      debug_hooks = &do_nothing_debug_hooks;
-    }
+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
+  int i;
 
-  /* Do any preparation, such as emitting abstract debug info for the inline
-     before it gets mangled by optimization.  */
-  (*debug_hooks->outlining_inline_function) (fndecl);
+  if (ivs == 0)
+    return NULL_RTX;
 
-  /* Compile this function all the way down to assembly code.  As a
-     side effect this destroys the saved RTL representation, but
-     that's okay, because we don't need to inline this anymore.  */
-  rest_of_compilation (fndecl);
-  DECL_INLINE (fndecl) = 0;
+  for (i = 0; i < ivs->num_entries; i++)
+    if (rtx_equal_p (ivs->entries[i].pseudo, reg))
+      return ivs->entries[i].hard_reg;
 
-  cfun = old_cfun;
-  current_function_decl = old_cfun ? old_cfun->decl : 0;
-  write_symbols = old_write_symbols;
-  debug_hooks = old_debug_hooks;
+  return NULL_RTX;
 }
 
-\f
-/* Functions to keep track of the values hard regs had at the start of
-   the function.  */
-
 rtx
-has_func_hard_reg_initial_val (fun, reg)
-     struct function *fun;
-     rtx reg;
+has_func_hard_reg_initial_val (struct function *fun, rtx reg)
 {
   struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
   int i;
@@ -2979,9 +1169,7 @@ has_func_hard_reg_initial_val (fun, reg)
 }
 
 rtx
-get_func_hard_reg_initial_val (fun, reg)
-     struct function *fun;
-     rtx reg;
+get_func_hard_reg_initial_val (struct function *fun, rtx reg)
 {
   struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
   rtx rv = has_func_hard_reg_initial_val (fun, reg);
@@ -2991,20 +1179,19 @@ get_func_hard_reg_initial_val (fun, reg)
 
   if (ivs == 0)
     {
-      fun->hard_reg_initial_vals = (void *) xmalloc (sizeof (initial_value_struct));
+      fun->hard_reg_initial_vals = ggc_alloc (sizeof (initial_value_struct));
       ivs = fun->hard_reg_initial_vals;
       ivs->num_entries = 0;
       ivs->max_entries = 5;
-      ivs->entries = (initial_value_pair *) xmalloc (5 * sizeof (initial_value_pair));
+      ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair));
     }
 
   if (ivs->num_entries >= ivs->max_entries)
     {
       ivs->max_entries += 5;
-      ivs->entries = 
-       (initial_value_pair *) xrealloc (ivs->entries,
-                                        ivs->max_entries
-                                        * sizeof (initial_value_pair));
+      ivs->entries = ggc_realloc (ivs->entries,
+                                 ivs->max_entries
+                                 * sizeof (initial_value_pair));
     }
 
   ivs->entries[ivs->num_entries].hard_reg = reg;
@@ -3014,57 +1201,19 @@ get_func_hard_reg_initial_val (fun, reg)
 }
 
 rtx
-get_hard_reg_initial_val (mode, regno)
-     enum machine_mode mode;
-     int regno;
+get_hard_reg_initial_val (enum machine_mode mode, int regno)
 {
   return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
 }
 
 rtx
-has_hard_reg_initial_val (mode, regno)
-     enum machine_mode mode;
-     int regno;
+has_hard_reg_initial_val (enum machine_mode mode, int regno)
 {
   return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
 }
 
 void
-mark_hard_reg_initial_vals (fun)
-     struct function *fun;
-{
-  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-  int i;
-
-  if (ivs == 0)
-    return;
-
-  for (i = 0; i < ivs->num_entries; i ++)
-    {
-      ggc_mark_rtx (ivs->entries[i].hard_reg);
-      ggc_mark_rtx (ivs->entries[i].pseudo);
-    }
-}
-
-static void
-setup_initial_hard_reg_value_integration (inl_f, remap)
-     struct function *inl_f;
-     struct inline_remap *remap;
-{
-  struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals;
-  int i;
-
-  if (ivs == 0)
-    return;
-
-  for (i = 0; i < ivs->num_entries; i ++)
-    remap->reg_map[REGNO (ivs->entries[i].pseudo)]
-      = get_func_hard_reg_initial_val (cfun, ivs->entries[i].hard_reg);
-}
-
-
-void
-emit_initial_value_sets ()
+emit_initial_value_sets (void)
 {
   struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
   int i;
@@ -3079,14 +1228,13 @@ emit_initial_value_sets ()
   seq = get_insns ();
   end_sequence ();
 
-  emit_insns_after (seq, get_insns ());
+  emit_insn_after (seq, entry_of_function ());
 }
 
 /* If the backend knows where to allocate pseudos for hard
    register initial values, register these allocations now.  */
 void
-allocate_initial_values (reg_equiv_memory_loc)
-     rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED;
+allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED)
 {
 #ifdef ALLOCATE_INITIAL_VALUE
   struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
@@ -3102,9 +1250,9 @@ allocate_initial_values (reg_equiv_memory_loc)
 
       if (x == NULL_RTX || REG_N_SETS (REGNO (ivs->entries[i].pseudo)) > 1)
        ; /* Do nothing.  */
-      else if (GET_CODE (x) == MEM)
+      else if (MEM_P (x))
        reg_equiv_memory_loc[regno] = x;
-      else if (GET_CODE (x) == REG)
+      else if (REG_P (x))
        {
          reg_renumber[regno] = REGNO (x);
          /* Poke the regno right into regno_reg_rtx
@@ -3115,3 +1263,5 @@ allocate_initial_values (reg_equiv_memory_loc)
     }
 #endif
 }
+
+#include "gt-integrate.h"