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
This commit is contained in:
Jan Hubicka 2014-06-29 01:22:56 +02:00 committed by Jan Hubicka
parent 16a4b3b9b2
commit 8910466afb
2 changed files with 74 additions and 23 deletions

View 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

View 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;
}