tree-inline.c (initialize_inlined_parameters): Pass proper function context to gimpli...
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Sat, 3 Jul 2004 14:48:14 +0000 (14:48 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Sat, 3 Jul 2004 14:48:14 +0000 (10:48 -0400)
* tree-inline.c (initialize_inlined_parameters): Pass proper function
context to gimplify_body.
(walk_tree): Don't walk into types twice.
(walk_tree, case POINTER_TYPE): Deal with mutually recursive pointers.

From-SVN: r84058

gcc/ChangeLog
gcc/tree-inline.c

index 50cc747ec22588b86ed4470cf87cb4b88a72bedf..7080815c770556801c5c0e47b7d57140d056a596 100644 (file)
@@ -1,5 +1,10 @@
 2004-07-03  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * tree-inline.c (initialize_inlined_parameters): Pass proper function
+       context to gimplify_body.
+       (walk_tree): Don't walk into types twice.
+       (walk_tree, case POINTER_TYPE): Deal with mutually recursive pointers.
+
        * tree-sra.c (generate_element_init): Remove any useless conversions.
        
        * gimplify.c (gimplify_conversion): Remove stripping useless
index d2d0fd4bab8dd546622d8dde5b7723b9ea4e2f3d..15fb9282e72fd302fb859d01ced09e7327989cc1 100644 (file)
@@ -863,7 +863,7 @@ initialize_inlined_parameters (inline_data *id, tree args, tree static_chain,
     }
 
   if (gimplify_init_stmts_p && lang_hooks.gimple_before_inlining)
-    gimplify_body (&init_stmts, fn);
+    gimplify_body (&init_stmts, current_function_decl);
 
   declare_inline_vars (bind_expr, vars);
   return init_stmts;
@@ -2038,19 +2038,19 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
       tree decl = DECL_EXPR_DECL (*tp);
       tree type = TREE_TYPE (decl);
 
-      /* Walk into fields of the DECL if it's not a type, then into fields
-        of the type in both cases.  */
-
-      if (TREE_CODE (decl) != TYPE_DECL
-         && TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != PARM_DECL)
+      /* Walk into fields of the DECL if it's not a type.  */
+      if (TREE_CODE (decl) != TYPE_DECL)
        {
-         WALK_SUBTREE (DECL_INITIAL (decl));
+         if (TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != PARM_DECL)
+           WALK_SUBTREE (DECL_INITIAL (decl));
+
          WALK_SUBTREE (DECL_SIZE (decl));
-         WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+         WALK_SUBTREE_TAIL (DECL_SIZE_UNIT (decl));
        }
 
-      /* First do the common fields via recursion, then the fields we only
-        do when we are declaring the type or object.  */
+      /* Otherwise, we are declaring a type.  First do the common fields via
+        recursion, then the fields we only do when we are declaring the type
+        or object.  */
       WALK_SUBTREE (type);
       WALK_SUBTREE (TYPE_SIZE (type));
       WALK_SUBTREE (TYPE_SIZE_UNIT (type));
@@ -2198,6 +2198,28 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
 
        case POINTER_TYPE:
        case REFERENCE_TYPE:
+         /* We have to worry about mutually recursive pointers.  These can't
+            be written in C.  They can in Ada.  It's pathlogical, but
+            there's an ACATS test (c38102a) that checks it.  Deal with this
+            by checking if we're pointing to another pointer, that one
+            points to another pointer, that one does too, and we have no htab.
+            If so, get a hash table.  We check three levels deep to avoid
+            the cost of the hash table if we don't need one.  */
+         if (POINTER_TYPE_P (TREE_TYPE (*tp))
+             && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*tp)))
+             && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (*tp))))
+             && !htab)
+           {
+             result = walk_tree_without_duplicates (&TREE_TYPE (*tp),
+                                                    func, data);
+             if (result)
+               return result;
+
+             break;
+           }
+
+         /* ... fall through ... */
+
        case COMPLEX_TYPE:
          WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
          break;