diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-09 21:25:11 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-09 21:25:11 +0000 |
commit | 14792f4e09135749d6631d113f0e73185ba50226 (patch) | |
tree | 42be312c545d91eee361dc8d399923279541e6a2 /gcc/ira.c | |
parent | 58d657fa30f9a8f4c020bae68bf141867aa5ef55 (diff) | |
download | gcc-14792f4e09135749d6631d113f0e73185ba50226.tar.gz |
2008-12-09 Vladimir Makarov <vmakarov@redhat.com>
* doc/tm.texi (TARGET_IRA_COVER_CLASSES): Modify description.
* doc/invoke.texi (-fira-region): Describe new option.
(-fira-algorithm): Change the values.
* ira-conflicts.c (build_conflict_bit_table,
build_allocno_conflicts): Use ira_reg_classes_intersect_p.
(ira_build_conflicts): Use flag flag_ira_region instead of
flag_ira_algorithm. Prohibit usage of callee-saved likely spilled
base registers for allocnos crossing calls.
* flags.h (enum ira_algorithm): Redefine.
(enum ira_region): New.
(flag_ira_region): New.
* cfgloopanal.c (estimate_reg_pressure_cost): Use flag_ira_region
instead of flag_ira_algorithm.
* toplev.c (flag_ira_algorithm): Change the initial value.
(flag_ira_region): New.
* ira-int.h (ira_reg_classes_intersect_p,
ira_reg_class_super_classes): New.
* ira-color.c (update_copy_costs): Use
ira_reg_classes_intersect_p. Use right class to find hard reg
index.
(update_conflict_hard_regno_costs): Ditto. Add a new parameter.
(assign_hard_reg): Ditto. Pass additional argument to
update_conflict_hard_regno_costs. Do not uncoalesce for priority
coloring.
(allocno_priorities, setup_allocno_priorities,
allocno_priority_compare_func): Move before color_allocnos.
(color_allocnos): Add priority coloring. Use flag flag_ira_region
instead of flag_ira_algorithm.
(move_spill_restore): Check classes of the same reg allocno from
different regions.
(update_curr_costs): Use ira_reg_classes_intersect_p.
(ira_reassign_conflict_allocnos): Ditto.
* opts.c (decode_options): Always set up flag_ira. Set up
flag_ira_algorithm. Warn CB can not be used for architecture.
(common_handle_option): Modify code for -fira-algorithm. Add code
to process -fira-region.
* ira-lives.c (update_allocno_pressure_excess_length): Process
superclasses too.
(set_allocno_live, clear_allocno_live, mark_reg_live,
mark_reg_dead, process_bb_node_lives): Ditto.
* ira-emit.c (ira_emit): Fix insn codes.
* ira-build.c (propagate_allocno_info): Use flag flag_ira_region
instead of flag_ira_algorithm.
(allocno_range_compare_func): Ignore classes for priority
coloring.
(setup_min_max_conflict_allocno_ids): Ditto.
(ira_flattening): Use ira_reg_classes_intersect_p.
* genpreds.c (write_enum_constraint_num): Output
CONSTRAINT__LIMIT.
* common.opt (fira-algorithm): Modify.
(fira-region): New.
* ira.c (setup_class_hard_regs): Initialize.
(setup_cover_and_important_classes): Modify code setting class
related info for priority coloring.
(setup_class_translate): Ditto.
(ira_reg_classes_intersect_p, ira_reg_class_super_classes): New.
(setup_reg_class_intersect_union): Rename to
setup_reg_class_relations. Add code for setting up new variables.
(find_reg_class_closure): Do not check targetm.ira_cover_classes.
(ira): Use flag flag_ira_region instead of flag_ira_algorithm.
* ira-costs.c (common_classes): New.
(print_costs): Use flag flag_ira_region instead of
flag_ira_algorithm.
(find_allocno_class_costs): Ditto. Use common_classes. Translate
alt_class.
(ira_costs): Allocate/deallocate common_classes.
* config/m32c/m32.h (REG_ALLOC_ORDER): Add reg 19.
(REG_CLASS_CONTENTS, reg_class, REG_CLASS_NAMES): New entries for
R02A_REGS.
* reload1.c (choose_reload_regs): Use MODE_INT for partial ints in
smallest_mode_for_size.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142610 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ira.c')
-rw-r--r-- | gcc/ira.c | 202 |
1 files changed, 156 insertions, 46 deletions
diff --git a/gcc/ira.c b/gcc/ira.c index 4b6854272f1..44f7032bf31 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -434,6 +434,8 @@ setup_class_hard_regs (void) COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); CLEAR_HARD_REG_SET (processed_hard_reg_set); + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + ira_class_hard_reg_index[cl][0] = -1; for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++) { #ifdef REG_ALLOC_ORDER @@ -714,22 +716,72 @@ enum reg_class ira_important_classes[N_REG_CLASSES]; classes. */ int ira_important_class_nums[N_REG_CLASSES]; -/* Check IRA_COVER_CLASSES and sets the four global variables defined - above. */ +/* Set the four global variables defined above. */ static void setup_cover_and_important_classes (void) { - int i, j; + int i, j, n; + bool set_p, eq_p; enum reg_class cl; - const enum reg_class *classes; + const enum reg_class *cover_classes; HARD_REG_SET temp_hard_regset2; + static enum reg_class classes[LIM_REG_CLASSES + 1]; + + if (targetm.ira_cover_classes == NULL) + cover_classes = NULL; + else + cover_classes = targetm.ira_cover_classes (); + if (cover_classes == NULL) + ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY); + else + { + for (i = 0; (cl = cover_classes[i]) != LIM_REG_CLASSES; i++) + classes[i] = cl; + classes[i] = LIM_REG_CLASSES; + } + + if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY) + { + n = 0; + for (i = 0; i <= LIM_REG_CLASSES; i++) + { + if (i == NO_REGS) + continue; +#ifdef CONSTRAINT__LIMIT + for (j = 0; j < CONSTRAINT__LIMIT; j++) + if ((int) regclass_for_constraint (j) == i) + break; + if (j < CONSTRAINT__LIMIT) + { + classes[n++] = i; + continue; + } +#endif + COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]); + AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + for (j = 0; j < LIM_REG_CLASSES; j++) + { + if (i == j) + continue; + COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[j]); + AND_COMPL_HARD_REG_SET (temp_hard_regset2, + no_unit_alloc_regs); + if (hard_reg_set_equal_p (temp_hard_regset, + temp_hard_regset2)) + break; + } + if (j >= i) + classes[n++] = i; + } + classes[n] = LIM_REG_CLASSES; + } - classes = targetm.ira_cover_classes (); ira_reg_class_cover_size = 0; for (i = 0; (cl = classes[i]) != LIM_REG_CLASSES; i++) { for (j = 0; j < i; j++) - if (reg_classes_intersect_p (cl, classes[j])) + if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY + && reg_classes_intersect_p (cl, classes[j])) gcc_unreachable (); COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); @@ -742,22 +794,34 @@ setup_cover_and_important_classes (void) COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); if (! hard_reg_set_empty_p (temp_hard_regset)) - for (j = 0; j < ira_reg_class_cover_size; j++) - { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - COPY_HARD_REG_SET (temp_hard_regset2, - reg_class_contents[ira_reg_class_cover[j]]); - AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); - if (cl == ira_reg_class_cover[j] - || (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2) - && ! hard_reg_set_equal_p (temp_hard_regset, - temp_hard_regset2))) - { - ira_important_class_nums[cl] = ira_important_classes_num; - ira_important_classes[ira_important_classes_num++] = cl; - } - } + { + set_p = eq_p = false; + for (j = 0; j < ira_reg_class_cover_size; j++) + { + COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + COPY_HARD_REG_SET (temp_hard_regset2, + reg_class_contents[ira_reg_class_cover[j]]); + AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); + if (cl == ira_reg_class_cover[j]) + { + eq_p = false; + set_p = true; + break; + } + else if (hard_reg_set_equal_p (temp_hard_regset, + temp_hard_regset2)) + eq_p = true; + else if (hard_reg_set_subset_p (temp_hard_regset, + temp_hard_regset2)) + set_p = true; + } + if (set_p && ! eq_p) + { + ira_important_class_nums[cl] = ira_important_classes_num; + ira_important_classes[ira_important_classes_num++] = cl; + } + } } } @@ -776,25 +840,44 @@ setup_class_translate (void) for (cl = 0; cl < N_REG_CLASSES; cl++) ira_class_translate[cl] = NO_REGS; + + if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY) + for (cl = 0; cl < LIM_REG_CLASSES; cl++) + { + COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + for (i = 0; i < ira_reg_class_cover_size; i++) + { + HARD_REG_SET temp_hard_regset2; + + cover_class = ira_reg_class_cover[i]; + COPY_HARD_REG_SET (temp_hard_regset2, + reg_class_contents[cover_class]); + AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); + if (hard_reg_set_equal_p (temp_hard_regset, temp_hard_regset2)) + ira_class_translate[cl] = cover_class; + } + } for (i = 0; i < ira_reg_class_cover_size; i++) { cover_class = ira_reg_class_cover[i]; - for (cl_ptr = &alloc_reg_class_subclasses[cover_class][0]; - (cl = *cl_ptr) != LIM_REG_CLASSES; - cl_ptr++) - { - if (ira_class_translate[cl] == NO_REGS) - ira_class_translate[cl] = cover_class; + if (flag_ira_algorithm != IRA_ALGORITHM_PRIORITY) + for (cl_ptr = &alloc_reg_class_subclasses[cover_class][0]; + (cl = *cl_ptr) != LIM_REG_CLASSES; + cl_ptr++) + { + if (ira_class_translate[cl] == NO_REGS) + ira_class_translate[cl] = cover_class; #ifdef ENABLE_IRA_CHECKING - else - { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - if (! hard_reg_set_empty_p (temp_hard_regset)) - gcc_unreachable (); - } + else + { + COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + if (! hard_reg_set_empty_p (temp_hard_regset)) + gcc_unreachable (); + } #endif - } + } ira_class_translate[cover_class] = cover_class; } /* For classes which are not fully covered by a cover class (in @@ -842,6 +925,17 @@ setup_class_translate (void) account. */ enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES]; +/* True if the two classes (that is calculated taking only hard + registers available for allocation into account) are + intersected. */ +bool ira_reg_classes_intersect_p[N_REG_CLASSES][N_REG_CLASSES]; + +/* Important classes with end marker LIM_REG_CLASSES which are + supersets with given important class (the first index). That + includes given class itself. This is calculated taking only hard + registers available for allocation into account. */ +enum reg_class ira_reg_class_super_classes[N_REG_CLASSES][N_REG_CLASSES]; + /* The biggest important reg_class inside of union of the two reg_classes (that is calculated taking only hard registers available for allocation into account). If the both reg_classes @@ -851,17 +945,23 @@ enum reg_class ira_reg_class_intersect[N_REG_CLASSES][N_REG_CLASSES]; reg_class_subunion value. */ enum reg_class ira_reg_class_union[N_REG_CLASSES][N_REG_CLASSES]; -/* Set up IRA_REG_CLASS_INTERSECT and IRA_REG_CLASS_UNION. */ +/* Set up the above reg class relations. */ static void -setup_reg_class_intersect_union (void) +setup_reg_class_relations (void) { int i, cl1, cl2, cl3; HARD_REG_SET intersection_set, union_set, temp_set2; + bool important_class_p[N_REG_CLASSES]; + memset (important_class_p, 0, sizeof (important_class_p)); + for (i = 0; i < ira_important_classes_num; i++) + important_class_p[ira_important_classes[i]] = true; for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++) { + ira_reg_class_super_classes[cl1][0] = LIM_REG_CLASSES; for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++) { + ira_reg_classes_intersect_p[cl1][cl2] = false; ira_reg_class_intersect[cl1][cl2] = NO_REGS; COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); @@ -882,6 +982,19 @@ setup_reg_class_intersect_union (void) ira_reg_class_union[cl1][cl2] = reg_class_subunion[cl1][cl2]; continue; } + ira_reg_classes_intersect_p[cl1][cl2] + = hard_reg_set_intersect_p (temp_hard_regset, temp_set2); + if (important_class_p[cl1] && important_class_p[cl2] + && hard_reg_set_subset_p (temp_hard_regset, temp_set2)) + { + enum reg_class *p; + + p = &ira_reg_class_super_classes[cl1][0]; + while (*p != LIM_REG_CLASSES) + p++; + *p++ = (enum reg_class) cl2; + *p = LIM_REG_CLASSES; + } ira_reg_class_union[cl1][cl2] = NO_REGS; COPY_HARD_REG_SET (intersection_set, reg_class_contents[cl1]); AND_HARD_REG_SET (intersection_set, reg_class_contents[cl2]); @@ -966,12 +1079,9 @@ static void find_reg_class_closure (void) { setup_reg_subclasses (); - if (targetm.ira_cover_classes) - { - setup_cover_and_important_classes (); - setup_class_translate (); - setup_reg_class_intersect_union (); - } + setup_cover_and_important_classes (); + setup_class_translate (); + setup_reg_class_relations (); } @@ -1804,8 +1914,8 @@ ira (FILE *f) if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL) fprintf (ira_dump_file, "Building IRA IR\n"); loops_p = ira_build (optimize - && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL - || flag_ira_algorithm == IRA_ALGORITHM_MIXED)); + && (flag_ira_region == IRA_REGION_ALL + || flag_ira_region == IRA_REGION_MIXED)); saved_flag_ira_share_spill_slots = flag_ira_share_spill_slots; if (too_high_register_pressure_p ()) |