diff options
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/haifa-sched.c | 85 | ||||
-rw-r--r-- | gcc/sched-int.h | 1 | ||||
-rw-r--r-- | gcc/sched-rgn.c | 13 |
4 files changed, 78 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0e3b699b6e..dbd04dbef42 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2014-02-18 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/58960 + * haifa-sched.c (alloc_global_sched_pressure_data): New, + factored out from ... + (sched_init): ... here. + (free_global_sched_pressure_data): New, factored out from ... + (sched_finish): ... here. + * sched-int.h (free_global_sched_pressure_data): Declare. + * sched-rgn.c (nr_regions_initial): New static global. + (haifa_find_rgns): Initialize it. + (schedule_region): Disable sched-pressure for the newly + generated regions. + 2014-02-17 Richard Biener <rguenther@suse.de> * tree-vect-stmts.c (free_stmt_vec_info): Clear BB and diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 4d51984f023..e0d467497fa 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -6553,6 +6553,54 @@ setup_sched_dump (void) ? stderr : dump_file); } +/* Allocate data for register pressure sensitive scheduling. */ +static void +alloc_global_sched_pressure_data (void) +{ + if (sched_pressure != SCHED_PRESSURE_NONE) + { + int i, max_regno = max_reg_num (); + + if (sched_dump != NULL) + /* We need info about pseudos for rtl dumps about pseudo + classes and costs. */ + regstat_init_n_sets_and_refs (); + ira_set_pseudo_classes (true, sched_verbose ? sched_dump : NULL); + sched_regno_pressure_class + = (enum reg_class *) xmalloc (max_regno * sizeof (enum reg_class)); + for (i = 0; i < max_regno; i++) + sched_regno_pressure_class[i] + = (i < FIRST_PSEUDO_REGISTER + ? ira_pressure_class_translate[REGNO_REG_CLASS (i)] + : ira_pressure_class_translate[reg_allocno_class (i)]); + curr_reg_live = BITMAP_ALLOC (NULL); + if (sched_pressure == SCHED_PRESSURE_WEIGHTED) + { + saved_reg_live = BITMAP_ALLOC (NULL); + region_ref_regs = BITMAP_ALLOC (NULL); + } + } +} + +/* Free data for register pressure sensitive scheduling. Also called + from schedule_region when stopping sched-pressure early. */ +void +free_global_sched_pressure_data (void) +{ + if (sched_pressure != SCHED_PRESSURE_NONE) + { + if (regstat_n_sets_and_refs != NULL) + regstat_free_n_sets_and_refs (); + if (sched_pressure == SCHED_PRESSURE_WEIGHTED) + { + BITMAP_FREE (region_ref_regs); + BITMAP_FREE (saved_reg_live); + } + BITMAP_FREE (curr_reg_live); + free (sched_regno_pressure_class); + } +} + /* Initialize some global state for the scheduler. This function works with the common data shared between all the schedulers. It is called from the scheduler specific initialization routine. */ @@ -6656,29 +6704,7 @@ sched_init (void) if (targetm.sched.init_global) targetm.sched.init_global (sched_dump, sched_verbose, get_max_uid () + 1); - if (sched_pressure != SCHED_PRESSURE_NONE) - { - int i, max_regno = max_reg_num (); - - if (sched_dump != NULL) - /* We need info about pseudos for rtl dumps about pseudo - classes and costs. */ - regstat_init_n_sets_and_refs (); - ira_set_pseudo_classes (true, sched_verbose ? sched_dump : NULL); - sched_regno_pressure_class - = (enum reg_class *) xmalloc (max_regno * sizeof (enum reg_class)); - for (i = 0; i < max_regno; i++) - sched_regno_pressure_class[i] - = (i < FIRST_PSEUDO_REGISTER - ? ira_pressure_class_translate[REGNO_REG_CLASS (i)] - : ira_pressure_class_translate[reg_allocno_class (i)]); - curr_reg_live = BITMAP_ALLOC (NULL); - if (sched_pressure == SCHED_PRESSURE_WEIGHTED) - { - saved_reg_live = BITMAP_ALLOC (NULL); - region_ref_regs = BITMAP_ALLOC (NULL); - } - } + alloc_global_sched_pressure_data (); curr_state = xmalloc (dfa_state_size); } @@ -6777,18 +6803,7 @@ void sched_finish (void) { haifa_finish_h_i_d (); - if (sched_pressure != SCHED_PRESSURE_NONE) - { - if (regstat_n_sets_and_refs != NULL) - regstat_free_n_sets_and_refs (); - if (sched_pressure == SCHED_PRESSURE_WEIGHTED) - { - BITMAP_FREE (region_ref_regs); - BITMAP_FREE (saved_reg_live); - } - BITMAP_FREE (curr_reg_live); - free (sched_regno_pressure_class); - } + free_global_sched_pressure_data (); free (curr_state); if (targetm.sched.finish_global) diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 2cec6247230..d04bf0876b1 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -1340,6 +1340,7 @@ extern void debug_ds (ds_t); extern void initialize_live_range_shrinkage (void); extern void finish_live_range_shrinkage (void); extern void sched_init_region_reg_pressure_info (void); +extern void free_global_sched_pressure_data (void); extern int haifa_classify_insn (const_rtx); extern void get_ebb_head_tail (basic_block, basic_block, rtx *, rtx *); extern int no_real_insns_p (const_rtx, const_rtx); diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 406dc1facd6..0573b6a6e8f 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -79,6 +79,9 @@ static int is_cfg_nonregular (void); /* Number of regions in the procedure. */ int nr_regions = 0; +/* Same as above before adding any new regions. */ +static int nr_regions_initial = 0; + /* Table of region descriptions. */ region *rgn_table = NULL; @@ -1064,6 +1067,7 @@ haifa_find_rgns (void) BLOCK_TO_BB (bb->index) = 0; } + nr_regions_initial = nr_regions; free (max_hdr); free (degree); free (stack); @@ -2991,6 +2995,15 @@ schedule_region (int rgn) rgn_n_insns = 0; + /* Do not support register pressure sensitive scheduling for the new regions + as we don't update the liveness info for them. */ + if (rgn >= nr_regions_initial) + { + if (sched_pressure != SCHED_PRESSURE_NONE) + free_global_sched_pressure_data (); + sched_pressure = SCHED_PRESSURE_NONE; + } + rgn_setup_region (rgn); /* Don't schedule region that is marked by |