This patch fixes the CFA notes used when an epilogue restores a GPR from an FPR. It also makes sure that s390_optimize_prologue preserves the CFA information.
Tested in the same way as the previous patch. OK to install? Thanks, Richard gcc/ * config/s390/s390.c (s390_restore_gprs_from_fprs): Add REG_CFA_RESTORE notes to each restore. Also add REG_CFA_DEF_CFA when restoring %r15. (s390_optimize_prologue): Don't clear RTX_FRAME_RELATED_P. Update the REG_CFA_RESTORE list when deciding not to restore a register. Index: gcc/config/s390/s390.c =================================================================== --- gcc/config/s390/s390.c 2014-01-31 17:20:31.582196663 +0000 +++ gcc/config/s390/s390.c 2014-02-04 11:15:41.085329442 +0000 @@ -8603,11 +8603,11 @@ s390_restore_gprs_from_fprs (void) emit_move_insn (gen_rtx_REG (DImode, i), gen_rtx_REG (DImode, cfun_gpr_save_slot (i))); df_set_regs_ever_live (i, true); - /* The frame related flag is only required on the save - operations. We nevertheless set it also for the restore - in order to recognize these instructions in - s390_optimize_prologue. The flag will then be - deleted. */ + add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, i)); + if (i == STACK_POINTER_REGNUM) + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (Pmode, stack_pointer_rtx, + STACK_POINTER_OFFSET)); RTX_FRAME_RELATED_P (insn) = 1; } } @@ -10847,12 +10847,6 @@ s390_optimize_prologue (void) || call_really_used_regs[gpr_regno]) continue; - /* For restores we have to revert the frame related flag - since no debug info is supposed to be generated for - these. */ - if (dest_regno == gpr_regno) - RTX_FRAME_RELATED_P (insn) = 0; - /* It must not happen that what we once saved in an FPR now needs a stack slot. */ gcc_assert (cfun_gpr_save_slot (gpr_regno) != -1); @@ -10935,8 +10929,6 @@ s390_optimize_prologue (void) if (GET_CODE (base) != REG || off < 0) continue; - RTX_FRAME_RELATED_P (insn) = 0; - if (cfun_frame_layout.first_restore_gpr != -1 && (cfun_frame_layout.first_restore_gpr < first || cfun_frame_layout.last_restore_gpr > last)) @@ -10954,8 +10946,19 @@ s390_optimize_prologue (void) - first) * UNITS_PER_LONG, cfun_frame_layout.first_restore_gpr, cfun_frame_layout.last_restore_gpr); - RTX_FRAME_RELATED_P (new_insn) = 0; + + /* Remove REG_CFA_RESTOREs for registers that we no + longer need to save. */ + REG_NOTES (new_insn) = REG_NOTES (insn); + for (rtx *ptr = ®_NOTES (new_insn); *ptr; ) + if (REG_NOTE_KIND (*ptr) == REG_CFA_RESTORE + && ((int) REGNO (XEXP (*ptr, 0)) + < cfun_frame_layout.first_restore_gpr)) + *ptr = XEXP (*ptr, 1); + else + ptr = &XEXP (*ptr, 1); new_insn = emit_insn_before (new_insn, insn); + RTX_FRAME_RELATED_P (new_insn) = 1; INSN_ADDRESSES_NEW (new_insn, -1); } @@ -10977,8 +10980,6 @@ s390_optimize_prologue (void) if (GET_CODE (base) != REG || off < 0) continue; - RTX_FRAME_RELATED_P (insn) = 0; - if (REGNO (base) != STACK_POINTER_REGNUM && REGNO (base) != HARD_FRAME_POINTER_REGNUM) continue;