summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/ira-costs.c22
-rw-r--r--gcc/ira-int.h5
-rw-r--r--gcc/ira.c68
4 files changed, 88 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 159092a8239..9151e7d4ab4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2012-06-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ * ira-int.h (struct target_ira_int): Add member
+ x_ira_uniform_class_p.
+ (ira_uniform_class_p): New macro.
+
+ * ira.c (setup_uniform_class_p): New function.
+ (setup_allocno_and_important_classes): Call the function.
+ (print_unform_and_important_classes): New function.
+ (print_classes): Rename to print_translated_classes.
+ (ira_debug_allocno_classes): Add call of
+ print_unform_and_important_classes.
+
+ * ira-costs.c (setup_regno_cost_classes_by_aclass): Use uniform
+ classes instead of pressure classes.
+
2012-06-04 Sterling Augustine <saugustine@google.com>
* gcc/c-family/c-pretty-print.h (pp_c_flag_gnu_v3): New enumerator.
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 62c8b7042f5..c59b28c8a73 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -239,33 +239,19 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
COPY_HARD_REG_SET (temp, reg_class_contents[aclass]);
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
/* We exclude classes from consideration which are subsets of
- ACLASS only if ACLASS is a pressure class or subset of a
- pressure class. It means by the definition of pressure classes
- that cost of moving between susbets of ACLASS is cheaper than
- load or store. */
- for (i = 0; i < ira_pressure_classes_num; i++)
- {
- cl = ira_pressure_classes[i];
- if (cl == aclass)
- break;
- COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
- AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
- if (hard_reg_set_subset_p (temp, temp2))
- break;
- }
- exclude_p = i < ira_pressure_classes_num;
+ ACLASS only if ACLASS is an uniform class. */
+ exclude_p = ira_uniform_class_p[aclass];
classes.num = 0;
for (i = 0; i < ira_important_classes_num; i++)
{
cl = ira_important_classes[i];
if (exclude_p)
{
- /* Exclude no-pressure classes which are subsets of
+ /* Exclude non-uniform classes which are subsets of
ACLASS. */
COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
- if (! ira_reg_pressure_class_p[cl]
- && hard_reg_set_subset_p (temp2, temp) && cl != aclass)
+ if (hard_reg_set_subset_p (temp2, temp) && cl != aclass)
continue;
}
classes.classes[classes.num++] = cl;
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 1fd285dacf7..8d44e35df0c 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -828,6 +828,9 @@ struct target_ira_int {
classes. */
int x_ira_important_class_nums[N_REG_CLASSES];
+ /* Map class->true if class is an uniform class, false otherwise. */
+ bool x_ira_uniform_class_p[N_REG_CLASSES];
+
/* The biggest important class inside of intersection of the two
classes (that is calculated taking only hard registers available
for allocation into account;. If the both classes contain no hard
@@ -905,6 +908,8 @@ extern struct target_ira_int *this_target_ira_int;
(this_target_ira_int->x_ira_important_classes)
#define ira_important_class_nums \
(this_target_ira_int->x_ira_important_class_nums)
+#define ira_uniform_class_p \
+ (this_target_ira_int->x_ira_uniform_class_p)
#define ira_reg_class_intersect \
(this_target_ira_int->x_ira_reg_class_intersect)
#define ira_reg_classes_intersect_p \
diff --git a/gcc/ira.c b/gcc/ira.c
index 81c5180b7d0..d477ec95803 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -903,6 +903,45 @@ setup_pressure_classes (void)
setup_stack_reg_pressure_class ();
}
+/* Set up IRA_UNIFORM_CLASS_P. Uniform class is a register class
+ whose register move cost between any registers of the class is the
+ same as for all its subclasses. We use the data to speed up the
+ 2nd pass of calculations of allocno costs. */
+static void
+setup_uniform_class_p (void)
+{
+ int i, cl, cl2, m;
+
+ for (cl = 0; cl < N_REG_CLASSES; cl++)
+ {
+ ira_uniform_class_p[cl] = false;
+ if (ira_class_hard_regs_num[cl] == 0)
+ continue;
+ /* We can not use alloc_reg_class_subclasses here because move
+ cost hooks does not take into account that some registers are
+ unavailable for the subtarget. E.g. for i686, INT_SSE_REGS
+ is element of alloc_reg_class_subclasses for GENERAL_REGS
+ because SSE regs are unavailable. */
+ for (i = 0; (cl2 = reg_class_subclasses[cl][i]) != LIM_REG_CLASSES; i++)
+ {
+ if (ira_class_hard_regs_num[cl2] == 0)
+ continue;
+ for (m = 0; m < NUM_MACHINE_MODES; m++)
+ if (contains_reg_of_mode[cl][m] && contains_reg_of_mode[cl2][m])
+ {
+ ira_init_register_move_cost_if_necessary ((enum machine_mode) m);
+ if (ira_register_move_cost[m][cl][cl]
+ != ira_register_move_cost[m][cl2][cl2])
+ break;
+ }
+ if (m < NUM_MACHINE_MODES)
+ break;
+ }
+ if (cl2 == LIM_REG_CLASSES)
+ ira_uniform_class_p[cl] = true;
+ }
+}
+
/* Set up IRA_ALLOCNO_CLASSES, IRA_ALLOCNO_CLASSES_NUM,
IRA_IMPORTANT_CLASSES, and IRA_IMPORTANT_CLASSES_NUM.
@@ -1008,6 +1047,7 @@ setup_allocno_and_important_classes (void)
for (j = 0; j < ira_allocno_classes_num; j++)
ira_reg_allocno_class_p[ira_allocno_classes[j]] = true;
setup_pressure_classes ();
+ setup_uniform_class_p ();
}
/* Setup translation in CLASS_TRANSLATE of all classes into a class
@@ -1292,10 +1332,27 @@ setup_reg_class_relations (void)
}
}
-/* Output all possible allocno classes and the translation map into
- file F. */
+/* Output all unifrom and important classes into file F. */
+static void
+print_unform_and_important_classes (FILE *f)
+{
+ static const char *const reg_class_names[] = REG_CLASS_NAMES;
+ int i, cl;
+
+ fprintf (f, "Uniform classes:\n");
+ for (cl = 0; cl < N_REG_CLASSES; cl++)
+ if (ira_uniform_class_p[cl])
+ fprintf (f, " %s", reg_class_names[cl]);
+ fprintf (f, "\nImportant classes:\n");
+ for (i = 0; i < ira_important_classes_num; i++)
+ fprintf (f, " %s", reg_class_names[ira_important_classes[i]]);
+ fprintf (f, "\n");
+}
+
+/* Output all possible allocno or pressure classes and their
+ translation map into file F. */
static void
-print_classes (FILE *f, bool pressure_p)
+print_translated_classes (FILE *f, bool pressure_p)
{
int classes_num = (pressure_p
? ira_pressure_classes_num : ira_allocno_classes_num);
@@ -1321,8 +1378,9 @@ print_classes (FILE *f, bool pressure_p)
void
ira_debug_allocno_classes (void)
{
- print_classes (stderr, false);
- print_classes (stderr, true);
+ print_unform_and_important_classes (stderr);
+ print_translated_classes (stderr, false);
+ print_translated_classes (stderr, true);
}
/* Set up different arrays concerning class subsets, allocno and