The following patch fixes PR49990. The problem is described on
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49936
Reg classes which can not change modes for some pseudo were excluded
from the consideration. As I wrote recently, they should not. Instead
the correct cost for changing mode (by moving through memory or other
class register) should be taken into the account. I believe the cost is
already calculated rightly for this case, fortunately.
The patch was successfully bootstrapped on x86-64 and ppc64. Actually I
did not find a difference in generated code on variety tests on
x86/x86-64 and arm (that is what I tried).
Committed as rev. 177575.
2011-08-08 Vladimir Makarov <vmaka...@redhat.com>
PR rtl-optimization/49990
* ira-costs.c (print_allocno_costs, print_pseudo_costs): Don't
ignore classes which can not change mode.
(find_costs_and_classes): Ditto.
Index: ira-costs.c
===================================================================
--- ira-costs.c (revision 177573)
+++ ira-costs.c (working copy)
@@ -1367,11 +1367,7 @@ print_allocno_costs (FILE *f)
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
-#ifdef CANNOT_CHANGE_MODE_CLASS
- && ! invalid_mode_change_p (regno, (enum reg_class) rclass)
-#endif
- )
+ if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)])
{
fprintf (f, " %s:%d", reg_class_names[rclass],
COSTS (costs, i)->cost[k]);
@@ -1409,11 +1405,7 @@ print_pseudo_costs (FILE *f)
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
-#ifdef CANNOT_CHANGE_MODE_CLASS
- && ! invalid_mode_change_p (regno, (enum reg_class) rclass)
-#endif
- )
+ if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)])
fprintf (f, " %s:%d", reg_class_names[rclass],
COSTS (costs, regno)->cost[k]);
}
@@ -1650,11 +1642,7 @@ find_costs_and_classes (FILE *dump_file)
rclass = cost_classes[k];
/* Ignore classes that are too small or invalid for this
operand. */
- if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)]
-#ifdef CANNOT_CHANGE_MODE_CLASS
- || invalid_mode_change_p (i, (enum reg_class) rclass)
-#endif
- )
+ if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)])
continue;
if (i_costs[k] < best_cost)
{
@@ -1725,11 +1713,7 @@ find_costs_and_classes (FILE *dump_file)
continue;
/* Ignore classes that are too small or invalid
for this operand. */
- if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)]
-#ifdef CANNOT_CHANGE_MODE_CLASS
- || invalid_mode_change_p (i, (enum reg_class) rclass)
-#endif
- )
+ if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)])
;
else if (total_a_costs[k] < best_cost)
{