]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/jump.c
jvspec.c (lang_specific_driver): Fix -C handling.
[gcc.git] / gcc / jump.c
index 1716f073107e6beb455c500cd6daf9cc746c5d19..6fc4deb10f9f0455c4126cdb4dcbef65d9ee94d6 100644 (file)
@@ -207,6 +207,9 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
   int first = 1;
   int max_uid = 0;
   rtx last_insn;
+#ifdef HAVE_trap
+  enum rtx_code reversed_code;
+#endif
 
   cross_jump_death_matters = (cross_jump == 2);
   max_uid = init_label_info (f) + 1;
@@ -419,6 +422,28 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
 
              if (temp2 == temp)
                {
+                 /* Ensure that we jump to the later of the two labels.  
+                    Consider:
+
+                       if (test) goto L2;
+                       goto L1;
+                       ...
+                     L1:
+                       (clobber return-reg)
+                     L2:
+                       (use return-reg)
+
+                    If we leave the goto L1, we'll incorrectly leave
+                    return-reg dead for TEST true.  */
+
+                 temp2 = next_active_insn (JUMP_LABEL (insn));
+                 if (!temp2)
+                   temp2 = get_last_insn ();
+                 if (GET_CODE (temp2) != CODE_LABEL)
+                   temp2 = prev_label (temp2);
+                 if (temp2 != JUMP_LABEL (temp))
+                   redirect_jump (temp, temp2, 1);
+
                  delete_jump (insn);
                  changed = 1;
                  continue;
@@ -525,9 +550,10 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
              && prev_active_insn (reallabelprev) == insn
              && no_labels_between_p (insn, reallabelprev)
              && (temp2 = get_condition (insn, &temp4))
-             && can_reverse_comparison_p (temp2, insn))
+             && ((reversed_code = reversed_comparison_code (temp2, insn))
+                 != UNKNOWN))
            {
-             rtx new = gen_cond_trap (reverse_condition (GET_CODE (temp2)),
+             rtx new = gen_cond_trap (reversed_code,
                                       XEXP (temp2, 0), XEXP (temp2, 1),
                                       TRAP_CODE (PATTERN (reallabelprev)));
 
@@ -1319,10 +1345,10 @@ duplicate_loop_exit_test (loop_start)
 }
 \f
 /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
-   eh-beg, eh-end notes between START and END out before START.  Assume that
-   END is not such a note.  START may be such a note.  Returns the value
-   of the new starting insn, which may be different if the original start
-   was such a note.  */
+   notes between START and END out before START.  Assume that END is not
+   such a note.  START may be such a note.  Returns the value of the new
+   starting insn, which may be different if the original start was such a
+   note.  */
 
 rtx
 squeeze_notes (start, end)
@@ -1340,9 +1366,7 @@ squeeze_notes (start, end)
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
+             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
        {
          if (insn == start)
            start = next;
@@ -1682,16 +1706,16 @@ jump_back_p (insn, target)
 
   if (XEXP (SET_SRC (set), 1) == pc_rtx)
     {
-      if (! can_reverse_comparison_p (cinsn, insn))
+      codei = reversed_comparison_code (cinsn, insn);
+      if (codei == UNKNOWN)
        return 0;
-      codei = reverse_condition (codei);
     }
 
   if (XEXP (SET_SRC (tset), 2) == pc_rtx)
     {
-      if (! can_reverse_comparison_p (ctarget, target))
+      codet = reversed_comparison_code (ctarget, target);
+      if (codei == UNKNOWN)
        return 0;
-      codet = reverse_condition (codet);
     }
 
   return (codei == codet
@@ -1766,7 +1790,7 @@ reversed_comparison_code_parts (code, arg0, arg1, insn)
 
   /* In case we give up IEEE compatibility, all comparisons are reversible.  */
   if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-      || flag_fast_math)
+      || flag_unsafe_math_optimizations)
     return reverse_condition (code);
 
   if (GET_MODE_CLASS (mode) == MODE_CC
@@ -1840,35 +1864,6 @@ reversed_comparison_code (comparison, insn)
                                         XEXP (comparison, 1), insn);
 }
 \f
