diff options
Diffstat (limited to 'gcc-4.9/gcc/config/s390/s390.c')
-rw-r--r-- | gcc-4.9/gcc/config/s390/s390.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/gcc-4.9/gcc/config/s390/s390.c b/gcc-4.9/gcc/config/s390/s390.c index aac8de848..866de858c 100644 --- a/gcc-4.9/gcc/config/s390/s390.c +++ b/gcc-4.9/gcc/config/s390/s390.c @@ -9130,11 +9130,14 @@ s390_emit_epilogue (bool sibcall) if (! sibcall) { /* Fetch return address from stack before load multiple, - this will do good for scheduling. */ - - if (cfun_frame_layout.save_return_addr_p - || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM - && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM)) + this will do good for scheduling. + + Only do this if we already decided that r14 needs to be + saved to a stack slot. (And not just because r14 happens to + be in between two GPRs which need saving.) Otherwise it + would be difficult to take that decision back in + s390_optimize_prologue. */ + if (cfun_gpr_save_slot (RETURN_REGNUM) == -1) { int return_regnum = find_unused_clobbered_reg(); if (!return_regnum) @@ -9149,6 +9152,12 @@ s390_emit_epilogue (bool sibcall) addr = gen_rtx_MEM (Pmode, addr); set_mem_alias_set (addr, get_frame_alias_set ()); emit_move_insn (return_reg, addr); + + /* Once we did that optimization we have to make sure + s390_optimize_prologue does not try to remove the + store of r14 since we will not be able to find the + load issued here. */ + cfun_frame_layout.save_return_addr_p = true; } } |