diff mbox

[3/8,tree-optimization] : Bitwise logic for fold_truth_andor.

Message ID CAEwic4Zq+U1rq8xSbV45GCaXu5PqwuTR-OoRYvfh44=Jo8u8rQ@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz July 13, 2011, 7:33 a.m. UTC
Hello,

This patch adds support to fold_truth_andor for one-bit precision
typed bitwise-binary and bitwise-not expressions.

ChangeLog

2011-07-13  Kai Tietz  <ktietz@redhat.com>

	* fold-const.c (fold_truth_andor): Add
	support for one-bit bitwise operations.

Bootstrapped and regression tested with prior patches of this series
for x86_64-pc-linux-gnu.
Ok for apply?

Regards,
Kai

Comments

Richard Biener July 13, 2011, 10:26 a.m. UTC | #1
On Wed, Jul 13, 2011 at 9:33 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
> Hello,
>
> This patch adds support to fold_truth_andor for one-bit precision
> typed bitwise-binary and bitwise-not expressions.

Quickly checking some testcases shows we already perform all
the foldings in other places.  So please _always_ check for
all transformations you add if there is a testcase that fails before
and passes after your patch.

(A|B)&(A|C) is already folded to (B&C)|A.

Richard.

> ChangeLog
>
> 2011-07-13  Kai Tietz  <ktietz@redhat.com>
>
>        * fold-const.c (fold_truth_andor): Add
>        support for one-bit bitwise operations.
>
> Bootstrapped and regression tested with prior patches of this series
> for x86_64-pc-linux-gnu.
> Ok for apply?
>
> Regards,
> Kai
>
> Index: gcc/gcc/fold-const.c
> ===================================================================
> --- gcc.orig/gcc/fold-const.c   2011-07-13 08:19:22.000000000 +0200
> +++ gcc/gcc/fold-const.c        2011-07-13 08:59:14.261620200 +0200
> @@ -8248,6 +8248,12 @@ fold_truth_andor (location_t loc, enum t
>   if (!optimize)
>     return NULL_TREE;
>
> +  /* If code is BIT_AND_EXPR or BIT_IOR_EXPR, type precision has to be
> +     one.  Otherwise return NULL_TREE.  */
> +  if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
> +      && (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1))
> +    return NULL_TREE;
> +
>   /* Check for things like (A || B) && (A || C).  We can convert this
>      to A || (B && C).  Note that either operator can be any of the four
>      truth and/or operations and the transformation will still be
> @@ -8258,7 +8264,9 @@ fold_truth_andor (location_t loc, enum t
>       && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
>          || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
>          || TREE_CODE (arg0) == TRUTH_AND_EXPR
> -         || TREE_CODE (arg0) == TRUTH_OR_EXPR)
> +         || TREE_CODE (arg0) == TRUTH_OR_EXPR
> +         || TREE_CODE (arg0) == BIT_AND_EXPR
> +         || TREE_CODE (arg0) == BIT_IOR_EXPR)
>       && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
>     {
>       tree a00 = TREE_OPERAND (arg0, 0);
> @@ -8266,9 +8274,13 @@ fold_truth_andor (location_t loc, enum t
>       tree a10 = TREE_OPERAND (arg1, 0);
>       tree a11 = TREE_OPERAND (arg1, 1);
>       int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
> -                         || TREE_CODE (arg0) == TRUTH_AND_EXPR)
> +                         || TREE_CODE (arg0) == TRUTH_AND_EXPR
> +                         || TREE_CODE (arg0) == BIT_IOR_EXPR
> +                         || TREE_CODE (arg0) == BIT_AND_EXPR)
>                         && (code == TRUTH_AND_EXPR
> -                            || code == TRUTH_OR_EXPR));
> +                            || code == TRUTH_OR_EXPR
> +                            || code == BIT_AND_EXPR
> +                            || code == BIT_IOR_EXPR));
>
>       if (operand_equal_p (a00, a10, 0))
>        return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
> @@ -9484,21 +9496,29 @@ fold_binary_loc (location_t loc,
>
>   if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
>        || code == EQ_EXPR || code == NE_EXPR)
> -      && ((truth_value_p (TREE_CODE (arg0))
> -          && (truth_value_p (TREE_CODE (arg1))
> +      && ((truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
> +          && (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1))
>               || (TREE_CODE (arg1) == BIT_AND_EXPR
>                   && integer_onep (TREE_OPERAND (arg1, 1)))))
> -         || (truth_value_p (TREE_CODE (arg1))
> -             && (truth_value_p (TREE_CODE (arg0))
> +         || (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1))
> +             && (truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
>                  || (TREE_CODE (arg0) == BIT_AND_EXPR
>                      && integer_onep (TREE_OPERAND (arg0, 1)))))))
>     {
> -      tem = fold_build2_loc (loc, code == BIT_AND_EXPR ? TRUTH_AND_EXPR
> -                        : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
> -                        : TRUTH_XOR_EXPR,
> -                        boolean_type_node,
> -                        fold_convert_loc (loc, boolean_type_node, arg0),
> -                        fold_convert_loc (loc, boolean_type_node, arg1));
> +      enum tree_code ncode;
> +
> +      /* Do we operate on a non-boolified tree?  */
> +      if (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1)
> +        ncode = code == BIT_AND_EXPR ? TRUTH_AND_EXPR
> +                                    : (code == BIT_IOR_EXPR
> +                                       ? TRUTH_OR_EXPR : TRUTH_XOR_EXPR);
> +      else
> +        ncode = (code == BIT_AND_EXPR || code == BIT_IOR_EXPR) ? code
> +                                                              : BIT_XOR_EXPR;
> +      tem = fold_build2_loc (loc, ncode,
> +                          boolean_type_node,
> +                          fold_convert_loc (loc, boolean_type_node, arg0),
> +                          fold_convert_loc (loc, boolean_type_node, arg1));
>
>       if (code == EQ_EXPR)
>        tem = invert_truthvalue_loc (loc, tem);
>
diff mbox

