fold-const.c (fold_ternary): Unroll the "for" loop to extract operands.
authorKazu Hirata <kazu@cs.umass.edu>
Fri, 4 Mar 2005 19:59:45 +0000 (19:59 +0000)
committerKazu Hirata <kazu@gcc.gnu.org>
Fri, 4 Mar 2005 19:59:45 +0000 (19:59 +0000)
* fold-const.c (fold_ternary): Unroll the "for" loop to
extract operands.

From-SVN: r95895

gcc/ChangeLog
gcc/fold-const.c

index 703d62cd60e18603988942918f3c94c75a00defe..1ed3dbd2c0cdec1b2c4dc771a345ff6592ec05b6 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-04  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * fold-const.c (fold_ternary): Unroll the "for" loop to
+       extract operands.  
+
 2005-03-04  Andrew Haley  <aph@redhat.com>
 
        * unwind-dw2-fde-glibc.c (struct
index 517c45d12c16313bd5c482b2240a3bd9ca01e4b7..df9e8a26d221de26077ab703573565c2f2babb7f 100644 (file)
@@ -7024,41 +7024,38 @@ fold_ternary (tree expr)
   const tree t = expr;
   const tree type = TREE_TYPE (expr);
   tree tem;
+  tree op0, op1, op2;
   tree arg0 = NULL_TREE, arg1 = NULL_TREE;
   enum tree_code code = TREE_CODE (t);
   enum tree_code_class kind = TREE_CODE_CLASS (code);
-  int i;
 
   gcc_assert (IS_EXPR_CODE_CLASS (kind)
              && TREE_CODE_LENGTH (code) == 3);
 
-  /* For now, we iterate only twice even though we are handling
-     ternary expressions.  This is because we haven't defined arg2
-     yet.  */
-  for (i = 0; i < 2; i++)
-    {
-      tree op = TREE_OPERAND (t, i);
-
-      if (op == 0)
-       continue;               /* Valid for CALL_EXPR, at least.  */
+  op0 = TREE_OPERAND (t, 0);
+  op1 = TREE_OPERAND (t, 1);
+  op2 = TREE_OPERAND (t, 2);
 
-      /* Strip any conversions that don't change the mode.  This is
-        safe for every expression, except for a comparison expression
-        because its signedness is derived from its operands.  So, in
-        the latter case, only strip conversions that don't change the
-        signedness.
+  /* Strip any conversions that don't change the mode.  This is safe
+     for every expression, except for a comparison expression because
+     its signedness is derived from its operands.  So, in the latter
+     case, only strip conversions that don't change the signedness.
 
-        Note that this is done as an internal manipulation within the
-        constant folder, in order to find the simplest representation
-        of the arguments so that their form can be studied.  In any
-        cases, the appropriate type conversions should be put back in
-        the tree that will get out of the constant folder.  */
-      STRIP_NOPS (op);
+     Note that this is done as an internal manipulation within the
+     constant folder, in order to find the simplest representation of
+     the arguments so that their form can be studied.  In any cases,
+     the appropriate type conversions should be put back in the tree
+     that will get out of the constant folder.  */
+  if (op0)
+    {
+      arg0 = op0;
+      STRIP_NOPS (arg0);
+    }
 
-      if (i == 0)
-       arg0 = op;
-      else if (i == 1)
-       arg1 = op;
+  if (op1)
+    {
+      arg1 = op1;
+      STRIP_NOPS (arg1);
     }
 
   switch (code)
@@ -7078,7 +7075,7 @@ fold_ternary (tree expr)
         so all simple results must be passed through pedantic_non_lvalue.  */
       if (TREE_CODE (arg0) == INTEGER_CST)
        {
-         tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
+         tem = integer_zerop (arg0) ? op2 : op1;
          /* Only optimize constant conditions when the selected branch
             has the same type as the COND_EXPR.  This avoids optimizing
             away "c ? x : throw", where the throw has a void type.  */
@@ -7087,7 +7084,7 @@ fold_ternary (tree expr)
            return pedantic_non_lvalue (tem);
          return t;
        }
-      if (operand_equal_p (arg1, TREE_OPERAND (t, 2), 0))
+      if (operand_equal_p (arg1, op2, 0))
        return pedantic_omit_one_operand (type, arg1, arg0);
 
       /* If we have A op B ? A : C, we may be able to convert this to a
@@ -7101,25 +7098,21 @@ fold_ternary (tree expr)
                                             arg1, TREE_OPERAND (arg0, 1))
          && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
        {
-         tem = fold_cond_expr_with_comparison (type, arg0,
-                                               TREE_OPERAND (t, 1),
-                                               TREE_OPERAND (t, 2));
+         tem = fold_cond_expr_with_comparison (type, arg0, op1, op2);
          if (tem)
            return tem;
        }
 
       if (COMPARISON_CLASS_P (arg0)
          && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
-                                            TREE_OPERAND (t, 2),
+                                            op2,
                                             TREE_OPERAND (arg0, 1))
-         && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 2)))))
+         && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
        {
          tem = invert_truthvalue (arg0);
          if (COMPARISON_CLASS_P (tem))
            {
-             tem = fold_cond_expr_with_comparison (type, tem,
-                                                   TREE_OPERAND (t, 2),
-                                                   TREE_OPERAND (t, 1));
+             tem = fold_cond_expr_with_comparison (type, tem, op2, op1);
              if (tem)
                return tem;
            }
@@ -7127,8 +7120,7 @@ fold_ternary (tree expr)
 
       /* If the second operand is simpler than the third, swap them
         since that produces better jump optimization results.  */
-      if (tree_swap_operands_p (TREE_OPERAND (t, 1),
-                               TREE_OPERAND (t, 2), false))
+      if (tree_swap_operands_p (op1, op2, false))
        {
          /* See if this can be inverted.  If it can't, possibly because
             it was a floating-point inequality comparison, don't do
@@ -7136,14 +7128,13 @@ fold_ternary (tree expr)
          tem = invert_truthvalue (arg0);
 
          if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
-           return fold (build3 (code, type, tem,
-                                TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
+           return fold (build3 (code, type, tem, op2, op1));
        }
 
       /* Convert A ? 1 : 0 to simply A.  */
-      if (integer_onep (TREE_OPERAND (t, 1))
-         && integer_zerop (TREE_OPERAND (t, 2))
-         /* If we try to convert TREE_OPERAND (t, 0) to our type, the
+      if (integer_onep (op1)
+         && integer_zerop (op2)
+         /* If we try to convert OP0 to our type, the
             call to fold will try to move the conversion inside
             a COND, which will recurse.  In that case, the COND_EXPR
             is probably the best choice, so leave it alone.  */
@@ -7152,8 +7143,8 @@ fold_ternary (tree expr)
 
       /* Convert A ? 0 : 1 to !A.  This prefers the use of NOT_EXPR
         over COND_EXPR in cases such as floating point comparisons.  */
-      if (integer_zerop (TREE_OPERAND (t, 1))
-         && integer_onep (TREE_OPERAND (t, 2))
+      if (integer_zerop (op1)
+         && integer_onep (op2)
          && truth_value_p (TREE_CODE (arg0)))
        return pedantic_non_lvalue (fold_convert (type,
                                                  invert_truthvalue (arg0)));
@@ -7161,7 +7152,7 @@ fold_ternary (tree expr)
       /* A < 0 ? <sign bit of A> : 0 is simply (A & <sign bit of A>).  */
       if (TREE_CODE (arg0) == LT_EXPR
           && integer_zerop (TREE_OPERAND (arg0, 1))
-          && integer_zerop (TREE_OPERAND (t, 2))
+          && integer_zerop (op2)
           && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
         return fold_convert (type, fold (build2 (BIT_AND_EXPR,
                                                 TREE_TYPE (tem), tem, arg1)));
@@ -7170,7 +7161,7 @@ fold_ternary (tree expr)
         already handled above.  */
       if (TREE_CODE (arg0) == BIT_AND_EXPR
          && integer_onep (TREE_OPERAND (arg0, 1))
-         && integer_zerop (TREE_OPERAND (t, 2))
+         && integer_zerop (op2)
          && integer_pow2p (arg1))
        {
          tree tem = TREE_OPERAND (arg0, 0);
@@ -7187,7 +7178,7 @@ fold_ternary (tree expr)
         is probably obsolete because the first operand should be a
         truth value (that's why we have the two cases above), but let's
         leave it in until we can confirm this for all front-ends.  */
-      if (integer_zerop (TREE_OPERAND (t, 2))
+      if (integer_zerop (op2)
          && TREE_CODE (arg0) == NE_EXPR
          && integer_zerop (TREE_OPERAND (arg0, 1))
          && integer_pow2p (arg1)
@@ -7198,13 +7189,13 @@ fold_ternary (tree expr)
                                                  TREE_OPERAND (arg0, 0)));
 
       /* Convert A ? B : 0 into A && B if A and B are truth values.  */
-      if (integer_zerop (TREE_OPERAND (t, 2))
+      if (integer_zerop (op2)
          && truth_value_p (TREE_CODE (arg0))
          && truth_value_p (TREE_CODE (arg1)))
        return fold (build2 (TRUTH_ANDIF_EXPR, type, arg0, arg1));
 
       /* Convert A ? B : 1 into !A || B if A and B are truth values.  */
-      if (integer_onep (TREE_OPERAND (t, 2))
+      if (integer_onep (op2)
          && truth_value_p (TREE_CODE (arg0))
          && truth_value_p (TREE_CODE (arg1)))
        {
@@ -7217,30 +7208,27 @@ fold_ternary (tree expr)
       /* Convert A ? 0 : B into !A && B if A and B are truth values.  */
       if (integer_zerop (arg1)
          && truth_value_p (TREE_CODE (arg0))
-         && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
+         && truth_value_p (TREE_CODE (op2)))
        {
          /* Only perform transformation if ARG0 is easily inverted.  */
          tem = invert_truthvalue (arg0);
          if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
-           return fold (build2 (TRUTH_ANDIF_EXPR, type, tem,
-                                TREE_OPERAND (t, 2)));
+           return fold (build2 (TRUTH_ANDIF_EXPR, type, tem, op2));
        }
 
       /* Convert A ? 1 : B into A || B if A and B are truth values.  */
       if (integer_onep (arg1)
          && truth_value_p (TREE_CODE (arg0))
-         && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
-       return fold (build2 (TRUTH_ORIF_EXPR, type, arg0,
-                            TREE_OPERAND (t, 2)));
+         && truth_value_p (TREE_CODE (op2)))
+       return fold (build2 (TRUTH_ORIF_EXPR, type, arg0, op2));
 
       return t;
 
     case CALL_EXPR:
       /* Check for a built-in function.  */
-      if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
-         && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))
-             == FUNCTION_DECL)
-         && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
+      if (TREE_CODE (op0) == ADDR_EXPR
+         && TREE_CODE (TREE_OPERAND (op0, 0)) == FUNCTION_DECL
+         && DECL_BUILT_IN (TREE_OPERAND (op0, 0)))
        {
          tree tmp = fold_builtin (t, false);
          if (tmp)