[PATCH] Use special routine for folding rhs in gimplifier

Richard Guenther rguenth@tat.physik.uni-tuebingen.de
Tue May 17 11:59:00 GMT 2005


This introduces a 1-to-1 copy of (current) fold-const.c:fold_indirect_ref
to gimplify.c as fold_indirect_ref_rhs and uses that in
gimplify_modify_expr_rhs to retain optimizations valid only if we know
we're dealing with a rhs and necessary for optimizing temp1.C.

This allows fold-const.c:fold_indirect_ref which is used elsewhere on
lhs, too, be fixed wrt type correctness without introducing optimization
regressions.  See
http://gcc.gnu.org/ml/gcc-patches/2005-05/msg01441.html
for this patch.

Bootstrapped on x86_64-unknown-linux-gnu and tested on
i686-unknown-linux-gnu and x86_64-unknown-linux-gnu without
regressions for C/C++.

Ok for mainline?  Ok for the fold-const fix after this?

Thanks,
Richard.


2005-05-17  Richard Guenther  <rguenth@gcc.gnu.org>

	* gimplify.c (fold_indirect_ref_rhs): New function.
	(gimplify_modify_expr_rhs): Use it instead of pessimistic
	fold_indirect_ref.


Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.126
diff -c -3 -p -r2.126 gimplify.c
*** gimplify.c	1 May 2005 23:23:33 -0000	2.126
--- gimplify.c	17 May 2005 11:20:10 -0000
*************** gimplify_init_constructor (tree *expr_p,
*** 2846,2851 ****
--- 2846,2905 ----
      return GS_ALL_DONE;
  }

+ /* Given a pointer value OP0, return a simplified version of an
+    indirection through OP0, or NULL_TREE if no simplification is
+    possible.  This may only be applied to a rhs of an expression
+    that does not care about the resulting type of the simplification.  */
+
+ static tree
+ fold_indirect_ref_rhs (tree t)
+ {
+   tree type = TREE_TYPE (TREE_TYPE (t));
+   tree sub = t;
+   tree subtype;
+
+   STRIP_NOPS (sub);
+   subtype = TREE_TYPE (sub);
+   if (!POINTER_TYPE_P (subtype))
+     return NULL_TREE;
+
+   if (TREE_CODE (sub) == ADDR_EXPR)
+     {
+       tree op = TREE_OPERAND (sub, 0);
+       tree optype = TREE_TYPE (op);
+       /* *&p => p */
+       if (lang_hooks.types_compatible_p (type, optype))
+         return op;
+       /* *(foo *)&fooarray => fooarray[0] */
+       else if (TREE_CODE (optype) == ARRAY_TYPE
+ 	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
+        {
+          tree type_domain = TYPE_DOMAIN (optype);
+          tree min_val = size_zero_node;
+          if (type_domain && TYPE_MIN_VALUE (type_domain))
+            min_val = TYPE_MIN_VALUE (type_domain);
+          return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
+        }
+     }
+
+   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
+   if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
+       && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
+     {
+       tree type_domain;
+       tree min_val = size_zero_node;
+       sub = fold_indirect_ref_rhs (sub);
+       if (! sub)
+ 	sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), sub);
+       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
+       if (type_domain && TYPE_MIN_VALUE (type_domain))
+         min_val = TYPE_MIN_VALUE (type_domain);
+       return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
+     }
+
+   return NULL_TREE;
+ }
+
  /* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
     based on the code of the RHS.  We loop for as long as something changes.  */

*************** gimplify_modify_expr_rhs (tree *expr_p,
*** 2869,2876 ****
  	     This kind of code arises in C++ when an object is bound
  	     to a const reference, and if "x" is a TARGET_EXPR we want
  	     to take advantage of the optimization below.  */
! 	  tree t = fold_indirect_ref (*from_p);
! 	  if (t != *from_p)
  	    {
  	      *from_p = t;
  	      ret = GS_OK;
--- 2923,2930 ----
  	     This kind of code arises in C++ when an object is bound
  	     to a const reference, and if "x" is a TARGET_EXPR we want
  	     to take advantage of the optimization below.  */
! 	  tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
! 	  if (t)
  	    {
  	      *from_p = t;
  	      ret = GS_OK;




More information about the Gcc-patches mailing list