Patch

Index: gcc/gcc/fold-const.c
===================================================================
--- gcc.orig/gcc/fold-const.c	2011-07-13 08:19:22.000000000 +0200
+++ gcc/gcc/fold-const.c	2011-07-13 08:59:14.261620200 +0200
@@ -8248,6 +8248,12 @@  fold_truth_andor (location_t loc, enum t
   if (!optimize)
     return NULL_TREE;

+  /* If code is BIT_AND_EXPR or BIT_IOR_EXPR, type precision has to be
+     one.  Otherwise return NULL_TREE.  */
+  if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
+      && (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1))
+    return NULL_TREE;
+
   /* Check for things like (A || B) && (A || C).  We can convert this
      to A || (B && C).  Note that either operator can be any of the four
      truth and/or operations and the transformation will still be
@@ -8258,7 +8264,9 @@  fold_truth_andor (location_t loc, enum t
       && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
 	  || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
 	  || TREE_CODE (arg0) == TRUTH_AND_EXPR
-	  || TREE_CODE (arg0) == TRUTH_OR_EXPR)
+	  || TREE_CODE (arg0) == TRUTH_OR_EXPR
+	  || TREE_CODE (arg0) == BIT_AND_EXPR
+	  || TREE_CODE (arg0) == BIT_IOR_EXPR)
       && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
     {
       tree a00 = TREE_OPERAND (arg0, 0);
@@ -8266,9 +8274,13 @@  fold_truth_andor (location_t loc, enum t
       tree a10 = TREE_OPERAND (arg1, 0);
       tree a11 = TREE_OPERAND (arg1, 1);
       int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
-			  || TREE_CODE (arg0) == TRUTH_AND_EXPR)
+			  || TREE_CODE (arg0) == TRUTH_AND_EXPR
+			  || TREE_CODE (arg0) == BIT_IOR_EXPR
+			  || TREE_CODE (arg0) == BIT_AND_EXPR)
 			 && (code == TRUTH_AND_EXPR
-			     || code == TRUTH_OR_EXPR));
+			     || code == TRUTH_OR_EXPR
+			     || code == BIT_AND_EXPR
+			     || code == BIT_IOR_EXPR));

       if (operand_equal_p (a00, a10, 0))
 	return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
@@ -9484,21 +9496,29 @@  fold_binary_loc (location_t loc,

   if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
        || code == EQ_EXPR || code == NE_EXPR)
-      && ((truth_value_p (TREE_CODE (arg0))
-	   && (truth_value_p (TREE_CODE (arg1))
+      && ((truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
+	   && (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1))
 	       || (TREE_CODE (arg1) == BIT_AND_EXPR
 		   && integer_onep (TREE_OPERAND (arg1, 1)))))
-	  || (truth_value_p (TREE_CODE (arg1))
-	      && (truth_value_p (TREE_CODE (arg0))
+	  || (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1))
+	      && (truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
 		  || (TREE_CODE (arg0) == BIT_AND_EXPR
 		      && integer_onep (TREE_OPERAND (arg0, 1)))))))
     {
-      tem = fold_build2_loc (loc, code == BIT_AND_EXPR ? TRUTH_AND_EXPR
-			 : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
-			 : TRUTH_XOR_EXPR,
-			 boolean_type_node,
-			 fold_convert_loc (loc, boolean_type_node, arg0),
-			 fold_convert_loc (loc, boolean_type_node, arg1));
+      enum tree_code ncode;
+
+      /* Do we operate on a non-boolified tree?  */
+      if (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1)
+        ncode = code == BIT_AND_EXPR ? TRUTH_AND_EXPR
+				     : (code == BIT_IOR_EXPR
+				        ? TRUTH_OR_EXPR : TRUTH_XOR_EXPR);
+      else
+        ncode = (code == BIT_AND_EXPR || code == BIT_IOR_EXPR) ? code
+        						       : BIT_XOR_EXPR;
+      tem = fold_build2_loc (loc, ncode,
+			   boolean_type_node,
+			   fold_convert_loc (loc, boolean_type_node, arg0),
+			   fold_convert_loc (loc, boolean_type_node, arg1));

       if (code == EQ_EXPR)
 	tem = invert_truthvalue_loc (loc, tem);