The following patch solves

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55342

LRA after spilling a pseudo tries to assign freed hard regno to other reload pseudos and chooses the best. The more reload pseudos got the freed hard regno, the less cost of spilling. But the reload pseudos could get another hard regno without spilling. So LRA code before the patch incorrectly evaluated the cost of spilling. The patch tries to allocate a hard reg to the other reload pseudos before and after spilling in order to correctly evaluate spilling cost.

  The patch was successfully bootstrapped on x86/x86-64.

  Committed as rev. 193588.

2012-11-17  Vladimir Makarov  <vmaka...@redhat.com>

        PR rtl-optimization/55342
        * lra-assigns.c (spill_for): Try to allocate other reload pseudos
        before and after spilling.


Index: lra-assigns.c
===================================================================
--- lra-assigns.c       (revision 193557)
+++ lra-assigns.c       (working copy)
@@ -795,9 +795,8 @@ spill_for (int regno, bitmap spilled_pse
 {
   int i, j, n, p, hard_regno, best_hard_regno, cost, best_cost, rclass_size;
   int reload_hard_regno, reload_cost;
-  enum machine_mode mode, mode2;
+  enum machine_mode mode;
   enum reg_class rclass;
-  HARD_REG_SET spilled_hard_regs;
   unsigned int spill_regno, reload_regno, uid;
   int insn_pseudos_num, best_insn_pseudos_num;
   lra_live_range_t r;
@@ -838,7 +837,6 @@ spill_for (int regno, bitmap spilled_pse
                           &try_hard_reg_pseudos[hard_regno + j]);
        }
       /* Spill pseudos.         */
-      CLEAR_HARD_REG_SET (spilled_hard_regs);
       EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
        if ((int) spill_regno >= lra_constraint_new_regno_start
            && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
@@ -853,13 +851,6 @@ spill_for (int regno, bitmap spilled_pse
        {
          if (bitmap_bit_p (&insn_conflict_pseudos, spill_regno))
            insn_pseudos_num++;
-         mode2 = PSEUDO_REGNO_MODE (spill_regno);
-         update_lives (spill_regno, true);
-         if (lra_dump_file != NULL)
-           fprintf (lra_dump_file, " spill %d(freq=%d)",
-                    spill_regno, lra_reg_info[spill_regno].freq);
-         add_to_hard_reg_set (&spilled_hard_regs,
-                              mode2, reg_renumber[spill_regno]);
          for (r = lra_reg_info[spill_regno].live_ranges;
               r != NULL;
               r = r->next)
@@ -877,19 +868,26 @@ spill_for (int regno, bitmap spilled_pse
                }
            }
        }
+      n = 0;
+      EXECUTE_IF_SET_IN_SPARSESET (live_range_reload_inheritance_pseudos,
+                                  reload_regno)
+       if ((int) reload_regno != regno
+           && (ira_reg_classes_intersect_p
+               [rclass][regno_allocno_class_array[reload_regno]])
+           && live_pseudos_reg_renumber[reload_regno] < 0
+           && find_hard_regno_for (reload_regno, &cost, -1) < 0)
+         sorted_reload_pseudos[n++] = reload_regno;
+      EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
+       {
+         update_lives (spill_regno, true);
+         if (lra_dump_file != NULL)
+           fprintf (lra_dump_file, " spill %d(freq=%d)",
+                    spill_regno, lra_reg_info[spill_regno].freq);
+       }
       hard_regno = find_hard_regno_for (regno, &cost, -1);
       if (hard_regno >= 0)
        {
          assign_temporarily (regno, hard_regno);
-         n = 0;
-         EXECUTE_IF_SET_IN_SPARSESET (live_range_reload_inheritance_pseudos,
-                                      reload_regno)
-           if (live_pseudos_reg_renumber[reload_regno] < 0
-               && (hard_reg_set_intersect_p
-                   (reg_class_contents
-                    [regno_allocno_class_array[reload_regno]],
-                    spilled_hard_regs)))
-             sorted_reload_pseudos[n++] = reload_regno;
          qsort (sorted_reload_pseudos, n, sizeof (int),
                 reload_pseudo_compare_func);
          for (j = 0; j < n; j++)
@@ -898,10 +896,7 @@ spill_for (int regno, bitmap spilled_pse
              lra_assert (live_pseudos_reg_renumber[reload_regno] < 0);
              if ((reload_hard_regno
                   = find_hard_regno_for (reload_regno,
-                                         &reload_cost, -1)) >= 0
-                 && (overlaps_hard_reg_set_p
-                     (spilled_hard_regs,
-                      PSEUDO_REGNO_MODE (reload_regno), reload_hard_regno)))
+                                         &reload_cost, -1)) >= 0)
                {
                  if (lra_dump_file != NULL)
                    fprintf (lra_dump_file, " assign %d(cost=%d)",

Reply via email to