OSDN Git Service

* ira-build.c (ira_create_object): New arg SUBWORD; all callers changed.
[pf3gnuchains/gcc-fork.git] / gcc / tree-nested.c
index fb95088..81ae38f 100644 (file)
@@ -1,5 +1,5 @@
 /* Nested function decomposition for GIMPLE.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -23,7 +23,6 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "rtl.h"
 #include "tm_p.h"
 #include "function.h"
 #include "tree-dump.h"
 #include "tree-iterator.h"
 #include "tree-flow.h"
 #include "cgraph.h"
-#include "expr.h"
+#include "expr.h"      /* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL.  */
 #include "langhooks.h"
 #include "pointer-set.h"
-#include "ggc.h"
 
 
 /* The object of this pass is to lower the representation of a set of nested
@@ -86,6 +84,7 @@ struct nesting_info
 
   struct pointer_map_t *field_map;
   struct pointer_map_t *var_map;
+  struct pointer_set_t *mem_refs;
   bitmap suppress_expansion;
 
   tree context;
@@ -149,7 +148,7 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
 
   tmp_var = create_tmp_var_raw (type, prefix);
   DECL_CONTEXT (tmp_var) = info->context;
-  TREE_CHAIN (tmp_var) = info->new_local_var_chain;
+  DECL_CHAIN (tmp_var) = info->new_local_var_chain;
   DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
   if (TREE_CODE (type) == COMPLEX_TYPE
       || TREE_CODE (type) == VECTOR_TYPE)
@@ -199,11 +198,11 @@ insert_field_into_struct (tree type, tree field)
 
   DECL_CONTEXT (field) = type;
 
-  for (p = &TYPE_FIELDS (type); *p ; p = &TREE_CHAIN (*p))
+  for (p = &TYPE_FIELDS (type); *p ; p = &DECL_CHAIN (*p))
     if (DECL_ALIGN (field) >= DECL_ALIGN (*p))
       break;
 
-  TREE_CHAIN (field) = *p;
+  DECL_CHAIN (field) = *p;
   *p = field;
 
   /* Set correct alignment for frame struct type.  */
@@ -699,7 +698,7 @@ check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl)
 
   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
     {
-      for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg))
+      for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = DECL_CHAIN (arg))
        if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl))
          return true;
 
@@ -719,6 +718,7 @@ create_nesting_tree (struct cgraph_node *cgn)
   struct nesting_info *info = XCNEW (struct nesting_info);
   info->field_map = pointer_map_create ();
   info->var_map = pointer_map_create ();
+  info->mem_refs = pointer_set_create ();
   info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
   info->context = cgn->decl;
 
@@ -760,7 +760,7 @@ get_static_chain (struct nesting_info *info, tree target_context,
        {
          tree field = get_chain_field (i);
 
-         x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+         x = build_simple_mem_ref (x);
          x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
          x = init_tmp_var (info, x, gsi);
        }
@@ -795,12 +795,12 @@ get_frame_field (struct nesting_info *info, tree target_context,
        {
          tree field = get_chain_field (i);
 
-         x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+         x = build_simple_mem_ref (x);
          x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
          x = init_tmp_var (info, x, gsi);
        }
 
-      x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+      x = build_simple_mem_ref (x);
     }
 
   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
@@ -843,16 +843,16 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
       for (i = info->outer; i->context != target_context; i = i->outer)
        {
          field = get_chain_field (i);
-         x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+         x = build_simple_mem_ref (x);
          x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
        }
-      x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+      x = build_simple_mem_ref (x);
     }
 
   field = lookup_field_for_decl (i, decl, INSERT);
   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
   if (use_pointer_in_frame (decl))
-    x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+    x = build_simple_mem_ref (x);
 
   /* ??? We should be remapping types as well, surely.  */
   new_decl = build_decl (DECL_SOURCE_LOCATION (decl),
@@ -875,7 +875,7 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
   DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
 
   *slot = new_decl;
-  TREE_CHAIN (new_decl) = info->debug_var_chain;
+  DECL_CHAIN (new_decl) = info->debug_var_chain;
   info->debug_var_chain = new_decl;
 
   if (!optimize
@@ -929,7 +929,7 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
              if (use_pointer_in_frame (t))
                {
                  x = init_tmp_var (info, x, &wi->gsi);
-                 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+                 x = build_simple_mem_ref (x);
                }
            }
 
@@ -1088,7 +1088,8 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
            {
              bitmap_set_bit (new_suppress, DECL_UID (decl));
              OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl);
-             need_chain = true;
+             if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE)
+               need_chain = true;
            }
          break;
 
