OSDN Git Service

2005-06-01 Daniel Berlin <dberlin@dberlin.org>
[pf3gnuchains/gcc-fork.git] / gcc / integrate.c
index 22a7c40..0f5cfcf 100644 (file)
@@ -1,6 +1,6 @@
 /* Procedure integration for GCC.
    Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -50,7 +50,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define CEIL_ROUND(VALUE,ALIGN)        (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
 \f
 
-/* Private type used by {get/has}_func_hard_reg_initial_val.  */
+/* Private type used by {get/has}_hard_reg_initial_val.  */
 typedef struct initial_value_pair GTY(()) {
   rtx hard_reg;
   rtx pseudo;
@@ -121,6 +121,7 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
       if (TREE_CODE (copy) == LABEL_DECL)
        {
          TREE_ADDRESSABLE (copy) = 0;
+          LABEL_DECL_UID (copy) = -1;
        }
     }
 
@@ -293,38 +294,27 @@ get_hard_reg_initial_reg (struct function *fun, rtx reg)
   return NULL_RTX;
 }
 
-static rtx
-has_func_hard_reg_initial_val (struct function *fun, rtx reg)
-{
-  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-  int i;
-
-  if (ivs == 0)
-    return NULL_RTX;
-
-  for (i = 0; i < ivs->num_entries; i++)
-    if (rtx_equal_p (ivs->entries[i].hard_reg, reg))
-      return ivs->entries[i].pseudo;
-
-  return NULL_RTX;
-}
+/* Make sure that there's a pseudo register of mode MODE that stores the
+   initial value of hard register REGNO.  Return an rtx for such a pseudo.  */
 
-static rtx
-get_func_hard_reg_initial_val (struct function *fun, rtx reg)
+rtx
+get_hard_reg_initial_val (enum machine_mode mode, unsigned int regno)
 {
-  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-  rtx rv = has_func_hard_reg_initial_val (fun, reg);
+  struct initial_value_struct *ivs;
+  rtx rv;
 
+  rv = has_hard_reg_initial_val (mode, regno);
   if (rv)
     return rv;
 
+  ivs = cfun->hard_reg_initial_vals;
   if (ivs == 0)
     {
-      fun->hard_reg_initial_vals = ggc_alloc (sizeof (initial_value_struct));
-      ivs = fun->hard_reg_initial_vals;
+      ivs = ggc_alloc (sizeof (initial_value_struct));
       ivs->num_entries = 0;
       ivs->max_entries = 5;
       ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair));
+      cfun->hard_reg_initial_vals = ivs;
     }
 
   if (ivs->num_entries >= ivs->max_entries)
@@ -335,22 +325,30 @@ get_func_hard_reg_initial_val (struct function *fun, rtx reg)
                                  * sizeof (initial_value_pair));
     }
 
-  ivs->entries[ivs->num_entries].hard_reg = reg;
-  ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (GET_MODE (reg));
+  ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno);
+  ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (mode);
 
   return ivs->entries[ivs->num_entries++].pseudo;
 }
 
-rtx
-get_hard_reg_initial_val (enum machine_mode mode, int regno)
-{
-  return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
-}
+/* See if get_hard_reg_initial_val has been used to create a pseudo
+   for the initial value of hard register REGNO in mode MODE.  Return
+   the associated pseudo if so, otherwise return NULL.  */
 
 rtx
-has_hard_reg_initial_val (enum machine_mode mode, int regno)
+has_hard_reg_initial_val (enum machine_mode mode, unsigned int regno)
 {
-  return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
+  struct initial_value_struct *ivs;
+  int i;
+
+  ivs = cfun->hard_reg_initial_vals;
+  if (ivs != 0)
+    for (i = 0; i < ivs->num_entries; i++)
+      if (GET_MODE (ivs->entries[i].hard_reg) == mode
+         && REGNO (ivs->entries[i].hard_reg) == regno)
+       return ivs->entries[i].pseudo;
+
+  return NULL_RTX;
 }
 
 void
@@ -395,11 +393,23 @@ allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED)
            reg_equiv_memory_loc[regno] = x;
          else
            {
+             basic_block bb;
+             int new_regno;
+
              gcc_assert (REG_P (x));
-             reg_renumber[regno] = REGNO (x);
+             new_regno = REGNO (x);
+             reg_renumber[regno] = new_regno;
              /* Poke the regno right into regno_reg_rtx so that even
                 fixed regs are accepted.  */
-             REGNO (ivs->entries[i].pseudo) = REGNO (x);
+             REGNO (ivs->entries[i].pseudo) = new_regno;
+             /* Update global register liveness information.  */
+             FOR_EACH_BB (bb)
+               {
+                 if (REGNO_REG_SET_P(bb->global_live_at_start, regno))
+                   SET_REGNO_REG_SET (bb->global_live_at_start, new_regno);
+                 if (REGNO_REG_SET_P(bb->global_live_at_end, regno))
+                   SET_REGNO_REG_SET (bb->global_live_at_end, new_regno);
+               }
            }
        }
     }