From 2710a27af098557e37d3d131fa5a43dbfddab408 Mon Sep 17 00:00:00 2001 From: Joern Rennecke Date: Mon, 13 May 2013 00:29:36 +0000 Subject: [PATCH] Fix EH handling issue in last change: * config/epiphany/epiphany.c (epiphany_init): Check size of NUM_MODES_FOR_MODE_SWITCHING. (epiphany_expand_prologue): Remove CONFIG_REGNUM initial value handling code. (epiphany_optimize_mode_switching): Handle EPIPHANY_MSW_ENTITY_CONFIG. (epiphany_mode_needed, epiphany_mode_entry_exit): Likewise. (emit_set_fp_mode, epiphany_mode_after): Likewise. (epiphany_mode_needed) : Don't return 1 for FP_MODE_NONE. * config/epiphany/epiphany.h (NUM_MODES_FOR_MODE_SWITCHING): Add value for EPIPHANY_MSW_ENTITY_CONFIG. (EPIPHANY_MSW_ENTITY_CONFIG, EPIPHANY_MSW_ENTITY_NUM): Define. * config/epiphany/epiphany.md (save_config): New pattern. From-SVN: r198811 --- gcc/ChangeLog | 2 +- gcc/config/epiphany/epiphany.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 554ae34..51deae8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -6,7 +6,7 @@ Remove CONFIG_REGNUM initial value handling code. (epiphany_optimize_mode_switching): Handle EPIPHANY_MSW_ENTITY_CONFIG. (epiphany_mode_needed, epiphany_mode_entry_exit): Likewise. - (emit_set_fp_mode): Likewise. + (emit_set_fp_mode, epiphany_mode_after): Likewise. (epiphany_mode_needed) : Don't return 1 for FP_MODE_NONE. * config/epiphany/epiphany.h (NUM_MODES_FOR_MODE_SWITCHING): diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index 74192bf..3b6f63a 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -2328,7 +2328,15 @@ epiphany_mode_needed (int entity, rtx insn) just unchanged from the function start. Because of the nature of the mode switching optimization, a restore will be dominated by a clobber. */ - return mode != FP_MODE_NONE && mode != FP_MODE_CALLER ? 1 : 2; + if (mode != FP_MODE_NONE && mode != FP_MODE_CALLER) + return 1; + /* A cpecial case are abnormal edges, which are deemed to clobber + the mode as well. We need to pin this effect on a actually + dominating insn, and one where the frame can be accessed, too, in + case the pseudo used to save CONFIG doesn't get a hard register. */ + if (CALL_P (insn) && find_reg_note (insn, REG_EH_REGION, NULL_RTX)) + return 1; + return 2; case EPIPHANY_MSW_ENTITY_ROUND_KNOWN: if (recog_memoized (insn) == CODE_FOR_set_fp_mode) mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn); @@ -2402,6 +2410,18 @@ epiphany_mode_after (int entity, int last_mode, rtx insn) return 0; return last_mode; } + /* If there is an abnormal edge, we don't want the config register to + be 'saved' again at the destination. + The frame pointer adjustment is inside a PARALLEL because of the + flags clobber. */ + if (entity == EPIPHANY_MSW_ENTITY_CONFIG && NONJUMP_INSN_P (insn) + && GET_CODE (PATTERN (insn)) == PARALLEL + && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET + && SET_DEST (XVECEXP (PATTERN (insn), 0, 0)) == frame_pointer_rtx) + { + gcc_assert (cfun->has_nonlocal_label); + return 1; + } if (recog_memoized (insn) < 0) return last_mode; if (get_attr_fp_mode (insn) == FP_MODE_ROUND_UNKNOWN -- 2.7.4