-/* Given a comparison, COMPARISON, inside a conditional jump insn, INSN,
-   return non-zero if it is safe to reverse this comparison.  It is if our
-   floating-point is not IEEE, if this is an NE or EQ comparison, or if
-   this is known to be an integer comparison.  
-   Use of this function is depreached and you should use
-   REVERSED_COMPARISON_CODE bits instead.
- */
-
-int
-can_reverse_comparison_p (comparison, insn)
-     rtx comparison;
-     rtx insn;
-{
-  enum rtx_code code;
-
-  /* If this is not actually a comparison, we can't reverse it.  */
-  if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
-    return 0;
-
-  code = reversed_comparison_code (comparison, insn);
-  if (code == UNKNOWN)
-    return 0;
-
-  /* The code will follow can_reverse_comparison_p with reverse_condition,
-     so see if it will get proper result.  */
-  return (code == reverse_condition (GET_CODE (comparison)));
-}
-
 /* Given an rtx-code for a comparison, return the code for the negated
    comparison.  If no such code exists, return UNKNOWN.
 
@@ -2085,6 +2080,12 @@ int
 comparison_dominates_p (code1, code2)
      enum rtx_code code1, code2;
 {
+  /* UNKNOWN comparison codes can happen as a result of trying to revert
+     comparison codes.
+     They can't match anything, so we have to reject them here.  */
+  if (code1 == UNKNOWN || code2 == UNKNOWN)
+    return 0;
+
   if (code1 == code2)
     return 1;
 
@@ -3308,16 +3309,19 @@ invert_exp_1 (insn)
     {
       register rtx comp = XEXP (x, 0);
       register rtx tem;
+      enum rtx_code reversed_code;
 
       /* We can do this in two ways:  The preferable way, which can only
         be done if this is not an integer comparison, is to reverse
         the comparison code.  Otherwise, swap the THEN-part and ELSE-part
         of the IF_THEN_ELSE.  If we can't do either, fail.  */
 
-      if (can_reverse_comparison_p (comp, insn))
+      reversed_code = reversed_comparison_code (comp, insn);
+
+      if (reversed_code != UNKNOWN)
        {
          validate_change (insn, &XEXP (x, 0),
-                          gen_rtx_fmt_ee (reverse_condition (GET_CODE (comp)),
+                          gen_rtx_fmt_ee (reversed_code,
                                           GET_MODE (comp), XEXP (comp, 0),
                                           XEXP (comp, 1)),
                           1);
@@ -3838,6 +3842,7 @@ thread_jumps (f, max_reg, flag_before_loop)
   int changed = 1;
   int i;
   int *all_reset;
+  enum rtx_code reversed_code1, reversed_code2;
 
   /* Allocate register tables and quick-reset table.  */
   modified_regs = (char *) xmalloc (max_reg * sizeof (char));
@@ -3927,14 +3932,20 @@ thread_jumps (f, max_reg, flag_before_loop)
          b1op0 = XEXP (XEXP (SET_SRC (set), 0), 0);
          b1op1 = XEXP (XEXP (SET_SRC (set), 0), 1);
          code1 = GET_CODE (XEXP (SET_SRC (set), 0));
+         reversed_code1 = code1;
          if (XEXP (SET_SRC (set), 1) == pc_rtx)
-           code1 = reverse_condition (code1);
+           code1 = reversed_comparison_code (XEXP (SET_SRC (set), 0), b1);
+         else
+           reversed_code1 = reversed_comparison_code (XEXP (SET_SRC (set), 0), b1);
 
          b2op0 = XEXP (XEXP (SET_SRC (set2), 0), 0);
          b2op1 = XEXP (XEXP (SET_SRC (set2), 0), 1);
          code2 = GET_CODE (XEXP (SET_SRC (set2), 0));
+         reversed_code2 = code2;
          if (XEXP (SET_SRC (set2), 1) == pc_rtx)
-           code2 = reverse_condition (code2);
+           code2 = reversed_comparison_code (XEXP (SET_SRC (set2), 0), b2);
+         else
+           reversed_code2 = reversed_comparison_code (XEXP (SET_SRC (set2), 0), b2);
 
          /* If they test the same things and knowing that B1 branches
             tells us whether or not B2 branches, check if we
@@ -3942,9 +3953,7 @@ thread_jumps (f, max_reg, flag_before_loop)
          if (rtx_equal_for_thread_p (b1op0, b2op0, b2)
              && rtx_equal_for_thread_p (b1op1, b2op1, b2)
              && (comparison_dominates_p (code1, code2)
-                 || (can_reverse_comparison_p (XEXP (SET_SRC (set), 0), b1)
-                     && comparison_dominates_p (code1,
-                                                reverse_condition (code2)))))
+                 || comparison_dominates_p (code1, reversed_code2)))
 
            {
              t1 = prev_nonnote_insn (b1);
@@ -4042,7 +4051,7 @@ rtx_equal_for_thread_p (x, y, yinsn)
      pessimistic, but this pass would only rarely do anything for FP
      anyway.  */
   if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
-      && FLOAT_MODE_P (GET_MODE (x)) && ! flag_fast_math)
+      && FLOAT_MODE_P (GET_MODE (x)) && ! flag_unsafe_math_optimizations)
     return 0;
 
   /* For commutative operations, the RTX match if the operand match in any
This page took 0.032066 seconds and 5 git commands to generate.