]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-inline.c (remap_type_1): Do not duplicate fields that are shared in between...
authorJan Hubicka <hubicka@ucw.cz>
Sat, 28 Jun 2014 23:22:56 +0000 (01:22 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 28 Jun 2014 23:22:56 +0000 (23:22 +0000)
* tree-inline.c (remap_type_1): Do not duplicate fields
that are shared in between type and its main variant.

From-SVN: r212111

gcc/ChangeLog
gcc/tree-inline.c

index 75b2816cb4672ab586438a1434098737cf627cec..b6f82408ff01110de08fbe3f48295085c715b587 100644 (file)
@@ -1,3 +1,8 @@
+2014-06-28  Jan Hubicka  <hubicka@ucw.cz>
+
+       * tree-inline.c (remap_type_1): Do not duplicate fields
+       that are shared in between type and its main variant.
+
 2014-06-28  Jan Hubicka  <hubicka@ucw.cz>
 
        * ipa-prop.c (ipa_set_jf_known_type): Record always the main variant
index f07c1a85d743918af3aef2a11032e6069cb16a6d..20e2aced25710fd917238e05d1343ba8f610cc1a 100644 (file)
@@ -451,6 +451,8 @@ remap_type_1 (tree type, copy_body_data *id)
   TYPE_POINTER_TO (new_tree) = NULL;
   TYPE_REFERENCE_TO (new_tree) = NULL;
 
+  /* Copy all types that may contain references to local variables; be sure to
+     preserve sharing in between type and its main variant when possible.  */
   switch (TREE_CODE (new_tree))
     {
     case INTEGER_TYPE:
@@ -458,40 +460,72 @@ remap_type_1 (tree type, copy_body_data *id)
     case FIXED_POINT_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
-      t = TYPE_MIN_VALUE (new_tree);
-      if (t && TREE_CODE (t) != INTEGER_CST)
-        walk_tree (&TYPE_MIN_VALUE (new_tree), copy_tree_body_r, id, NULL);
+      if (TYPE_MAIN_VARIANT (new_tree) != new_tree)
+       {
+         gcc_checking_assert (TYPE_MIN_VALUE (type) == TYPE_MIN_VALUE (TYPE_MAIN_VARIANT (type)));
+         gcc_checking_assert (TYPE_MAX_VALUE (type) == TYPE_MAX_VALUE (TYPE_MAIN_VARIANT (type)));
 
-      t = TYPE_MAX_VALUE (new_tree);
-      if (t && TREE_CODE (t) != INTEGER_CST)
-        walk_tree (&TYPE_MAX_VALUE (new_tree), copy_tree_body_r, id, NULL);
+         TYPE_MIN_VALUE (new_tree) = TYPE_MIN_VALUE (TYPE_MAIN_VARIANT (new_tree));
+         TYPE_MAX_VALUE (new_tree) = TYPE_MAX_VALUE (TYPE_MAIN_VARIANT (new_tree));
+       }
+      else
+       {
+         t = TYPE_MIN_VALUE (new_tree);
+         if (t && TREE_CODE (t) != INTEGER_CST)
+           walk_tree (&TYPE_MIN_VALUE (new_tree), copy_tree_body_r, id, NULL);
+
+         t = TYPE_MAX_VALUE (new_tree);
+         if (t && TREE_CODE (t) != INTEGER_CST)
+           walk_tree (&TYPE_MAX_VALUE (new_tree), copy_tree_body_r, id, NULL);
+       }
       return new_tree;
 
     case FUNCTION_TYPE:
-      TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id);
-      walk_tree (&TYPE_ARG_TYPES (new_tree), copy_tree_body_r, id, NULL);
+      if (TYPE_MAIN_VARIANT (new_tree) != new_tree
+         && TREE_TYPE (type) == TREE_TYPE (TYPE_MAIN_VARIANT (type)))
+       TREE_TYPE (new_tree) = TREE_TYPE (TYPE_MAIN_VARIANT (new_tree));
+      else
+        TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id);
+      if (TYPE_MAIN_VARIANT (new_tree) != new_tree
+         && TYPE_ARG_TYPES (type) == TYPE_ARG_TYPES (TYPE_MAIN_VARIANT (type)))
+       TYPE_ARG_TYPES (new_tree) = TYPE_ARG_TYPES (TYPE_MAIN_VARIANT (new_tree));
+      else
+        walk_tree (&TYPE_ARG_TYPES (new_tree), copy_tree_body_r, id, NULL);
       return new_tree;
 
     case ARRAY_TYPE:
