diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/ira-costs.c | 22 | ||||
-rw-r--r-- | gcc/ira-int.h | 5 | ||||
-rw-r--r-- | gcc/ira.c | 68 |
4 files changed, 88 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 159092a..9151e7d 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 62c8b70..c59b28c 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 1fd285d..8d44e35 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 \ @@ -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 |