OSDN Git Service

PR c++/49102
[pf3gnuchains/gcc-fork.git] / gcc / ira.c
index de7f5b6..9235cb3 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -583,11 +583,11 @@ setup_class_subset_and_memory_move_costs (void)
            ira_max_memory_move_cost[mode][cl][0]
              = ira_memory_move_cost[mode][cl][0]
              = memory_move_cost ((enum machine_mode) mode,
-                                 (enum reg_class) cl, false);
+                                 (reg_class_t) cl, false);
            ira_max_memory_move_cost[mode][cl][1]
              = ira_memory_move_cost[mode][cl][1]
              = memory_move_cost ((enum machine_mode) mode,
-                                 (enum reg_class) cl, true);
+                                 (reg_class_t) 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.  */
@@ -863,7 +863,7 @@ setup_pressure_classes (void)
      registers available for the allocation.  */
   CLEAR_HARD_REG_SET (temp_hard_regset);
   CLEAR_HARD_REG_SET (temp_hard_regset2);
-  for (cl = 0; cl <= LIM_REG_CLASSES; cl++)
+  for (cl = 0; cl < LIM_REG_CLASSES; cl++)
     {
       for (i = 0; i < n; i++)
        if ((int) pressure_classes[i] == cl)
@@ -923,7 +923,7 @@ setup_allocno_and_important_classes (void)
   /* Collect classes which contain unique sets of allocatable hard
      registers.  Prefer GENERAL_REGS to other classes containing the
      same set of hard registers.  */
-  for (i = 0; i <= LIM_REG_CLASSES; i++)
+  for (i = 0; i < LIM_REG_CLASSES; i++)
     {
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
@@ -1422,6 +1422,12 @@ clarify_prohibited_class_mode_regs (void)
          if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno))
            continue;
          nregs = hard_regno_nregs[hard_regno][j];
