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 type correctness of fold_indirect_ref and fallout


This series of patches fixes type correctness of fold_indirect_ref
and build_fold_indirect_ref and the missed-optimization / ICE fallout
resulting from it.  The tree-inline.c part was approved by rth
separately, the fold_indirect_ref change was considered ok by Roger
on IRC if regressions were addressed.

This patch series passed bootstrap and regtesting on
x86_64-unknown-linux-gnu for all languages but ada with a tree
containing the cfg-inliner and Jeffs forward-prop change
(top of ChangeLog is
 2005-05-18  Geoffrey Keating  <geoffk@apple.com>

	* dummy-checksum.c: New.
	* genchecksum.c: New.
) - I believe it will not cause any problems noticed by the testsuite.

Ok for mainline?

Thanks,
Richard.


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

	* tree-inline.c (copy_body_r): Manually fold *& to deal
	with ADDR_EXPRs with mismatched types for now.

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.

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

	* fold-const.c (fold_indirect_ref_1): Add type argument;
	make sure the resulting expression is of this type.
	(build_fold_indirect_ref, fold_indirect_ref): Adjust callers.


Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.581
diff -c -3 -p -r1.581 fold-const.c
*** fold-const.c	17 May 2005 09:55:20 -0000	1.581
--- fold-const.c	19 May 2005 08:58:41 -0000
*************** build_fold_addr_expr (tree t)
*** 11448,11461 ****
    return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
  }

! /* Given a pointer value T, return a simplified version of an indirection
!    through T, or NULL_TREE if no simplification is possible.  */

  static tree
! fold_indirect_ref_1 (tree t)
  {
!   tree type = TREE_TYPE (TREE_TYPE (t));
!   tree sub = t;
    tree subtype;

    STRIP_NOPS (sub);
--- 11448,11461 ----
    return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
  }

! /* Given a pointer value OP0 and a type TYPE, return a simplified version
!    of an indirection through OP0, or NULL_TREE if no simplification is
!    possible.  */

  static tree
! fold_indirect_ref_1 (tree type, tree op0)
  {
!   tree sub = op0;
    tree subtype;

    STRIP_NOPS (sub);
*************** fold_indirect_ref_1 (tree t)
*** 11468,11478 ****
        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;
--- 11468,11478 ----
        tree op = TREE_OPERAND (sub, 0);
        tree optype = TREE_TYPE (op);
        /* *&p => p */
!       if (type == optype)
  	return op;
        /* *(foo *)&fooarray => fooarray[0] */
        else if (TREE_CODE (optype) == ARRAY_TYPE
! 	       && type == TREE_TYPE (optype))
  	{
  	  tree type_domain = TYPE_DOMAIN (optype);
  	  tree min_val = size_zero_node;
*************** fold_indirect_ref_1 (tree t)
*** 11484,11490 ****

    /* *(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;
--- 11484,11490 ----

    /* *(foo *)fooarrptr => (*fooarrptr)[0] */
    if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
!       && type == TREE_TYPE (TREE_TYPE (subtype)))
      {
        tree type_domain;
        tree min_val = size_zero_node;
*************** fold_indirect_ref_1 (tree t)
*** 11504,11515 ****
  tree
  build_fold_indirect_ref (tree t)
  {
!   tree sub = fold_indirect_ref_1 (t);

    if (sub)
      return sub;
    else
!     return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
  }

  /* Given an INDIRECT_REF T, return either T or a simplified version.  */
--- 11504,11516 ----
  tree
  build_fold_indirect_ref (tree t)
  {
!   tree type = TREE_TYPE (TREE_TYPE (t));
!   tree sub = fold_indirect_ref_1 (type, t);

    if (sub)
      return sub;
    else
!     return build1 (INDIRECT_REF, type, t);
  }

  /* Given an INDIRECT_REF T, return either T or a simplified version.  */
*************** build_fold_indirect_ref (tree t)
*** 11517,11523 ****
  tree
  fold_indirect_ref (tree t)
  {
!   tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));

    if (sub)
      return sub;
--- 11518,11524 ----
  tree
  fold_indirect_ref (tree t)
  {
!   tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));

    if (sub)
      return sub;
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	19 May 2005 09:07:42 -0000
*************** gimplify_init_constructor (tree *expr_p,
*** 2846,2851 ****
--- 2846,2907 ----
      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.
+    Note that the resulting type may be different from the type pointed
+    to in the sense that it is still compatible from the langhooks
+    point of view. */
+
+ 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;
--- 2925,2932 ----
  	     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;
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.185
diff -c -3 -p -r1.185 tree-inline.c
*** tree-inline.c	17 May 2005 16:56:27 -0000	1.185
--- tree-inline.c	19 May 2005 08:58:43 -0000
*************** copy_body_r (tree *tp, int *walk_subtree
*** 613,619 ****
  	  n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
  	  if (n)
  	    {
! 	      *tp = build_fold_indirect_ref ((tree)n->value);
  	      *walk_subtrees = 0;
  	      return NULL;
  	    }
--- 613,629 ----
  	  n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
  	  if (n)
  	    {
! 	      /* If we happen to get an ADDR_EXPR in n->value, strip
! 	         it manually here as we'll eventually get ADDR_EXPRs
! 		 which lie about their types pointed to.  In this case
! 		 build_fold_indirect_ref wouldn't strip the INDIRECT_REF,
! 		 but we absolutely rely on that.  */
! 	      if (TREE_CODE ((tree)n->value) == ADDR_EXPR)
! 		*tp = TREE_OPERAND ((tree)n->value, 0);
! 	      else
! 	        *tp = build1 (INDIRECT_REF,
! 			      TREE_TYPE (TREE_TYPE ((tree)n->value)),
! 			      (tree)n->value);
  	      *walk_subtrees = 0;
  	      return NULL;
  	    }


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