@@ -1201,7 +1202,7 @@ note_nonlocal_block_vlas (struct nesting_info *info, tree block)
 {
   tree var;
 
-  for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
+  for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
     if (TREE_CODE (var) == VAR_DECL
        && variably_modified_type_p (TREE_TYPE (var), NULL)
        && DECL_HAS_VALUE_EXPR_P (var)
@@ -1366,7 +1367,7 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
   DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
   *slot = new_decl;
 
-  TREE_CHAIN (new_decl) = info->debug_var_chain;
+  DECL_CHAIN (new_decl) = info->debug_var_chain;
   info->debug_var_chain = new_decl;
 
   /* Do not emit debug info twice.  */
@@ -1499,6 +1500,21 @@ convert_local_reference_op (tree *tp, int *walk_subtrees, void *data)
       wi->val_only = save_val_only;
       break;
 
+    case MEM_REF:
+      save_val_only = wi->val_only;
+      wi->val_only = true;
+      wi->is_lhs = false;
+      walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op,
+                wi, NULL);
+      /* We need to re-fold the MEM_REF as component references as
+        part of a ADDR_EXPR address are not allowed.  But we cannot
+        fold here, as the chain record type is not yet finalized.  */
+      if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
+         && !DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
+       pointer_set_insert (info->mem_refs, tp);
+      wi->val_only = save_val_only;
+      break;
+
     case VIEW_CONVERT_EXPR:
       /* Just request to look at the subtrees, leaving val_only and lhs
         untouched.  This might actually be for !val_only + lhs, in which
@@ -2180,7 +2196,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
        subblock = BLOCK_CHAIN (subblock))
     remap_vla_decls (subblock, root);
 
-  for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
+  for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
     {
       if (TREE_CODE (var) == VAR_DECL
          && variably_modified_type_p (TREE_TYPE (var), NULL)
@@ -2201,7 +2217,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
   id.cb.decl_map = pointer_map_create ();
   id.root = root;
 
-  for (; var; var = TREE_CHAIN (var))
+  for (; var; var = DECL_CHAIN (var))
     if (TREE_CODE (var) == VAR_DECL
        && variably_modified_type_p (TREE_TYPE (var), NULL)
        && DECL_HAS_VALUE_EXPR_P (var))
@@ -2248,6 +2264,15 @@ remap_vla_decls (tree block, struct nesting_info *root)
   pointer_map_destroy (id.cb.decl_map);
 }
 
+/* Fold the MEM_REF *E.  */
+static bool
+fold_mem_refs (const void *e, void *data ATTRIBUTE_UNUSED)
+{
+  tree *ref_p = CONST_CAST2(tree *, const tree *, (const tree *)e);
+  *ref_p = fold (*ref_p);
+  return true;
+}
+
 /* Do "everything else" to clean up or complete state collected by the
    various walking passes -- lay out the types and decls, generate code
    to initialize the frame decl, store critical expressions in the
@@ -2283,11 +2308,11 @@ finalize_nesting_tree_1 (struct nesting_info *root)
         expression get substituted in instantiate_virtual_regs().  */
       for (adjust = &root->new_local_var_chain;
           *adjust != root->frame_decl;
-          adjust = &TREE_CHAIN (*adjust))
-       gcc_assert (TREE_CHAIN (*adjust));
-      *adjust = TREE_CHAIN (*adjust);
+          adjust = &DECL_CHAIN (*adjust))
+       gcc_assert (DECL_CHAIN (*adjust));
+      *adjust = DECL_CHAIN (*adjust);
 
-      TREE_CHAIN (root->frame_decl) = NULL_TREE;
+      DECL_CHAIN (root->frame_decl) = NULL_TREE;
       declare_vars (root->frame_decl,
                    gimple_seq_first_stmt (gimple_body (context)), true);
     }
@@ -2298,7 +2323,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
   if (root->any_parm_remapped)
     {
       tree p;
-      for (p = DECL_ARGUMENTS (context); p ; p = TREE_CHAIN (p))
+      for (p = DECL_ARGUMENTS (context); p ; p = DECL_CHAIN (p))
        {
          tree field, x, y;
 
@@ -2403,7 +2428,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
       remap_vla_decls (DECL_INITIAL (root->context), root);
 
       for (debug_var = root->debug_var_chain; debug_var;
-          debug_var = TREE_CHAIN (debug_var))
+          debug_var = DECL_CHAIN (debug_var))
        if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
          break;
 
@@ -2418,7 +2443,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
          id.cb.decl_map = pointer_map_create ();
          id.root = root;
 
-         for (; debug_var; debug_var = TREE_CHAIN (debug_var))
+         for (; debug_var; debug_var = DECL_CHAIN (debug_var))
            if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
              {
                tree type = TREE_TYPE (debug_var);
@@ -2462,6 +2487,9 @@ finalize_nesting_tree_1 (struct nesting_info *root)
                     root->debug_var_chain);
     }
 
+  /* Fold the rewritten MEM_REF trees.  */
+  pointer_set_traverse (root->mem_refs, fold_mem_refs, NULL);
+
   /* Dump the translated tree function.  */
   if (dump_file)
     {
@@ -2515,6 +2543,7 @@ free_nesting_tree (struct nesting_info *root)
       next = iter_nestinfo_next (node);
       pointer_map_destroy (node->var_map);
       pointer_map_destroy (node->field_map);
+      pointer_set_destroy (node->mem_refs);
       free (node);
       node = next;
     }