This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 2/2] PR 63340: Avoid harmful union classes in ira-costs.c
- From: Richard Sandiford <richard dot sandiford at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: vmakarov at redhat dot com
- Date: Tue, 30 Sep 2014 14:07:45 +0100
- Subject: [PATCH 2/2] PR 63340: Avoid harmful union classes in ira-costs.c
- Authentication-results: sourceware.org; auth=none
This part of the patch actually fixes the PR. It takes the reginfo.c
"invalid mode changes" into account when computing the cost classes,
rather than when using them. The code in the first patch then ensures
that we don't add X_AND_Y_REGS to the cost classes if only X or Y allow
the required mode changes.
Tested in the same way as patch 1. OK to install?
Thanks,
Richard
gcc/
PR rtl-optimization/63340 (part 2)
* ira-costs.c (setup_regno_cost_classes_by_aclass): Restrict the
classes to registers that are allowed by valid_mode_changes_for_regno.
(setup_regno_cost_classes_by_mode): Likewise.
(print_allocno_costs): Remove invalid_mode_change_p test.
(print_pseudo_costs, find_costs_and_classes): Likewise.
Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c 2014-09-30 10:56:20.352946321 +0100
+++ gcc/ira-costs.c 2014-09-30 11:05:02.678826946 +0100
@@ -378,12 +378,18 @@ setup_regno_cost_classes_by_aclass (int
classes_ptr = cost_classes_aclass_cache[aclass] = (cost_classes_t) *slot;
}
if (regno_reg_rtx[regno] != NULL_RTX)
- /* Restrict the classes to those that are valid for REGNO's mode
- (which might for example exclude singleton classes if the mode requires
- two registers). */
- classes_ptr = restrict_cost_classes (classes_ptr,
- PSEUDO_REGNO_MODE (regno),
- reg_class_contents[ALL_REGS]);
+ {
+ /* Restrict the classes to those that are valid for REGNO's mode
+ (which might for example exclude singleton classes if the mode
+ requires two registers). Also restrict the classes to those that
+ are valid for subregs of REGNO. */
+ const HARD_REG_SET *valid_regs = valid_mode_changes_for_regno (regno);
+ if (!valid_regs)
+ valid_regs = ®_class_contents[ALL_REGS];
+ classes_ptr = restrict_cost_classes (classes_ptr,
+ PSEUDO_REGNO_MODE (regno),
+ *valid_regs);
+ }
regno_cost_classes[regno] = classes_ptr;
}
@@ -396,11 +402,17 @@ setup_regno_cost_classes_by_aclass (int
static void
setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
{
- if (cost_classes_mode_cache[mode] == NULL)
- cost_classes_mode_cache[mode]
- = restrict_cost_classes (&all_cost_classes, mode,
- reg_class_contents[ALL_REGS]);
- regno_cost_classes[regno] = cost_classes_mode_cache[mode];
+ if (const HARD_REG_SET *valid_regs = valid_mode_changes_for_regno (regno))
+ regno_cost_classes[regno] = restrict_cost_classes (&all_cost_classes,
+ mode, *valid_regs);
+ else
+ {
+ if (cost_classes_mode_cache[mode] == NULL)
+ cost_classes_mode_cache[mode]
+ = restrict_cost_classes (&all_cost_classes, mode,
+ reg_class_contents[ALL_REGS]);
+ regno_cost_classes[regno] = cost_classes_mode_cache[mode];
+ }
}
/* Finilize info about the cost classes for each pseudo. */
@@ -1526,14 +1538,11 @@ print_allocno_costs (FILE *f)
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- if (! invalid_mode_change_p (regno, (enum reg_class) rclass))
- {
- fprintf (f, " %s:%d", reg_class_names[rclass],
- COSTS (costs, i)->cost[k]);
- if (flag_ira_region == IRA_REGION_ALL
- || flag_ira_region == IRA_REGION_MIXED)
- fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]);
- }
+ fprintf (f, " %s:%d", reg_class_names[rclass],
+ COSTS (costs, i)->cost[k]);
+ if (flag_ira_region == IRA_REGION_ALL
+ || flag_ira_region == IRA_REGION_MIXED)
+ fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]);
}
fprintf (f, " MEM:%i", COSTS (costs, i)->mem_cost);
if (flag_ira_region == IRA_REGION_ALL
@@ -1564,9 +1573,8 @@ print_pseudo_costs (FILE *f)
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- if (! invalid_mode_change_p (regno, (enum reg_class) rclass))
- fprintf (f, " %s:%d", reg_class_names[rclass],
- COSTS (costs, regno)->cost[k]);
+ fprintf (f, " %s:%d", reg_class_names[rclass],
+ COSTS (costs, regno)->cost[k]);
}
fprintf (f, " MEM:%i\n", COSTS (costs, regno)->mem_cost);
}
@@ -1803,10 +1811,6 @@ find_costs_and_classes (FILE *dump_file)
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- /* Ignore classes that are too small or invalid for this
- operand. */
- if (invalid_mode_change_p (i, (enum reg_class) rclass))
- continue;
if (i_costs[k] < best_cost)
{
best_cost = i_costs[k];
@@ -1896,11 +1900,7 @@ find_costs_and_classes (FILE *dump_file)
rclass = cost_classes[k];
if (! ira_class_subset_p[rclass][aclass])
continue;
- /* Ignore classes that are too small or invalid
- for this operand. */
- if (invalid_mode_change_p (i, (enum reg_class) rclass))
- ;
- else if (total_a_costs[k] < best_cost)
+ if (total_a_costs[k] < best_cost)
{
best_cost = total_a_costs[k];
allocno_cost = a_costs[k];
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c 2014-09-30 10:56:20.352946321 +0100
+++ gcc/reginfo.c 2014-09-30 11:06:30.085805954 +0100
@@ -1326,14 +1326,10 @@ init_subregs_of_mode (void)
find_subregs_of_mode (PATTERN (insn));
}
-/* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
- mode. */
-bool
-invalid_mode_change_p (unsigned int regno, enum reg_class rclass)
+const HARD_REG_SET *
+valid_mode_changes_for_regno (unsigned int regno)
{
- return (valid_mode_changes[regno]
- && !hard_reg_set_intersect_p (reg_class_contents[rclass],
- *valid_mode_changes[regno]));
+ return valid_mode_changes[regno];
}
void
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h 2014-09-30 10:56:20.352946321 +0100
+++ gcc/rtl.h 2014-09-30 10:56:20.348946368 +0100
@@ -3496,7 +3496,9 @@ extern void init_reg_sets (void);
extern void regclass (rtx, int);
extern void reg_scan (rtx_insn *, unsigned int);
extern void fix_register (const char *, int, int);
-extern bool invalid_mode_change_p (unsigned int, enum reg_class);
+#ifdef HARD_CONST
+extern const HARD_REG_SET *valid_mode_changes_for_regno (unsigned int);
+#endif
/* In reload1.c */
extern int function_invariant_p (const_rtx);