summaryrefslogtreecommitdiff
path: root/gcc/reginfo.c
diff options
context:
space:
mode:
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-02 18:54:25 +0000
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-02 18:54:25 +0000
commita7dcf969769c6cd5f8dbe9f898d6f4ef74ed3605 (patch)
tree4fff239f690be40be173f6b04a6883338c271d49 /gcc/reginfo.c
parent1b9055fcbf86cce61f62555fa731a1ab7552dc74 (diff)
downloadgcc-a7dcf969769c6cd5f8dbe9f898d6f4ef74ed3605.tar.gz
2009-09-02 Vladimir Makarov <vmakarov@redhat.com>
* doc/invoke.texi (-fsched-pressure): Document it. (-fsched-reg-pressure-heuristic): Remove it. * reload.c (ira.h): Include. (find_reloads): Add choosing reload on number of small spilled classes. * haifa-sched.c (ira.h): Include. (sched_pressure_p, sched_regno_cover_class, curr_reg_pressure, saved_reg_pressure, curr_reg_live, saved_reg_live, region_ref_regs): New variables. (sched_init_region_reg_pressure_info, mark_regno_birth_or_death, initiate_reg_pressure_info, setup_ref_regs, initiate_bb_reg_pressure_info, save_reg_pressure, restore_reg_pressure, dying_use_p, print_curr_reg_pressure): New functions. (setup_insn_reg_pressure_info): New function. (rank_for_schedule): Add pressure checking and insn issue time. Remove comparison of insn reg weights. (ready_sort): Set insn reg pressure info. (update_register_pressure, setup_insn_max_reg_pressure, update_reg_and_insn_max_reg_pressure, sched_setup_bb_reg_pressure_info): New functions. (schedule_insn): Add code for printing and updating reg pressure info. (find_set_reg_weight, find_insn_reg_weight): Remove. (ok_for_early_queue_removal): Do nothing if pressure_only_p. (debug_ready_list): Print reg pressure info. (schedule_block): Ditto. Check insn issue time. (sched_init): Set up sched_pressure_p. Allocate and set up some reg pressure related info. (sched_finish): Free some reg pressure related info. (fix_tick_ready): Make insn always ready if pressure_p. (init_h_i_d): Don't call find_insn_reg_weight. (haifa_finish_h_i_d): Free insn reg pressure info. * ira-int.h (ira_hard_regno_cover_class, ira_reg_class_nregs, ira_memory_move_cost, ira_class_hard_regs, ira_class_hard_regs_num, ira_no_alloc_regs, ira_available_class_regs, ira_reg_class_cover_size, ira_reg_class_cover, ira_class_translate): Move to ira.h. * ira-lives.c (single_reg_class): Check mode to find how many registers are necessary for operand. (ira_implicitly_set_insn_hard_regs): New. * common.opt (fsched-pressure): New options. (fsched-reg-pressure-heuristic): Remove. * ira.c (setup_eliminable_regset): Rename to ira_setup_eliminable_regset. Make it external. (expand_reg_info): Pass cover class to setup_reg_classes. (ira): Call resize_reg_info instead of allocate_reg_info. * sched-deps.c: Include ira.h. (implicit_reg_pending_clobbers, implicit_reg_pending_uses): New. (create_insn_reg_use, create_insn_reg_set, setup_insn_reg_uses, reg_pressure_info, insn_use_p, mark_insn_pseudo_birth, mark_insn_hard_regno_birth, mark_insn_reg_birth, mark_pseudo_death, mark_hard_regno_death, mark_reg_death, mark_insn_reg_store, mark_insn_reg_clobber, setup_insn_reg_pressure_info): New. (sched_analyze_1): Update implicit_reg_pending_uses. (sched_analyze_insn): Find implicit sets, uses, clobbers of regs. Use them to create dependencies. Set insn reg uses and pressure info. Process reg_pending_uses in one place. (free_deps): Free implicit sets. (remove_from_deps): Remove implicit sets if necessary. Check implicit sets when clearing reg_last_in_use. (init_deps_global): Clear implicit_reg_pending_clobbers and implicit_reg_pending_uses. * ira.h (ira_hard_regno_cover_class, ira_reg_class_nregs, ira_memory_move_cost, ira_class_hard_regs, ira_class_hard_regs_num, ira_no_alloc_regs, ira_available_class_regs, ira_reg_class_cover_size, ira_reg_class_cover, ira_class_translate): Move from ira-int.h. (ira_setup_eliminable_regset, ira_set_pseudo_classes, ira_implicitly_set_insn_hard_regs): New prototypes. * ira-costs.c (pseudo_classes_defined_p, allocno_p, cost_elements_num): New variables. (allocno_costs, total_costs): Rename to costs and total_allocno_costs. (COSTS_OF_ALLOCNO): Rename to COSTS. (allocno_pref): Rename to pref. (allocno_pref_buffer): Rename to pref_buffer. (common_classes): Rename to regno_cover_class. (COST_INDEX): New. (record_reg_classes): Set allocno attributes only if allocno_p. (record_address_regs): Ditto. Use COST_INDEX instead of ALLOCNO_NUM. (scan_one_insn): Use COST_INDEX and COSTS instead of ALLOCNO_NUM and COSTS_OF_ALLOCNO. (print_costs): Rename to print_allocno_costs. (print_pseudo_costs): New. (process_bb_node_for_costs): Split into 2 functions with new function process_bb_for_costs. Pass BB to process_bb_for_costs. (find_allocno_class_costs): Rename to find_costs_and_classes. Add new parameter dump_file. Use cost_elements_num instead of ira_allocnos_num. Make one iteration if preferred classes were already calculated for scheduler. Make 2 versions of code depending on allocno_p. (setup_allocno_cover_class_and_costs): Check allocno_p. Use regno_cover_class and COSTS instead of common_classes and COSTS_OF_ALLOCNO. (init_costs, finish_costs): New. (ira_costs): Set up allocno_p and cost_elements_num. Call init_costs and finish_costs. (ira_set_pseudo_classes): New. * rtl.h (allocate_reg_info): Remove. (resize_reg_info): Change return type. (reg_cover_class): New. (setup_reg_classes): Add new parameter. * sched-int.h (struct deps_reg): New member implicit_sets. (sched_pressure_p, sched_regno_cover_class): New external definitions. (INCREASE_BITS): New macro. (struct reg_pressure_data, struct reg_use_data): New. (struct _haifa_insn_data): Remove reg_weight. Add members reg_pressure, reg_use_list, reg_set_list, and reg_pressure_excess_cost_change. (struct deps): New member implicit_sets. (pressure_p): New variable. (COVER_CLASS_BITS, INCREASE_BITS): New macros. (struct reg_pressure_data, struct reg_use_data): New. (INSN_REG_WEIGHT): Remove. (INSN_REG_PRESSURE, INSN_MAX_REG_PRESSURE, INSN_REG_USE_LIST, INSN_REG_SET_LIST, INSN_REG_PRESSURE_EXCESS_COST_CHANGE): New macros. (sched_init_region_reg_pressure_info, sched_setup_bb_reg_pressure_info): New prototypes. * reginfo.c (struct reg_pref): New member coverclass. (reg_cover_class): New function. (reginfo_init, pass_reginfo_init): Move after free_reg_info. (reg_info_size): New variable. (allocate_reg_info): Make static. Setup reg_info_size. (resize_reg_info): Use reg_info_size. Return flag of resizing. (setup_reg_classes): Add a new parameter. Setup cover class too. * Makefile.in (reload.o, haifa-sched.o, sched-deps.o): Add ira.h to the dependencies. * sched-rgn.c (deps_join): Set up implicit_sets. (schedule_region): Set up region and basic blocks pressure relative info. * passes.c (init_optimization_passes): Move pass_subregs_of_mode_init before pass_sched. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151348 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reginfo.c')
-rw-r--r--gcc/reginfo.c114
1 files changed, 70 insertions, 44 deletions
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index d5da41aeae1..9842dc14f77 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -898,6 +898,10 @@ struct reg_pref
but since it is recommended that there be a class corresponding to the
union of most major pair of classes, that generality is not required. */
char altclass;
+
+ /* coverclass is a register class that IRA uses for allocating
+ the pseudo. */
+ char coverclass;
};
/* Record preferences of each pseudo. This is available after RA is
@@ -925,65 +929,51 @@ reg_alternate_class (int regno)
return (enum reg_class) reg_pref[regno].altclass;
}
-/* Initialize some global data for this pass. */
-static unsigned int
-reginfo_init (void)
+/* Return the reg_class which is used by IRA for its allocation. */
+enum reg_class
+reg_cover_class (int regno)
{
- if (df)
- df_compute_regs_ever_live (true);
-
- /* This prevents dump_flow_info from losing if called
- before reginfo is run. */
- reg_pref = NULL;
+ if (reg_pref == 0)
+ return NO_REGS;
- /* No more global register variables may be declared. */
- no_global_reg_vars = 1;
- return 1;
+ return (enum reg_class) reg_pref[regno].coverclass;
}
-struct rtl_opt_pass pass_reginfo_init =
-{
- {
- RTL_PASS,
- "reginfo", /* name */
- NULL, /* gate */
- reginfo_init, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
-};
-
+/* Current size of reg_info. */
+static int reg_info_size;
+
/* Allocate space for reg info. */
-void
+static void
allocate_reg_info (void)
{
- int size = max_reg_num ();
-
+ reg_info_size = max_reg_num ();
gcc_assert (! reg_pref && ! reg_renumber);
- reg_renumber = XNEWVEC (short, size);
- reg_pref = XCNEWVEC (struct reg_pref, size);
- memset (reg_renumber, -1, size * sizeof (short));
+ reg_renumber = XNEWVEC (short, reg_info_size);
+ reg_pref = XCNEWVEC (struct reg_pref, reg_info_size);
+ memset (reg_renumber, -1, reg_info_size * sizeof (short));
}
/* Resize reg info. The new elements will be uninitialized. */
-void
+bool
resize_reg_info (void)
{
- int size = max_reg_num ();
+ int old;
+ gcc_assert (reg_pref != NULL);
+ if (reg_info_size == max_reg_num ())
+ return false;
+ old = reg_info_size;
+ reg_info_size = max_reg_num ();
gcc_assert (reg_pref && reg_renumber);
- reg_renumber = XRESIZEVEC (short, reg_renumber, size);
- reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, size);
+ reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size);
+ reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size);
+ memset (reg_pref + old, -1,
+ (reg_info_size - old) * sizeof (struct reg_pref));
+ memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short));
+ return true;
}
@@ -1004,19 +994,55 @@ free_reg_info (void)
}
}
+/* Initialize some global data for this pass. */
+static unsigned int
+reginfo_init (void)
+{
+ if (df)
+ df_compute_regs_ever_live (true);
+
+ /* This prevents dump_flow_info from losing if called
+ before reginfo is run. */
+ reg_pref = NULL;
+ allocate_reg_info ();
+ /* No more global register variables may be declared. */
+ no_global_reg_vars = 1;
+ return 1;
+}
+
+struct rtl_opt_pass pass_reginfo_init =
+{
+ {
+ RTL_PASS,
+ "reginfo", /* name */
+ NULL, /* gate */
+ reginfo_init, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+ }
+};
-/* Set up preferred and alternate classes for REGNO as PREFCLASS and
- ALTCLASS. */
+/* Set up preferred, alternate, and cover classes for REGNO as
+ PREFCLASS, ALTCLASS, and COVERCLASS. */
void
setup_reg_classes (int regno,
- enum reg_class prefclass, enum reg_class altclass)
+ enum reg_class prefclass, enum reg_class altclass,
+ enum reg_class coverclass)
{
if (reg_pref == NULL)
return;
reg_pref[regno].prefclass = prefclass;
reg_pref[regno].altclass = altclass;
+ reg_pref[regno].coverclass = coverclass;
}