OSDN Git Service

2004-12-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Dec 2004 18:51:24 +0000 (18:51 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Dec 2004 18:51:24 +0000 (18:51 +0000)
        * trans.c (mark_visited): Set TYPE_SIZES_GIMPLIFIED.

2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

        * tree.h (TYPE_SIZES_GIMPLIFIED): New.
        * function.c (gimplify_parm_type): Don't gimplify type if already done.
        * gimplify.c (gimplify_decl_expr): Likewise.
        (gimplify_type_sizes): Set TYPE_SIZES_GIMPLIFIED.  Examine nested
        array types.

2004-12-22  Richard Henderson  <rth@redhat.com>

        * gimplify.c (eval_save_expr): Remove.
        (gimplify_one_sizepos): Unshare expr before gimplifying.
        * stor-layout.c (variable_size): Revert 2004-12-19 change.
        (layout_decl): Revert 2004-12-18 change.
        (layout_type): Revert 2004-12-21 change.

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

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/trans.c
gcc/function.c
gcc/gimplify.c
gcc/stor-layout.c
gcc/tree.h

index 9d04f8b..b2e063b 100644 (file)
@@ -1,5 +1,21 @@
 2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * tree.h (TYPE_SIZES_GIMPLIFIED): New.
+       * function.c (gimplify_parm_type): Don't gimplify type if already done.
+       * gimplify.c (gimplify_decl_expr): Likewise.
+       (gimplify_type_sizes): Set TYPE_SIZES_GIMPLIFIED.  Examine nested
+       array types.
+       
+2004-12-22  Richard Henderson  <rth@redhat.com>
+
+       * gimplify.c (eval_save_expr): Remove.
+       (gimplify_one_sizepos): Unshare expr before gimplifying.
+       * stor-layout.c (variable_size): Revert 2004-12-19 change.
+       (layout_decl): Revert 2004-12-18 change.
+       (layout_type): Revert 2004-12-21 change.
+
+2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
        * tree-sra.c (type_can_be_decomposed_p): Reject variable sized types.
 
 2004-12-22  Mark Mitchell  <mark@codesourcery.com>
index 1676f35..479443a 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * trans.c (mark_visited): Set TYPE_SIZES_GIMPLIFIED.
+
 2004-12-19  Richard Henderson  <rth@redhat.com>
 
        * trans.c (gigi): Update gimplify_body call.
index e3d5f47..0db1709 100644 (file)
@@ -4283,9 +4283,10 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
     }
 }
 
-/* Utility function to mark nodes with TREE_VISITED.  Called from walk_tree.
-   We use this to indicate all variable sizes and positions in global types
-   may not be shared by any subprogram.  */
+/* Utility function to mark nodes with TREE_VISITED and types as having their
+   sized gimplified.  Called from walk_tree.  We use this to indicate all
+   variable sizes and positions in global types may not be shared by any
+   subprogram.  */
 
 static tree
 mark_visited (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
@@ -4298,6 +4299,9 @@ mark_visited (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
   else if (!TYPE_IS_DUMMY_P (*tp))
     TREE_VISITED (*tp) = 1;
 
+  if (TYPE_P (*tp))
+    TYPE_SIZES_GIMPLIFIED (*tp) = 1;
+
   return NULL_TREE;
 }
 
index a7dc223..4f1af4f 100644 (file)
@@ -3172,7 +3172,8 @@ gimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
     {
       if (POINTER_TYPE_P (t))
        *walk_subtrees = 1;
-      else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t)))
+      else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t))
+              && !TYPE_SIZES_GIMPLIFIED (t))
        {
          gimplify_type_sizes (t, (tree *) data);
          *walk_subtrees = 1;
index c92d9a5..2434a81 100644 (file)
@@ -996,7 +996,12 @@ gimplify_decl_expr (tree *stmt_p)
             of the emitted code: see mx_register_decls().  */
          tree t, args, addr, ptr_type;
 
-         gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+         /* ??? We really shouldn't need to gimplify the type of the variable
+            since it already should have been done.  But leave this here
+            for now to avoid disrupting too many things at once.  */
+         if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
+           gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+
          gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
          gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
 
@@ -4180,7 +4185,17 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 void
 gimplify_type_sizes (tree type, tree *list_p)
 {
-  tree field;
+  tree field, t;
+
+  /* Note that we do not check for TYPE_SIZES_GIMPLIFIED already set because
+     that's not supposed to happen on types where gimplifcation does anything.
+     We should assert that it isn't set, but we can indeed be called multiple
+     times on pointers.  Unfortunately, this includes fat pointers which we
+     can't easily test for.  We could pass TYPE down to gimplify_one_sizepos
+     and test there, but it doesn't seem worth it.  */
+
+  /* We first do the main variant, then copy into any other variants. */
+  type = TYPE_MAIN_VARIANT (type);
 
   switch (TREE_CODE (type))
     {
@@ -4194,11 +4209,22 @@ gimplify_type_sizes (tree type, tree *list_p)
     case REAL_TYPE:
       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
+
+      for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+       {
+         TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
+         TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
+         TYPE_SIZES_GIMPLIFIED (t) = 1;
+       }
       break;
 
     case ARRAY_TYPE:
-      /* These anonymous types don't have declarations, so handle them here.  */
-      gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
+      /* These types may not have declarations, so handle them here.  */
+      if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (type)))
+       gimplify_type_sizes (TREE_TYPE (type), list_p);
+
+      if (!TYPE_SIZES_GIMPLIFIED (TYPE_DOMAIN (type)))
+         gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
       break;
 
     case RECORD_TYPE:
@@ -4215,23 +4241,15 @@ gimplify_type_sizes (tree type, tree *list_p)
 
   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
-}
 
