diff mbox

[gimplifier] : Boolify more strict conditional expressions and transform simple form to binary

Message ID BANLkTi=RoeGa+SK84T+gjtaoJ7x3goqoUg@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz May 10, 2011, 1:56 p.m. UTC
Hello,

this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
expressions
on gimplification to their binary form.  Additionally it takes care
that conditions
are getting boolified for operation.

ChangeLog

2011-05-10  Kai Tietz

	* gimplify.c (gimplify_exit_expr): Boolify conditional
	expression part.
	(shortcut_cond_r): Likewise.
	(shortcut_cond_expr): Likewise.
	(gimplify_cond_expr): Likewise.
	(gimplify_modify_expr_rhs): Likewise.
	(gimplify_boolean_expr): Likewise.
	(gimple_boolify): Boolify operands for BOOLEAN typed
	base expressions.
	(gimplify_expr): Boolify TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
	TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR. Additionally
	move TRUTH_AND|OR|XOR_EXPR to its binary form.

Tested for x86_64-w64-mingw32 and x86_64-pc-linux-gnu. Ok for apply?

Regards,
Kai

Comments

Eric Botcazou May 11, 2011, 9:53 a.m. UTC | #1
> this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
> expressions on gimplification to their binary form.

What is it for?  This will redirect the compilation stream from proven paths to 
others so there must be a good reason to do it.  What's the effect on the code?
Kai Tietz May 11, 2011, 10:03 a.m. UTC | #2
2011/5/11 Eric Botcazou <ebotcazou@adacore.com>:
>> this patch converts TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR
>> expressions on gimplification to their binary form.
>
> What is it for?  This will redirect the compilation stream from proven paths to
> others so there must be a good reason to do it.  What's the effect on the code?
>
> --
> Eric Botcazou

Well, it would have some effects.  First we don't need to handle TRUTH
and BINARY variants of AND, OR, XOR any longer special.  Second cause
is that on BINARY trees the reassociation pass can operate, which
leads to better optimized boolean logic.

Regards,
Kai
diff mbox

Patch

Index: gcc/gcc/gimplify.c
===================================================================
--- gcc.orig/gcc/gimplify.c	2011-05-10 15:44:49.000000000 +0200
+++ gcc/gcc/gimplify.c	2011-05-10 15:46:58.365473600 +0200
@@ -1664,10 +1664,12 @@  build_and_jump (tree *label_p)
 static enum gimplify_status
 gimplify_exit_expr (tree *expr_p)
 {
-  tree cond = TREE_OPERAND (*expr_p, 0);
-  tree expr;
+  tree cond, expr;
 
+  TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0));
+  cond = TREE_OPERAND (*expr_p, 0);
   expr = build_and_jump (&gimplify_ctxp->exit_label);
+
   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
   *expr_p = expr;
 
@@ -2586,6 +2588,7 @@  shortcut_cond_r (tree pred, tree *true_l
       /* Keep the original source location on the first 'if'.  Set the source
 	 location of the ? on the second 'if'.  */
       new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
+      TREE_OPERAND (pred, 0) = gimple_boolify (TREE_OPERAND (pred, 0));
       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
 		     shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
 				      false_label_p, locus),
@@ -2594,7 +2597,7 @@  shortcut_cond_r (tree pred, tree *true_l
     }
   else
     {
-      expr = build3 (COND_EXPR, void_type_node, pred,
+      expr = build3 (COND_EXPR, void_type_node, gimple_boolify (pred),
 		     build_and_jump (true_label_p),
 		     build_and_jump (false_label_p));
       SET_EXPR_LOCATION (expr, locus);
@@ -2625,7 +2628,8 @@  shortcut_cond_expr (tree expr)
   bool emit_end, emit_false, jump_over_else;
   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
-
+  
+  pred = TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   /* First do simple transformations.  */
   if (!else_se)
     {
@@ -2665,7 +2669,7 @@  shortcut_cond_expr (tree expr)
 	    SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
 	  else_ = shortcut_cond_expr (expr);
 	  else_se = else_ && TREE_SIDE_EFFECTS (else_);
-	  pred = TREE_OPERAND (pred, 0);
+	  pred = gimple_boolify (TREE_OPERAND (pred, 0));
 	  expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
 	  SET_EXPR_LOCATION (expr, locus);
 	}
@@ -2824,9 +2828,6 @@  gimple_boolify (tree expr)
 	}
     }
 
