OSDN Git Service

PR target/33135
[pf3gnuchains/gcc-fork.git] / gcc / ira-costs.c
index 4fa12a2..34e6ef9 100644 (file)
@@ -1,5 +1,5 @@
 /* IRA hard register and memory cost calculation for allocnos or pseudos.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -1306,14 +1306,21 @@ scan_one_insn (rtx insn)
 
      Similarly if we're loading other constants from memory (constant
      pool, TOC references, small data areas, etc) and this is the only
-     assignment to the destination pseudo.  */
+     assignment to the destination pseudo.
+
+     Don't do this if SET_SRC (set) isn't a general operand, if it is
+     a memory requiring special instructions to load it, decreasing
+     mem_cost might result in it being loaded using the specialized
+     instruction into a register, then stored into stack and loaded
+     again from the stack.  See PR52208.  */
   if (set != 0 && REG_P (SET_DEST (set)) && MEM_P (SET_SRC (set))
       && (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
       && ((MEM_P (XEXP (note, 0)))
          || (CONSTANT_P (XEXP (note, 0))
              && targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
                                                XEXP (note, 0))
-             && REG_N_SETS (REGNO (SET_DEST (set))) == 1)))
+             && REG_N_SETS (REGNO (SET_DEST (set))) == 1))
+      && general_operand (SET_SRC (set), GET_MODE (SET_SRC (set))))
     {
       enum reg_class cl = GENERAL_REGS;
       rtx reg = SET_DEST (set);
@@ -1391,7 +1398,7 @@ print_allocno_costs (FILE *f)
       if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
        fprintf (f, "b%d", bb->index);
       else
-       fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
+       fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
       fprintf (f, ") costs:");
       for (k = 0; k < cost_classes_ptr->num; k++)
        {
@@ -1693,7 +1700,14 @@ find_costs_and_classes (FILE *dump_file)
              else if (i_costs[k] == best_cost)
                best = ira_reg_class_subunion[best][rclass];
              if (pass == flag_expensive_optimizations
-                 && i_costs[k] < i_mem_cost
+                 /* We still prefer registers to memory even at this
+                    stage if their costs are the same.  We will make
+                    a final decision during assigning hard registers
+                    when we have all info including more accurate
+                    costs which might be affected by assigning hard
+                    registers to other pseudos because the pseudos
+                    involved in moves can be coalesced.  */
+                 && i_costs[k] <= i_mem_cost
                  && (reg_class_size[reg_class_subunion[alt_class][rclass]]
                      > reg_class_size[alt_class]))
                alt_class = reg_class_subunion[alt_class][rclass];
@@ -1782,7 +1796,7 @@ find_costs_and_classes (FILE *dump_file)
                    fprintf (dump_file, "b%d", bb->index);
                  else
                    fprintf (dump_file, "l%d",
-                            ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
+                            ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
                  fprintf (dump_file, ") best %s, allocno %s\n",
                           reg_class_names[best],
                           reg_class_names[regno_aclass[i]]);