This patch fixes cases where we start a new group although the previous one has not ended.
Regression tested on s390x. gcc/ChangeLog: 2017-10-11 Robin Dapp <rd...@linux.vnet.ibm.com> * config/s390/s390.c (s390_has_ok_fallthru): New function. (s390_sched_score): Temporarily change s390_sched_state. (s390_sched_variable_issue): Use s390_last_sched_state in case the group is not finished yet. (s390_sched_init): Init s390_last_sched_state. --- gcc/config/s390/s390.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 2411c67..7f08ba2 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -14346,6 +14346,31 @@ s390_z10_prevent_earlyload_conflicts (rtx_insn **ready, int *nready_p) ready[0] = tmp; } +static bool +s390_has_ok_fallthru (rtx_insn *insn) +{ + edge e, fallthru_edge; + edge_iterator ei; + bool other_likely_edge = false; + + fallthru_edge = + find_fallthru_edge (BLOCK_FOR_INSN (insn)->preds); + FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->preds) + { + if (e != fallthru_edge + && e->probability >= profile_probability::unlikely ()) + { + other_likely_edge = true; + break; + } + } + + if (fallthru_edge && !other_likely_edge) + return true; + + return false; +} + /* The s390_sched_state variable tracks the state of the current or the last instruction group. @@ -14355,6 +14380,7 @@ s390_z10_prevent_earlyload_conflicts (rtx_insn **ready, int *nready_p) 4 the last group was a cracked/expanded insn */ static int s390_sched_state; +static int s390_last_sched_state; #define S390_SCHED_STATE_NORMAL 3 #define S390_SCHED_STATE_CRACKED 4 @@ -14430,7 +14456,14 @@ s390_sched_score (rtx_insn *insn) unsigned int mask = s390_get_sched_attrmask (insn); int score = 0; - switch (s390_sched_state) + int temp_sched_state = s390_sched_state; + + if (s390_sched_state < s390_last_sched_state + && s390_last_sched_state < S390_SCHED_STATE_NORMAL + && s390_has_ok_fallthru (insn)) + temp_sched_state = s390_last_sched_state; + + switch (temp_sched_state) { case 0: /* Try to put insns into the first slot which would otherwise @@ -14656,11 +14689,15 @@ s390_sched_variable_issue (FILE *file, int verbose, rtx_insn *insn, int more) switch (s390_sched_state) { case 0: + if (s390_last_sched_state > 0 && s390_has_ok_fallthru (insn)) + s390_sched_state = s390_last_sched_state; + + if (s390_sched_state == 0) + starts_group = true; + /* fallthrough */ case 1: case 2: case S390_SCHED_STATE_NORMAL: - if (s390_sched_state == 0) - starts_group = true; if (s390_sched_state == S390_SCHED_STATE_NORMAL) { starts_group = true; @@ -14768,6 +14805,7 @@ s390_sched_init (FILE *file ATTRIBUTE_UNUSED, { last_scheduled_insn = NULL; memset (last_scheduled_unit_distance, 0, MAX_SCHED_UNITS * sizeof (int)); + s390_last_sched_state = s390_sched_state; s390_sched_state = 0; } -- 2.9.4