aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-06-29 01:22:56 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-06-28 23:22:56 +0000
commit8910466afbc2208117531c016b79fd864a04ac66 (patch)
treed2ae7a51e46a7e6db69c7b0aea502f87c78e41ab /gcc/tree-inline.c
parent16a4b3b9b2e06c99a827f237a7e51243e0a510db (diff)
downloadgcc-8910466afbc2208117531c016b79fd864a04ac66.zip
gcc-8910466afbc2208117531c016b79fd864a04ac66.tar.gz
gcc-8910466afbc2208117531c016b79fd864a04ac66.tar.bz2
tree-inline.c (remap_type_1): Do not duplicate fields that are shared in between type and its main variant.
* tree-inline.c (remap_type_1): Do not duplicate fields that are shared in between type and its main variant. From-SVN: r212111
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c92
1 files changed, 69 insertions, 23 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index f07c1a8..20e2ace 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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;
}