X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fira.c;h=e3d3fe3038598a18d4bbe082cf9c23b3c212c86d;hb=084e63568d05c56b5c0ac234c2fe80933487aa4e;hp=79deab6344ddf84a15654015bcba774abbc09e78;hpb=212e5c4fd6d50814fa16c907fed34b465cc3f876;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/ira.c b/gcc/ira.c index 79deab6344d..e3d3fe30385 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -383,6 +383,7 @@ along with GCC; see the file COPYING3. If not see #include "integrate.h" #include "ggc.h" #include "ira-int.h" +#include "dce.h" struct target_ira default_target_ira; @@ -583,11 +584,11 @@ setup_class_subset_and_memory_move_costs (void) ira_max_memory_move_cost[mode][cl][0] = ira_memory_move_cost[mode][cl][0] = memory_move_cost ((enum machine_mode) mode, - (enum reg_class) cl, false); + (reg_class_t) cl, false); ira_max_memory_move_cost[mode][cl][1] = ira_memory_move_cost[mode][cl][1] = memory_move_cost ((enum machine_mode) mode, - (enum reg_class) cl, true); + (reg_class_t) cl, true); /* Costs for NO_REGS are used in cost calculation on the 1st pass when the preferred register classes are not known yet. In this case we take the best scenario. */ @@ -799,27 +800,35 @@ setup_pressure_classes (void) { if (ira_available_class_regs[cl] == 0) continue; - /* Check that the moves between any hard registers of the - current class are not more expensive for a legal mode than - load/store of the hard registers of the current class. Such - class is a potential candidate to be a register pressure - class. */ - for (m = 0; m < NUM_MACHINE_MODES; m++) + if (ira_available_class_regs[cl] != 1 + /* A register class without subclasses may contain a few + hard registers and movement between them is costly + (e.g. SPARC FPCC registers). We still should consider it + as a candidate for a pressure class. */ + && alloc_reg_class_subclasses[cl][0] != LIM_REG_CLASSES) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - AND_COMPL_HARD_REG_SET (temp_hard_regset, - ira_prohibited_class_mode_regs[cl][m]); - if (hard_reg_set_empty_p (temp_hard_regset)) + /* Check that the moves between any hard registers of the + current class are not more expensive for a legal mode + than load/store of the hard registers of the current + class. Such class is a potential candidate to be a + register pressure class. */ + for (m = 0; m < NUM_MACHINE_MODES; m++) + { + COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + AND_COMPL_HARD_REG_SET (temp_hard_regset, + ira_prohibited_class_mode_regs[cl][m]); + if (hard_reg_set_empty_p (temp_hard_regset)) + continue; + ira_init_register_move_cost_if_necessary ((enum machine_mode) m); + cost = ira_register_move_cost[m][cl][cl]; + if (cost <= ira_max_memory_move_cost[m][cl][1] + || cost <= ira_max_memory_move_cost[m][cl][0]) + break; + } + if (m >= NUM_MACHINE_MODES) continue; - ira_init_register_move_cost_if_necessary ((enum machine_mode) m); - cost = ira_register_move_cost[m][cl][cl]; - if (cost <= ira_max_memory_move_cost[m][cl][1] - || cost <= ira_max_memory_move_cost[m][cl][0]) - break; } - if (m >= NUM_MACHINE_MODES) - continue; curr = 0; insert_p = true; COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); @@ -848,6 +857,8 @@ setup_pressure_classes (void) && (! hard_reg_set_equal_p (temp_hard_regset2, temp_hard_regset) || cl == (int) GENERAL_REGS)) continue; + if (hard_reg_set_equal_p (temp_hard_regset2, temp_hard_regset)) + insert_p = false; pressure_classes[curr++] = (enum reg_class) cl2; } /* If the current candidate is a subset of a so far added @@ -858,23 +869,44 @@ setup_pressure_classes (void) n = curr; } #ifdef ENABLE_IRA_CHECKING - /* Check pressure classes correctness: here we check that hard - registers from all register pressure classes contains all hard - registers available for the allocation. */ - CLEAR_HARD_REG_SET (temp_hard_regset); - CLEAR_HARD_REG_SET (temp_hard_regset2); - for (cl = 0; cl <= LIM_REG_CLASSES; cl++) - { - for (i = 0; i < n; i++) - if ((int) pressure_classes[i] == cl) - break; - IOR_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl]); - if (i >= n) - IOR_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); - } - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); - ira_assert (hard_reg_set_subset_p (temp_hard_regset2, temp_hard_regset)); + { + HARD_REG_SET ignore_hard_regs; + + /* Check pressure classes correctness: here we check that hard + registers from all register pressure classes contains all hard + registers available for the allocation. */ + CLEAR_HARD_REG_SET (temp_hard_regset); + CLEAR_HARD_REG_SET (temp_hard_regset2); + COPY_HARD_REG_SET (ignore_hard_regs, no_unit_alloc_regs); + for (cl = 0; cl < LIM_REG_CLASSES; cl++) + { + /* For some targets (like MIPS with MD_REGS), there are some + classes with hard registers available for allocation but + not able to hold value of any mode. */ + for (m = 0; m < NUM_MACHINE_MODES; m++) + if (contains_reg_of_mode[cl][m]) + break; + if (m >= NUM_MACHINE_MODES) + { + IOR_HARD_REG_SET (ignore_hard_regs, reg_class_contents[cl]); + continue; + } + for (i = 0; i < n; i++) + if ((int) pressure_classes[i] == cl) + break; + IOR_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl]); + if (i < n) + IOR_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + } + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + /* Some targets (like SPARC with ICC reg) have alocatable regs + for which no reg class is defined. */ + if (REGNO_REG_CLASS (i) == NO_REGS) + SET_HARD_REG_BIT (ignore_hard_regs, i); + AND_COMPL_HARD_REG_SET (temp_hard_regset, ignore_hard_regs); + AND_COMPL_HARD_REG_SET (temp_hard_regset2, ignore_hard_regs); + ira_assert (hard_reg_set_subset_p (temp_hard_regset2, temp_hard_regset)); + } #endif ira_pressure_classes_num = 0; for (i = 0; i < n; i++) @@ -923,7 +955,7 @@ setup_allocno_and_important_classes (void) /* Collect classes which contain unique sets of allocatable hard registers. Prefer GENERAL_REGS to other classes containing the same set of hard registers. */ - for (i = 0; i <= LIM_REG_CLASSES; i++) + for (i = 0; i < LIM_REG_CLASSES; i++) { COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); @@ -1371,7 +1403,7 @@ setup_reg_class_nregs (void) for (cl = 0; cl < N_REG_CLASSES; cl++) ira_reg_class_max_nregs[cl][m] = ira_reg_class_min_nregs[cl][m] - = CLASS_MAX_NREGS ((enum reg_class) cl, (enum machine_mode) m); + = targetm.class_max_nregs ((reg_class_t) cl, (enum machine_mode) m); for (cl = 0; cl < N_REG_CLASSES; cl++) for (i = 0; (cl2 = alloc_reg_class_subclasses[cl][i]) != LIM_REG_CLASSES; @@ -1422,6 +1454,12 @@ clarify_prohibited_class_mode_regs (void) if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno)) continue; nregs = hard_regno_nregs[hard_regno][j]; + if (hard_regno + nregs > FIRST_PSEUDO_REGISTER) + { + SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], + hard_regno); + continue; + } pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)]; for (nregs-- ;nregs >= 0; nregs--) if (((enum reg_class) pclass @@ -1463,6 +1501,10 @@ ira_init_register_move_cost (enum machine_mode mode) sizeof (move_table) * N_REG_CLASSES); for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++) { + /* Some subclasses are to small to have enough registers to hold + a value of MODE. Just ignore them. */ + if (ira_reg_class_max_nregs[cl1][mode] > ira_available_class_regs[cl1]) + continue; COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); if (hard_reg_set_empty_p (temp_hard_regset)) @@ -1556,16 +1598,11 @@ free_register_move_costs (void) for (mode = 0; mode < MAX_MACHINE_MODE; mode++) { - if (ira_max_register_move_cost[mode] != NULL) - free (ira_max_register_move_cost[mode]); - if (ira_may_move_in_cost[mode] != NULL) - free (ira_may_move_in_cost[mode]); - if (ira_may_move_out_cost[mode] != NULL) - free (ira_may_move_out_cost[mode]); - if (ira_max_may_move_in_cost[mode] != NULL) - free (ira_max_may_move_in_cost[mode]); - if (ira_max_may_move_out_cost[mode] != NULL) - free (ira_max_may_move_out_cost[mode]); + free (ira_max_register_move_cost[mode]); + free (ira_may_move_in_cost[mode]); + free (ira_may_move_out_cost[mode]); + free (ira_max_may_move_in_cost[mode]); + free (ira_max_may_move_out_cost[mode]); ira_register_move_cost[mode] = NULL; ira_max_register_move_cost[mode] = NULL; ira_may_move_in_cost[mode] = NULL; @@ -1724,16 +1761,10 @@ compute_regs_asm_clobbered (void) { df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); - if (dregno < FIRST_PSEUDO_REGISTER) - { - unsigned int i; - enum machine_mode mode = GET_MODE (DF_REF_REAL_REG (def)); - unsigned int end = dregno - + hard_regno_nregs[dregno][mode] - 1; - - for (i = dregno; i <= end; ++i) - SET_HARD_REG_BIT(crtl->asm_clobbers, i); - } + if (HARD_REGISTER_NUM_P (dregno)) + add_to_hard_reg_set (&crtl->asm_clobbers, + GET_MODE (DF_REF_REAL_REG (def)), + dregno); } } } @@ -1926,8 +1957,8 @@ setup_reg_renumber (void) reg_class_contents[pclass]); } if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 - && ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), - call_used_reg_set)) + && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), + call_used_reg_set)) { ira_assert (!optimize || flag_caller_saves || regno >= ira_reg_equiv_len @@ -1965,10 +1996,10 @@ setup_allocno_assignment_flags (void) || ALLOCNO_EMIT_DATA (a)->mem_optimized_dest_p || (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)) < 0); - ira_assert (hard_regno < 0 - || ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), - reg_class_contents - [ALLOCNO_CLASS (a)])); + ira_assert + (hard_regno < 0 + || ira_hard_reg_in_set_p (hard_regno, ALLOCNO_MODE (a), + reg_class_contents[ALLOCNO_CLASS (a)])); } } @@ -1986,9 +2017,9 @@ calculate_allocation_cost (void) { hard_regno = ALLOCNO_HARD_REGNO (a); ira_assert (hard_regno < 0 - || ! ira_hard_reg_not_in_set_p - (hard_regno, ALLOCNO_MODE (a), - reg_class_contents[ALLOCNO_CLASS (a)])); + || (ira_hard_reg_in_set_p + (hard_regno, ALLOCNO_MODE (a), + reg_class_contents[ALLOCNO_CLASS (a)]))); if (hard_regno < 0) { cost = ALLOCNO_MEMORY_COST (a); @@ -3467,8 +3498,7 @@ build_insn_chain (void) } for (i = 0; i < (unsigned int) max_regno; i++) - if (live_subregs[i]) - free (live_subregs[i]); + free (live_subregs[i]); reload_insn_chain = c; *p = NULL; @@ -3501,6 +3531,7 @@ ira (FILE *f) int rebuild_p; int saved_flag_ira_share_spill_slots; basic_block bb; + bool need_dce; timevar_push (TV_IRA); @@ -3590,9 +3621,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_region == IRA_REGION_ALL - || flag_ira_region == IRA_REGION_MIXED)); + loops_p = ira_build (flag_ira_region == IRA_REGION_ALL + || flag_ira_region == IRA_REGION_MIXED); ira_assert (ira_conflicts_p || !loops_p); @@ -3692,7 +3722,7 @@ ira (FILE *f) df_set_flags (DF_NO_INSN_RESCAN); build_insn_chain (); - reload_completed = !reload (get_insns (), ira_conflicts_p); + need_dce = reload (get_insns (), ira_conflicts_p); timevar_pop (TV_RELOAD); @@ -3735,7 +3765,7 @@ ira (FILE *f) #endif /* The code after the reload has changed so much that at this point - we might as well just rescan everything. Not that + we might as well just rescan everything. Note that df_rescan_all_insns is not going to help here because it does not touch the artificial uses and defs. */ df_finish_pass (true); @@ -3747,6 +3777,9 @@ ira (FILE *f) if (optimize) df_analyze (); + if (need_dce && optimize) + run_fast_dce (); + timevar_pop (TV_IRA); } @@ -3781,7 +3814,6 @@ struct rtl_opt_pass pass_ira = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } };