OSDN Git Service

2010-07-05 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / ira.c
index 372539e..0f0b70a 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -310,6 +310,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "hard-reg-set.h"
 #include "basic-block.h"
+#include "df.h"
 #include "expr.h"
 #include "recog.h"
 #include "params.h"
@@ -318,9 +319,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 #include "except.h"
 #include "reload.h"
-#include "errors.h"
+#include "toplev.h"
 #include "integrate.h"
-#include "df.h"
 #include "ggc.h"
 #include "ira-int.h"
 
@@ -331,9 +331,6 @@ int internal_flag_ira_verbose;
 /* Dump file of the allocator if it is not NULL.  */
 FILE *ira_dump_file;
 
-/* Pools for allocnos, copies, allocno live ranges.  */
-alloc_pool allocno_pool, copy_pool, allocno_live_range_pool;
-
 /* The number of elements in the following array.  */
 int ira_spilled_reg_stack_slots_num;
 
@@ -358,9 +355,10 @@ HARD_REG_SET eliminable_regset;
    of given mode starting with given hard register.  */
 HARD_REG_SET ira_reg_mode_hard_regset[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
 
-/* The following two variables are array analogs of the macros
-   MEMORY_MOVE_COST and REGISTER_MOVE_COST.  */
+/* Array analogous to target hook TARGET_MEMORY_MOVE_COST.  */
 short int ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
+
+/* Array based on TARGET_REGISTER_MOVE_COST.  */
 move_table *ira_register_move_cost[MAX_MACHINE_MODE];
 
 /* Similar to may_move_in_cost but it is calculated in IRA instead of
@@ -527,11 +525,11 @@ setup_class_subset_and_memory_move_costs (void)
        for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
          {
            ira_memory_move_cost[mode][cl][0] =
-             MEMORY_MOVE_COST ((enum machine_mode) mode,
-                               (enum reg_class) cl, 0);
+             memory_move_cost ((enum machine_mode) mode,
+                               (enum reg_class) cl, false);
            ira_memory_move_cost[mode][cl][1] =
-             MEMORY_MOVE_COST ((enum machine_mode) mode,
-                               (enum reg_class) cl, 1);
+             memory_move_cost ((enum machine_mode) mode,
+                               (enum reg_class) cl, true);
            /* Costs for NO_REGS are used in cost calculation on the
               1st pass when the preferred register classes are not
               known yet.  In this case we take the best scenario.  */
@@ -742,7 +740,7 @@ setup_cover_and_important_classes (void)
 {
   int i, j, n, cl;
   bool set_p;
-  const enum reg_class *cover_classes;
+  const reg_class_t *cover_classes;
   HARD_REG_SET temp_hard_regset2;
   static enum reg_class classes[LIM_REG_CLASSES + 1];
 
@@ -1374,6 +1372,46 @@ setup_prohibited_mode_move_regs (void)
 
 \f
 
+/* Return nonzero if REGNO is a particularly bad choice for reloading X.  */
+static bool
+ira_bad_reload_regno_1 (int regno, rtx x)
+{
+  int x_regno;
+  ira_allocno_t a;
+  enum reg_class pref;
+
+  /* We only deal with pseudo regs.  */
+  if (! x || GET_CODE (x) != REG)
+    return false;
+
+  x_regno = REGNO (x);
+  if (x_regno < FIRST_PSEUDO_REGISTER)
+    return false;
+
+  /* If the pseudo prefers REGNO explicitly, then do not consider
+     REGNO a bad spill choice.  */
+  pref = reg_preferred_class (x_regno);
+  if (reg_class_size[pref] == 1)
+    return !TEST_HARD_REG_BIT (reg_class_contents[pref], regno);
+
+  /* If the pseudo conflicts with REGNO, then we consider REGNO a
+     poor choice for a reload regno.  */
+  a = ira_regno_allocno_map[x_regno];
+  if (TEST_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), regno))
+    return true;
+
+  return false;
+}
+
+/* Return nonzero if REGNO is a particularly bad choice for reloading
+   IN or OUT.  */
+bool
+ira_bad_reload_regno (int regno, rtx in, rtx out)
+{
+  return (ira_bad_reload_regno_1 (regno, in)
+         || ira_bad_reload_regno_1 (regno, out));
+}
+
 /* Function specific hard registers that can not be used for the
    register allocation.  */
 HARD_REG_SET ira_no_alloc_regs;
@@ -1397,14 +1435,12 @@ insn_contains_asm (rtx insn)
   return for_each_rtx (&insn, insn_contains_asm_1, NULL);
 }
 
-/* Set up regs_asm_clobbered.  */
+/* Add register clobbers from asm statements.  */
 static void
-compute_regs_asm_clobbered (char *regs_asm_clobbered)
+compute_regs_asm_clobbered (void)
 {
   basic_block bb;
 
-  memset (regs_asm_clobbered, 0, sizeof (char) * FIRST_PSEUDO_REGISTER);
-
   FOR_EACH_BB (bb)
     {
       rtx insn;
@@ -1425,7 +1461,7 @@ compute_regs_asm_clobbered (char *regs_asm_clobbered)
                      + hard_regno_nregs[dregno][mode] - 1;
 
                    for (i = dregno; i <= end; ++i)
-                     regs_asm_clobbered[i] = 1;
+                     SET_HARD_REG_BIT(crtl->asm_clobbers, i);
                  }
              }
        }
