This patch attempts to fix problems with the first scheduling pass creating too much register pressure. It does this by enabling the target hook to compute the pressure classes for rs6000 target since the first thing I observed while investigating the testcase in the subject PR is that IRA was picking NON_SPECIAL_REGS as a pressure class which led to the sched-pressure code computing too high of a value for number of regs available for pseudos preferring GENERAL_REGS. It also enables -fsched-pressure by default, using the 'model' algorithm.
I ran various runs of cpu20006 to determine the set of pressure classes and which sched-pressure algorithm to use. Net result is that with these patches I see 6 benchmarks improve in the 2.4-6% range but there are also a couple 2% degradations which will need follow up in GCC 8. There was also one benchmark that showed a much bigger improvement with the 'weighted' sched-pressure algorithm that also needs follow up ('weighted' was not chosen as default since it showed more degradations). Bootstrap/regtest on powerpc64/powerpc64le. There were 2 testcases that failed (sms-3.c/sms-6.c) but I have submitted a separate patch to fix those. Ok for trunk? -Pat 2016-12-20 Pat Haugen <pthau...@us.ibm.com> PR rtl-optimization/11488 * common/config/rs6000/rs6000-common.c (rs6000_option_optimization_table): Enable -fsched-pressure. * config/rs6000/rs6000.c (TARGET_COMPUTE_PRESSURE_CLASSES): Define target hook. (rs6000_option_override_internal): Set default -fsched-pressure algorithm. (rs6000_compute_pressure_classes): Implement target hook.
Index: common/config/rs6000/rs6000-common.c =================================================================== --- common/config/rs6000/rs6000-common.c (revision 243651) +++ common/config/rs6000/rs6000-common.c (working copy) @@ -32,6 +32,8 @@ static const struct default_options rs6000_option_optimization_table[] = { { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + /* Enable -fsched-pressure for first pass instruction scheduling. */ + { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; Index: config/rs6000/rs6000.c =================================================================== --- config/rs6000/rs6000.c (revision 243651) +++ config/rs6000/rs6000.c (working copy) @@ -1807,6 +1807,9 @@ static const struct attribute_spec rs600 #undef TARGET_LRA_P #define TARGET_LRA_P rs6000_lra_p +#undef TARGET_COMPUTE_PRESSURE_CLASSES +#define TARGET_COMPUTE_PRESSURE_CLASSES rs6000_compute_pressure_classes + #undef TARGET_CAN_ELIMINATE #define TARGET_CAN_ELIMINATE rs6000_can_eliminate @@ -5100,6 +5103,12 @@ rs6000_option_override_internal (bool gl global_options.x_param_values, global_options_set.x_param_values); + /* Use the 'model' -fsched-pressure algorithm by default. */ + maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, + SCHED_PRESSURE_MODEL, + global_options.x_param_values, + global_options_set.x_param_values); + /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0) can be optimized to ap = __builtin_next_arg (0). */ @@ -37450,6 +37459,32 @@ rs6000_lra_p (void) return TARGET_LRA; } +/* Compute register pressure classes. We implement the target hook to avoid + IRA picking something like NON_SPECIAL_REGS as a pressure class, which can + lead to incorrect estimates of number of available registers and therefor + increased register pressure/spill. */ +static int +rs6000_compute_pressure_classes (enum reg_class *pressure_classes) +{ + int n; + + n = 0; + pressure_classes[n++] = GENERAL_REGS; + if (TARGET_VSX) + pressure_classes[n++] = VSX_REGS; + else + { + if (TARGET_ALTIVEC) + pressure_classes[n++] = ALTIVEC_REGS; + if (TARGET_HARD_FLOAT && TARGET_FPRS) + pressure_classes[n++] = FLOAT_REGS; + } + pressure_classes[n++] = CR_REGS; + pressure_classes[n++] = SPECIAL_REGS; + + return n; +} + /* Given FROM and TO register numbers, say whether this elimination is allowed. Frame pointer elimination is automatically handled.