Fix EH handling issue in last change:
authorJoern Rennecke <joern.rennecke@embecosm.com>
Mon, 13 May 2013 00:29:36 +0000 (00:29 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Mon, 13 May 2013 00:29:36 +0000 (01:29 +0100)
        * 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) <Handle EPIPHANY_MSW_ENTITY_AND>:
        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
gcc/config/epiphany/epiphany.c

index 554ae34..51deae8 100644 (file)
@@ -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) <Handle EPIPHANY_MSW_ENTITY_AND>:
        Don't return 1 for FP_MODE_NONE.
        * config/epiphany/epiphany.h (NUM_MODES_FOR_MODE_SWITCHING):
index 74192bf..3b6f63a 100644 (file)
@@ -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