OSDN Git Service

2005-05-18 Richard Guenther <rguenth@gcc.gnu.org>
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 May 2005 17:23:30 +0000 (17:23 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 May 2005 17:23:30 +0000 (17:23 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100267 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/gimplify.c
gcc/tree-inline.c

index 557ed56..c1dafb0 100644 (file)
@@ -1,3 +1,16 @@
+2005-05-27  Richard Guenther  <rguenth@gcc.gnu.org>
+
+       * tree-inline.c (copy_body_r): Manually fold *& to deal
+       with ADDR_EXPRs with mismatched types for now.
+
+       * gimplify.c (fold_indirect_ref_rhs): New function.
+       (gimplify_modify_expr_rhs): Use it instead of pessimistic
+       fold_indirect_ref.
+
+       * 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.
+
 2005-05-27  Kazu Hirata  <kazu@cs.umass.edu>
 
        PR tree-optimization/21658
index 0d5f4eb..9880327 100644 (file)
@@ -11451,14 +11451,14 @@ build_fold_addr_expr (tree t)
   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.  */
+/* 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 t)
+fold_indirect_ref_1 (tree type, tree op0)
 {
-  tree type = TREE_TYPE (TREE_TYPE (t));
-  tree sub = t;
+  tree sub = op0;
   tree subtype;
 
   STRIP_NOPS (sub);
@@ -11471,11 +11471,11 @@ fold_indirect_ref_1 (tree t)
       tree op = TREE_OPERAND (sub, 0);
       tree optype = TREE_TYPE (op);
       /* *&p => p */
-      if (lang_hooks.types_compatible_p (type, optype))
+      if (type == optype)
        return op;
       /* *(foo *)&fooarray => fooarray[0] */
       else if (TREE_CODE (optype) == ARRAY_TYPE
-              && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
+              && type == TREE_TYPE (optype))
        {
          tree type_domain = TYPE_DOMAIN (optype);
          tree min_val = size_zero_node;
@@ -11487,7 +11487,7 @@ fold_indirect_ref_1 (tree t)
 
   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
   if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
-      && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
+      && type == TREE_TYPE (TREE_TYPE (subtype)))
     {
       tree type_domain;
       tree min_val = size_zero_node;
@@ -11507,12 +11507,13 @@ fold_indirect_ref_1 (tree t)
 tree
 build_fold_indirect_ref (tree t)
 {
-  tree sub = fold_indirect_ref_1 (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, TREE_TYPE (TREE_TYPE (t)), t);
+    return build1 (INDIRECT_REF, type, t);
 }
 
 /* Given an INDIRECT_REF T, return either T or a simplified version.  */
@@ -11520,7 +11521,7 @@ build_fold_indirect_ref (tree t)
 tree
 fold_indirect_ref (tree t)
 {
-  tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
+  tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));
 
   if (sub)
     return sub;
index 9452973..657d531 100644 (file)
@@ -2846,6 +2846,62 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
     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.  */
 
@@ -2869,8 +2925,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
             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)
+         tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
+         if (t)
            {
              *from_p = t;
              ret = GS_OK;
index 118f493..c04fe33 100644 (file)
@@ -613,7 +613,17 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
          n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
          if (n)
            {
-             *tp = build_fold_indirect_ref ((tree)n->value);
+             /* 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;
            }