OSDN Git Service

* a29k/unix.h (ASM_FILE_START): Const-ify.
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index da3f93a..a4f483a 100644 (file)
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "varray.h"
 #include "hashtab.h"
 #include "splay-tree.h"
+#include "langhooks.h"
 
 /* This should be eventually be generalized to other languages, but
    this would require a shared function-as-trees infrastructure.  */
@@ -147,8 +148,6 @@ remap_decl (decl, id)
       /* The decl T could be a dynamic array or other variable size type,
         in which case some fields need to be remapped because they may
         contain SAVE_EXPRs.  */
-      walk_tree (&DECL_SIZE (t), copy_body_r, id, NULL);
-      walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
       if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
          && TYPE_DOMAIN (TREE_TYPE (t)))
        {
@@ -164,7 +163,7 @@ remap_decl (decl, id)
        {
          /* For a VAR_DECL of anonymous type, we must also copy the
             member VAR_DECLS here and rechain the
-            DECL_ANON_UNION_ELEMS. */
+            DECL_ANON_UNION_ELEMS.  */
          tree members = NULL;
          tree src;
          
@@ -667,8 +666,12 @@ inlinable_function_p (fn, id)
   if (! flag_inline_trees)
     ;
   /* If we're not inlining all functions and the function was not
-     declared `inline', we don't inline it.  */
-  else if (flag_inline_trees < 2 && ! DECL_INLINE (fn))
+     declared `inline', we don't inline it.  Don't think of
+     disregarding DECL_INLINE when flag_inline_trees == 2; it's the
+     front-end that must set DECL_INLINE in this case, because
+     dwarf2out loses if a function is inlined that doesn't have
+     DECL_INLINE set.  */
+  else if (! DECL_INLINE (fn))
     ;
   /* We can't inline functions that are too big.  Only allow a single
      function to eat up half of our budget.  Make special allowance
@@ -1084,6 +1087,15 @@ walk_tree (tp, func, data, htab_)
     }                                                  \
   while (0)
 
+#define WALK_SUBTREE_TAIL(NODE)                                \
+  do                                                   \
+    {                                                  \
+       tp = & (NODE);                                  \
+       goto tail_recurse;                              \
+    }                                                  \
+  while (0)
+
+ tail_recurse:
   /* Skip empty subtrees.  */
   if (!*tp)
     return NULL_TREE;
@@ -1093,10 +1105,10 @@ walk_tree (tp, func, data, htab_)
       void **slot;
       
       /* Don't walk the same tree twice, if the user has requested
-         that we avoid doing so. */
+         that we avoid doing so.  */
       if (htab_find (htab, *tp))
        return NULL_TREE;
-      /* If we haven't already seen this node, add it to the table. */
+      /* If we haven't already seen this node, add it to the table.  */
       slot = htab_find_slot (htab, *tp, INSERT);
       *slot = *tp;
     }
@@ -1118,7 +1130,7 @@ walk_tree (tp, func, data, htab_)
       if (statement_code_p (code) || code == TREE_LIST
          || (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
        /* But we still need to check our siblings.  */
-       return walk_tree (&TREE_CHAIN (*tp), func, data, htab);
+       WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
       else
        return NULL_TREE;
     }
@@ -1166,7 +1178,7 @@ walk_tree (tp, func, data, htab_)
            }
 
          /* This can be tail-recursion optimized if we write it this way.  */
-         return walk_tree (&TREE_CHAIN (*tp), func, data, htab);
+         WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
        }
 
       /* We didn't find what we were looking for.  */
@@ -1174,10 +1186,7 @@ walk_tree (tp, func, data, htab_)
     }
   else if (TREE_CODE_CLASS (code) == 'd')
     {
-      WALK_SUBTREE (TREE_TYPE (*tp));
-
-      /* We didn't find what we were looking for.  */
-      return NULL_TREE;
+      WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
     }
 
   result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
@@ -1209,30 +1218,35 @@ walk_tree (tp, func, data, htab_)
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
-      WALK_SUBTREE (TREE_TYPE (*tp));
+      WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
       break;
 
     case TREE_LIST:
       WALK_SUBTREE (TREE_VALUE (*tp));
-      WALK_SUBTREE (TREE_CHAIN (*tp));
+      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
       break;
 
     case TREE_VEC:
       {
        int len = TREE_VEC_LENGTH (*tp);
-       while (len--)
+
+       if (len == 0)
+         break;
+
+       /* Walk all elements but the first.  */
+       while (--len)
          WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
+
+       /* Now walk the first one as a tail call.  */
+       WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
       }
-      break;
 
     case COMPLEX_CST:
       WALK_SUBTREE (TREE_REALPART (*tp));
-      WALK_SUBTREE (TREE_IMAGPART (*tp));
-      break;
+      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
 
     case CONSTRUCTOR:
-      WALK_SUBTREE (CONSTRUCTOR_ELTS (*tp));
-      break;
+      WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
 
     case METHOD_TYPE:
       WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
@@ -1251,18 +1265,15 @@ walk_tree (tp, func, data, htab_)
 
     case ARRAY_TYPE:
       WALK_SUBTREE (TREE_TYPE (*tp));
-      WALK_SUBTREE (TYPE_DOMAIN (*tp));
-      break;
+      WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
 
     case INTEGER_TYPE:
       WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
-      WALK_SUBTREE (TYPE_MAX_VALUE (*tp));
-      break;
+      WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
 
     case OFFSET_TYPE:
       WALK_SUBTREE (TREE_TYPE (*tp));
-      WALK_SUBTREE (TYPE_OFFSET_BASETYPE (*tp));
-      break;
+      WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
 
     default:
       abort ();
@@ -1369,6 +1380,9 @@ remap_save_expr (tp, st_, fn, walk_subtrees)
       n = splay_tree_insert (st,
                             (splay_tree_key) *tp,
                             (splay_tree_value) t);
+      /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
+      splay_tree_insert (st, (splay_tree_key) t,
+                        (splay_tree_value) error_mark_node);
     }
   else
     /* We've already walked into this SAVE_EXPR, so we needn't do it