2014-10-07 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 Oct 2014 16:17:57 +0000 (16:17 +0000)
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 Oct 2014 16:17:57 +0000 (16:17 +0000)
Backport from trunk r209643, r211881.
2014-06-22  Richard Henderson  <rth@redhat.com>

PR target/61565
* compare-elim.c (struct comparison): Add eh_note.
(find_comparison_dom_walker::before_dom_children): Don't eliminate
a redundant comparison in a different EH region.  Purge EH edges if
necessary.

2014-04-22  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>

* config/aarch64/aarch64.c (TARGET_FLAGS_REGNUM): Define.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@215975 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog.linaro
gcc/compare-elim.c
gcc/config/aarch64/aarch64.c

index e8e203b..40ddf23 100644 (file)
@@ -1,3 +1,18 @@
+2014-10-07  Venkataramanan Kumar  <venkataramanan.kumar@linaro.org>
+
+       Backport from trunk r209643, r211881.
+       2014-06-22  Richard Henderson  <rth@redhat.com>
+
+       PR target/61565
+       * compare-elim.c (struct comparison): Add eh_note.
+       (find_comparison_dom_walker::before_dom_children): Don't eliminate
+       a redundant comparison in a different EH region.  Purge EH edges if
+       necessary.
+
+       2014-04-22  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+
+       * config/aarch64/aarch64.c (TARGET_FLAGS_REGNUM): Define.
+
 2014-10-06  Charles Baylis  <charles.baylis@linaro.org>
 
        Backport from trunk r214945.
index 3fbe140..1af3122 100644 (file)
@@ -100,6 +100,9 @@ struct comparison
      constants.  */
   rtx in_a, in_b;
 
+  /* The REG_EH_REGION of the comparison.  */
+  rtx eh_note;
+
   /* Information about how this comparison is used.  */
   struct comparison_use uses[MAX_CMP_USE];
 
@@ -262,6 +265,7 @@ find_comparison_dom_walker::before_dom_children (basic_block bb)
   struct comparison *last_cmp;
   rtx insn, next, last_clobber;
   bool last_cmp_valid;
+  bool need_purge = false;
   bitmap killed;
 
   killed = BITMAP_ALLOC (NULL);
@@ -303,44 +307,60 @@ find_comparison_dom_walker::before_dom_children (basic_block bb)
       if (src)
        {
          enum machine_mode src_mode = GET_MODE (src);
+         rtx eh_note = NULL;
 
-         /* Eliminate a compare that's redundant with the previous.  */
-         if (last_cmp_valid
-             && rtx_equal_p (last_cmp->in_a, XEXP (src, 0))
-             && rtx_equal_p (last_cmp->in_b, XEXP (src, 1)))
-           {
-             rtx flags, x;
-             enum machine_mode new_mode
-               = targetm.cc_modes_compatible (last_cmp->orig_mode, src_mode);
+         if (flag_non_call_exceptions)
+           eh_note = find_reg_note (insn, REG_EH_REGION, NULL);
 
-             /* New mode is incompatible with the previous compare mode.  */
-             if (new_mode == VOIDmode)
-               continue;
+         if (!last_cmp_valid)
+           goto dont_delete;
 
-             if (new_mode != last_cmp->orig_mode)
-               {
-                 flags = gen_rtx_REG (src_mode, targetm.flags_regnum);
+         /* Take care that it's in the same EH region.  */
+         if (flag_non_call_exceptions
+             && !rtx_equal_p (eh_note, last_cmp->eh_note))
+           goto dont_delete;
 
-                 /* Generate new comparison for substitution.  */
-                 x = gen_rtx_COMPARE (new_mode, XEXP (src, 0), XEXP (src, 1));
-                 x = gen_rtx_SET (VOIDmode, flags, x);
+         /* Make sure the compare is redundant with the previous.  */
+         if (!rtx_equal_p (last_cmp->in_a, XEXP (src, 0))
+             || !rtx_equal_p (last_cmp->in_b, XEXP (src, 1)))
+           goto dont_delete;
 
-                 if (!validate_change (last_cmp->insn,
-                                       &PATTERN (last_cmp->insn), x, false))
-                   continue;
+         /* New mode must be compatible with the previous compare mode.  */
+         {
+           enum machine_mode new_mode
+             = targetm.cc_modes_compatible (last_cmp->orig_mode, src_mode);
+           if (new_mode == VOIDmode)
+             goto dont_delete;
 
-                 last_cmp->orig_mode = new_mode;
-               }
+           if (new_mode != last_cmp->orig_mode)
+             {
+               rtx x, flags = gen_rtx_REG (src_mode, targetm.flags_regnum);
 
-             delete_insn (insn);
-             continue;
-           }
+               /* Generate new comparison for substitution.  */
+               x = gen_rtx_COMPARE (new_mode, XEXP (src, 0), XEXP (src, 1));
+               x = gen_rtx_SET (VOIDmode, flags, x);
 
+               if (!validate_change (last_cmp->insn,
+                                     &PATTERN (last_cmp->insn), x, false))
+                 goto dont_delete;
+
+               last_cmp->orig_mode = new_mode;
+             }
+         }
+
+         /* All tests and substitutions succeeded!  */
+         if (eh_note)
+           need_purge = true;
+         delete_insn (insn);
+         continue;
+
+       dont_delete:
          last_cmp = XCNEW (struct comparison);
          last_cmp->insn = insn;
          last_cmp->prev_clobber = last_clobber;
          last_cmp->in_a = XEXP (src, 0);
          last_cmp->in_b = XEXP (src, 1);
+         last_cmp->eh_note = eh_note;
          last_cmp->orig_mode = src_mode;
          all_compares.safe_push (last_cmp);
 
@@ -404,6 +424,11 @@ find_comparison_dom_walker::before_dom_children (basic_block bb)
            }
        }
     }
+
+  /* If we deleted a compare with a REG_EH_REGION note, we may need to
+     remove EH edges.  */
+  if (need_purge)
+    purge_dead_edges (bb);
 }
 
 /* Find all comparisons in the function.  */
index 8fa5c37..bcafa5a 100644 (file)
@@ -9945,6 +9945,9 @@ aarch64_expand_movmem (rtx *operands)
 #undef TARGET_FIXED_CONDITION_CODE_REGS
 #define TARGET_FIXED_CONDITION_CODE_REGS aarch64_fixed_condition_code_regs
 
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM CC_REGNUM
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-aarch64.h"