> On Sun, Jun 29, 2014 at 12:44 AM, Jan Hubicka <hubi...@ucw.cz> wrote: > > Hi, > > this patch fixes another problem where we manage to produce a variant of > > variadic array that has different TYPE_SIZE (but an equivalent expression). > > This happens because remap_type_1 blindly copies all expressions referred by > > variadic type while for variants it may just reuse ones it earlier copied > > when > > producing a copy of the main variant. > > > > Bootstrapped/regtested x86_64-linux, lto-bootstrapped and tested on Firefox > > build with the main variant checking patch in, comitted. > > Note that we do have variant types which do _not_ share the fields list > of the main variant (see PR61456). Not sure if your patches fix that. > But if they didn't yet the following patch silently re-write those types.
We still have these. I know of Fotran and C++ Fe producing those. The patch makes fields shared only if they was shared before. Honza > > Richard. > > > Honza > > > > * tree-inline.c (remap_type_1): Do not duplicate fields > > that are shared in between type and its main variant. > > Index: tree-inline.c > > =================================================================== > > --- tree-inline.c (revision 212098) > > +++ tree-inline.c (working copy) > > @@ -451,6 +451,8 @@ remap_type_1 (tree type, copy_body_data > > 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 > > 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); > > - > > - 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); > > + 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))); > > + > > + 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; > > - > > - 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); > > - } > > + 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); > > + } > > break; > > > > case OFFSET_TYPE: > > @@ -500,8 +534,20 @@ remap_type_1 (tree type, copy_body_data > > 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; > > }