re-apply fold_indirect_ref patch
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Feb 2005 16:07:16 +0000 (16:07 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Feb 2005 16:07:16 +0000 (16:07 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95024 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 2657a00..50289f2 100644 (file)
@@ -63,7 +63,6 @@
 2005-02-13  Jason Merrill  <jason@redhat.com>
 
        [reverted temporarily]
-
        PR mudflap/19319
        * gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return
        slot explicit.
index ae4b7e5..03285ec 100644 (file)
@@ -11214,17 +11214,21 @@ build_fold_addr_expr (tree t)
   return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
 }
 
-/* Builds an expression for an indirection through T, simplifying some
-   cases.  */
+/* Given a pointer value T, return a simplified version of an indirection
+   through T, or NULL_TREE if no simplification is possible.  */
 
-tree
-build_fold_indirect_ref (tree t)
+static tree
+fold_indirect_ref_1 (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);
@@ -11239,7 +11243,6 @@ build_fold_indirect_ref (tree t)
     }
 
   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
-  subtype = TREE_TYPE (sub);
   if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
       && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
     {
@@ -11247,7 +11250,34 @@ build_fold_indirect_ref (tree t)
       return build4 (ARRAY_REF, type, sub, size_zero_node, NULL_TREE, NULL_TREE);
     }
 
-  return build1 (INDIRECT_REF, type, t);
+  return NULL_TREE;
+}
+
+/* Builds an expression for an indirection through T, simplifying some
+   cases.  */
+
+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.  */
+
+tree
+fold_indirect_ref (tree t)
+{
+  tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
+
+  if (sub)
+    return sub;
+  else
+    return t;
 }
 
 /* Strip non-trapping, non-side-effecting tree nodes from an expression
index 0fd3943..d461d77 100644 (file)
@@ -1433,8 +1433,15 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
   VARRAY_GENERIC_PTR_NOGC_INIT (stack, 10, "stack");
 
   /* We can handle anything that get_inner_reference can deal with.  */
-  for (p = expr_p; handled_component_p (*p); p = &TREE_OPERAND (*p, 0))
-    VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
+  for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
+    {
+      /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
+      if (TREE_CODE (*p) == INDIRECT_REF)
+       *p = fold_indirect_ref (*p);
+      if (!handled_component_p (*p))
+       break;
+      VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
+    }
 
   gcc_assert (VARRAY_ACTIVE_SIZE (stack));
 
@@ -2845,16 +2852,10 @@ 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 pointer;
-
-         pointer = TREE_OPERAND (*from_p, 0);
-         STRIP_NOPS (pointer);
-         if (TREE_CODE (pointer) == ADDR_EXPR
-             && (lang_hooks.types_compatible_p 
-                 (TREE_TYPE (TREE_OPERAND (pointer, 0)),
-                  TREE_TYPE (*from_p))))
+         tree t = fold_indirect_ref (*from_p);
+         if (t != *from_p)
            {
-             *from_p = TREE_OPERAND (pointer, 0); 
+             *from_p = t;
              ret = GS_OK;
            }
          else
@@ -3544,7 +3545,7 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
          ret = GS_OK;
           if (TREE_CODE (init) == BIND_EXPR)
            gimplify_bind_expr (&init, temp, pre_p);
-          if (init != temp)
+         if (init != temp)
            {
              init = build (MODIFY_EXPR, void_type_node, temp, init);
              ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
@@ -3795,9 +3796,13 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          recalculate_side_effects (*expr_p);
          break;
 
+       case INDIRECT_REF:
+         *expr_p = fold_indirect_ref (*expr_p);
+         if (*expr_p != save_expr)
+           break;
+         /* else fall through.  */
        case ALIGN_INDIRECT_REF:
        case MISALIGNED_INDIRECT_REF:
-       case INDIRECT_REF:
          ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
                               is_gimple_reg, fb_rvalue);
          recalculate_side_effects (*expr_p);
index dea3136..62e9bb3 100644 (file)
@@ -3546,6 +3546,7 @@ extern tree fold_build_cleanup_point_expr (tree type, tree expr);
 extern tree fold_strip_sign_ops (tree);
 extern tree build_fold_addr_expr_with_type (tree, tree);
 extern tree build_fold_indirect_ref (tree);
+extern tree fold_indirect_ref (tree);
 extern tree constant_boolean_node (int, tree);
 extern tree build_low_bits_mask (tree, unsigned);