-      TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id);
-      TYPE_DOMAIN (new_tree) = remap_type (TYPE_DOMAIN (new_tree), id);
+      if (TYPE_MAIN_VARIANT (new_tree) != new_tree
+         && TREE_TYPE (type) == TREE_TYPE (TYPE_MAIN_VARIANT (type)))
+       TREE_TYPE (new_tree) = TREE_TYPE (TYPE_MAIN_VARIANT (new_tree));
+
+      if (TYPE_MAIN_VARIANT (new_tree) != new_tree)
+       {
+         gcc_checking_assert (TYPE_DOMAIN (type) == TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)));
+         TYPE_DOMAIN (new_tree) = TYPE_DOMAIN (TYPE_MAIN_VARIANT (new_tree));
+       }
+      else
+       TYPE_DOMAIN (new_tree) = remap_type (TYPE_DOMAIN (new_tree), id);
       break;
 
     case RECORD_TYPE:
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
-      {
-       tree f, nf = NULL;
+      if (TYPE_MAIN_VARIANT (type) != type
+         && TYPE_FIELDS (type) == TYPE_FIELDS (TYPE_MAIN_VARIANT (type)))
+       TYPE_FIELDS (new_tree) = TYPE_FIELDS (TYPE_MAIN_VARIANT (new_tree));
+      else
+       {
+         tree f, nf = NULL;
 
-       for (f = TYPE_FIELDS (new_tree); f ; f = DECL_CHAIN (f))
-         {
-           t = remap_decl (f, id);
-           DECL_CONTEXT (t) = new_tree;
-           DECL_CHAIN (t) = nf;
-           nf = t;
-         }
-       TYPE_FIELDS (new_tree) = nreverse (nf);
-      }
+         for (f = TYPE_FIELDS (new_tree); f ; f = DECL_CHAIN (f))
+           {
+             t = remap_decl (f, id);
+             DECL_CONTEXT (t) = new_tree;
+             DECL_CHAIN (t) = nf;
+             nf = t;
+           }
+         TYPE_FIELDS (new_tree) = nreverse (nf);
+       }
       break;
 
     case OFFSET_TYPE:
@@ -500,8 +534,20 @@ remap_type_1 (tree type, copy_body_data *id)
       gcc_unreachable ();
     }
 
-  walk_tree (&TYPE_SIZE (new_tree), copy_tree_body_r, id, NULL);
-  walk_tree (&TYPE_SIZE_UNIT (new_tree), copy_tree_body_r, id, NULL);
+  /* All variants of type share the same size, so use the already remaped data.  */
+  if (TYPE_MAIN_VARIANT (new_tree) != new_tree)
+    {
+      gcc_checking_assert (TYPE_SIZE (type) == TYPE_SIZE (TYPE_MAIN_VARIANT (type)));
+      gcc_checking_assert (TYPE_SIZE_UNIT (type) == TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type)));
+
+      TYPE_SIZE (new_tree) = TYPE_SIZE (TYPE_MAIN_VARIANT (new_tree));
+      TYPE_SIZE_UNIT (new_tree) = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (new_tree));
+    }
+  else
+    {
+      walk_tree (&TYPE_SIZE (new_tree), copy_tree_body_r, id, NULL);
+      walk_tree (&TYPE_SIZE_UNIT (new_tree), copy_tree_body_r, id, NULL);
+    }
 
   return new_tree;
 }