-  if (TREE_CODE (type) == BOOLEAN_TYPE)
-    return expr;
-
   switch (TREE_CODE (expr))
     {
     case TRUTH_AND_EXPR:
@@ -2851,6 +2852,8 @@  gimple_boolify (tree expr)
     default:
       /* Other expressions that get here must have boolean values, but
 	 might need to be converted to the appropriate mode.  */
+      if (TREE_CODE (type) == BOOLEAN_TYPE)
+	return expr;
       return fold_convert_loc (loc, boolean_type_node, expr);
     }
 }
@@ -2865,7 +2868,7 @@  gimplify_pure_cond_expr (tree *expr_p, g
   enum gimplify_status ret, tret;
   enum tree_code code;
 
-  cond = gimple_boolify (COND_EXPR_COND (expr));
+  cond = COND_EXPR_COND (expr) = gimple_boolify (COND_EXPR_COND (expr));
 
   /* We need to handle && and || specially, as their gimplification
      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
@@ -2937,6 +2940,7 @@  gimplify_cond_expr (tree *expr_p, gimple
   enum tree_code pred_code;
   gimple_seq seq = NULL;
 
+  TREE_OPERAND (*expr_p, 0) = gimple_boolify (TREE_OPERAND (*expr_p, 0));
   /* If this COND_EXPR has a value, copy the values into a temporary within
      the arms.  */
   if (!VOID_TYPE_P (type))
@@ -4276,6 +4280,7 @@  gimplify_modify_expr_rhs (tree *expr_p,
 					    false);
 
 	case COND_EXPR:
+
 	  /* If we're assigning to a non-register type, push the assignment
 	     down into the branches.  This is mandatory for ADDRESSABLE types,
 	     since we cannot generate temporaries for such, but it saves a
@@ -4287,6 +4292,7 @@  gimplify_modify_expr_rhs (tree *expr_p,
 	      tree cond = *from_p;
 	      tree result = *to_p;
 
+	      TREE_OPERAND (cond, 0) = gimple_boolify (TREE_OPERAND (cond, 0));
 	      ret = gimplify_expr (&result, pre_p, post_p,
 				   is_gimple_lvalue, fb_lvalue);
 	      if (ret != GS_ERROR)
@@ -4710,6 +4716,7 @@  gimplify_boolean_expr (tree *expr_p, loc
 {
   /* Preserve the original type of the expression.  */
   tree type = TREE_TYPE (*expr_p);
+  *expr_p = gimple_boolify (*expr_p);
 
   *expr_p = build3 (COND_EXPR, type, *expr_p,
 		    fold_convert_loc (locus, type, boolean_true_node),
@@ -6762,6 +6769,13 @@  gimplify_expr (tree *expr_p, gimple_seq
 
 	case TRUTH_ANDIF_EXPR:
 	case TRUTH_ORIF_EXPR:
+	  if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+	    {
+	      tree type = TREE_TYPE (*expr_p);
+	      *expr_p = fold_convert (type, gimple_boolify (*expr_p));
+	      ret = GS_OK;
+	      break;
+	    }
 	  /* Pass the source location of the outer expression.  */
 	  ret = gimplify_boolean_expr (expr_p, saved_location);
 	  break;
@@ -7203,6 +7217,30 @@  gimplify_expr (tree *expr_p, gimple_seq
 	case TRUTH_AND_EXPR:
 	case TRUTH_OR_EXPR:
 	case TRUTH_XOR_EXPR:
+	  if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+	    {
+	      tree type = TREE_TYPE (*expr_p);
+	      *expr_p = fold_convert (type, gimple_boolify (*expr_p));
+	      ret = GS_OK;
+	      break;
+	    }
+	  /* Call it to make sure that operands are boolified, too. */
+	  *expr_p = gimple_boolify (*expr_p);
+	  switch (TREE_CODE (*expr_p))
+	    {
+	    case TRUTH_AND_EXPR:
+	      TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
+	      break;
+	    case TRUTH_OR_EXPR:
+	      TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
+	      break;
+	    case TRUTH_XOR_EXPR:
+	      TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
+	      break;
+	    default:
+	      break;
+	    }
+
 	  /* Classified as tcc_expression.  */
 	  goto expr_2;