-/* A subroutine of gimplify_one_sizepos, called via walk_tree.  Evaluate
-   the expression if it's a SAVE_EXPR and add it to the statement list 
-   in DATA.  */
-
-static tree
-eval_save_expr (tree *tp, int *walk_subtrees, void *data)
-{
-  if (TREE_CODE (*tp) == SAVE_EXPR)
+  for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     {
-      *walk_subtrees = 0;
-      gimplify_and_add (*tp, (tree *) data);
+      TYPE_SIZE (t) = TYPE_SIZE (type);
+      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
+      TYPE_SIZES_GIMPLIFIED (t) = 1;
     }
-  else if (TYPE_P (*tp) || DECL_P (*tp))
-    *walk_subtrees = 0;
-  return NULL;
+
+  TYPE_SIZES_GIMPLIFIED (type) = 1;
 }
 
 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
@@ -4251,7 +4269,8 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
       || CONTAINS_PLACEHOLDER_P (*expr_p))
     return;
 
-  walk_tree (expr_p, eval_save_expr, stmt_p, NULL);
+  *expr_p = unshare_expr (*expr_p);
+  gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
 }
 \f
 #ifdef ENABLE_CHECKING
index 13fdb3c..ac7fb74 100644 (file)
@@ -125,19 +125,11 @@ variable_size (tree size)
      just return SIZE unchanged.  Likewise for self-referential sizes and
      constant sizes.  */
   if (TREE_CONSTANT (size)
-      || TREE_CODE (size) == SAVE_EXPR
       || lang_hooks.decls.global_bindings_p () < 0
       || CONTAINS_PLACEHOLDER_P (size))
     return size;
 
-  /* Force creation of a SAVE_EXPR.  This solves (1) code duplication 
-     problems between parent and nested functions that occasionally can't
-     be cleaned up because of portions of the expression escaping the
-     parent function via the FRAME object, and (2) tree sharing problems
-     between the type system and the gimple code, which can leak SSA_NAME
-     objects into e.g. TYPE_SIZE, which cause heartburn when emitting
-     debug information.  */
-  size = build1 (SAVE_EXPR, TREE_TYPE (size), size);
+  size = save_expr (size);
 
   /* If an array with a variable number of elements is declared, and
      the elements require destruction, we will emit a cleanup for the
@@ -333,8 +325,8 @@ layout_decl (tree decl, unsigned int known_align)
 
   if (DECL_SIZE (decl) == 0)
     {
-      DECL_SIZE (decl) = unshare_expr (TYPE_SIZE (type));
-      DECL_SIZE_UNIT (decl) = unshare_expr (TYPE_SIZE_UNIT (type));
+      DECL_SIZE (decl) = TYPE_SIZE (type);
+      DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
     }
   else if (DECL_SIZE_UNIT (decl) == 0)
     DECL_SIZE_UNIT (decl)
@@ -1644,8 +1636,8 @@ layout_type (tree type)
        if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
            && TYPE_SIZE (element))
          {
-           tree ub = unshare_expr (TYPE_MAX_VALUE (index));
-           tree lb = unshare_expr (TYPE_MIN_VALUE (index));
+           tree ub = TYPE_MAX_VALUE (index);
+           tree lb = TYPE_MIN_VALUE (index);
            tree length;
            tree element_size;
 
index f70683c..76424a5 100644 (file)
@@ -368,6 +368,8 @@ struct tree_common GTY(())
            all expressions
           all decls
           all constants
+       TYPE_SIZES_GIMPLIFIED
+           ..._TYPE
 
    unsigned_flag:
 
@@ -934,6 +936,9 @@ extern void tree_operand_check_failed (int, enum tree_code,
    also appear in an expression or decl where the value is constant.  */
 #define TREE_CONSTANT(NODE) (NON_TYPE_CHECK (NODE)->common.constant_flag)
 
+/* Nonzero if NODE, a type, has had its sizes gimplified.  */
+#define TYPE_SIZES_GIMPLIFIED(NODE) (TYPE_CHECK (NODE)->common.constant_flag)
+
 /* In a decl (most significantly a FIELD_DECL), means an unsigned field.  */
 #define DECL_UNSIGNED(NODE) (DECL_CHECK (NODE)->common.unsigned_flag)