diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 62 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/pr89952.c | 12 |
4 files changed, 86 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c70df7..6d09649 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-04-24 Andreas Krebbel <krebbel@linux.ibm.com> + + PR target/89952 + * config/s390/s390.c (s390_restore_gprs_from_fprs): Restore GPRs + from FPRs in reverse order. Generate REG_CFA_DEF_CFA note also + for restored hard frame pointer. + (s390_sched_dependencies_evaluation): Implement new target hook. + (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK): New macro definition. + 2019-04-24 Claudiu Zissulescu <claziss@sysnopsys.com> * config/arc/arc-options.def: Fix typos and spelling mistakes. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index ad8eacd..fc4571d 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -10685,7 +10685,11 @@ s390_restore_gprs_from_fprs (void) if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf) return; - for (i = 6; i < 16; i++) + /* Restore the GPRs starting with the stack pointer. That way the + stack pointer already has its original value when it comes to + restoring the hard frame pointer. So we can set the cfa reg back + to the stack pointer. */ + for (i = STACK_POINTER_REGNUM; i >= 6; i--) { rtx_insn *insn; @@ -10701,7 +10705,13 @@ s390_restore_gprs_from_fprs (void) df_set_regs_ever_live (i, true); add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, i)); - if (i == STACK_POINTER_REGNUM) + + /* If either the stack pointer or the frame pointer get restored + set the CFA value to its value at function start. Doing this + for the frame pointer results in .cfi_def_cfa_register 15 + what is ok since if the stack pointer got modified it has + been restored already. */ + if (i == STACK_POINTER_REGNUM || i == HARD_FRAME_POINTER_REGNUM) add_reg_note (insn, REG_CFA_DEF_CFA, plus_constant (Pmode, stack_pointer_rtx, STACK_POINTER_OFFSET)); @@ -16294,6 +16304,49 @@ s390_case_values_threshold (void) return default_case_values_threshold (); } +/* Evaluate the insns between HEAD and TAIL and do back-end to install + back-end specific dependencies. + + Establish an ANTI dependency between r11 and r15 restores from FPRs + to prevent the instructions scheduler from reordering them since + this would break CFI. No further handling in the sched_reorder + hook is required since the r11 and r15 restore will never appear in + the same ready list with that change. */ +void +s390_sched_dependencies_evaluation (rtx_insn *head, rtx_insn *tail) +{ + if (!frame_pointer_needed || !epilogue_completed) + return; + + while (head != tail && DEBUG_INSN_P (head)) + head = NEXT_INSN (head); + + rtx_insn *r15_restore = NULL, *r11_restore = NULL; + + for (rtx_insn *insn = tail; insn != head; insn = PREV_INSN (insn)) + { + rtx set = single_set (insn); + if (!INSN_P (insn) + || !RTX_FRAME_RELATED_P (insn) + || set == NULL_RTX + || !REG_P (SET_DEST (set)) + || !FP_REG_P (SET_SRC (set))) + continue; + + if (REGNO (SET_DEST (set)) == HARD_FRAME_POINTER_REGNUM) + r11_restore = insn; + + if (REGNO (SET_DEST (set)) == STACK_POINTER_REGNUM) + r15_restore = insn; + } + + if (r11_restore == NULL || r15_restore == NULL) + return; + add_dependence (r11_restore, r15_restore, REG_DEP_ANTI); +} + + + /* Initialize GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -16585,6 +16638,11 @@ s390_case_values_threshold (void) #undef TARGET_CASE_VALUES_THRESHOLD #define TARGET_CASE_VALUES_THRESHOLD s390_case_values_threshold +#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK +#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \ + s390_sched_dependencies_evaluation + + /* Use only short displacement, since long displacement is not available for the floating point instructions. */ #undef TARGET_MAX_ANCHOR_OFFSET diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 42e7516..6a34f20 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-24 Andreas Krebbel <krebbel@linux.ibm.com> + + PR target/89952 + * gcc.target/s390/pr89952.c: New test. + 2019-04-24 Jakub Jelinek <jakub@redhat.com> PR target/90187 diff --git a/gcc/testsuite/gcc.target/s390/pr89952.c b/gcc/testsuite/gcc.target/s390/pr89952.c new file mode 100644 index 0000000..9f48e08 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr89952.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=zEC12 -fno-omit-frame-pointer -Os" } */ + + +extern void j(int); + +void +d(int e, long f, int g, int h, int i) { + if (h == 5 && i >= 4 && i <= 7) + h = e; + j(h); +} |