]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* jump.c (reversed_comparison_code_parts, reversed_comparison_code):
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Jan 2001 18:39:19 +0000 (18:39 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Jan 2001 18:39:19 +0000 (18:39 +0000)
New.
(can_reverse_comparison_p): Rewrite to use reversed_comparison_code.
(reverse_condition_maybe_unordered): Abort on unsigned comparisons.
* rtl.h (reversed_comparison_code_parts, reversed_comparison_code):
Declare.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38779 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/jump.c
gcc/rtl.h

index de0d48cfc562d9fe7bbc50f3d61e03f733d1115f..f76676620a2e7712992704c1db6e41710490c2c1 100644 (file)
@@ -1,3 +1,12 @@
+Sun Jan  7 19:37:48 MET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * jump.c (reversed_comparison_code_parts, reversed_comparison_code):
+       New.
+       (can_reverse_comparison_p): Rewrite to use reversed_comparison_code.
+       (reverse_condition_maybe_unordered): Abort on unsigned comparisons.
+       * rtl.h (reversed_comparison_code_parts, reversed_comparison_code):
+       Declare.
+
 2001-01-07  Neil Booth  <neil@daikokuya.demon.co.uk>
 
         * fix-header.c (read_scan_file): s/pfile/scan_in/.
index 2dae0e53333b254ebe93e5f234aec04ee02ca5cb..6fa1f339187274cc025ba03883be6646001a5dc9 100644 (file)
@@ -1699,80 +1699,174 @@ jump_back_p (insn, target)
          && rtx_renumbered_equal_p (XEXP (cinsn, 1), XEXP (ctarget, 1)));
 }
 \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.  */
-
-int
-can_reverse_comparison_p (comparison, insn)
-     rtx comparison;
-     rtx insn;
+/* Given a comparison (CODE ARG0 ARG1), inside a insn, INSN, return an code
+   of reversed comparison if it is possible to do so.  Otherwise return UNKNOWN.
+   UNKNOWN may be returned in case we are having CC_MODE compare and we don't
+   know whether it's source is floating point or integer comparison.  Machine
+   description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
+   to help this function avoid overhead in these cases.  */
+enum rtx_code
+reversed_comparison_code_parts (code, arg0, arg1, insn)
+     rtx insn, arg0, arg1;
+     enum rtx_code code;
 {
-  rtx arg0;
+  enum machine_mode mode;
 
   /* If this is not actually a comparison, we can't reverse it.  */
-  if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
-    return 0;
+  if (GET_RTX_CLASS (code) != '<')
+    return UNKNOWN;
 
-  if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-      /* If this is an NE comparison, it is safe to reverse it to an EQ
-        comparison and vice versa, even for floating point.  If no operands
-        are NaNs, the reversal is valid.  If some operand is a NaN, EQ is
-        always false and NE is always true, so the reversal is also valid.  */
-      || flag_fast_math
-      || GET_CODE (comparison) == NE
-      || GET_CODE (comparison) == EQ)
-    return 1;
+  mode = GET_MODE (arg0);
+  if (mode == VOIDmode)
+    mode = GET_MODE (arg1);
 
-  arg0 = XEXP (comparison, 0);
+  /* First see if machine description supply us way to reverse the comparison.
+     Give it priority over everything else to allow machine description to do
+     tricks.  */
+#ifdef REVERSIBLE_CC_MODE
+  if (GET_MODE_CLASS (mode) == MODE_CC)
+      && REVERSIBLE_CC_MODE (mode))
+    {
+#ifdef REVERSE_CONDITION
+          return REVERSE_CONDITION (code, mode);
+#endif
+          return reverse_condition (code);
+       }
+#endif
 
-  /* Make sure ARG0 is one of the actual objects being compared.  If we
-     can't do this, we can't be sure the comparison can be reversed.
+  /* Try few special cases based on the comparison code.  */
+  switch (code)
+    {
+      case GEU:
+      case GTU:
+      case LEU:
+      case LTU:
+      case NE:
+      case EQ:
+        /* It is always safe to reverse EQ and NE, even for the floating
+          point.  Similary the unsigned comparisons are never used for
+          floating point so we can reverse them in the default way.  */
+       return reverse_condition (code);
+      case ORDERED:
+      case UNORDERED:
+      case LTGT:
+      case UNEQ:
+       /* In case we already see unordered comparison, we can be sure to
+          be dealing with floating point so we don't need any more tests.  */
+       return reverse_condition_maybe_unordered (code);
+      case UNLT:
+      case UNLE:
+      case UNGT:
+      case UNGE:
+       /* We don't have safe way to reverse these yet.  */
+       return UNKNOWN;
+      default:
+       break;
+    }
+
+  /* In case we give up IEEE compatibility, all comparisons are reversible.  */
+  if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
+      || flag_fast_math)
+    return reverse_condition (code);
 