@@ -1437,12 +1473,6 @@ compute_regs_asm_clobbered (char *regs_asm_clobbered)
 void
 ira_setup_eliminable_regset (void)
 {
-  /* Like regs_ever_live, but 1 if a reg is set or clobbered from an
-     asm.  Unlike regs_ever_live, elements of this array corresponding
-     to eliminable regs (like the frame pointer) are set if an asm
-     sets them.  */
-  char *regs_asm_clobbered
-    = (char *) alloca (FIRST_PSEUDO_REGISTER * sizeof (char));
 #ifdef ELIMINABLE_REGS
   int i;
   static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
@@ -1466,7 +1496,8 @@ ira_setup_eliminable_regset (void)
   COPY_HARD_REG_SET (ira_no_alloc_regs, no_unit_alloc_regs);
   CLEAR_HARD_REG_SET (eliminable_regset);
 
-  compute_regs_asm_clobbered (regs_asm_clobbered);
+  compute_regs_asm_clobbered ();
+
   /* Build the regset of all eliminable registers and show we can't
      use those that we already know won't be eliminated.  */
 #ifdef ELIMINABLE_REGS
@@ -1476,7 +1507,7 @@ ira_setup_eliminable_regset (void)
        = (! targetm.can_eliminate (eliminables[i].from, eliminables[i].to)
           || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
 
-      if (! regs_asm_clobbered[eliminables[i].from])
+      if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, eliminables[i].from))
        {
            SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
 
@@ -1490,7 +1521,7 @@ ira_setup_eliminable_regset (void)
        df_set_regs_ever_live (eliminables[i].from, true);
     }
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-  if (! regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM])
+  if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
     {
       SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
       if (need_fp)
@@ -1504,7 +1535,7 @@ ira_setup_eliminable_regset (void)
 #endif
 
 #else
-  if (! regs_asm_clobbered[FRAME_POINTER_REGNUM])
+  if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
     {
       SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
       if (need_fp)
@@ -1552,12 +1583,8 @@ find_reg_equiv_invariant_const (void)
 
          x = XEXP (note, 0);
 
-         if (! function_invariant_p (x)
-             || ! flag_pic
-             /* A function invariant is often CONSTANT_P but may
-                include a register.  We promise to only pass CONSTANT_P
-                objects to LEGITIMATE_PIC_OPERAND_P.  */
-             || (CONSTANT_P (x) && LEGITIMATE_PIC_OPERAND_P (x)))
+         if (! CONSTANT_P (x)
+             || ! flag_pic || LEGITIMATE_PIC_OPERAND_P (x))
            {
              /* It can happen that a REG_EQUIV note contains a MEM
                 that is not a legitimate memory operand.  As later
@@ -1757,8 +1784,7 @@ fix_reg_equiv_init (void)
 
   if (reg_equiv_init_size < max_regno)
     {
-      reg_equiv_init
-       = (rtx *) ggc_realloc (reg_equiv_init, max_regno * sizeof (rtx));
+      reg_equiv_init = GGC_RESIZEVEC (rtx, reg_equiv_init, max_regno);
       while (reg_equiv_init_size < max_regno)
        reg_equiv_init[reg_equiv_init_size++] = NULL_RTX;
       for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
@@ -1899,7 +1925,7 @@ mark_elimination (int from, int to)
   FOR_EACH_BB (bb)
     {
       /* We don't use LIVE info in IRA.  */
-      regset r = DF_LR_IN (bb);
+      bitmap r = DF_LR_IN (bb);
 
       if (REGNO_REG_SET_P (r, from))
        {
@@ -2337,7 +2363,7 @@ update_equiv_regs (void)
   recorded_label_ref = 0;
 
   reg_equiv = XCNEWVEC (struct equivalence, max_regno);
-  reg_equiv_init = GGC_CNEWVEC (rtx, max_regno);
+  reg_equiv_init = ggc_alloc_cleared_vec_rtx (max_regno);
   reg_equiv_init_size = max_regno;
 
   init_alias_analysis ();
@@ -3116,8 +3142,19 @@ build_insn_chain (void)
   if (dump_file)
     print_insn_chains (dump_file);
 }
-
 \f
+/* Allocate memory for reg_equiv_memory_loc.  */
+static void
+init_reg_equiv_memory_loc (void)
+{
+  max_regno = max_reg_num ();
+
+  /* And the reg_equiv_memory_loc array.  */
+  VEC_safe_grow (rtx, gc, reg_equiv_memory_loc_vec, max_regno);
+  memset (VEC_address (rtx, reg_equiv_memory_loc_vec), 0,
+         sizeof (rtx) * max_regno);
+  reg_equiv_memory_loc = VEC_address (rtx, reg_equiv_memory_loc_vec);
+}
 
 /* All natural loops.  */
 struct loops ira_loops;
@@ -3222,6 +3259,8 @@ ira (FILE *f)
   record_loop_exits ();
   current_loops = &ira_loops;
 
+  init_reg_equiv_memory_loc ();
+
   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     fprintf (ira_dump_file, "Building IRA IR\n");
   loops_p = ira_build (optimize
@@ -3282,13 +3321,8 @@ ira (FILE *f)
 #endif
 
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
-  max_regno = max_reg_num ();
 
-  /* And the reg_equiv_memory_loc array.  */
-  VEC_safe_grow (rtx, gc, reg_equiv_memory_loc_vec, max_regno);
-  memset (VEC_address (rtx, reg_equiv_memory_loc_vec), 0,
-         sizeof (rtx) * max_regno);
-  reg_equiv_memory_loc = VEC_address (rtx, reg_equiv_memory_loc_vec);
+  init_reg_equiv_memory_loc ();
 
   if (max_regno != max_regno_before_ira)
     {