+          if (hard_regno + nregs > FIRST_PSEUDO_REGISTER)
+            {
+              SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
+                                hard_regno);
+               continue;
+            }
          pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)];
          for (nregs-- ;nregs >= 0; nregs--)
            if (((enum reg_class) pclass
@@ -1556,16 +1562,11 @@ free_register_move_costs (void)
 
   for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
     {
-      if (ira_max_register_move_cost[mode] != NULL)
-       free (ira_max_register_move_cost[mode]);
-      if (ira_may_move_in_cost[mode] != NULL)
-       free (ira_may_move_in_cost[mode]);
-      if (ira_may_move_out_cost[mode] != NULL)
-       free (ira_may_move_out_cost[mode]);
-      if (ira_max_may_move_in_cost[mode] != NULL)
-       free (ira_max_may_move_in_cost[mode]);
-      if (ira_max_may_move_out_cost[mode] != NULL)
-       free (ira_max_may_move_out_cost[mode]);
+      free (ira_max_register_move_cost[mode]);
+      free (ira_may_move_in_cost[mode]);
+      free (ira_may_move_out_cost[mode]);
+      free (ira_max_may_move_in_cost[mode]);
+      free (ira_max_may_move_out_cost[mode]);
       ira_register_move_cost[mode] = NULL;
       ira_max_register_move_cost[mode] = NULL;
       ira_may_move_in_cost[mode] = NULL;
@@ -1724,16 +1725,10 @@ compute_regs_asm_clobbered (void)
              {
                df_ref def = *def_rec;
                unsigned int dregno = DF_REF_REGNO (def);
-               if (dregno < FIRST_PSEUDO_REGISTER)
-                 {
-                   unsigned int i;
-                   enum machine_mode mode = GET_MODE (DF_REF_REAL_REG (def));
-                   unsigned int end = dregno
-                     + hard_regno_nregs[dregno][mode] - 1;
-
-                   for (i = dregno; i <= end; ++i)
-                     SET_HARD_REG_BIT(crtl->asm_clobbers, i);
-                 }
+               if (HARD_REGISTER_NUM_P (dregno))
+                 add_to_hard_reg_set (&crtl->asm_clobbers,
+                                      GET_MODE (DF_REF_REAL_REG (def)),
+                                      dregno);
              }
        }
     }
@@ -1836,15 +1831,15 @@ rtx *ira_reg_equiv_const;
 static void
 find_reg_equiv_invariant_const (void)
 {
-  int i;
+  unsigned int i;
   bool invariant_p;
   rtx list, insn, note, constant, x;
 
-  for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
+  for (i = FIRST_PSEUDO_REGISTER; i < VEC_length (reg_equivs_t, reg_equivs); i++)
     {
       constant = NULL_RTX;
       invariant_p = false;
-      for (list = reg_equiv_init[i]; list != NULL_RTX; list = XEXP (list, 1))
+      for (list = reg_equiv_init (i); list != NULL_RTX; list = XEXP (list, 1))
        {
          insn = XEXP (list, 0);
          note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
@@ -2104,17 +2099,18 @@ check_allocation (void)
 static void
 fix_reg_equiv_init (void)
 {
-  int max_regno = max_reg_num ();
-  int i, new_regno;
+  unsigned int max_regno = max_reg_num ();
+  int i, new_regno, max;
   rtx x, prev, next, insn, set;
 
-  if (reg_equiv_init_size < max_regno)
+  if (VEC_length (reg_equivs_t, reg_equivs) < max_regno)
     {
-      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++)
-       for (prev = NULL_RTX, x = reg_equiv_init[i]; x != NULL_RTX; x = next)
+      max = VEC_length (reg_equivs_t, reg_equivs);
+      grow_reg_equivs ();
+      for (i = FIRST_PSEUDO_REGISTER; i < max; i++)
+       for (prev = NULL_RTX, x = reg_equiv_init (i);
+            x != NULL_RTX;
+            x = next)
          {
            next = XEXP (x, 1);
            insn = XEXP (x, 0);
@@ -2136,11 +2132,11 @@ fix_reg_equiv_init (void)
            else
              {
                if (prev == NULL_RTX)
-                 reg_equiv_init[i] = next;
+                 reg_equiv_init (i) = next;
                else
                  XEXP (prev, 1) = next;
-               XEXP (x, 1) = reg_equiv_init[new_regno];
-               reg_equiv_init[new_regno] = x;
+               XEXP (x, 1) = reg_equiv_init (new_regno);
+               reg_equiv_init (new_regno) = x;
              }
          }
     }
@@ -2645,7 +2641,7 @@ no_equiv (rtx reg, const_rtx store ATTRIBUTE_UNUSED,
      should keep their initialization insns.  */
   if (reg_equiv[regno].is_arg_equivalence)
     return;
-  reg_equiv_init[regno] = NULL_RTX;
+  reg_equiv_init (regno) = NULL_RTX;
   for (; list; list =  XEXP (list, 1))
     {
       rtx insn = XEXP (list, 0);
@@ -2697,8 +2693,7 @@ update_equiv_regs (void)
   recorded_label_ref = 0;
 
   reg_equiv = XCNEWVEC (struct equivalence, max_regno);
-  reg_equiv_init = ggc_alloc_cleared_vec_rtx (max_regno);
-  reg_equiv_init_size = max_regno;
+  grow_reg_equivs ();
 
   init_alias_analysis ();
 
@@ -2763,8 +2758,8 @@ update_equiv_regs (void)
 
              /* Record for reload that this is an equivalencing insn.  */
              if (rtx_equal_p (src, XEXP (note, 0)))
-               reg_equiv_init[regno]
-                 = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
+               reg_equiv_init (regno)
+                 = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
 
              /* Continue normally in case this is a candidate for
                 replacements.  */
@@ -2864,8 +2859,8 @@ update_equiv_regs (void)
              /* If we haven't done so, record for reload that this is an
                 equivalencing insn.  */
              if (!reg_equiv[regno].is_arg_equivalence)
-               reg_equiv_init[regno]
-                 = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
+               reg_equiv_init (regno)
+                 = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
 
              /* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
                 We might end up substituting the LABEL_REF for uses of the
@@ -2965,7 +2960,7 @@ update_equiv_regs (void)
            {
              /* This insn makes the equivalence, not the one initializing
                 the register.  */
-             reg_equiv_init[regno]
+             reg_equiv_init (regno)
                = gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
              df_notes_rescan (init_insn);
            }
@@ -3068,7 +3063,7 @@ update_equiv_regs (void)
                      reg_equiv[regno].init_insns
                        = XEXP (reg_equiv[regno].init_insns, 1);
 
-                     reg_equiv_init[regno] = NULL_RTX;
+                     reg_equiv_init (regno) = NULL_RTX;
                      bitmap_set_bit (cleared_regs, regno);
                    }
                  /* Move the initialization of the register to just before
@@ -3101,7 +3096,7 @@ update_equiv_regs (void)
                      if (insn == BB_HEAD (bb))
                        BB_HEAD (bb) = PREV_INSN (insn);
 
-                     reg_equiv_init[regno]
+                     reg_equiv_init (regno)
                        = gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
                      bitmap_set_bit (cleared_regs, regno);
                    }
@@ -3467,8 +3462,7 @@ build_insn_chain (void)
     }
 
   for (i = 0; i < (unsigned int) max_regno; i++)
-    if (live_subregs[i])
-      free (live_subregs[i]);
+    free (live_subregs[i]);
 
   reload_insn_chain = c;
   *p = NULL;
@@ -3481,19 +3475,8 @@ 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);
-}
+\f
 
 /* All natural loops.  */
 struct loops ira_loops;
@@ -3599,8 +3582,6 @@ 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
@@ -3670,8 +3651,6 @@ ira (FILE *f)
   if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
     df_analyze ();
 
-  init_reg_equiv_memory_loc ();
-
   if (max_regno != max_regno_before_ira)
     {
       regstat_free_n_sets_and_refs ();
@@ -3680,10 +3659,10 @@ ira (FILE *f)
       regstat_compute_ri ();
     }
 
-  allocate_initial_values (reg_equiv_memory_loc);
-
   overall_cost_before = ira_overall_cost;
-  if (ira_conflicts_p)
+  if (! ira_conflicts_p)
+    grow_reg_equivs ();
+  else
     {
       fix_reg_equiv_init ();
 
@@ -3699,6 +3678,7 @@ ira (FILE *f)
       memset (ira_spilled_reg_stack_slots, 0,
              max_regno * sizeof (struct ira_spilled_reg_stack_slot));
     }
+  allocate_initial_values (reg_equivs);
 
   timevar_pop (TV_IRA);