-     Handle cc0 and a MODE_CC register.  */
-  if ((GET_CODE (arg0) == REG && GET_MODE_CLASS (GET_MODE (arg0)) == MODE_CC)
+  if (GET_MODE_CLASS (mode) == MODE_CC
 #ifdef HAVE_cc0
       || arg0 == cc0_rtx
 #endif
       )
     {
-      rtx prev, set;
-
-      /* First see if the condition code mode alone if enough to say we can
-        reverse the condition.  If not, then search backwards for a set of
-        ARG0. We do not need to check for an insn clobbering it since valid
-        code will contain set a set with no intervening clobber.  But
-        stop when we reach a label.  */
-#ifdef REVERSIBLE_CC_MODE
-      if (GET_MODE_CLASS (GET_MODE (arg0)) == MODE_CC
-         && REVERSIBLE_CC_MODE (GET_MODE (arg0)))
-       return 1;
-#endif
-
+      rtx prev;
+      /* Try to search for the comparison to determine the real mode.
+         This code is expensive, but with sane machine description it
+         will be never used, since REVERSIBLE_CC_MODE will return true
+         in all cases.  */
       if (! insn)
-       return 0;
+       return UNKNOWN;
 
       for (prev = prev_nonnote_insn (insn);
           prev != 0 && GET_CODE (prev) != CODE_LABEL;
           prev = prev_nonnote_insn (prev))
-       if ((set = single_set (prev)) != 0
-           && rtx_equal_p (SET_DEST (set), arg0))
-         {
-           arg0 = SET_SRC (set);
+       {
+         rtx set = set_of (arg0, prev);
+         if (set && GET_CODE (set) == SET
+             && rtx_equal_p (SET_DEST (set), arg0))
+           {
+             rtx src = SET_SRC (set);
 
-           if (GET_CODE (arg0) == COMPARE)
-             arg0 = XEXP (arg0, 0);
-           break;
-         }
+             if (GET_CODE (src) == COMPARE)
+               {
+                 rtx comparison = src;
+                 arg0 = XEXP (src, 0);
+                 mode = GET_MODE (arg0);
+                 if (mode == VOIDmode)
+                   mode = GET_MODE (XEXP (comparison, 1));
+                 break;
+               }
+             /* We can get past reg-reg moves.  This may be usefull for model
+                of i387 comparisons that first move flag registers around.  */
+             if (REG_P (src))
+               {
+                 arg0 = src;
+                 continue;
+               }
+           }
+         /* If register is clobbered in some ununderstandable way,
+            give up.  */
+         if (set)
+           return UNKNOWN;
+       }
     }
 
-  /* We can reverse this if ARG0 is a CONST_INT or if its mode is
-     not VOIDmode and neither a MODE_CC nor MODE_FLOAT type.  */
-  return (GET_CODE (arg0) == CONST_INT
-         || (GET_MODE (arg0) != VOIDmode
-             && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_CC
-             && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_FLOAT));
+  /* An integer condition.  */
+  if (GET_CODE (arg0) == CONST_INT
+      || (GET_MODE (arg0) != VOIDmode
+         && GET_MODE_CLASS (mode) != MODE_CC
+         && ! FLOAT_MODE_P (mode)))
+    return reverse_condition (code);
+
+  return UNKNOWN;
+}
+
+/* An wrapper around the previous function to take COMPARISON as rtx
+   expression.  This simplifies many callers.  */
+enum rtx_code
+reversed_comparison_code (comparison, insn)
+     rtx comparison, insn;
+{
+  if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
+    return UNKNOWN;
+  return reversed_comparison_code_parts (GET_CODE (comparison),
+                                        XEXP (comparison, 0),
+                                        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
@@ -1781,7 +1875,7 @@ can_reverse_comparison_p (comparison, insn)
    WATCH OUT!  reverse_condition is not safe to use on a jump that might
    be acting on the results of an IEEE floating point comparison, because
    of the special treatment of non-signaling nans in comparisons.
-   Use can_reverse_comparison_p to be sure.  */
+   Use reversed_comparison_code instead.  */
 
 enum rtx_code
 reverse_condition (code)
@@ -1855,14 +1949,6 @@ reverse_condition_maybe_unordered (code)
       return UNGT;
     case LTGT:
       return UNEQ;
-    case GTU:
-      return LEU;
-    case GEU:
-      return LTU;
-    case LTU:
-      return GEU;
-    case LEU:
-      return GTU;
     case UNORDERED:
       return ORDERED;
     case ORDERED:
index 6e2aee68c07b532c43316f46b44825f8f145f03d..9db7a37183c915dbeb7f8f463858aec8e50a6cb1 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1701,6 +1701,9 @@ extern void rebuild_jump_labels           PARAMS ((rtx));
 extern void thread_jumps               PARAMS ((rtx, int, int));
 extern int rtx_equal_for_thread_p      PARAMS ((rtx, rtx, rtx));
 extern int can_reverse_comparison_p    PARAMS ((rtx, rtx));
+extern enum rtx_code reversed_comparison_code PARAMS ((rtx, rtx));
+extern enum rtx_code reversed_comparison_code_parts PARAMS ((enum rtx_code,
+                                                            rtx, rtx, rtx));
 extern void delete_for_peephole                PARAMS ((rtx, rtx));
 extern int condjump_in_parallel_p      PARAMS ((rtx));
 extern void never_reached_warning      PARAMS ((rtx));