This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix 14844/15459/21608: Forward-propagate casts that willcollapse


Hi!

This implements forward propagation of NOP and CONVERT_EXPRs of
the form

  T1 x;
  T2 y.1 = (T2)x;
  T1 y.2 = (T1)y.1;

to remove the (unnecessary) casts and transform the above to

  T1 x;
  T1 y.2 = x;

This transformation is applied under the conservative conditions it
it applied in fold_unary.

This solves many optimization PRs (some partly) and is similar to
some code on autovect branch that there is twiddled into the old
forwprop engine.  It is especially useful to avoid endless casting
between int and bool due to type promotion rules with C/C++ and
inlining (see PR21608).

Bootstrapped and regtested on x86_64-unknown-linux-gnu.

Ok for mainline after slush?

Thanks,
Richard.
2005-05-23  Richard Guenther  <rguenth@gcc.gnu.org>

	PR tree-optimization/14844
	PR tree-optimization/15459
	PR tree-optimization/21608
	* tree-ssa-forwprop.c (forward_propagate_nop_expr):
	Propagate NOP_EXPRs so they possibly collapse with each other.


Index: tree-ssa-forwprop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-forwprop.c,v
retrieving revision 2.19
diff -c -3 -p -r2.19 tree-ssa-forwprop.c
*** tree-ssa-forwprop.c	19 May 2005 03:05:40 -0000	2.19
--- tree-ssa-forwprop.c	23 May 2005 15:25:43 -0000
*************** forward_propagate_addr_expr (tree stmt)
*** 673,678 ****
--- 675,734 ----
    return false;
  }
  
+ /* STMT is a statement of the form SSA_NAME = NOP_EXPR <whatever>.
+ 
+    Try to forward propagate the NOP_EXPR into the uses of the SSA_NAME
+    if that results in the collapse of two casts.  This will especially
+    help languages with weird promotion rules for bool, like C and C++.  */
+ 
+ static bool
+ forward_propagate_nop_expr (tree stmt)
+ {
+   tree name = TREE_OPERAND (stmt, 0);
+   use_operand_p imm_use;
+   tree use_stmt, rhs, nop;
+ 
+   /* We require that the SSA_NAME holding the result of the NOP_EXPR
+      be used only once.  That may be overly conservative in that we
+      could propagate into multiple uses.  However, that would effectively
+      be un-cseing the NOP_EXPR, which is probably not what we want.  */
+   single_imm_use (name, &imm_use, &use_stmt);
+   if (!use_stmt)
+     return false;
+ 
+   /* If the use is not in a simple assignment statement, then
+      there is nothing we can do.  */
+   if (TREE_CODE (use_stmt) != MODIFY_EXPR)
+     return false;
+ 
+   /* Get at both cast operations.  */
+   rhs = TREE_OPERAND (use_stmt, 1);
+   nop = TREE_OPERAND (stmt, 1);
+ 
+   /* We only can propagate the NOP_EXPR if it collapses together
+      with another NOP_EXPR or CONVERT_EXPR.  For now only do it
+      if they cancel each other.  */
+   if ((TREE_CODE (rhs) != NOP_EXPR
+        && TREE_CODE (rhs) != CONVERT_EXPR)
+       || TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
+          != TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (nop, 0))))
+     return false;
+ 
+   /* Be careful to not collapse NOPs which change values.  */
+   if (! ((INTEGRAL_TYPE_P (TREE_TYPE (nop))
+ 	  && INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
+ 	 || (FLOAT_TYPE_P (TREE_TYPE (nop))
+ 	     && FLOAT_TYPE_P (TREE_TYPE (rhs))))
+       || TYPE_PRECISION (TREE_TYPE (nop)) < TYPE_PRECISION (TREE_TYPE (rhs)))
+     return false;
+ 
+   TREE_OPERAND (use_stmt, 1) = unshare_expr (TREE_OPERAND (nop, 0));
+   update_stmt (use_stmt);
+ 
+   return true;
+ }
+ 
+ 
  /* Main entry point for the forward propagation optimizer.  */
  
  static void
*************** tree_ssa_forward_propagate_single_use_va
*** 702,707 ****
--- 758,775 ----
  	      else
  		bsi_next (&bsi);
  	    }
+ 	  /* If this statement is a conversion, try to propagate it
+ 	     into uses of the SSA_NAME resulting in cast collapse.  */
+ 	  else if (TREE_CODE (stmt) == MODIFY_EXPR
+ 		   && (TREE_CODE (TREE_OPERAND (stmt, 1)) == NOP_EXPR
+ 		       || TREE_CODE (TREE_OPERAND (stmt, 1)) == CONVERT_EXPR)
+ 		   && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
+ 	    {
+ 	      if (forward_propagate_nop_expr (stmt))
+ 		bsi_remove (&bsi);
+ 	      else
+ 		bsi_next (&bsi);
+ 	    }
  	  else if (TREE_CODE (stmt) == COND_EXPR)
  	    {
  	      forward_propagate_into_cond (stmt);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]