]> gcc.gnu.org Git - gcc.git/commitdiff
ifcvt.c (noce_get_alt_condition): If the condition is a compare against a constant...
authorDJ Delorie <dj@redhat.com>
Sat, 28 Jul 2001 03:13:34 +0000 (23:13 -0400)
committerDJ Delorie <dj@gcc.gnu.org>
Sat, 28 Jul 2001 03:13:34 +0000 (23:13 -0400)
* ifcvt.c (noce_get_alt_condition): If the condition is a compare
against a constant, try to adjust the compare to have the desired
constant in it so that min/max optimizations happen more often.

From-SVN: r44435

gcc/ChangeLog
gcc/ifcvt.c

index 8a0143f6c3ccdfba9f59ef363ae59c0eee7085b2..6b0f4f7118a794a5492dcf2de0aefda801036fc8 100644 (file)
@@ -1,3 +1,9 @@
+2001-07-27  DJ Delorie  <dj@redhat.com>
+
+       * ifcvt.c (noce_get_alt_condition): If the condition is a compare
+       against a constant, try to adjust the compare to have the desired
+       constant in it so that min/max optimizations happen more often.
+
 Fri Jul 27 17:53:00 CEST 2001  Jan Hubicka  <jh@suse.cz>
 
        * flow.c (last_loop_beg_note): New function.
index 08ec087e4ca562a235c779d22d3b6deb00388042..4de879d7d82648f4fa45ed1eed21d7d785c37b92 100644 (file)
@@ -1,5 +1,5 @@
 /* If-conversion support.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GNU CC.
 
@@ -1150,6 +1150,114 @@ noce_get_alt_condition (if_info, target, earliest)
     = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
       && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
 
+  /* If we're looking for a constant, try to make the conditional
+     have that constant in it.  There are two reasons why it may
+     not have the constant we want:
+
+     1. GCC may have needed to put the constant in a register, because
+        the target can't compare directly against that constant.  For
+        this case, we look for a SET immediately before the comparison
+        that puts a constant in that register.
+
+     2. GCC may have canonicalized the conditional, for example
+       replacing "if x < 4" with "if x <= 3".  We can undo that (or
+       make equivalent types of changes) to get the constants we need
+       if they're off by one in the right direction.  */
+
+  if (GET_CODE (target) == CONST_INT)
+    {
+      enum rtx_code code = GET_CODE (if_info->cond);
+      rtx op_a = XEXP (if_info->cond, 0);
+      rtx op_b = XEXP (if_info->cond, 1);
+      rtx prev_insn;
+
+      /* First, look to see if we put a constant in a register.  */
+      prev_insn = PREV_INSN (if_info->cond_earliest);
+      if (prev_insn
+         && INSN_P (prev_insn)
+         && GET_CODE (PATTERN (prev_insn)) == SET)
+       {
+         rtx src = find_reg_equal_equiv_note (prev_insn);
+         if (!src)
+           src = SET_SRC (PATTERN (prev_insn));
+         if (GET_CODE (src) == CONST_INT)
+           {
+             if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn))))
+               {
+                 op_a = src;
+                 if_info->cond_earliest = prev_insn;
+               }
+             else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
+               {
+                 op_b = src;
+                 if_info->cond_earliest = prev_insn;
+               }
+
+             if (GET_CODE (op_a) == CONST_INT)
+               {
+                 rtx tmp = op_a;
+                 op_a = op_b;
+                 op_b = tmp;
+                 code = swap_condition (code);
+               }
+           }
+       }
+
+      /* Now, look to see if we can get the right constant by
+        adjusting the conditional.  */
+      if (GET_CODE (op_b) == CONST_INT)
+       {
+         HOST_WIDE_INT desired_val = INTVAL (target);
+         HOST_WIDE_INT actual_val = INTVAL (op_b);
+
+         switch (code)
+           {
+           case LT:
+             if (actual_val == desired_val + 1)
+               {
+                 code = LE;
+                 op_b = GEN_INT (desired_val);
+               }
+             break;
+           case LE:
+             if (actual_val == desired_val - 1)
+               {
+                 code = LT;
+                 op_b = GEN_INT (desired_val);
+               }
+             break;
+           case GT:
+             if (actual_val == desired_val - 1)
+               {
+                 code = GE;
+                 op_b = GEN_INT (desired_val);
+               }
+             break;
+           case GE:
+             if (actual_val == desired_val + 1)
+               {
+                 code = GT;
+                 op_b = GEN_INT (desired_val);
+               }
+             break;
+           default:
+             break;
+           }
+       }
+
+      /* If we made any changes, generate a new conditional that is
+        equivalent to what we started with, but has the right
+        constants in it.  */
+      if (code != GET_CODE (if_info->cond)
+         || op_a != XEXP (if_info->cond, 0)
+         || op_b != XEXP (if_info->cond, 1))
+       {
+         cond = gen_rtx_fmt_ee (code, GET_MODE (cond), op_a, op_b);
+         *earliest = if_info->cond_earliest;
+         return cond;
+       }
+    }
+
   cond = canonicalize_condition (if_info->jump, cond, reverse,
                                 earliest, target);
   if (! cond || ! reg_mentioned_p (target, cond))
This page took 0.070727 seconds and 5 git commands to generate.