OSDN Git Service

2010-04-30 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / reginfo.c
index 9842dc1..4cfcf84 100644 (file)
@@ -43,7 +43,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-config.h"
 #include "recog.h"
 #include "reload.h"
-#include "real.h"
 #include "toplev.h"
 #include "output.h"
 #include "ggc.h"
@@ -101,13 +100,11 @@ char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
 #endif
 
 
-/* Indexed by hard register number, contains 1 for registers that are
-   fixed use or call used registers that cannot hold quantities across
-   calls even if we are willing to save and restore them.  call fixed
-   registers are a subset of call used registers.  */
-char call_fixed_regs[FIRST_PSEUDO_REGISTER];
+/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
+   a function value return register or TARGET_STRUCT_VALUE_RTX or
+   STATIC_CHAIN_REGNUM.  These are the registers that cannot hold quantities
+   across calls even if we are willing to save and restore them.  */
 
-/* The same info as a HARD_REG_SET.  */
 HARD_REG_SET call_fixed_reg_set;
 
 /* Indexed by hard register number, contains 1 for registers
@@ -515,8 +512,6 @@ init_reg_sets_1 (void)
   else
     CLEAR_REG_SET (regs_invalidated_by_call_regset);
 
-  memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);
-
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
       /* call_used_regs must include fixed_regs.  */
@@ -531,8 +526,6 @@ init_reg_sets_1 (void)
 
       if (call_used_regs[i])
        SET_HARD_REG_BIT (call_used_reg_set, i);
-      if (call_fixed_regs[i])
-       SET_HARD_REG_BIT (call_fixed_reg_set, i);
 
       /* There are a couple of fixed registers that we know are safe to
         exclude from being clobbered by calls:
@@ -571,12 +564,14 @@ init_reg_sets_1 (void)
         }
     }
 
+  COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set);
+
   /* Preserve global registers if called more than once.  */
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
       if (global_regs[i])
        {
-         fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1;
+         fixed_regs[i] = call_used_regs[i] = 1;
          SET_HARD_REG_BIT (fixed_reg_set, i);
          SET_HARD_REG_BIT (call_used_reg_set, i);
          SET_HARD_REG_BIT (call_fixed_reg_set, i);
@@ -670,6 +665,8 @@ void
 reinit_regs (void)
 {
   init_regs ();
+  /* caller_save needs to be re-initialized.  */
+  caller_save_initialized_p = false;
   ira_init ();
 }
 
@@ -870,7 +867,7 @@ globalize_reg (int i)
   if (fixed_regs[i])
     return;
 
-  fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1;
+  fixed_regs[i] = call_used_regs[i] = 1;
 #ifdef CALL_REALLY_USED_REGISTERS
   call_really_used_regs[i] = 1;
 #endif
@@ -908,6 +905,9 @@ struct reg_pref
    run.  */
 static struct reg_pref *reg_pref;
 
+/* Current size of reg_info.  */
+static int reg_info_size;
+
 /* Return the reg_class in which pseudo reg number REGNO is best allocated.
    This function is sometimes called before the info has been computed.
    When that happens, just return GENERAL_REGS, which is innocuous.  */
@@ -941,9 +941,6 @@ reg_cover_class (int regno)
 
 \f
 
-/* Current size of reg_info.  */
-static int reg_info_size;
-
 /* Allocate space for reg info.  */
 static void
 allocate_reg_info (void)
@@ -956,13 +953,18 @@ allocate_reg_info (void)
 }
 
 
-/* Resize reg info. The new elements will be uninitialized.  */
+/* Resize reg info. The new elements will be uninitialized.  Return
+   TRUE if new elements (for new pseudos) were added.  */
 bool
 resize_reg_info (void)
 {
   int old;
 
-  gcc_assert (reg_pref != NULL);
+  if (reg_pref == NULL)
+    {
+      allocate_reg_info ();
+      return true;
+    }
   if (reg_info_size == max_reg_num ())
     return false;
   old = reg_info_size;
@@ -995,7 +997,7 @@ free_reg_info (void)
 }
 
 /* Initialize some global data for this pass.  */
-static unsigned int 
+static unsigned int
 reginfo_init (void)
 {
   if (df)
@@ -1004,7 +1006,6 @@ reginfo_init (void)
   /* This prevents dump_flow_info from losing if called
      before reginfo is run.  */
   reg_pref = NULL;
-  allocate_reg_info ();
   /* No more global register variables may be declared.  */
   no_global_reg_vars = 1;
   return 1;
@@ -1040,6 +1041,7 @@ setup_reg_classes (int regno,
 {
   if (reg_pref == NULL)
     return;
+  gcc_assert (reg_info_size == max_reg_num ());
   reg_pref[regno].prefclass = prefclass;
   reg_pref[regno].altclass = altclass;
   reg_pref[regno].coverclass = coverclass;
@@ -1297,7 +1299,7 @@ record_subregs_of_mode (rtx subreg)
 }
 
 /* Call record_subregs_of_mode for all the subregs in X.  */
-static void 
+static void
 find_subregs_of_mode (rtx x)
 {
   enum rtx_code code = GET_CODE (x);
@@ -1306,7 +1308,7 @@ find_subregs_of_mode (rtx x)
 
   if (code == SUBREG)
     record_subregs_of_mode (x);
-    
+
   /* Time for some deep diving.  */
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
@@ -1321,7 +1323,7 @@ find_subregs_of_mode (rtx x)
     }
 }
 
-static unsigned int
+void
 init_subregs_of_mode (void)
 {
   basic_block bb;
@@ -1336,8 +1338,6 @@ init_subregs_of_mode (void)
     FOR_BB_INSNS (bb, insn)
     if (INSN_P (insn))
       find_subregs_of_mode (PATTERN (insn));
-
-  return 0;
 }
 
 /* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
@@ -1367,74 +1367,22 @@ invalid_mode_change_p (unsigned int regno,
   return false;
 }
 
-static unsigned int
+void
 finish_subregs_of_mode (void)
 {
   htab_delete (subregs_of_mode);
   subregs_of_mode = 0;
-  return 0;
 }
 #else
-static unsigned int
+void
 init_subregs_of_mode (void)
 {
-  return 0;
 }
-static unsigned int
+void
 finish_subregs_of_mode (void)
 {
-  return 0;
 }
 
 #endif /* CANNOT_CHANGE_MODE_CLASS */
 
-static bool
-gate_subregs_of_mode_init (void)
-{
-#ifdef CANNOT_CHANGE_MODE_CLASS
-  return true;
-#else
-  return false;
-#endif
-}
-
-struct rtl_opt_pass pass_subregs_of_mode_init =
-{
- {
-  RTL_PASS,
-  "subregs_of_mode_init",               /* name */
-  gate_subregs_of_mode_init,            /* gate */
-  init_subregs_of_mode,                 /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_NONE,                              /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  0                                     /* todo_flags_finish */
- }
-};
-
-struct rtl_opt_pass pass_subregs_of_mode_finish =
-{
- {
-  RTL_PASS,
-  "subregs_of_mode_finish",               /* name */
-  gate_subregs_of_mode_init,            /* gate */
-  finish_subregs_of_mode,               /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_NONE,                              /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  0                                     /* todo_flags_finish */
- }
-};
-
-
 #include "gt-reginfo.h"