Hello,
As detailed in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58960#c6, we
fail to use the DF liveness info in the register pressure sensitive
scheduling for the new blocks as we do not properly compute it in this
case. The patch fixes this by avoiding to use the sched-pressure for the
new regions, as currently these are only ia64 recovery blocks and supposed
to be cold. In the case we'd get other cases of the new blocks, this may
be reconsidered. The other options of computing the DF info sketched at
the above link do not seem plausible for this stage.
Bootstrapped and tested on ia64, also tested by Andreas Schwab on ia64 (see
PR log). OK for trunk?
Andrey
2013-01-30 Andrey Belevantsev
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.
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 4d51984..45398bf 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -6553,6 +6553,53 @@ 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. */
+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 +6703,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 +6802,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 3b1106f..b5481b9 100644
--- a/gcc/sched-int.h
+++ b/gcc/sched-int.h
@@ -1337,6 +1337,7 @@ extern void debug_ds (ds_t);
extern void initialize_live_range_shrinkage (void);
extern void finish_live_range_shrinkage (void);
extern voi